iOS More Than One Unwind Segues on a Button - ios

In my app I have a Done button.
Depending on which screen the user came from (namely a saved list screen or a new list screen) I'd like the Done button to use a different unwind segue.
Is this possible - if so how?
Thanks.

I am new to IOS, but as per my knowledge, the simplest thing you can do is to create macros in your AppDelegate with different states and set a property whose value will be set according to those states, so that you can perform segue depending on the current status of the property. You can do like this:
//in AppDelegate.h
#import <UIKit/UIKit.h>
#define SAVED_LIST_SCREEN 1
#define NEW_LIST_SCREEN 2
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) int previousScreen;
#end
You can set the property "previousScreen" as SAVED_LIST_SCREEN or NEW_LIST_SCREEN depending on your current screen. And then you can check in "if codition" whether the previous state is Saved List or New List. And you can perform the segue operation accordingly.
if(app.previousScreen == SAVED_LIST_SCREEN)
{
//perform 1st segue
}
else
{
//perform 1st segue
}
Check it out and please let me know if it works.

Related

Segue not passing data between ViewControllers

I am making an iOS app that uses payment methods.
At the moment I am trying to work on the checkout flow, which contains an OderFormViewController and a CheckoutTableViewController as you can see below:
I connected both by dragging a segue, as highlighted in blue. I also added a segue identifier for my segue.
I called the first view controller as E_OrderFormViewController(Its title is Shipping Address), and in it I created an IBActionfor my Continue button and also used -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender to pass in the information.
I also have an Order model, with some properties in it. On my CheckoutTableViewController, I have got my labels and orderInfo as public properties, so the first view controller one can access it.
#import <Foundation/Foundation.h>
#interface Order : NSObject
#property(strong, nonatomic) NSString *shippingName;
#property (strong, nonatomic) NSString *shippingAddress;
#property (strong, nonatomic) NSString *shippingCity;
#property(strong, nonatomic) NSString *shippingState;
#property(strong, nonatomic) NSString *shippingZip;
#end
//E_OrderFormViewController.m
#import "E_OrderFormViewController.h"
#import "F_CheckoutTableViewController.h"
...
#pragma mark - My Actions
- (IBAction)storePaymentInfoProceedToConfirmation:(id)sender {
[self performSegueWithIdentifier:#"toCheckout" sender:self];
}
#pragma mark - Navigation
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"toCheckout"]) {
F_CheckoutTableViewController *checkoutView = segue.destinationViewController;
//Store Information and pass it to next view
checkoutView.orderInfo.shippingName = self.txtFieldNameOnCard.text;
NSLog(#"Shipping Name Stored: %#",checkoutView.orderInfo.shippingName);
}
}
My NSLog always returns (null) for whatever text I type inside my first textField, which is the one I am testing first.
Here is my CheckoutTableViewController, with its public property. The orderInfois listed here. I am using it to pass in the information, as I mentioned above:
//F_CheckoutTableViewController.h
#import <UIKit/UIKit.h>
#interface F_CheckoutTableViewController : UITableViewController
#property (strong, nonatomic)Order *orderInfo;
#end
On my viewDidLoad, on my destination view controller, I did:
//F_CheckoutTableViewController.m
#implementation F_CheckoutTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
//Load all information
self.labelShippingName.text = self.orderInfo.shippingName;
NSLog(#"Typed Name: %#",self.orderInfo.shippingName);
}
I just pasted the viewDidLoad as a reference, as I am aware if my NSLog in my prepareForSegue is not returning anything, the information is not being passed.
I really don't know where the error is. I searched in a couple of threads here on StackOverFlow, and none of them helped me, one which seems to be similar, is this one, but it didn't help with my issue:
Multiple segues not passing Object data between themselves
This seems to be pretty simple, but I am making some mistake that I can not find.
I really appreciate your help.
orderInfo must be null, because you didn't initialize it, therfore you cannot set its properties... so you got 2 options:
checkoutView.orderInfo = [[OrderInfo alloc]init];
checkoutView.orderInfo.shippingName = self.txtFieldNameOnCard.text;
or change your property from:
#property (strong, nonatomic)Order *orderInfo;
to:
#property (strong, nonatomic)NSString *shippingName ;
Based on the storyboard set up, you are using Textfield in Shipping Address View Controller, it may miss the delegation of Textfield to its controller.

Referencing outlet not showing up in xcode 6

I am trying to write my first hello world in xcode. I have two labels and two buttons in my view, and my AppDelegate.h file is like this:
#interface QuizAppDelegate : NSObject <UIApplicationDelegate>
{
int currentQuestionIndex;
// The model objects
NSMutableArray *questions;
NSMutableArray *answers;
// The view objects
IBOutlet UILabel *questionField;
IBOutlet UILabel *answerField;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
- (IBAction)showQuestion:(id)sender;
- (IBAction)showAnswer:(id)sender;
#end
Now i am trying to add reference to my label. I go to LaunchScreen.xib and right click on the label. According to the tutorial, i have to see "answerField" and "questionField" under the "Outlets" tab, but nothing shows up. Can anyone tell me why this can be happening?
Thanks
A few things:
1) That code should really be in a view controller and not the application delegate
2) You probably should be looking in the Main.storyboard file and not LaunchScreen.xib
3) Make sure that File's Owner is set to the correct view controller on Main.storyboard after you move that code into a view controller.

Storyboard, drag link to an IBAction from a container view to the parent

