In order not to make duplicate, I didn't ask until now and I was trying all day long. So I know it has been asked before, but none of them helped me. I'm having trouble with using storyboard and it is getting more and more confusing.
I found out on the internet that using segues and overriding the method performSegueWithIdentifier:sender
: would have me and I tried to that. I implemented that as:
- (IBAction)segmentChanged{
if([segmentedControl selectedSegmentIndex] == 0)
[self performSegueWithIdentifier:#"Doviz" sender:self];
else
[self performSegueWithIdentifier:#"Altin" sender:self];
}
Here is my storyboard:
Please note that I'm connecting with push method rather than embed, modal and custom, and connecting them not to the segmentedController but to the view. Maybe there might be also something wrong.
Lastly, when I'm trying to running my application, I took the error:
Could not find a navigation controller for segue 'Altin'. Push segues
can only be used when the source controller is managed by an instance
of UINavigationController.
I'm new and learning Xcode 'til 1 week, so I'll be much appreciated if you can give me an detailed answer on this.
Setup your storyboard so it looks like this:
An ensure to give each segue the appropriate identifier in the Attributes Inspector (Command+Option+4).
Please bare in mind that using a segmented control for pushing on view controllers isn't a standard UI paradigm. It may be more appropriate to use regular UIButton controls.
Related
I have the following storyboard structure:
Essentially I have a UIButon that I want to link to the "TargetTableViewController" via an IBAction - NOT by 'Ctrl+Dragging' but programatically by way of some code instead.
I believe I have to present "NavViewControllerTwo" as a NavigationController (as it 'holds' "HoldingViewController") and have tried various renditions of this via the many threads at StackOverflow. But this did not work.
I suspect it is because the actual "TargetTableViewController" is embedded in a ContainerView of "HoldingViewController" and that causes the problems.
I have tried implementing other renditions of presenting "TargetTableViewController" as a child of the "HoldingViewController", but that caused me more problems.
I realise I may have over-complicated things here, but the reason for the container is I want to display a BannerView at the bottom of my eventually presented view.
If anyone can be kind to point me in the right direction, I will be very grateful. Thank you for your time.
** CLARIFICATION **
I am actually trying to present "HoldingViewController" as that would effectively display my "TargetTableViewController".
Please refer to amended image below:
Apologies for the confusion and lack of clarification.
Setup a segue from MainViewController to NavViewControllerTwo in the storyboard, give it an identifier and then perform that segue from your code on the button press action using [self performSegueWithIdentifier...
I am in a situation exactly like this post, but for whatever reason, only one of my performSegueWithIdentifier:sender works.
I have a View Controller (embedded in a UINavigationController) with two buttons, Cancel and Done. When clicked I want Cancel to unwind to one screen, and Done to unwind to another screen; however, this only works with one of the two segues I have set up.
- (IBAction)clickedDone:(id)sender {
[self performSegueWithIdentifier:#"unwindToHome" sender:self];
}
- (IBAction)clickedCancel:(id)sender {
[self performSegueWithIdentifier:#"unwindToViewEntries" sender:self];
}
"unwindToHome" works fine while "unwindToViewEntries" does nothing. No error, no printing, nothing. If I switch the segues and buttons, "unwindToHome" will still work while "unwindToViewEntries" does nothing.
I have unwind methods in both ViewControllers I want to unwind to and there are no other actions attached to the buttons.
I find it really odd that only one works. I've looked them over several times and there is nothing different that I can see.
Thanks in advance for the help. If there are some more things I should check please let me know!
I've already looked at solutions for the following posts:
How to unwind programmatically to 2 different VC
performSegueWithIdentifier not working
I've also tried removing the segues and re-adding them, as well as deleting and re-adding the entire view controller. Every time, the same behavior.
EDIT: I should also mention that I've tried adding other segues in different views and none of the new ones I add work. Only "unwindToHome" seems to work, and I can't figure out why.
In the storyboard make sure that both segues show that it is a show (push) segues. There was a question earlier,which is a little bit different, that if you create two segues from the same button Xcode was setting one push the other modal.
Happy coding!
Yan
In my view controller if I navigate through the Root view controller it works okay through this code,
[self.navigationController popToRootViewControllerAnimated:YES];
But when i try to custom navigation to viewcontroller through below code,
ViewController2 *vc = [[[ViewController2 alloc] init]];
[self.navigationController popToViewController:vc animated:YES];
by this my application is crashed and show me the Below error:
terminate called throwing an exception.
Help me to shortout it.
uinavigation just like a box , you can push anyVC in this box , but when you want to out ,you just popToRootVC .. you can't push VC that it outside in this box .
You can only use that method to pop to a vc already in the array of view controllers.
EDIT: as developer new to iOS, you need to spend the time to read (and re-read) the UINavigation Controller class description, and the two or three Apple Guides on using UIViewController and the catalog of various view controller. Yes, its a lot of stuff to read and comprehend - but then, all of us doing iOS work now have done it too. There is no magic way to get your app to work. Your use of popToViewController demonstrates to the community that you have not done the above, as you would not have posted the question if you'd read the documents.
People who try to help others here on SO are much more likely to do so if it appears you have made an honest effort to get something to work, but are stymied in some way where an experienced person can provide insight.
after searching, looking and experimenting I continue to fail at a specific problem.
I am a programming novice, so by chance I simply did not use the right search term - so please bear with me in case I created a duplicate.
Here is the situation I'm struggling with.
ViewController 1 has two UIToolBars. The upper Toolbar Button displays a value, the lower Toolbar Button triggers an action in ViewController 2 which happens to be a TableViewController embedded via a container view.
The reason for that is - I need the keep the ToolBars in place while scrolling the TableView.
I use a delegate protocol to send the value from VC2 to the upper Toolbar in VC1, works fine.
But I fail to trigger the action in VC2 using the lower toolbar in VC1.
I kindly want to ask three question:
1.) What is the best practice to trigger the action / solve the problem ?
2.) How would the code look actually like when using a method named "theButtonWasTapped" on VC2 ?
3.) Is the method to embed the TableView via a container view the right way or is there a better way?
I tried to read through various documentations, but I don't even know where to start in this case.
Any help would be greatly appreciated since I'm sitting on this frustrated for days already and don't know where my mental block ends and my absent knowledge starts.
Thank you so much!
If VC2 is embedded in a container view, then it will be a child view controller of VC1. Therefore you can access it from VC1 with self.childViewControllers[0]. So you should be able to do something like this in VC1:
-(IBAction)toolBarButtonTapped:(id) sender {
SecondViewController *vc2 = self.childViewControllers[0];
[vc2 methodInVC2];
}
I'm moving my App to Storyboards and, so far, so good.
However, I've found something that I don't really understand and worries me. I would appreciate if someone can provide some insight on this.
My app uses a normal Navigation Controller. For moving "forward" to new View Controllers, I'm using custom segues; no problems there. However, there's a point in the App where I want to move back to the beginning of the Navigation Stack. I have also configured that "navigation" using a custom segue, for that, I created the segue in Interface Builder by dragging the last view controller to the first one (that already looks weird to me), and I've implemented the custom segue perform method in the following way:
-(void)perform
{
UIViewController *src = (UIViewController *)self.sourceViewController;
UIViewController *dest = (UIViewController *)self.destinationViewController;
[src.navigationController popToRootViewControllerAnimated:NO];
// Custom animation code here
}
... It works great. However, I don't understand why it works. In my mind, the custom segue should be instantiating a new instance of my first view controller and assign it as "dest", but it looks like the segue is smart enough to realize I want to navigate to a previous, existent, instance of a View Controller and, instead of creating a new instance, it assigns to "dest" the existing one.
Does anybody know if using segues in this way is ok? Is it possible that it works by chance but might stop working in the future? Am I wasting memory in anyway as the segue is instantiating a View Controller I'm not going to use?
Thanks a lot in advance!
Am I wasting memory in anyway as the segue is instantiating a View
Controller I'm not going to use?
Yes sir! By using a segue, you effectively allocate a new view controller as it's needed to set the DestinationController property for your custom segue. Test by yourself : add a static counter into your root controller, increment it each time this class is initialized and display it in your view : you'll see it getting incremented every time you pop to root using this trick.
Does anybody know if using segues in this way is ok?
As long as you're effectively wasting memory, no!
There's at least one solution to this problem : release the DestinationController of the segue in your (void)perform implentation. This is really quick to implement, but kinda ugly since you allocate and immediately release your view controller every time... even if it's better than just leaking it, it's not what I'd call a good practice!
To my mind, a better way to achieve what you want would be to not use a segue for that transition, just to use a button or whatever and call popToRootViewController:animated when getting a touch on this button.
Is it possible that it works by chance but might stop working in the
future?
For both the first solution I suggested and the way you're currently doing it, I see absolutely no reason : these are not complicated tweaks, just 'bad-implemented' standard navigation. The second solution is perfectly normal so no worries.