I would like to have three separate tableViews, show the middle view automatically (root view), and access the other two via a button or segmented control. That logic can come later. When I access the first I want it to slide in from the left, when I access the third I want it to slide in from the right to give it the appearance of the middle view controller always being there and only moving left and right via transitions.
Using storyboard segues is giving way to many complications - because my tableViewController is the initial root view, there is no way to segue to self from self when the button or segmented control is accessed. I feel like this must be a semi-standard implementation. Is there a best practice to implement this UI? Should I build my own custom container class and swap controllers and associated view in and out?
You should create 2 segues from you root to left and right table view. When you would like to go back, to root controller, use unwind segues.
What are Unwind segues for and how do you use them?
Related
I'd like to know the best way to handle view controllers when there are multiple ways for the user to navigate through an app. The problem is that the user might (for example) trigger a segue by selecting a table row, Then, from the presented view controller they might click a button in a custom toolbar to go somewhere else.
I'm pretty new at this, so while I understand using a segue to present a view controller, and then having to dismiss the presented view controller at some point, I'm less clear on how to manage things when a user has free reign to go wherever they want! I'm using container views to embed a header and a custom toolbar at the bottom of each view. Should I be using a container for each view controller as well?
If you are quite down the stack and you don‘t want to offer a back button for simplicity, then you go up the stack by calling dismiss and tell the delegate where you want to go until you reach the appropriate level which can move you up until you are where you wanted to go.
The alternative is to move up the delegate chain until you can move down again and from there call dismiss and then go down where you want to go.
I have a UIView which is embedded inside of a NavigationController. When the user clicks on a cell in a TableView he is taken to the UIView. However, the UIView pops out from the bottom instead of sliding out from the right side. I have the segue set to Show, so I am not sure why it is doing this.
The slide-in from the side behavior only works when all of the child navigation controllers are children of the same UINavigationController. This requirement includes the "root", or first, child. In your case the root child is the UITableViewController.
It will look like this in Storyboard:
UINavVC ---> RootChildVC ---> SecondChildVC ---> ThirdChildVC etc.
A show segue is contextual. If it is as in the diagram above, it will be a horizontal slide.
In any other situation at all, including a hand-drawn segue between two arbitrary VCs, a show is interpreted as a modal presentation which comes in from the bottom and slides back down. You also don't get the automatic "back" button installation because there is no "navigation" relationship detected.
You're probably confused and need to re-do your Storyboard into the above simple idiom. If you're segueing between "cousins" that is VCs whose direct parents are different UINavigationControllers, they fall under "any other situation".
A Navigation controller shouldn't be embedded inside another navigation controller.
remove root view relationship between View and NavigationController, delete the NavigationController and set "show" segue directly from TableView to that view.
I have my structure like
Controller 1 <-> Controller 2 <-> Controller 3 <-> ...<->Controller N
I need to be able to access to controller 1 or 3 directly from another controllers. I need swipe animation between controllers 1-n , and navigation bar with < and > buttons.
What is the best solution for this swiping controllers? I need be able to do some animation there. Do i need use paged UIScrollView? or UIPageViewController? With animation - CALayer transition?
Please, help me to choose.
Hello #Alexander and anyone else who needs a solution to this problem,
I think the easiest way to deal with this situation would be to use the UIGestures which will give great animations and will simply be justified using the storyboard. To use it from one view controller to the other, just do the following:
If your side view is open, this will show up on the bottom right side of the storyboard:
Then, you will have to drag the swipe gesture recognizer to the initial view controller and then let go when the whole view is highlighted in blue:
After that, you will have to control-drag the gesture icon on the top of the initial view controller to the controller you want to connect to. Then it will show a drop down list after you let go of the highlighted controller. Pick any segue:
You can do this with all the view controllers by creating more gestures and segues. You can also do it from the same view controller back or even skip controllers with different types of gesture recognizers.
I hoped it helped :)
Custom transitions are fairly new to me. I had to incorporate them into the last project I worked on and ended up using both the UIViewControllerAnimatedTransitioning protocol and custom segues.
Custom segues seem a bit cleaner/friendly in that you can choose them in a storyboard and be done with it. However there doesn't seem to be as-friendly way to set up a back/pop segue. I've read about unwinding segues but I can't seem to find anything around tying one to the back button of a nav controller.
The UIViewControllerAnimatedTransitioning protocol approach has a bit more set up but allows you to specify both the entering and exit of the views.
In the case of my app not being able to pop back with my custom segues wasn't an issue because the flow of the app doesn't allow you to go back to the previous views. Most applications though require this thus a custom segue seems worthless unless you subclass UINavigationController and allow for custom popping segues.
Am I missing something because it seems UIViewControllerAnimatedTransitioning is the best approach to take for animations between view controllers. Why would I ever want to subclass UIStoryboardSegue?
I agree that there is a lack of documentation on unwind segues compared to other types of segues, but after you get the hang of them, they are pretty straightforward. My understanding is that segues (including unwind segues) is the way that Apple intends you to transition between view controllers. Even when you create custom segues, the regular unwind segues should still function.
In my own work, I have subclassed a UIStoryboardSegue to execute a custom animation when transitioning between segues. Using a widely known app as an example, when you tap the menu button in Uber's app, the map view controller moves down, and a table view controller appears. And when you a tap a row in the table, the new view controller slides in from the right, but the map view controller is still visible on the screen. And when you tap the map view controller, it returns to its original position. For some reason, I believe that Uber actually didn't implement segues at all, but just place view controllers on top of view controllers, but I have implemented something similar in my own app with custom segues. These segues are difficult to replicate with Apple's default segues, so I used custom ones.
If you are tying an unwind segue to a back button, then you will want to override the normal unwind that comes along with the default back button in the uinavigationcontroller. I have found it very difficult to customize that segue. I would recommend hiding the default back button that comes with the uinavigationcontroller, adding your own bar button, and tying this new button to an unwind segue. I know that this is annoying, considering the default back button has some added functionality, such as using the title from the previous view controller as its text when the title is short enough. Unfortunately though, I think Apple really wants to discourage you from customizing the default button and makes it difficult to alter. I have left out how to replace the default back button with the custom one, so let me know if you have trouble.
Anyway, to create the unwind segue, you must first create a method in the class (or parent class) of the uiviewcontroller you are unwinding to (not from).
- (IBAction) methodName:(UIStoryboardSegue *)segueName
You can change the methodName and segueName to whatever you like. Now go to your storyboard, and go to the scene containing the uiviewcontroller you are unwinding from. If you now ctrl drag from this uiviewcontroller (the yellow button on the left side of the bar at the top of the controller) to the exit button (the orange button on the right side of the same bar) you will now see a menu popping up that contains the methodName above. Click that method, and your unwind segue will now be created.
After you have created the unwind segue, you now see it in the outline on the left of the storyboard. If you click the segue, you can inspect it and give it an identifier.
Now to deal with tying it to the back button...
Again, viewing the uiviewcontroller you are unwinding from , if you control drag from the custom back button (not the default back button) in the storyboard to the class of this uiviewcontroller, an IBAction will be created for you tied to the button. In this method, add in:
[self performSegueWithIdentifier: segueIdentifier sender:nil];
where segueIdentiferis the identifier you gave the unwind segue above. Now when you tap the back button, the unwind segue will be executed. You can also do some animations or what not before the unwind segue is executed.
I have actually done some complicated custom unwind segues dealing with animating both the source and destination view controllers. If you can be more specific regarding how you would like the unwinding to look, I can try to help you out.
I have a split view working great. However, I'd like to be able to drill down on my Master-Detail view's UITableView. For example, I have a list of ages: 0, 1, 2, 3, 4, 5. When the user presses 3 I would like a new UITableView to be presented with all the kids names that are 3.
Ideally I'd like use Storyboards to accomplish this (link an add button to take me to the next UITableView). When I try and add a view it shows up as a full screen view. How can I make this view show up in the Master section of the split view?
When using Storyboards, if you want to have multiple UITableViews so it will allow the user to drill down categories, you must use the Push Segue (set it to Master). Make sure you are not pushing a UINavigationController, but just the view you want listed. Then, to get back just use [self.navigationcontroller popViewControllerAnimated:YES];.
EDIT: (more info as asked for)
So in XCode/IB when you are on your main view and right click and drag it to another view, you will be presented with different choices. You want to select Push instead of Modal. This will allow it to push a new view onto the stack. You can also set it's destination to Master and it will size the IB view correctly.
Also, you don't always have to use a button to connect a view. You can also drag from the view controller itself to another view controller instead of a button to view controller. Then in your button code you can call [self performSegueWithIdentifier:#"someNameHere" sender:self]; to call the transition. This lets you do checks and validation before you move on to the next screen.
Just remember to click on your segue and name it (under identifier in the properties view). Then add the function prepareForSegue:sender: in order to transfer any variables or anything before it transfers (I rarely have to use this).