2016-06-21 5 views
0

Я использую UISplitViewController с preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay, и я искал способ отклонить главный контроллер вида. Мой мастер содержит табличное представление, и я хотел бы закрыть его всякий раз, когда я выбираю ячейку. Удивительно, что UISplitViewController, похоже, не предлагает метода для этого (но я вижу, что Apple Mail делает то, что вы выбираете электронное письмо в портретном режиме).Странный основной серый обведенный вид, пытающийся программно запустить мастер UISplitViewController

Я нашел следующее обходное решение, описанное здесь: Hiding the master view controller with UISplitViewController in iOS8 (посмотрите на ответ фатмана). Это работает, но также создает странную анимацию, когда она увольняется, есть основное серое выделенное представление, которое не анимируется вместе с представлением моего хозяина. Проблема также возникла здесь: iOS Swift 2 UISplitViewController opens detail screen on master's place when on iPad/ iPhone 6+

Проблема возникает только тогда, когда я отклоняю мастер с помощью этого обходного пути, а не когда я нажимаю на вторичный, поэтому я думаю, что UISplitViewController не следует регулярному потоку отклонения, когда вы просто вызываете sendAction на кнопка.

ответ

1

Я использовал следующий код для решения этой проблемы. Возможно, лучший способ сопоставить конкретное представление, вызывающее проблему. Тем не менее, этот код был в приложении, одобренном 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!!!") 
     }) 
    } 
} 
Смежные вопросы