My iOS 5 app uses storyboarding with a UITabBarController. There are three "tabs" each displaying a view controller which has been linked using a relationship back to the UITabBarController. At the moment each view controller appears when you tap the relevant tab, as expected. However, for a more gracious transition I would like to slide the view controllers on and off screen.
By way of example, if I am currently on Tab 0 and then select Tab 1 the view controller on screen (for Tab 0) should slide off to the left-hand side of the screen, and the new view controller (for Tab 1) should slide on from the right-hand side of the screen.
I have been able to achieve this behaviour using a custom UIView as the tab bar but would like to know whether this is possible with a custom segue in storyboarding, as that would certainly save a lot of coding (and also would keep things a fair bit neater in the project)?
Thanks in advance for any assistance.
I am trying to do the same thing.
Unfortunately I think the relationship segue does not allow any customization as it just connect tab bar and the tab bar items together, and not a transition.
My guess is we have to do the transition ourselves when the view appeared.
Related
I'm trying to create a tabbed application with navigation elements inside the tab bar, as seen in the picture below (the red bar) using Swift/XCode 6.2. Basically those three icons in the middle will direct the user to different view controllers. The other two icons would be context-based. For example, on a table view page you would see the menu icon and add new icon as seen in the image. However, clicking on a row would change the menu icon to a back icon, and the add icon to something else.
That's the general idea, but I'm having a very hard time implementing something even close to this. The first issue is that whenever I embed a view in a Tab Bar Controller, I can't move the tab bar to the top. However, when I create a custom UITabView in a View Controller, Control + Click and dragging a Tab Bar Item to another view doesn't create a segue. I haven't even begun to tackle having the navigation elements inside the bar.
I guess what I'm asking is just for a little guidance on what route to take to tackle this. I'm assuming I can't use a Tab Bar Controller or Navigation Controller because it doesn't seem like I can customize them all that much. So custom Tab Bar and Navigation Bars, and then implemnt the segues and button changes programmatically?
Thanks.
I will try to guide you from an architectural perspective (so you won't find much code below).
Using a UITabBarController
In order to achieve what you are suggesting, you are right you cannot use a UITabBarController straight away, among several reasons, the most immediate one is that they are meant to be always at the bottom and you want it in top (check Apple's docs). The good news is that probably you don't need it!
Note: If you still want to go with a UITabBarController for whatever reason, please see #Matt's answer.
Using a UINavigationController
You can use a UINavigationController to solve this task, since the UINavigationBar of a UINavigationController can be customized. There are multiple ways on how you can organize your view's hierarchy to achieve what you propose, but let me elaborate one option:
To customize a UINavigationBar's to add buttons, you just need to set its navigationItem's title view:
// Assuming viewWithTopButtons is a view containing the 3 top buttons
self.navigationItem.titleView = viewWithTopButtons
To add the burger menu functionality on a UINavigationController you can find several posts on how to do it and infinite frameworks you can use. Check this other SO Question for a more detailed answer (e.g. MMDrawerController, ECSlidingViewController to mention a couple).
About organizing your view hierarchy, it really depends on if when the user taps one of the main top buttons, it will always go to the first view controller in the new section or if you want to bring him back to the last view in the section where he was.
3.1 Switching sections displays the first view of the new section
Your app's UIWindow will have a single UINavigationController on top of the hierarchy. Then each of the 3 top buttons, when tapped, will change the root view controller of the UINavigationController.
Then, when the user changes section, the current navigation hierarchy is discarded by setting the new section view controller as the UINavigationController root view controller.
self.navigationController = [sectionFirstViewController]
3.2 Switching sections displays the last displayed view in the new section
This will require a slightly modified version of the above, where your each of your sections will have its own UINavigationController, so you can always keep a navigation hierarchy per section.
Then, when the user taps one of the top buttons to switch section, instead of changing as previously described, you will change the UIWindowroot view controller to the new section's UINavigationController.
window.rootViewController = sectionNavigationController
Using a custom implementation
Of course, the last and also very valid option would be that you implement yourself your own component to achieve your requirements. This is probably the option requiring the biggest effort in exchange of the highest customizability.
Choosing this option is definitely not recommend to less experienced developers.
I'd like to take a stab at this--I think it is possible to use a tab bar controller here.
Your topmost-level view controller will be a UITabBarController with a hidden UITabBar.
Each tab is contained in a UINavigationController.
All view controllers in the navigation controller will be a subclass of a view controller (say, SwitchableViewController).
In SwitchableViewController's viewDidLoad, you set the navigation item's title view (i.e. whatever's at the center; self.navigationItem.titleView) to be the view that holds the three center buttons. Could be a UISegmentedControl, or a custom view.
Whenever you tap on any of the buttons, you change the topmost UITabBarController's selected index to the view controller you want to show.
Issues you may encounter:
Table views inside tabs will have a scrollIndicatorOffset at the bottom even if the tab bar is hidden.
Solution: Play around with the automaticallyAdjustsScrollViewInsets of the tab bar controller, or the inner view controller. https://stackoverflow.com/a/29264073/855680
Your title view will be animated every time you push a new view controller in the navigation stack.
Solution: Take a look at creating a custom transition animation for the UINavigationController.
I have 4 screens in a project. I know two ways to move from one view to other:
UINavigationController
One UIViewController and add subviews to that UIViewController.
But, In all screens bottom bar is same. Bottom bar is having some buttons.
So, In my point of view, adding subView to one UIViewController is better way.
But I don't know which is best method and standard way for developers?
The answer depends entirely on the way that you expect the users to navigate from one screen to the other:
If end-users should be able to get from any screen to any other screen, use tab bar controller - UITabBarController will hold the other four views, and present a tab bar at the bottom. If you do not want the tab bar, you can hide it.
If end-users on each view have two choices of view controllers to go to, next and prior, use a page view controller - This is more appropriate in situations when the navigation is limited to next/previous page.
If end-users need to be able to go back to the previous screen, use navigation controller - UINavigationController keeps track of the views that you visited, and provides navigation to go back.
i am making one iOS tabbar application in that i have put 4 different tabs and whenever i click on 1 st tab and load another view after clicking of the first tab. After that when i press back button then tabbar is not displaying .So that i want hint that how can i show that
back the tabbar when we move from one tab from another and yes how i can use consistent the tabbar in whole application can you just guys help me on this i am new to iOS development.
here i am put the screen shot ...
here first screen is this one..
when i tap the video button that are first in the view then another window open
which are as under and see the tabbar is not there...
when in video controller there is tabbar is there but i drag and connect to that then tabbar is disabled
Looking at your screen snapshots, do I correctly assume you're attempting to transition to the "Videos" scene by touching the big "Videos" button in the center of the "Home" scene (rather than touching the tab bar button at the bottom of the screen, which I assume works fine)? If that's the case, you need to have your button tell the view controller's tab bar controller that you want to change the index of the tab bar, and it takes care of it for you. You cannot do the transition using a segue (or at least not without a custom segue, which is even more complicated than the procedure I outline below). If you're changing the view some other way (e.g. using a standard segue or using presentViewController, pushViewController programmatically, etc.), your tab bar can disappear on you.
You later said:
when in video controller there is tabbar is there but i drag and connect to that then tabbar is disabled
Yes, that's true. You cannot use a segue from one of your big buttons to one of the tabs in your tab bar. (Or technically, if you wanted to use a segue, it would be a custom segue which would do something very much like my below code, though perhaps a tad more complicated.) So, rather than using a segue for your big button, you need to write an IBAction (connected to the big Videos button on the Home scene), that tells the tab bar to change its selection:
- (IBAction)clickedVideosButton:(id)sender
{
[self.tabBarController setSelectedIndex:1];
}
A couple of comments:
My answer was predicated on the assumption that your tab bar works as expected when you tap on the buttons of the tab bar, itself. If you tap the buttons at the bottom of the screen, do you transition to your other views correctly and preserve the tab bar? If so, my answer above should solve your issues in getting the big buttons to work. If not, though, then the problem rests elsewhere and you need to show us your code that might account for that (either you're something non-standard in the UITabBarControllerDelegate methods, or your viewDidLoad of the view is doing something nonstandard).
If I understand your user interface design right, you have the tab bar at the bottom as well as the big buttons in the middle, which presumably do the same thing. That is, no offense, a curious user interface design (duplicative buttons, requiring extra tap on a button, etc.). You might want to choose to either use either big buttons (in which you can retire the tab bar, eliminate the IBAction code I've provided above, and just use a nice simple navigation controller and push segues, for example), or just use the tab bar (and lose the home screen, lose the big buttons, etc.).
You also made reference to "press back button", and I don't see any "back" button on any of your screen snapshots. Do I infer that you have a navigation controller and you're doing a pushViewController or push segue somewhere? If you're doing something with back buttons, you might need to clarify your question further.
I'd like to use a slide up / down effect to display various viewControllers inside a navigation controller. A few other apps do this like square, and every day. Basically when the app loads, I want to display a base view in the navigation controller. Then slide up another view controller over top of it. When then hit a button in the nav bar, I want to slide that down and show the base controller, all the while retaining the navigation bar, and changing up nav items.
Originally I tried to make this work by showing a modal but that requires using a new nav bar.
Has anyone done this, or knows of a good example that illustrates this UI pattern? Thank you!
You could have UIViews in a UIScrollView
I'm developing an iOS app just now with a Tab Bar navigation.
I have two screens which show the same information but in different formats (say, list and grid).
The two screens are different enough that they require separate controllers.
Users can toggle between the two views from a shared control bar button (toggle) at the top.
Scenario:
User presses the 'Places' button for the first time and it shows the places as a list.
They press 'grid' to see the same places displayed as a grid.
The user presses another tab bar button to navigate to a different screen.
When they press the "Places" button again, the app remembers their last viewed screen for places was the grid so the grid view is shown.
The user may then toggle back to list view. etc...
Can anybody recommend the best approach to achieving this?
One approach is to use one view controller that manages both views. That way, you don't have to bother with synchronizing data or subverting the normal function of UITabBarController -- there's just one controller. Also, don't try to overload the meaning of the tab for that controller. Instead, add a button to both views that tells the controller to switch to the other view. That'll be easier for your to build, and (more importantly) easier for the user to understand. It's not nice to make familiar controls do unfamiliar tricks.
If your view controllers are such that combining them into one would be complicated, then you can use two controllers and simply swap them in and out of the tab bar by modifying the tab bar controller's viewControllers array. You can still avoid having to sync data between them by having both controllers refer to the same data model.
I was trying to achieve this same thing, and it can actually be done with a basic setup of a TabBarController, NavigationControllers, ViewControllers, push segues, and unwinds.
TabBarController
|==> NavigationController --> PlacesController(grid view) --(push segue from nav bar)--> PlacesController(list view)
|==> NavigationController --> OtherController
|...
Make sure to have an unwind segue back from the list view controller to the grid view controller.
If you toggle between views then go to another tab (e.g. otherController) and come back, you'll return to the last view you were seeing because that's what is at the top of the stack of the NavigationController.