Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIModalPresentationStyle.CurrentContext Swift iOS 7

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
    }
}
like image 409
Sategroup Avatar asked Sep 02 '15 05:09

Sategroup


2 Answers

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.

like image 85
DBoyer Avatar answered Sep 28 '22 06:09

DBoyer


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

like image 36
bobics Avatar answered Sep 28 '22 04:09

bobics