Hiding the master view controller with UISplitViewController in iOS8

后端 未结 10 970
囚心锁ツ
囚心锁ツ 2020-12-12 19:06

I have an iOS7 application, which was based on the Xcode master-detail template, that I am porting to iOS8. One area that has changed a lot is the UISplitViewControlle

相关标签:
10条回答
  • 2020-12-12 19:48

    Extend the UISplitViewController as follows:

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

    In didSelectRowAtIndexPath or prepareForSegue, do the following:

    self.splitViewController?.toggleMasterView()
    

    This will smoothly slide the master view out of the way.

    I got the idea of using the displayModeButtonItem() from this post and I am simulating a tap on it per this post.

    I am not really happy with this solution, since it seems like a hack. But it works well and there seems to be no alternative yet.

    0 讨论(0)
  • 2020-12-12 19:48

    I was able to have the desired behavior in a Xcode 6.3 Master-Detail Application (universal) project by adding the following code in the MasterViewController's - prepareForSegue:sender: method:

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

    The complete - prepareForSegue:sender: implementation should look like this:

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

    Using traitCollection may also be an alternative/supplement to displayMode in some projects. For example, the following code also works for a Xcode 6.3 Master-Detail Application (universal) project:

    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 讨论(0)
  • 2020-12-12 19:50

    Swift 4 update:

    Insert it into prepare(for segue: ...

    if splitViewController?.displayMode == .primaryOverlay {
        let animations: () -> Void = {
            self.splitViewController?.preferredDisplayMode = .primaryHidden
        }
        let completion: (Bool) -> Void = { _ in
            self.splitViewController?.preferredDisplayMode = .automatic
        }
        UIView.animate(withDuration: 0.3, animations: animations, completion: completion)
    }
    
    0 讨论(0)
  • 2020-12-12 19:55

    Modifying the answers above this is all I needed in a method of my detail view controller that configured the view:

     [self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden];
    

    Of course it lacks the grace of animation.

    0 讨论(0)
提交回复
热议问题