2016-06-21 12 views
0

我使用UISplitViewControllerpreferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay,我正在寻找一种方法来关闭主视图控制器。我的主人包含一个表格视图,我想在选择一个单元格时关闭它。令人惊讶的是,UISplitViewController似乎没有提供一种方法(但我确实看到Apple Mail在做,我们选择了纵向模式下的电子邮件)。奇怪的底层灰色概述视图试图通过编程解雇UISplitViewController的主人

我在此处发现了以下解决方法: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+

只有当我解雇这个解决方法的主人,而不是当我点击辅助,所以我猜UISplitViewController是不是跟随常规解雇流时,你只需调用sendAction按钮。

回答

1

我用下面的代码来解决这个问题。可能有更好的方法来匹配导致问题的具体视图。也就是说,这段代码是在今年4月份被Apple批准的应用程序中。代码所做的是查找特定类型的特定视图,如果找到,则隐藏它直到动画完成。它有点未来的证明,因为如果它没有检测到特殊的观点,它什么也不做。我还为采用者添加了一些关于您想要进行更改的评论。

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!!!") 
     }) 
    } 
}