Here's a trivial VC called Club
Club has a function:
#implementation Club
-(IBAction)clickMe
{
NSLog(#"Whoa!");
}
#end
Now regarding ButtonA. Obviously in Storyboard you can drag from ButtonA to the function "clickMe" in "Club".
Now. Regarding ButtonB.
Is there any way, in Storyboard, to drag from ButtonB, to "clickMe" in "Club"?
Perhaps using the mysterious "object" objects, or ... ??
Note that, obviously, you can make a class for the small view, and have a function:
#implementation SmallViewOnRight
-(IBAction)sameAsClickMe
{
[(Club*)self.parentViewController clickMe];
}
#end
Then, you can drag from ButtonB to sameAsClickMe. But that's a complete nuisance.
Note that it's very normal to use container views like this, to handle different "areas" of your main view (particularly if you have stuff sliding around and so on, and when you have many things "on top of each other"). It's hugely convenient to move "sections" outside the main view, using container views. But it's a complete nuisance "passing up" the clicks.
Is there an obscure way to do this in Storyboard? Cheers!
Just FTR, iOS7+ only, nothing older
Note - going in the "other direction" is well-explored and easy enough to do.
No, you can't do that but you can use delegates for this behavior.
In SecondViewController.h:
#protocol SecondViewControllerDelegate <NSObject>
-(void)clickMe;
#end
#interface SecondViewController.h: UIViewController
#property (weak, nonatomic) id <SecondViewControllerDelegate> delegate;
#end
In SecondViewController.m:
#implementation SecondViewController
- (IBAction) buttonBClicked:(id)sender {
if ([self.delegate respondsToSelector:#selector(clickMe)] {
[self.delegate performSelector:#selector(clickMe)];
}
}
#end
In ClubViewController.m:
#import "SecondViewController.h"
#interface ClubViewController () <SecondViewControllerDelegate>
#end
#implementation ClubViewController.m
// make yourself a delegate of SecondViewController somewhere in your code. For example, in prepareForSegue.
-(void)clickMe {
NSLog (#"Clicked");
}
#end
EDIT:
Try with Unwind Segues!
I've posted an answer here on how to use them. But skip step 4.

maintain object state when moved away of the screen

I have a class declaration which contains an singleton object that manages the data (called sharedDatacontroller).
Now there are many other screen and declaration is the last one. I have to check if the user moves back from declaration screen and alters any data , then have to reset a switch button on the declaration screen.
My Approach:
-(void) viewWillDisappear:(BOOL)animated
{
self.sharedControllerClone=sharedController;
}
-(void) viewWillAppear:(BOOL)animated
{
if ([self.sharedControllerClone isEqual:sharedController])
{
NSLog(#"Not Same");
self.acceptDeclarationSwitch.on= self.acceptDeclarationSwitch.on;
}
else
{
self.acceptDeclarationSwitch.on= !self.acceptDeclarationSwitch.on;
}
}
But when the control comes in after navigating from back screen , the self.sharedControllerClone is reseting to Nil. How to preserve its state..any ideas?
Hope I am clear this time.
You can try this thing by creating Macros in your AppDelegate and assigning different states to a property taken in AppDelegate so that you will come to know that what is your current state. You can create an object of your AppDelegate in your required controllers and in their ViewDidLoad, you can assign the current state to AppDelegate like this:
//in AppDelegate
#import <UIKit/UIKit.h>
#define FIRST_CONTROLLER 1
#define SECOND_CONTROLLER 2
#define THIRD_CONTROLLER 3
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property int previousControllerState;
#end
And then, you can set your previousControllerState in the ViewDidLoad of your required controller.
//in your ViewControllers
- (void)viewDidLoad
{
[super viewDidLoad];
app.previousControllerState = FIRST_CONTROLLER;
}
And you can check your state in if condition in the next controller.
You have to take the states in AppDelegate to prevent the objects from getting nil. Otherwise, as soon as you move from one controller to another, the object of the previous controller might be getting nil.

iOS Add a row to UITableView on button click from another ViewController

I am a new in iOS Development and I canĀ“t move forwards... Is here somebody with experience, who can help me to solve my problem?
I use a Storyboard. First you see a ViewController with buttons. When you click on one of the button, informations about this button appear in a TableViewCell. - until now is it clear.
Than you click on a button "Continue" (than you come back to ViewController with buttons) and choose another button from ViewController.
HOW to do it, that informations from this button comes to a TableView as a second Cell? (so that when you click on for example three of the buttons, they appear as 3 cells under each other in this table?)
My Sample Code is here to download. - (on this website click on the smallest icon "Download").
Thank you very very much for your help!!!
Iva
You need a Model to store your selections/data.
For example: On MainViewController, when you click on button1, record that in the Model using array or just variable. Then, when you load SecondViewController, check the values in Model and load cells accordingly.
=> Example code for Model
// Header
#interface ModelData : NSObject
#property (nonatomic) NSMutableArray selectedProducts;
#property (nonatomic) NSInteger value1;
#property (nonatomic) NSInteger value2;
#property (nonatomic) NSInteger value3;
#end
// Implementation
#implementation ModelData
#synthesize selectedProducts = _selectedProducts;
#synthesize value1 = _value1;
#synthesize value2 = _value2;
#synthesize value3 = _value3;
#end
Various options:
Use NSUserDefaults to store information like settings
Use a Model class as described above - it could be a singleton class
Use CoreData to store and retrieve your data - complicated approach and suitable for dynamic things
Here is a reference to a good Data Model tutorial (reported by Iva)

Resources