UIModalPresentationStyle.CurrentContext Swift iOS 7
Asked Answered
C

2

12

I want to show a View - PresentedView over another view - Background View using iOS 7. In my app, I am using UITabBArController, so at runtime I don't know which view would be the background view (could be any of the tab bar items). Below is the structure:

UITabBarController
  ---> TabItem1 - FirstUIViewController
  ---> TabItem2 - SecondUIViewController
  ---> TabItem3 - ThirdUIViewController

Need something Like this:

enter image description here

When app loads, I am on TabItem1 - FirstUIViewController. When I click on TabItem3, I want ThirdUIViewController to appear on Top on FirstUIViewController and 'FirstUIViewController' should appear in background with no user interaction enabled.

What I did so far:

  1. Since, UIViewControllers are added as Relationship Controllers to appear as TabBar Item in `UITabBarController, I added a segue from tabbarcontroller to ThridViewController.

  2. Changed PresentationStyle for this Segue to UIModalPresentationStyle.CurrentContext and did below modification

    func `viewDidLoad()` {
        super.viewDidLoad()
        self.performSegue("identifier", sender: self)
    }
    

Nothing happens and I just see 'ThridViewController' with white background

  1. I tried manual coding approach:

    func `viewDidLoad()` {
        super.viewDidLoad()
        let overlayController:UIThirdViewController = UIThirdViewController() //This controller has a view added on top of it, which covers top half screen only
        overlayController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
        self.presentViewController(overlayController, animated: true, completion: nil)
    }
    

No change. New view overrides the previos view. if I add this overlayController.view.backgroundColor = UIColor.clearColor(), I see half screen black and half containing my new view

Problem Points:

  1. Where should I write the code to initialize/call ThirdViewController to appear on top of current view?
  2. How to fix the black screen issue and make it work on iOS 7?

I am using Xcode 7 and running on iOS7. Please help. Working code snippet will be appreciated. Don't post other stack overflow posts as answer, unless code works & you have tried on your own.

UPDATE: - With this approach, I get a black screen

class TabBarViewController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {

        let switchController:UIViewController = SwitchViewController()

        self.presentingViewController?.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
        self.presentingViewController?.view.backgroundColor = UIColor.clearColor()
        self.presentViewController(switchController, animated: true, completion: nil)
        return false
    }
}
Colous answered 2/9, 2015 at 5:33 Comment(0)
K
3

Make it a Custom Container View Controller (Apple Docs). Working example code:

class MyTabVC: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
        presentThirdVC()
        return false
    }

    func presentThirdVC() {
        let myThirdVC = MyThirdVC.makeVC()

        myThirdVC.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.1)
        addChildViewController(myThirdVC)
        var newFrame = CGRectInset(view.bounds, 0, 50) // hack, do what you want
        myThirdVC.view.frame = newFrame
        view.addSubview(myThirdVC.view)
        didMoveToParentViewController(myThirdVC)
    }

}

class MyThirdVC: UIViewController {
    class func makeVC() -> MyThirdVC {
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myThirdVC") as! MyThirdVC
    }
}

Screenshot:

enter image description here

Kalindi answered 10/9, 2015 at 7:37 Comment(1)
Yes, I believe these APIs have been around since iOS 5, by looking at the version support for addChildViewController.Kalindi
A
4

You should subclass UITabBarController and add it the behaviour into the custom subclass. Set the UITabBarController delegate as self and then when the specific index is tapped instead of letting it switch tabs you modally present the menu. The UITabBarControllerDelegate methods will give you the chance to do that.

Specifcally using this delegate method....

- tabBarController:shouldSelectViewController:

You can present the menu when this is called for which ever tab and return NO. Just you a blank viewController for this tab since it will never get shown to the user.

For the transition itself I highly recommend using a subclass of UIPresentationController to set the container views frame to be a bit smaller than the size of the screen, and add in a "dimmingView". This is only available on iOS8 though so if you want iOS7 you will need to do more hackish things.

Averir answered 5/9, 2015 at 5:46 Comment(1)
Please check my UPDATE in descriptionColous
K
3

Make it a Custom Container View Controller (Apple Docs). Working example code:

class MyTabVC: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
        presentThirdVC()
        return false
    }

    func presentThirdVC() {
        let myThirdVC = MyThirdVC.makeVC()

        myThirdVC.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.1)
        addChildViewController(myThirdVC)
        var newFrame = CGRectInset(view.bounds, 0, 50) // hack, do what you want
        myThirdVC.view.frame = newFrame
        view.addSubview(myThirdVC.view)
        didMoveToParentViewController(myThirdVC)
    }

}

class MyThirdVC: UIViewController {
    class func makeVC() -> MyThirdVC {
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myThirdVC") as! MyThirdVC
    }
}

Screenshot:

enter image description here

Kalindi answered 10/9, 2015 at 7:37 Comment(1)
Yes, I believe these APIs have been around since iOS 5, by looking at the version support for addChildViewController.Kalindi

© 2022 - 2024 — McMap. All rights reserved.