Can't send data between views using a protocol & delegate with presentModalViewController - ios

I'm making elevator thing. I'm having trouble sending data with different views using presentModalViewController. I got red message "favoriteColorString" property not found. I copied exactly the same but different form names and buttons. The "favoriteColorString" appears an error and unable to send elevator2 data.
I tried two different thing.
Elevator2View.favoriteColorString = [[NSString alloc] initWithFormat:#"Your favorite color is %#", favoriteColorTextField.text];
And
favoriteColorString = [[NSString alloc] initWithFormat:#"Your favorite color is %#", favoriteColorTextField.text];
Here's my code:
ElevatorView.h
#import <UIKit/UIKit.h>
#import "Elevator2View.h"
#interface ElevatorView : UIViewController<PassSecondColor>
{
Elevator2View *Elevator2View;
IBOutlet UITextField *favoriteColorTextField;
IBOutlet UILabel *favoriteColorLabel;
IBOutlet UILabel *secondFavoriteColorLabel;
NSString *secondFavoriteColorString;
}
#property (nonatomic, retain) Elevator2View *Elevator2View;
#property (nonatomic, retain) IBOutlet UITextField *favoriteColorTextField;
#property (nonatomic, retain) IBOutlet UILabel *favoriteColorLabel;
#property (nonatomic, retain) IBOutlet UILabel *secondFavoriteColorLabel;
#property (copy) NSString *secondFavoriteColorString;
#end
ElevatorView.m
#import "ElevatorView.h"
#import "Elevator2View.h"
#implementation ElevatorView
#synthesize Elevator2View, favoriteColorTextField, favoriteColorLabel, secondFavoriteColorLabel;
#synthesize secondFavoriteColorString;
-(IBAction)level1:(id)sender;{
favoriteColorTextField.text = #"1";
Elevator2View.favoriteColorString = [[NSString alloc] initWithFormat:#"Your favorite color is %#", favoriteColorTextField.text];
[self presentModalViewController:[[[Elevator2View alloc] init]
autorelease] animated:NO];
}
Elevator2View.h
#import <UIKit/UIKit.h>
#protocol PassSecondColor <NSObject>
#required
- (void) setSecondFavoriteColor:(NSString *)secondFavoriteColor;
#end
#interface Elevator2View : UIViewController{
IBOutlet UITextField *secondFavoriteColorTextField;
IBOutlet UILabel *favoriteColorLabel;
IBOutlet UILabel *secondFavoriteColorLabel;
NSString *favoriteColorString;
id <PassSecondColor> delegate;
}
#property (copy) NSString *favoriteColorString;
#property (nonatomic, retain) IBOutlet UITextField *secondFavoriteColorTextField;
#property (nonatomic, retain) IBOutlet UILabel *favoriteColorLabel;
#property (nonatomic, retain) IBOutlet UILabel *secondFavoriteColorLabel;
#property (retain) id delegate;
#end
Elevator2View.m
#import "Elevator2View.h"
#interface Elevator2View ()
#end
#implementation Elevator2View
#synthesize secondFavoriteColorTextField, favoriteColorLabel, secondFavoriteColorLabel;
#synthesize favoriteColorString;
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
favoriteColorLabel.text = favoriteColorString;
}
- (void) viewWillDisappear:(BOOL) animated
{
// [[self delegate] setSecondFavoriteColor:secondFavoriteColorTextField.text];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
favoriteColorLabel.text = favoriteColorString;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
See http://www.theappcodeblog.com/?p=90

The reason for your "property not found" is that you named your ivar same as class.
Dot notation is just a syntactic sugar: object.property = value is equivalent to [object setProperty:value]. In Objective C classes are also objects, and when you call Elevator2View.favoriteColorString = whatever, Xcode apparently thinks that you are attempting to call class method setFavoriteColorString of class Elevator2View.
Getting rid of this error is easy: just rename your ivar Elevator2View *Elevator2View to something else. In fact, Xcode 4.4 and newer autosynthesizes ivars for your properties: if you have a property propertyName, then Xcode will autosynthesize ivar _propertyName. Your property Elevator2View will have _Elevator2View ivar. So unless you really really need to have ivars with different naming scheme, you can get rid of your #synthesize, and you also don't need to declare ivars for you properties.
(Though I prefer to declare ivars for properties (following Xcode naming scheme), because far too often lldb doesn't show autosynthesized-without-declaring ivars in object inspector.)
That was about properties, ivars and naming conventions. But what are you doing in this code?
-(IBAction)level1:(id)sender;{
favoriteColorTextField.text = #"1";
Elevator2View.favoriteColorString = [[NSString alloc] initWithFormat:#"Your favorite color is %#", favoriteColorTextField.text];
[self presentModalViewController:[[[Elevator2View alloc] init]
autorelease] animated:NO];
}
You set value of Elevator2View's - your instance variable's - property, then create brand new object of Elevator2View class and present that as modal view controller. (By the way, presentModalViewController:animated: is deprecated in iOS 6.0). Of course, this brand new Elevator2View object has no idea what Elevator2View's (your instance variable's) properties are!

Related

Copying one NSString into other one Xcode

I have a problem in Xcode.I am trying to copy one NSString into other one but is not working.
The original NSString pageTitle is on the RestViewController:
This is my RestViewContoller.h:
#import <UIKit/UIKit.h>
#import "Restaurant.h"
#interface RestViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UILabel *DescriptionLabel;
#property (strong, nonatomic) IBOutlet UIImageView *ImageView;
#property (nonatomic, strong) Restaurant *DetailModal;
#property (nonatomic, strong) NSString *pageTitle;
#property (nonatomic, strong) NSString *pageDescription;
#end
The NSString I want to save the data is on the RestViewController:
#property (nonatomic, strong) Restaurant *DetailModal;
but is a Restaurant class type.
My Restaurant class is:
Restaurant.h:
#import <Foundation/Foundation.h>
#interface Restaurant : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *desc;
#property (nonatomic, copy) NSString *image;
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image;
#end
Restaurant.m:
#import "Restaurant.h"
#implementation Restaurant
- (instancetype)init:(NSString *)title descripiton:(NSString *)description image:(NSString *)image {
self = [super init];
if (self != nil) {
self.title = title;
self.desc = description;
self.image = image;
}
return self;
}
#end
And finally the place where I want to copy this NSStrings is my RestViewController.m:
#import "RestViewController.h"
#import <QuartzCore/QuartzCore.h>
#interface RestViewController ()
#end
#implementation RestViewController
- (void)viewDidLoad {
[super viewDidLoad];
_pageTitle = #"Test";
_DetailModal.title = _pageTitle;
NSLog(#"_DetailModal.title: %#", _DetailModal.title);
}
#end
The problem is when I see the result of the
NSLog(#"_DetailModal.title: %#", _DetailModal.title);on the console,
it puts me:2016-11-21 11:42:05.407 MadEat[3667:104028]
_DetailModal.title: (null)
What can I do? I know I have a low level of Xcode, but I need your help please. Thank you very much.
Initailize the instance of DataModel First.
Then proceed with assignment
_DetailModal = [[DetailModal alloc] init:_pageTitle descripiton:#"Desc" image:#"image"];
There is a instance method defined already to do the task.
After this also you can alter the value by
_DetailModal.title = #"title_of_yours"
If you have to use detailmodal, you must alloc the restaurant class object (detailmodal). Then only the objects can be used.
detailmodal=[[restaurant alloc]init];
detailmodal.title=_pagetitle;
Before you can use a object, you have to create it first.
DetailModal *detailModal = [DetailModal new];
That way the object will be created and values stored to the class properties will be reserved.
Try:
_DetailModal.title = [[NSString alloc] initWithString: _pageTitle];
(Did not test this)
plz chek you _DetailModal is not nil
if it's nil then
first you need to alloc the memory for you DetailModal Class object
like this
DetailModal *detailModal = [DetailModal new];
then after set the value you want
detailModal.title = _pageTitle;

After converting to ARC I am getting "message sent to deallocated instance"

I am creatinng an instance of a View like this...
- (IBAction)findPatientTapped:(id)sender {
RequestDialogViewController *findPatientViewController = [[RequestDialogViewController alloc] initWithNibName:#"RequestDialogViewController" bundle:nil];
findPatientViewController.delegate = self;
findPatientViewController.autoCorrectOff = YES;
findPatientViewController.defaultResponse = #"";
findPatientViewController.keyboardType = #"ASCII";
findPatientViewController.returnKeyType = #"Go";
findPatientViewController.tag = findRequestTag;
findPatientViewController.editSet = YES;
findPatientViewController.titleText = #"Find Patient";
findPatientViewController.messageText =#"Enter all or a portion of the patient's name...";
findPatientViewController.messageText2 = #"Last Name...";
findPatientViewController.messageText3 = #"First Name...";
findPatientViewController.showResponse2 = YES;
findPatientViewController.showNavBarSaveButton = NO;
findPatientViewController.infoTextFile = #"";
findPatientViewController.view.frame = CGRectMake(280, 230, 480, 300);
[self.view addSubview:findPatientViewController.view];
}
The view contains 2 UITextField fields for entry by the user. This all worked fine before running the convert to ARC tool. After the conversion the view crashes when trying to enter a value in either of the 2 fields with...
-[RequestDialogViewController respondsToSelector:]: message sent to deallocated instance
Here is the .h file of the UIViewController after running the conversion to ARC tool...
#import <UIKit/UIKit.h>
#protocol RequestDialogViewControllerDelegate;
#interface RequestDialogViewController : UIViewController <UITextFieldDelegate>{
id<RequestDialogViewControllerDelegate> __weak delegate;
IBOutlet UINavigationBar *navBar;
IBOutlet UITextField *response;
IBOutlet UITextField *response2;
IBOutlet UILabel *message;
IBOutlet UILabel *message2;
IBOutlet UILabel *message3;
IBOutlet UIButton *saveButton;
NSTimer *selectAllTimer;
NSString *defaultResponse;
NSString *titleText, *infoTextFile;
NSString *messageText, *messageText2, *messageText3;
NSString *placeHolderText;
NSString *keyboardType, *returnKeyType;
BOOL editSet, showSaveButton,showNavBarSaveButton, showResponse2, autoCorrectOff;
int tag;
}
#property (weak) id<RequestDialogViewControllerDelegate> delegate;
#property (nonatomic, strong)IBOutlet UITextField *response;
#property (nonatomic, strong) IBOutlet UITextField *response2;
#property (nonatomic, strong)IBOutlet UILabel *message;
#property (nonatomic, strong)IBOutlet UILabel *message2;
#property (nonatomic, strong) IBOutlet UILabel *message3;
#property (nonatomic, strong)IBOutlet UIButton *saveButton;
#property (nonatomic, strong)NSString *defaultResponse;
#property (nonatomic, strong)NSString *titleText, *infoTextFile;
#property (nonatomic, strong)NSString *messageText, *messageText2, *messageText3;
#property (nonatomic, strong)NSString *placeHolderText;
#property (nonatomic, strong)NSString *keyboardType, *returnKeyType;
#property (nonatomic, strong)IBOutlet UINavigationBar *navBar;
#property (readwrite)BOOL editSet, showSaveButton, showNavBarSaveButton, showResponse2, autoCorrectOff;
#property (readwrite)int tag;
#property (nonatomic, strong) NSTimer *selectAllTimer;
- (IBAction)saveButtonPressed:(id)sender;
- (void)selectAll;
- (IBAction)editingDidEnd:(id)sender;
#end
#protocol RequestDialogViewControllerDelegate <NSObject>
#optional
- (void)requestDialogViewDidDismiss:(RequestDialogViewController *)controller withResponse:(NSString*)reqResponse response2:(NSString*)reqResponse2;
#end
Here is the pertenant references in the .h file of the class creating the instance of the RequestDialog view...
#import "RequestDialogViewController.h"
#interface OrthoViewController : UIViewController <RequestDialogViewControllerDelegate>{
}
- (void)requestDialogViewDidDismiss:(RequestDialogViewController *)controller withResponse:(NSString*)reqResponse response2:(NSString*)reqResponse2;
#end
What do I need to do to make this work under ARC? I am thinking it might have something to do with how the protocol is formed.
Thanks,
John
**** Thanks to Dan I resolved this by making findPatientViewController a property of the calling class...
RequestDialogViewController *findPatientViewController;
#implementation OrthoViewController
- (IBAction)findPatientTapped:(id)sender {
findPatientViewController = [[RequestDialogViewController alloc] initWithNibName:#"RequestDialogViewController" bundle:nil];
//set all the properties and add the subview
}
#end
Your findPatientViewController has nothing retaining it, so it gets deallocated at the end of the method where you create it. Then, when something in it's view tries to call a delegate method on it you get that crash.
If findPatientTapped is a method in a view controller then you should add the findPatientViewController as a child view controller. If it's in a view, then you need to least store the findPatientViewController in a property so it doesn't get deallocated while you are still using it.
Your code didn't really work properly before ARC, you just had a memory leak.

Problems in adding object from one view to a mutableArray in another view

Hi everyone I have been building an app and have met some problems.
My app has two viewControllers. One is MenuViewController and another one is MainViewController.
I want to pass a string from MainViewController to a mutableArray in MenuViewController, but have no idea how.
Here are my codes:
<MenuViewController.h>
#import <UIKit/UIKit.h>
#interface MenuViewController : UITableViewController {
NSMutableArray *secondFavourite;
}
#property (nonatomic, strong) NSMutableArray *secondFavourite;
#end
.
<MenuViewController.m>
#import "MenuViewController.h"
#import "MainViewController.h"
#interface MenuViewController ()
#property (strong, nonatomic) NSArray *menu;
#end
#implementation MenuViewController
#synthesize menu;
#synthesize secondFavourite;
- (void)viewDidLoad
{
[super viewDidLoad];
self.secondFavourite = [[NSMutableArray alloc] init];
self.menu = self.secondFavourite;
}
.
<MainViewController.h>
#import <UIKit/UIKit.h>
#import <social/Social.h>
#interface MainViewController : UIViewController {
IBOutlet UIImageView *imagepost;
UILabel *predictionLabel;
}
- (IBAction)sampleSelector:(UIButton *)sender;
- (IBAction)showAllClick:(id)sender;
#property (nonatomic, retain) IBOutlet UILabel *predictionLabel;
#property (strong, nonatomic) NSArray *predictionArray;
#property (strong, nonatomic) UIButton *menuBtn;
#property (strong, nonatomic) NSMutableArray *fav;
#property (strong, nonatomic) IBOutlet UILabel *favLabel;
#property (strong, nonatomic) IBOutlet UITableView* tableView;
#property (nonatomic, strong) NSMutableArray *favourite;
#end
.
<MainViewController.m>
- (void)viewDidLoad
{
[super viewDidLoad];
self.predictionArray = [[NSArray alloc] initWithObjects:#"Hey gurl", nil];
}
//Add to favourite
- (void) addToFav {
self.favourite = [[NSMutableArray alloc] init];
[self.favourite addObject:self.predictionLabel.text];
[self.tableView reloadData];
NSLog(#"%#", self.favourite);
}
//add to favourite button action
- (IBAction)addToFavButton:(id)sender {
[self addToFav];
//pass data from favourite here to secondFacourite in MenuViewController (found on stack overflow)
MenuViewController *menuViewController = [[MenuViewController alloc]initWithNibName:#"MenuViewController" bundle:nil];
menuViewController.secondFavourite = [[NSMutableArray alloc]initWithArray:self.favourite];
[self.navigationController pushViewController:menuViewController animated:YES];
}
I used NSLog to check that the menuViewController.secondFavourite in MainViewController successfully added the string into the array, isn't the array the same array in MenuViewController? Why doesn't the menu.tableView update and show the new string added? I am very confused and I hope someone will help me out.
Thanks for reading this.
This has to do with the fact that your menu viewDidLoad is overwriting the value in these two lines:
self.secondFavourite = [[NSMutableArray alloc] init];
self.menu = self.secondFavourite;
That first line is setting your secondFavourite property to an empty NSMutableArray instance. And since viewDidLoad will be called only after the view has been loaded into memory (in this case, when you try to push the view controller onto the stack), your initial values in the secondFavourite property will be lost.
Instead, you should move that initialization code into the an init method.

How to save UITextField Text to NSString?

In my main view controller, I have a UITextField, and I am trying to save the text input into it to a NSString in my Homework model(class).
Homework.h
#import <Foundation/Foundation.h>
#interface Homework : NSObject
#property (nonatomic, strong) NSString *className;
#property (nonatomic, strong) NSString *assignmentTitle;
#end
Homework.m
#import "Homework.h"
#implementation Homework
#synthesize className = _className;
#synthesize assignmentTitle = _assignmentTitle;
#end
In my assignmentViewController, I create an object of type Homework and try to set it equal to whatever is entered into the the UITextField when the Save Button is pressed.
Assignment View Controller
#import <UIKit/UIKit.h>
#import "Homework.h"
#interface Assignment : UIViewController {
}
#property(nonatomic) IBOutlet UITextField *ClassNameField;
#property(nonatomic) IBOutlet UILabel *ClassNameLabel;
#property (weak, nonatomic) IBOutlet UIButton *SaveButton;
#property (nonatomic, strong) Homework *homeworkAssignment;
- (IBAction)Save:(UIButton *)sender;
#end
AssignmentViewController.m
- (IBAction)Save:(UIButton *)sender {
self.homeworkAssignment.className = self.ClassNameField.text;
NSLog(#"SaveButtonPressed %#", self.homeworkAssignment.className);
}
The NSLog prints out that className is (null). Can anyone help me figure out what I am doing wrong? This is my first ever iOS app (besides Hello World).
Edit: This is using ARC
Edit: I tried changing
self.homeworkAssignment.className = self.ClassNameField.text; to
self.homeworkAssignment.className = #"TEST";
and the log still shows (Null).
Double check you properly linked ClassNameField outlet and that you're initializing homeworkAssignment. Something like.-
self.homeworkAssignment = [[Homework alloc] init];
By the way, you should consider using camelCase notation for your variable names :)
Well to be honest the first steps are always hard but you should learn it the right way, héhé
First of all synthesize this way:
#synthesize labelAssignmentTitle,labelClassName;
or
#synthesize labelAssignmentTitle;
#synthesize labelClassName;
there is no need to do the following:
#synthesize className = _className;
#synthesize assignmentTitle = _assignmentTitle;
Now if you initialize the right way from the the start you'll find it a lot easier later!
HomeWork.h
#interface HomeWork : NSObject
#property (nonatomic, strong) NSString *className;
#property (nonatomic, strong) NSString *assignmentTitle;
-(id)initWithClassName:(NSString *)newClassName andAssignmentTitle:(NSString*)newAssigmentTitle;
HomeWork.m
#implementation HomeWork
#synthesize assignmentTitle,className;
-(id)initWithClassName:(NSString *)newClassName andAssignmentTitle:(NSString*)newAssigmentTitle {
self = [super init];
if(self){
assignmentTitle = newAssigmentTitle;
className = newClass;
}
return self;
}
#end
ViewController.m
- (IBAction)saveIt:(id)sender {
HomeWork *newHomeWork = [[HomeWork alloc]initWithClassName:[labelClassName text]andAssignmentTitle:[labelAssignmentTitle text]];
}
Because of this, you directly make a newHomeWork object with the parameters given by your two UITextFields.
Now print it out in your logmessage and see what happends ;)

Issue Passing Values From One View Controller To Another

I am trying to take the text that is typed into UITextFields in one view, and pass those values into a different View Controller when a button is pressed. In the first view controller (CreateViewController) I have:
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#class ThePreviewViewController;
#interface CreateViewController : UIViewController <UIAlertViewDelegate, MFMailComposeViewControllerDelegate> {
UIDatePicker *datePicker;
UIDatePicker *datePicker2;
ThePreviewViewController *_thePreview;
}
#property (nonatomic, retain) IBOutlet UITextField *toName;
#property (nonatomic, retain) IBOutlet UITextField *fromName;
#property (nonatomic, retain) IBOutlet UITextField *issue;
#property (nonatomic, retain) ThePreviewViewController *thePreview;
#property (nonatomic, retain) IBOutlet UITextField *expire;
#property (nonatomic, retain) IBOutlet UITextField *loveMessage;
#property (nonatomic, retain) IBOutlet UITextField *gift;
-(IBAction)build;
#end
The implementation file is:
#import "ThePreviewViewController.h"
#implementation CreateViewController
#synthesize toName, fromName, gift, loveMessage, issue, expire, datePicker, datePicker2;
#synthesize thePreview = _thePreview;
-(IBAction)preview {
if (_thePreview == nil) {
self.thePreview = [[ThePreviewViewController alloc] initWithNibName:#"ThePreviewViewController" bundle:[NSBundle mainBundle]] ;
}
_thePreview.issue.text = issue.text;
_thePreview.gift.text = gift.text;
_thePreview.expire.text = expire.text;
[self.navigationController pushViewController:_thePreview animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
However, after I connect all the outlets, the labels in ThePreviewViewController stay at null. Thoughts?
It looks like this is due to an issue which has been discussed here before: when you instantiate your ThePreviewViewController its UIKit instances are not yet available to have their properties set.
The solution is to create and set NSString properties on your ThePreviewViewController (or more compactly use an NSDictionary) which then use, in its ViewWillAppear event handler to set the properties of its UIKit elements.
Instead of setting UITextField text in ThePreview VC, you should set a NSString property. This is because the UITextField might not have been loaded yet and _thePreview.issue.text = issue.text, will have no effect, since _thePreview.issue has still not been created. So create a property (eg. NSString *issueString) in your ThePreview VC and then set that property as _thePreview.issueString = issue.text in your CreateViewController, and then finally in your ThePreview VC set your textField text in your viewDidLoad method using self.issue.text = self.issueString;
Hope this helps.

Resources