I have a UITabBarController
with three tabs. When a certain one is pressed, I'd like the user to immediately see a person view controller (an instance of the ABPersonViewController
class).
I don't want to just use the presentViewController()
method with a person view controller as a parameter because this results in a lag, when the user can see the underlying view controller from which it's presented.
I also can't make the view controller inherit from ABPersonViewController
, because it's set by Apple so that it can't be subclassed. Is there a way I can accomplish this?
Thanks to JAL's answer:
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
let navViewController = viewController as! UINavigationController
// First, check to see if the view controller is the one you want to override
if let myViewController = navViewController.viewControllers[0] as? ThirdViewController {
let abpvc = ABPersonViewController()
abpvc.personViewDelegate = self
self.navigationController?.pushViewController(abpvc, animated: true)
return false
}
return true
}
Answer
The essential idea is to subclass UITabBarController and put a UIButton on the tab bar, cover up the original tab area and add an action to that button, which will trigger relevant function calls.
So that the tap event actually never being passed to the tabBarController, but only to the button. So that the user will never "see the underlying view controller".
Sample Code
Sample Swift 1.2 code that add a button to the center of UITabBarController
func AddSampleButton(){
let SampleButton = UIButton()
SampleButton.setTranslatesAutoresizingMaskIntoConstraints(false)
SampleButton.setBackgroundImage(addImage, forState: UIControlState.Normal)
SampleButton.addConstraint(NSLayoutConstraint(item: addButton, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.view.frame.size.width/5))
SampleButton.addConstraint(NSLayoutConstraint(item: addButton, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 50))
self.view.addSubview(addButton)
self.view.addConstraint(NSLayoutConstraint(item: self.view, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: addButton, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: self.view, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: addButton, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0))
SampleButton.enabled = true
SampleButton.addTarget(self, action: "SampleAction", forControlEvents: UIControlEvents.TouchUpInside)
}
func SampleAction() {
let abpvc = ABPersonViewController()
abpvc.personViewDelegate = self
self.navigationController?.pushViewController(abpvc, animated: true)
}
Reference:
http://idevrecipes.com/2010/12/16/raised-center-tab-bar-button/
Notice
If you didn't see the button, be mindful of the lifecycle of UIViewContoller, cause that maybe the source of your error.
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