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;
}
}
Related
I'm new on Stackoverflow and I'm currently learning XCode from scratch and I'm in a process of making a Single Page Application with options.
Anyone knows how to efficiently make a simple menu with multiple selectable UIButtons that make the main ViewController display different datasets depending on the selection in XCode?
Tried different things (creating SecondViewController for example but can't figure out how to pass data from it to main ViewController).
Any help will be greatly appreciated.
Refer this:
https://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
How to pass prepareForSegue: an object
Simple Test from above Answer Reference:
Simply grab a reference to the target view controller in prepareForSegue: method and pass any objects you need to there. Here's an example...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
REVISION: You can also use performSegueWithIdentifier:sender: method to activate the transition to a new view based on a selection or button press.
For instance, consider I had two view controllers. The first contains three buttons and the second needs to know which of those buttons has been pressed before the transition. You could wire the buttons up to an IBAction in your code which uses performSegueWithIdentifier: method, like this...
//When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
// Get destination view
SecondView *vc = [segue destinationViewController];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}
Hope this help but please go through refernces!
This is probably a basic question - but I cant seem to find the answer to it in my searches!
I have a uiview setup which contains two input areas which are linked to a child modal view via separate segues.
this is my parent prepare for segue method -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"goalInfo"])
{
[segue.destinationViewController setYourGoalViewController:self];
}
if ([segue.identifier isEqualToString:#"longGoalInfo"])
{
[segue.destinationViewController setYourGoalViewController:self];
}
}
basically i'd like to determine which segue had been used in the child view so I can apply the relevant filed updates and alter a title/description in the child view. - I basically need something very similar to
if ([segue.identifier isEqualToString:#"goalInfo"])
but i'm not sure how to access this from teh child? Any tips?
The segue identifier is check on the source ViewController during its prepareForSegue: method. What you rather need is during prepare for segue is to set properties on the destination viewController and then when it loads, read these properties and set UI outlets.
Look at this example: I am stuck at presenting a full image on tapping the cell in UICollectionViewController. It's about CollectionVC and its detailVC, but the principle is the same.
In my app, I have 4 view controllers, (login,welcome,game view and results view). In the game view, I have two additional views (like this)[screen shot link to the views]. I am using a web api to get data, and my data is consist of items(each item has 1 image and 4 string). Item number is not constant so based on the amount of items(which I store it inside an array), I transition my views from one to another until I ran out of items.(The way I present is really similar to view transitions sample from apple. After displaying the last item, I use perform segue to go to next view.
The problem that I am trying to solve
I am trying to create an additional view/ or view controller that uses some part of the information from my items array.
my question
Why I am getting null for container views array ?(_results array is the array that has the items)
this is what I tried:
based on this question:
GameView
ContainerViewController *container = [[ContainerViewController alloc]init];
container.array = _results;
[self performSegueWithIdentifier:#"changetoResults" sender:self];
ContainerViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"items in the array - containerviewcontroller.m %#",array);
}
this is the console:
2013-11-26 19:11:29.157 GuessTheImage[3664:70b] there are 8 , of items in the current index -gameviewcontroller.m
2013-11-26 19:12:44.439 GuessTheImage[3664:70b] items in the array - containerviewcontroller.m (null)
Thank you.
Because the ViewController that you create isn't the ViewController that you go to via the segue.
If you'd like to use a segue, you can get the destination ViewController (it already exists) in a prepareForSegue method and tune it however you want (in your case - add an array).
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"changetoResults"])
{
ContainerViewController *vc = (ContainerViewController *)[segue destinationViewController];
vc.array = _results;
}
}
There are two things that you are not doing correctly:
You are setting the array on a temporary view controller different from the instance activated by your segue, and
You are logging the array too early: viewDidLoad: is called before the segue code manages to put the array into the new view controller.
To fix the first problem, remove the two lines above the "perform segue" call, and add this method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"changetoResults"]) {
ContainerViewController *container = segue.destinationViewController;
container.array = _results;
}
}
To fix the second problem, move the logging code into the viewDidAppear:. NSLog should start showing the correct number of items.
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
}
}
First, a little background. I'm new to iOS development, I've been in .Net land for a long time, and that's probably why I'm even asking this question, but here goes.
The basic setup is this. You have a UINavigationController with a RootViewController we'll call MasterViewController. When some action happens on this MasterViewController, we want to drill into a DetailsViewController. However, we also want to pass some data to the DetailsViewController.
It is my understanding, that in previous versions of the SDK (prior to iOS 5) the approach was similiar to this:
#implementation MasterViewController
-(IBAction)someAction
{
DetailsViewController *dvc = [[DetailsViewController alloc]initWithNibName:#"DetailsView" bundle:nil];
dvc.someDataProp = [self getSomeDataSomeHow];
[[self navigationController] pushViewController:dvc animated:YES];
}
#end
Now however, in iOS 5, it seems that this is now done using the Storyboard and segues. In XCode you set up the segue from the MasterViewController to the DetailsViewController, and then in code you do something like this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]];
}
My question is basically this: The older approach somehow feels a lot cleaner to me. You're being very explicit about the type of ViewController you're pushing on to the navigation stack and you can set properties easily on it. In the new approach though, destinationViewController is of type id (for obvious reasons), and it just feels a lot less clean to me. Again, this could be my .Net side coming out, but is this common in iOS? Just use id and throw caution to the wind?
With Storyboards you can assign a named identifier to the segue,
Select the segue and in the Attribute inspector you can add a name to the segue Identifier.
And in the prepareForSegue method you should check for this Identifier and thus you will explicitly know which segue is about to be performed and what the destinationViewController will be.
if ([segue.identifier isEqualToString:#"My First Segue Identifier"])
{
DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController;
// Set the DVC's properties
}
In many cases, the destination view controller for a segue may be a UINavigationViewController, and in that case, the solution (a slight modification of Dennis Mathews' solution above) will need to use the message"topViewController":
if ([segue.identifier isEqualToString:#"My First Segue Identifier"])
{
NavitationViewController* navController = [segue destinationViewController];
DetailsViewController *dvc = (DetailsViewController*) [navController topViewController]
// Set the DVC's properties
}
I haven't been working with iOS that long, but I've seen a few examples where you don't have to cast because of objective-c's loose coupled messaging system.
Instead of checking the segue identifier or casting to a specific ViewController you can do this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector: #selector(setCompany:)]) {
[segue.destinationViewController performSelector: #selector(setCompany:) withObject: self.company];
}
}
In the first line I ask if the destinationViewController has a method setCompany (if you have a property named company this one would be generated for you). If it does, you can call that method/set that property with the second line of code.
So in this case you don't really have to know the destination ViewController and could easily replace it with a different one that supports handling Companies.