2014-12-02 88 views
36

我有一個基於Xcode主/從模板的iOS7應用程序,我將它移植到iOS8。一個變化很大的領域是UISplitViewController在iOS8中使用UISplitViewController隱藏主視圖控制器

當在縱向模式下,如果用戶輕擊細節視圖控制器上,主視圖控制器被駁回:

enter image description here

我還希望能夠以編程隱藏如果主視圖控制器用戶點擊一行。

在iOS系統7中,主視圖控制器被顯示爲酥料餅,並且可以隱藏如下:

[self.masterPopoverController dismissPopoverAnimated:YES]; 

與iOS 8,主不再是酥料餅,因此上述技術不管用。

我試圖解僱主視圖控制器:

self.dismissViewControllerAnimated(true, completion: nil) 

或者告訴拆分視圖控制器可顯示詳細信息視圖控制器:

self.splitViewController?.showDetailViewController(bookViewController!, sender: self) 

但沒有什麼至今工作。有任何想法嗎?

+0

可以請你接受下面的答案嗎? – phatmann 2015-01-14 15:08:50

回答

54

擴展UISplitViewController如下:

extension UISplitViewController { 
    func toggleMasterView() { 
     let barButtonItem = self.displayModeButtonItem() 
     UIApplication.sharedApplication().sendAction(barButtonItem.action, to: barButtonItem.target, from: nil, forEvent: nil) 
    } 
} 

didSelectRowAtIndexPathprepareForSegue,執行以下操作:

self.splitViewController?.toggleMasterView() 

這將主視圖平滑地滑動的方式進行。

我得到了從this post使用displayModeButtonItem()的想法,並且我正在模擬點擊它,每this post

我對這個解決方案並不滿意,因爲它看起來像一個黑客。但它運作良好,似乎沒有其他選擇。

+0

不錯的解決方案。我剛剛測試過它,它按預期工作,在iPad肖像模式下動畫製作彈出窗口。唯一的一個副作用就是在iPhone 6+橫向模式(而不是iPad)上隱藏主視圖 - 另一種iPhone 6+既不是手機也不是平板電腦的歡快方式! – pjh68 2015-01-11 21:35:09

+1

我最終實現了iPhone 6 Plus的設備專用旁路 - 請參閱http://stackoverflow.com/questions/25780283/ios-how-to-detect-iphone-6-plus-iphone-6-iphone-5-by - 宏檢測這種簡單的方法。 – pjh68 2015-01-11 21:45:50

+1

嘿非常好的答案,它的作品,但我有另一個問題。它也動畫細節視圖控制器的變化。這也發生在你身上嗎?謝謝 – Sanandrea 2015-02-20 21:08:55

9

使用preferredDisplayMode。在didSelectRowAtIndexPathprepareForSegue

self.splitViewController?.preferredDisplayMode = .PrimaryHidden 
self.splitViewController?.preferredDisplayMode = .Automatic 

不幸的是,主視圖突然消失,而不是滑開,儘管文件指出:

如果更改此屬性的值導致的實際變化在 當前顯示模式下,分屏視圖控制器會動畫產生更改的 。

希望有一個更好的方法來做到這一點,實際上是動畫變化。

+0

這根本不起作用。在選擇了一行後,主視圖會保留在屏幕上,並且不會在橫向模式下並排顯示。 – phatmann 2014-12-10 09:42:26

+0

@phatmann它的工作,我想在我的didSelectRowAtIndexPath方法添加以下代碼: - (空)的tableView:(UITableView的*)的tableView didSelectRowAtIndexPath方法:(NSIndexPath *)indexPath { self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden; } – 2014-12-10 10:12:28

+1

如果我把上面的代碼放在'prepareForSegue'中,主視圖確實消失了。之後我還必須調用'preferredDisplayMode = .Automatic',這樣橫向操作纔是正確的。問題在於主視圖不能平滑滑落,使得這種技術不夠理想。另一方面,沒有人提供了更好的答案,所以謝謝! – phatmann 2014-12-10 10:34:10

8

我能夠在Xcode 6中獲得所需的行爲。3主從應用程序(通用)項目MasterViewController- prepareForSegue:sender:方法添加以下代碼:

