Having trouble passing contents of UITextField from one controller to another - ios

I want to pass whatever string a user inputs into a UITextField' over to the destination view controller, but when I NSLog the value in the destination, it shows up as null. I'm also getting a warning stating:incompatible pointer types assigning to UITextField from NSString`. How can I properly make the assignment and send it over?
Originating view controller
SearchViewController.m:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
controller.itemSearch = self.itemSearch.text;
}
SearchViewController.h:
#property (weak, nonatomic) IBOutlet UITextField *itemSearch;
Destination view controller
UserCategoryChooserViewController.h:
#import <UIKit/UIKit.h>
#import "SearchViewController.h"
#interface UserCategoryChooserViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *itemSearch;
UserCategoryChooserViewController.m:
NSLog(#"The text is:'%#'", self.itemSearch.text); // results in (null)

The above two answer are also correct. But if you want to make the assignment properly then modified textfield variable as NSString variable like that below:
#interface UserCategoryChooserViewController:UIViewController
#property (strong, nonatomic) NSString *itemSearch;
After doing this your warning
incompatible pointer types assigning to UITextField from NSString will get removed

controller.itemSearch is a UITextField *, and you tried to set it to a NSString *, that's what that warning is for. To set text of a UITextField, try this:
[controller.itemSearch setText:self.itemSearch.text];
There might be other issues, but let's start from here.

Let's go through the error you are seeing. It says that you are assigning an NSString * to a UITextField *. Unfortunately, you cannot do that. Here, itemSearch is the text field.
To make your code run properly, you need to set the text property of the itemSearch text field. The correct code would be:
controller.itemSearch.text = self.itemSearch.text;
As a side note, you should really not be meddling so deep into iOS development until you have made a strong foundation, which you have not.

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.

Xcode Property Not Retaining Value

I have a view controller called LoginWindowViewController.h that declared a property called usernameTextField:
#property (strong, nonatomic) IBOutlet UITextField *usernameTextField;
A string called James is associated to this TextField.
I then import another view controller,FirstViewController.h into my LoginWindowViewController.m and I also imported LoginWindowViewController.h into FirstViewController.m . In my FirstViewController.h there is a property called username.
#property (strong, nonatomic) IBOutlet NSString *userName;
Then i assign usernameTextField to username(In my FirstViewController.m). But when i NSlog the property username in my FirstViewController.m, it gives a null value.How do i fix this?
When you import classes you do not actually import any values. When you set the value of a property it is only set on that instance of the class. You will need to explicitly reference the property of your current instance to get the value you have set.
One note: IBOutlet stands for Interface Builder Outlet and is how you create a link from a storyboard or xib file UI element to a class property. So, no need to use IBOutlet if you are not linking to something in interface builder.
String should be declared
#property (nonatomic, strong) NSString *userName;
Then when you instantiate your login view controller from first view controller you can set the property like this
LoginWindowViewController *loginVC = [[LoginWindowViewController alloc] init];
[loginVC.usernameTextField setText:self.userName];

Setting UImageView and UILabel based on user

I have a registration for a user in my app. When the user registers they are redirected to a home ViewContoller. I am just wondering how i can set the UIImageView and a label on the home ViewController to the data that the user used when registering. I also am wondering how i can also achieve this when the user logs into the app. Any suggestions would be great:)
First you need what is called a data model in software engineering. It contains the basic data structures your app should work with.
In your case, the data model would probably contain a class User. This User class should have properties. In your case probably the class would probably look somewhat like that:
#interface User : NSObject
#property (strong, nonatomic) NSString *userId;
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) UIImage *image;
#end
Then in the viewDidLoad of your view controller, you need to set the labels which you e.g. can declare as IBOutlet from Interface Builder, this will look somewhat like that:
- (void)viewDidLoad
{
[super viewDidLoad];
self.nameLabel = self.user.name; // nameLabel is a UILabel
self.userIcon.image = self.user.image; // userIcon is a UIImageView
}
Hope it helps.

How to bind the control on the form with variable

I am just start studying iOS developing watching Stanford iOS course, but it looks like I have already missing something.
I have a form with UILabel and UIButton. When an user press the button the title of the button must be added to the text of label.
Here is my current CalculatorViewController.h:
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *display;
#end
and here is a CalculatorViewController.m:
#import "CalculatorViewController.h"
#implementation CalculatorViewController
#synthesize display = _display;
- (IBAction)digitPressed:(UIButton *)sender {
NSString *digit = [sender currentTitle];
UILabel *myDisplay = self.display;
myDisplay.text = [myDisplay.text stringByAppendingString:digit];
}
#end
The problem is that self.display (and myDisplay) variables have a nil value. Looks like I need to do something to link my variable with control on the form. What ?
Thanks in advance.
You need to link the control, the UILabel in Interface Builder to the variable in your CalculatorViewController class.
It is very likely that the file's owner (talking about the Xib file) is your CalculatorViewController, so you need to Control+drag the file's owner (or the object representing your VC) to the control and you will be shown a menu with the possible IBOutlet variables declared in your class, so you select the one you want to represent the control.
You can check if this link is properly set in two ways: (1) Select the UILabel in Interface Builder and see if there's a connection to the variable in the Connections Inspector, or (2) In your code you'll see a bullet near the IBOutlet declaration, if the bullet is hollow the connections is not set, if the bullet is filled the connection is set.
There is no need of this line
UILabel *myDisplay = self.display;
You have already declared your label in your interface file
- (IBAction)digitPressed:(UIButton *)sender
{
NSMutableString *string = [myDisplay.text stringByAppendingString:sender.titleLabel.text];
myDisplay.text = string;
}

Changing outlet object properties

I have a view controller alertForNeedsClassification as a property in another class, as such:
#interface SCAAppDelegate()
{
HomeScreenViewController * _homeScreenViewController;
NSInteger SCAStatus;
}
#property (strong, nonatomic) PromptClassifyViewController * alertForNeedsClassification;
#end
#implementation SCAAppDelegate
#synthesize alertForNeedsClassification;
#synthesize window = _window;
PromptClassifyViewController's interface looks like this:
#interface PromptClassifyViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *headerTitle;
#property (weak, nonatomic) IBOutlet UITextView *message;
#property (weak, nonatomic) IBOutlet UIButton *notNowButton;
#property (weak, nonatomic) IBOutlet UIButton *classifyButton;
#property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;
#property (weak, nonatomic) IBOutlet UIView *alertView;
#property NSUInteger tag;
#property (weak, nonatomic) IBOutlet id<PromptClassifyViewControllerDelegate> delegate;
- (void)show;
- (void)showFromView:(UIView *)view;
- (IBAction)show:(id)sender;
- (IBAction)dismiss:(id)sender;
- (IBAction)buttonWasPressed:(id)sender;
- (void)setHeaderTitleWithText:(NSString *)text;
#end
I am trying to change the values of IBOutlets message and headerTitle text, like this:
alertForNeedsClassification = [[PromptClassifyViewController alloc] initWithNibName:#"PromptClassifyViewController" bundle:nil];
//[alertForNeedsClassification setDelegate:self];
self.alertForNeedsClassification.headerTitle.text = #"A title";
alertForNeedsClassification.message.text = #"A message";
Then I show alertForNeedsClassification calling a show method (it's like a custom uialertview, but it doesn't subclass from uialertview).
Thing is, no matter how I change it, the text on alertForNeedsClassification.view is always that which is defined in the nib, ie. I can't change it programmatically.
My custom alert view is based on Jeff LaMarche's design: http://iphonedevelopment.blogspot.com/2010/05/custom-alert-views.html
Any ideas what might be going on?
Please be careful when you allocate and initialize the UIView object, especially if you trying to mix using Nib and dynamically generating objects. The best place is within -(void)awakeFromNib or -(void)viewDidLoad
Also, make sure these methods are called. By using -(id)initWithNibName:bundle: only cannot make sure your view to be loaded. Try -(void)addChildViewController and -(void)addSubview: on parentViewController's view to make sure view is loaded after being initialized.
If the text had to be prepared before being loaded, assign it to separate NSString property within PromptClassifyViewController class. Since this property is independent from view being loaded, you can change it's value BEFORE view is appeared. Make sure this text is used and applied to the headerTitle within -(void)show method.
Since you allocate PromptClassifyViewController and access weak referenced headerTitle from self. alertForNeedsClassification, make sure it's not deallocated right afterward.
Usually, weak option is not used for IBOutlet properties. Though it is used when generating outlet connection code by dragging objects from Interface Builder. Try testing your code using strong.
I was assigning values to the IBOutlets before they were alloc'd/initialized. The solution I implemented was to set the values I needed to non-IBOutlet properties (NSStrings in this case) and assign those where needed, in Prompt...Controller's viewDidLoad;

Resources