Currently I am working for an IPad application which shows a Slideshow on the first scene - realized with a paged UIScrollView. When I click on one page in the slideshow I want to push a new VC (to a new scene, which should present multiple thumbnails... a kind of detail layer if you want so).
How can I do this via segue? Currently I simply pulled out a new VC and connected the SlideshowVC with the the next VC in the scene - but nothing happens. I wrapped my head around a couple of tutorials but most of them use a button which is connected to the next VC. Is it able to simply connect the SlideshowVC with the next VC or do I really need to strap a button over the whole scrollview and connect the button with the next VC?
Currently my scene look like the following picture. The first one is a NavVC - the second the SlidehsowVC and the third the DetailVC.
If you don't want to connect the segue to a button, when you intercept the user interaction, just do this -
[self performSegueWithIdentifier:#"mySegueIdentifier" sender:self];
If you need to set anything up before you get there, use this -
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"mySegueIdentifier"]) {
MyViewController *myViewController = segue.destinationViewController;
// do something here
}
}
Related
I have 2 view controllers in my app that user can navigate from one to another.
In my first view controller I dragged from an icon in the toolbar to the second view controller to setup a segues and selected “show” from the popup.
So far no issue, I can click on the icon in the toolbar and will take me to the second view controller without any problem.
However I have also created an action from that icon using drag and drop so now I have something like this
#IBAction func setting(sender: UIBarButtonItem) {
println("Test")
}
The problem I have is the setting action is not getting fired when I click on the toolbar icon, however it will navigate to the second view controller without a problem.
Reason I want to call the setting function is to perform something prior to moving the second view controller.
Do you see any problem with the way I have implemented this?
As you are using segue from your storyboard, then that segue is triggered before the button action.If you want to perform some action on your button click, then you have to manually call the segue like this
[self performSegueWithIdentifier:#"YourSegueName" sender:sender];
then instantiate your segue like this
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YourSegueName"])
{
}
}
It has been some months that I've programmed for iOS, and want to finish my game with new features. Now when people play the game and lose they will see a "Game Over" view.
Now what I want is that people first see a view where they can use the bought credits they gotten and go back to the game with the extra seconds or life. But I'm not doing it on the right way.
Way I'm trying to do:
- Save Me View (Segue)
Game view -
- Game Over View (Segue)
So, you lose, go automatically to the save me view, presses close and go to game over immediately. Otherwise use the NSUserDefaults that has been saved before showing the Save Me view.
So I'm using NSUserDefaults for saving previous game levels/points etc and that is not the right way of doing and the flow is getting complicated.
Second try:
I've tried it but I'm stuck at the last step. Because I'm using Segue's and delegates, I don't know how to make my GameView the delegate of the SaveView, while the protocols are already there.. I've followed this: Passing Data between View Controllers
Now at step 6 it doesn't work because i'm using modal segue's with my UIViewControllers and no UINavigationControllers. I've this in my code atm:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"SaveMe"]){
SaveMeViewController *vc = [segue destinationViewController];
// Here needs to come that GameView (This Class) is the delegate for SaveMeViewController. Tried vc.delegate = self; but this doesn't work.
[self savePoints];
}
}
You could setup a delegate in the gave view that passes back how the game ended.
As my understanding use #property or delegate to pass data it will help you.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SaveMe"]) {
SaveMeViewController * vc = segue.destinationViewController;
// create property in SaveMeViewController and access that property and pass values
vc.property = value to assgin;
}
}
I have a simple app with 2 screens.
When I press a button to go from the first to the second, everything is performed successfully (including animation). However, when I click the back button on the second screen, I get the following warning:
Warning: Attempt to present <getTextViewController: 0x8f6aa30> on <SecondViewController: 0x946cc80> whose view is not in the window hierarchy!
EDIT: Please don't refer me to other questions regarding above warning - I already saw those, and they refer to other issues.
However, it still switches back to the first screen. Yet, the animation of the segue does not perform.
Also: Information (such as inputted text) in the first screen remains when I return to the first screen, while information in the second screen resets every time the screen comes up.
Here is how I call both operations:
Segue from View 1 to View 2:
Name: F21, Style: Modal, Transition: Cross Dissolve, Animation: True.
Segue from View 2 to View 1:
Name: F12, Style: Modal, Transition: Cross Dissolve, Animation: True.
Code in getTextViewController.m (View 1):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"F21"]){
UIViewController *v = [segue destinationViewController];
[self dismissViewControllerAnimated:NO completion:nil];
v = self;
}
}
-(void)performSegue:(NSString*)str{
[self performSegueWithIdentifier:str sender:self];
}
//In some other method:
[self performSegue:#"F21"];
Code in SecondViewController.m (View 2):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"F12"]){
UIViewController *v = [segue destinationViewController];
[self dismissViewControllerAnimated:NO completion:nil];
v = self;
}
}
-(void)performSegue:(NSString*)str{
[self performSegueWithIdentifier:str sender:self];
}
- (IBAction)goBack:(id)sender {
[self performSegue:#"F12"];
}
I would very much appreciate any help to understand why the first segue works while the second doesn't.
Thank you,
Dean
NOTE: Here is the full project - https://github.com/dean13-meet/firstIOSApp
EDIT: Updated git.
Im not exactly sure what you're trying to do in your prepareForSegue, their is no need to be dismissing VC's there. If you want to have a simple app where you go from VC1 to VC2 and then back again, your best bet is to use a segue and an unwindSegue.
So in your storyboard control drag from a button on VC1 to VC2 and select your segue type. Then in VC1.m setup the unwind segue such as:
- (IBAction)unwindFromViewController:(UIStoryboardSegue *)segue
{
//empty implementation
}
Finally, in your VC2 control drag from the back button to the green exit icon on VC2 and select your unwindFromViewController method.
That should do what you're looking for.
For the sake of simplicity, I would suggest using a push segue opposed to modal because it takes care of all the back buttons for you. If you don't like the idea of a navigation controller however, try dismissing the view with the following: Moving back from a Controller to a previous one
I'm working on an iPhone app whose main navigation happens through a tab bar. However, it opens with a welcome screen that does not show the tab bar, but rather has two buttons to go to the two most common tabs. One goes to the first tab, so in my storyboard I added a segue to the main tab bar controller. This works great.
But the second button goes to the third tab, so I added a segue directly to that screen in my storyboard. This results in the tab bar not being shown. All my research into this has been obfuscated by the dozens of people who want to retain the tab bar, not create it, so I'm a bit lost on what to do. Thanks!
For the second button, you should also segue to your tabBarViewController and call
[self setSelectedIndex:2]; // If you want to show the third tab
in viewWillApear method in your tabBarViewController
If you are using storyboard segue,
add this method in your first View Controller
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"yourSegueName"])
{
MyTabBarVC *destinationVC = segue.destinationViewController;
destinationVC.selectedIndex = myIndex;
// myIndex's value depends on which button you pressed
}
}
So I got a ViewController with 4 seperate buttons. When clicking on button1 TableViewController1 pops over the ViewController with a list of items. When selecting an item the TableViewController1 drops down and button1 now has the text that was selected in the table. This is all good. But when I do the exact same thing for button2 with TableViewController2 the data from button1 is reseted.
I use segues with identifiers, some of the code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showEducation"]) {
NSIndexPath *indexPath = [self.tableViewEducation indexPathForSelectedRow];
ViewController *destViewController = segue.destinationViewController;
destViewController.educationText = [tableViewArray objectAtIndex:indexPath.row];
}
}
So at the moment I got multiple segue identifiers for each button and multiple .h and .m files for the tableviews. Am I using a completely wrong technique to get this to work? I hope im clear enough, otherwise I can upload images.
Edit: I just noticed, I also have a slider on my ViewController. When clicking on a button and selecting a row in the TableView the slider gets reseted to the original position. Same problem as above kind of.
I am thinking that you're pushing to a new instance of your View Controller every time you push from either tableViewController.
Imagine that you click on one button on ViewController0, this creates an instance of tableViewController1. When you click a row, you're just using a performSegue to create a NEW instance of ViewController0, and this has its own ViewDidLoad - resetting the buttons.
(You're saying that the view "drops down", so it's modal?)
Don't use performSegue from the tableViewController back to the viewController, try using [self dismissModalViewController: withCompletion:](or something similar, can't remember), then your tableViewController should remove itself and reveal the original ViewController.
Now, you don't have a way to change the name of the button though, but that can be done by accessing the sender from the tableView, which will give you the original View Controller, and not a new instance of it.
One way of getting the sender is to use [performSegue... from ViewController0, and in it's own prepareForSegue, you could do something like
//In the first ViewController, not in the TableViewControllers
-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender{
if(sender == button1)
{
UITableViewController1 *dest = segue.destinationViewController;
[dest setSender: self];
}
}
And in TableViewController1 you'd create a variable ViewController *home;, and a method -(void)setSender:(ViewController*)sender;, so that in your didSelectRowAtIndexPath, you could now say [[(ViewController0*)home button1]setTitle:#..];, and then [dismissModalViewController..]
There are other ways to do it as well, depending on how you are pushing from your viewController to the tableViewController. And I'm sure there are easier ways to access the sender than this, but it works and is useful if you're already sending other data.