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:
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:
Since, UIViewControllers
are added as Relationship Controllers
to appear as TabBar Item
in `UITabBarController, I added a segue from tabbarcontroller to ThridViewController.
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
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:
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
}
}
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With