if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { 
    let animations:() -> Void = { 
     self.splitViewController?.preferredDisplayMode = .PrimaryHidden 
    } 
    let completion: Bool -> Void = { _ in 
     self.splitViewController?.preferredDisplayMode = .Automatic 
    } 
    UIView.animateWithDuration(0.3, animations: animations, completion: completion) 
} 

完整- prepareForSegue:sender:實施應該是這樣的:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showDetail" { 
     if let indexPath = self.tableView.indexPathForSelectedRow() { 
      let object = objects[indexPath.row] as! NSDate 
      let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController 
      controller.detailItem = object 
      controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() 
      controller.navigationItem.leftItemsSupplementBackButton = true 

      if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { 
       let animations:() -> Void = { 
        self.splitViewController?.preferredDisplayMode = .PrimaryHidden 
       } 
       let completion: Bool -> Void = { _ in 
        self.splitViewController?.preferredDisplayMode = .Automatic 
       } 
       UIView.animateWithDuration(0.3, animations: animations, completion: completion) 
      } 
     } 
    } 
} 

使用traitCollection也在某些項目中成爲displayMode的替代/補充。例如,下面的代碼也適用於一個的Xcode 6.3主詳細應用(通用)項目

let traits = view.traitCollection 
if traits.userInterfaceIdiom == .Pad && traits.horizontalSizeClass == .Regular { 
    let animations:() -> Void = { 
     self.splitViewController?.preferredDisplayMode = .PrimaryHidden 
    } 
    let completion: Bool -> Void = { _ in 
     self.splitViewController?.preferredDisplayMode = .Automatic 
    } 
    UIView.animateWithDuration(0.3, animations: animations, completion: completion) 
} 
+0

卓越的解決方案 – AlexD 2015-07-30 05:43:46

0

我在夫特1.2

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){ 
    var screen = UIScreen.mainScreen().currentMode?.size.height 
    if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) || screen >= 2000 && UIDevice.currentDevice().orientation.isLandscape == true && (UIDevice.currentDevice().userInterfaceIdiom == .Phone){ 
     performSegueWithIdentifier("showDetailParse", sender: nil) 
     self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden 
    } else if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) { 
     performSegueWithIdentifier("showParse", sender: nil) 
    } 
} 
6

溶液下面的代碼隱藏在主視圖與動畫

UIView.animateWithDuration(0.5) {() -> Void in 
      self.splitViewController?.preferredDisplayMode = .PrimaryHidden 
     } 
+0

簡單和工作的iOS 10,斯威夫特3.0 – 2017-03-29 09:11:45

+0

@ jithinroy這工作!我一直堅持這個天感謝! – 2017-06-17 21:27:15

3

只是改善一點點在這裏列出的答案已經在這裏,下面的代碼對我來說工作正常,我t結合處理動畫順利:

extension UISplitViewController { 
    func toggleMasterView() { 
     var nextDisplayMode: UISplitViewControllerDisplayMode 
     switch(self.preferredDisplayMode){ 
     case .PrimaryHidden: 
      nextDisplayMode = .AllVisible 
     default: 
      nextDisplayMode = .PrimaryHidden 
     } 
     UIView.animateWithDuration(0.5) {() -> Void in 
      self.preferredDisplayMode = nextDisplayMode 
     } 
    } 
} 

然後,如前所述,你只需要使用擴展功能在您的視圖控制器的任何地方

self.splitViewController?.toggleMasterView() 
0

爲iPad添加菜單按鈕,這樣

UIBarButtonItem *menuButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"burger_menu"] 
                     style:UIBarButtonItemStylePlain 
                     target:self.splitViewController.displayModeButtonItem.target 
                     action:self.splitViewController.displayModeButtonItem.action]; 
[self.navigationItem setLeftBarButtonItem:menuButtonItem]; 

這項工作與橫向和縱向模式很好。 要以編程方式關閉酥料餅的VC,你只需要迫使這樣

[self.splitViewController.displayModeButtonItem.target performSelector:appDelegate.splitViewController.displayModeButtonItem.action]; 
1

修改上面這個問題的答案的按鈕動作時,所有我需要的是配置的視圖我的詳細視圖控制器的方法:

[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden]; 

當然,它缺乏動畫的優雅。

0

嘗試

let svc = self.splitViewController 
svc.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden
相關問題