我使用UISplitViewController
与preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay
,我正在寻找一种方法来解雇主视图控制器。我的主人包含一个表视图,每当我选择一个单元格时我都想关闭它。令人惊讶的是,UISplitViewController似乎没有为此提供方法(但我确实看到Apple Mail这样做,我们在纵向模式下选择了一个电子邮件)。
我在此处发现了以下解决方法:Hiding the master view controller with UISplitViewController in iOS8(请参阅phatmann答案)。这有效,但它也会在它被解散时创建一个奇怪的动画,有一个基本的灰色轮廓视图,它不会与我的主视图一起动画。这里也报告了这个问题:iOS Swift 2 UISplitViewController opens detail screen on master's place when on iPad/ iPhone 6+
只有在我使用此解决方法解雇master时才会出现问题,而不是当我点击辅助设备时,我猜UISplitViewController在按钮上调用sendAction时不会遵循常规解除流程。
答案 0 :(得分:1)
我使用以下代码来解决此问题。可能有更好的方法来匹配导致问题的特定视图。也就是说,这段代码是在Apple今年4月批准的应用程序中。代码所做的是查找特定类型的特定视图,如果找到,则会使其隐藏,直到动画完成。它有点未来的证明,因为如果它没有检测到特殊视图,它什么都不做。我还为采用者添加了一些关于您可能想要进行更改的评论。
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!!!")
} )
}
}