Tab bar, tap to Root View Controller - ios

I have a Swift project.
It has a UINavigationViewController inside a UITabBarController. When tapping the tab responsible for showing the Navigation View Controller twice, it jumps back to the root view controller of the Nav.
How can I disable this using swift?
NB. I've seen Objective C implementations using the UITabBarControllerDelegate but I don't think I'm doing the right thing in Swift.
Thanks.

Swift 3.0
add UITabBarControllerDelegate to master class
override func viewDidLoad() {
tabBarController?.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
_ = navigationController?.popToRootViewController(animated: true)
}

The proper way to achieve it is to use the tabBarController:shouldSelectViewController: method of the UITabBarControllerDelegate protocol. The problem I could see here is that you are not sure where to set the delegate. There must be no big difference between doing in Objective C or Swift.
Here are a few simple steps you may need to try:
Retrieve the tab bar controller:
I don't know your app's UI structure, but you should be able to get the tab bar controller easily from code. It could be a property if you created it programmatically, or merely the key window's rootViewController if you drag & drop it to the main storybard.
Assign the tab bar controller's delegate to an instance of any class you want as long as the class conform to the UITabBarControllerDelegate protocol.
Implement the tabBarController:shouldSelectViewController: method mentioned above to decide what should be shown when a tab is selected.
If you can provide some code, I can also show you how you can make it by example.
Good luck.

Related

How to programmatically tap Tabbar item (not selectedIndex)

here is resume of my app:
I have tab bar. When user tap on the tabbar item
appropriate view controller is presented by "slide-to-side"
animation (like in iP homescreen).
Code is in method tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool.
I have alert. When user tap on button, I want to direct him to the specific tab. But when I use self.selectedIndex = #, VC is showen, but without animation. Is there any way to achieve same action like tap on item? Thank you
Programmatically selecting the tab doesn't trigger any delegate methods. This is true of any control. Since you explicitly chose to do something, you already know you did it. You don't need a delegate method to tell you. This is by design and it is a good thing.
There is a simple solution. Put whatever animation code is inside the delegate method into its own method. Then call that method from the delegate method. Now you can also call that new method when you call self.selectedIndex = #.

how to pass a variable back to root navigation controller from the UIViewController using Protocol and Delegate in Swift

Xcode Image
As you can see in the image attached I have the root navigation controller called - Notifications and a UIViewController called NotificationsController.
So my Question is how can i pass a variable from NotificationsController back to Notifications using Protocol and Delegate, because in this case there is no segue but a default relationship between them.
Is my question correct or is there another way to do what i need.
Any help is really appreciated
To reference the navigation controller from the view controller (it is an optional so you need to handle that):
// self is a UIViewController
self.navigationController
To reference the view controller from the navigation controller:
// self is a UINavigationController
let index = // Index of the view controller. You may need to iterate over viewControllers to find this.
self.viewControllers[index]
You don't really need to set up a delegate. As keithbhunter pointed out in his answer, a view controller has a navigationController property that will point to the navigation controller that manages it.
I suggest you define a protocol for the messages you want to send to your navigation controller, and then have your custom subclass of UINavigationController conform to that protocol.
Within the view controllers that are on the navigation controller's stack you can fetch a pointer to your navigation controller and cast it to type UINavigationController<myNavControllerProtocol>.
(UINavigationController that conforms to myNavControllerProtocol. I'm working in Objective-C these days and don't remember the exact syntax for that.)

Xcode - What is transition Gmail use to swipe left-right to next-previous mail item

I use Gmail and like the way to view next - previous mail by swipe left-right when in detailview of an email item. I'm writing some application and want to make the apps like that. What is transition between two detailviews that Gmail used? And what is animation be used?
When i swipe, current view will scroll out and next view also scroll in like two view are sequential with other.
But, in fact, two views be init by the same DetailViewController.
I read some tutorial, but not found solution. I think that is UISplitViewController??
I think you are looking for something that's called Custom View Controller Transitions.
Long story shot, you'll need to:
1) Create a create a class that conforms to UIViewControllerAnimatedTransitioning protocol. There you'll write your animation code. Don't forget to call transitionContext. completeTransition (true) when you your animation is done.
To trigger a custom transition, your UINavigationController have to implement UINavigationControllerDelegate method protocol: func navigationController(_ navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController,toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? and return the object that you created in 1) (The one which conforms to UIViewControllerAnimatedTransitioning).
Returning nil will trigger the default animation push, pop and so on.
Have a look at this WWDC Session which explains how to use it.
I strongly recommend you reading this issue too.

What is the proper way to dismiss a modal when using storyboards?

Using storyboards, what is the proper way to dismiss a modal?
using IBAction and writing code to dismiss after a button click?
using segue and notify the parent view controller after a button click?
See Here Dismissing a Presented View Controller about halfway down
When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it.
So you should use an IBAction and writing code to dismiss after a button click
According Alex Cio answer for Swift 3 and XCode 8.3:
Create class:
import UIKit
class DismissSegue: UIStoryboardSegue {
override func perform() {
self.source.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
But in storyboard you should choose:
Action Segue -> Custom -> dismiss
Only after this option appear on Action Segue menu
I've found that usually when I'm attempting to do this in storyboard I'd rather not create extra classes. It still makes sense to perform the dismiss from the presenting view controller, so that requires a class to back it.
If you create an IBAction in the presenting view controller and name it appropriately e.g.
- (IBAction)dismissAnyModel:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Then from storyboard wherever you want to trigger the dismiss from you create an action to the first responder as shown below. You can extend this to work with multiple presenting view controllers by creating unique names for the IBActions.
More information on first responder and the responder chain
See my answer here. It gives you two ways to dismiss the modal view controller with storyboard. I like method two described because one you add the class in your project your return from modal views can be done with no code using storyboard alone. That said, if you have implemented a delegate and delegate protocol, it is also a good place to put the dismissModalViewController statement.
To do this inside the UIStoryboard you need first to create an Object of the type UIStoryboardSegue in your project
Then insert following method inside the class. Here is my class
#implementation DismissController
- (void)perform{
UIViewController *sourceVC = self.sourceViewController;
[sourceVC.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
Now you can use it inside your UIStoryboard. Select the button that should make the UIViewController Disappear and drag it to the UIViewController you want to go to. In my case it shows **dismiss Controller* because of the name of my Class.
Select it and you are done!
There is also a very good explanation on this website.
As the Apple online documentation indicates, the presenting view controller is responsible for dismissing the modal (presented) view.
There's a post and example available
here

How do I tell why my UIViewController is disappearing?

My UIViewController is in a navigation stack. How can I detect when the user is trying to pop up to a previous level vs. pushing a new view controller over it?
I want to post a notification when the view is removed from the stack, as if the user had tapped a Save button that I don't have.
If you're using a UINavigationController, then UINavigationBarDelegate is the delegate class and it implements the following methods.
Pushing Items
– navigationBar:shouldPushItem:
– navigationBar:didPushItem:
Popping Items
– navigationBar:shouldPopItem:
– navigationBar:didPopItem:
You can put code in these method that you want to be executed when the view is popped from the stack.
You could do something in viewWillDisappear: and there is also the UINavigationControllerDelegate protocol that has two methods for detecting when views will or have been shown.

Resources