Weird underlying gray outlined view trying to dismiss programmatically the master of UISplitViewController

﹥>﹥吖頭↗ 提交于 2020-01-07 00:35:43

问题


I use a UISplitViewController with preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay and I was looking for a way to dismiss master view controller. My master contains a table view and I'd like to close it whenever I select a cell. Surprisingly UISplitViewController doesn't seem to offer a method for that (but I do see Apple Mail doing that we you select an email in portrait mode).

I found the following workaround reported here: Hiding the master view controller with UISplitViewController in iOS8 (look at phatmann answer). This works but it also creates a weird animation when it's dismissed, there's an underlying gray outlined view which is not animated together with my master's view. The problem has been reported also here: iOS Swift 2 UISplitViewController opens detail screen on master's place when on iPad/ iPhone 6+

The problem occurs only when I dismiss master with this workaround, not when I tap on the secondary so I guess UISplitViewController is not following the regular dismiss flow when you just call sendAction on the button.


回答1:


I used the following code to address this problem. There might be a better way to match on the specific view that is causing the issue. That said, this code was in an app approved by Apple in April of this year. What the code does is look for a specific view of a certain type, and if found, then it makes it hidden until the animation is complete. Its somewhat future proof, since if it does't detect the special view, it does nothing. I also added some comments for adopters on where you might want to make changes.

func closePrimaryIfOpen(finalClosure fc: (() -> Void)? = nil) {
    guard let
        primaryNavController = viewControllers[0] as? MySpecialNavSubclass,
        primaryVC = primaryNavController.topViewController as? MySpecialCalss
    else { fatalError("NO Special Class?") }

    // no "official" way to know if its open or not. 
    // The view could keep track of didAppear and willDisappear, but those are not reliable
    let isOpen = primaryVC.view.frame.origin.x >= -10   // -10 because could be some slight offset when presented
    if isOpen {
        func findChromeViewInView(theView: UIView) -> UIView? {
            var foundChrome = false
            var view: UIView! = theView
            var popView: UIView!

            repeat {
                // Mirror may bring in a lot of overhead, could use NSStringFromClass
                // Also, don't match on the full class name! For sure Apple won't like that!
                //print("View: ", Mirror(reflecting: view).subjectType, " frame: \(view.frame)")
                if Mirror(reflecting: view).description.containsString("Popover") { // _UIPopoverView
                    for v in view.subviews {
                        //print("SV: ", Mirror(reflecting: v).subjectType, " frame: \(v.frame)")
                        if Mirror(reflecting: v).description.containsString("Chrome") {
                            foundChrome = true
                            popView = v
                            //popView.hidden = true
                            break
                        }
                    }
                    if foundChrome { break }
                }
                view = view.superview
            } while view != nil
            return popView
        }

        // Note: leave it as optional - Apple changes things and we don't find the view, things still work!
        let chromeView = findChromeViewInView(self.view)

        UIView.animateWithDuration(0.250, animations: {
            chromeView?.hidden = true
            self.preferredDisplayMode = .PrimaryHidden
        }, completion: { Bool in
            self.preferredDisplayMode = .PrimaryOverlay
            chromeView?.hidden = false
            if let finalClosure = fc {
                finalClosure()
            }
            //print("SLIDER CLOSED DONE!!!")
        } )
    }
}


来源:https://stackoverflow.com/questions/37939151/weird-underlying-gray-outlined-view-trying-to-dismiss-programmatically-the-maste

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!