I have two classes, Step1 and Step2. Step1 contains a textfield called wrp. When the user enters a number in wrp in Step1, I would like to be able to work with it in Step2. Here is what I have tried (this is code in Step2):
int AdditionalDays;
Step1ViewController *wrp1 = [Step1ViewController new];
UITextField *wrp = [wrp1 wrp];
AdditionalDays = [wrp.text intValue];
TotalTotal.text = [[NSString alloc] initWithFormat:#"%i", AdditionalDays];
The app does not throw an error message, but the user-entered number in wrp in Step1 is disregarded in Step2. I don't know why it is not working. Any suggestions?
Because you create a new Step1ViewController
In the line Step1ViewController *wrp1 = [Step1ViewController new]; you are creating a new instance of Step1ViewController. What you need to to is get a reference to the original Step1ViewController the user entered the text in.
To do this, you would probably create a property in your Step2ViewController where you can pass in either the Step1ViewController, or even better, the value the user entered.
So in your Step2ViewController class header, add a property like this:
#property (assign) int additionalDays;
Then, when you create the Step2ViewController to display it on screen, you set this property to the value the user entered, like this:
Step2ViewController *controller = [Step2ViewController new];
controller.additionalDays = [wrp.text intValue];
// push the controller on a UINavigationController or something
The reason that this is happening is that in Step2 you have said:
Step1ViewController *wrp1 = [Step1ViewController new];
UITextField *wrp = [wrp1 wrp];
Unfortunately this isn't doing what you want it to do. Your app doesn't know what you're trying to do and so what the code is actually doing is "Please create a brand new Step1 and also create a brand new TextField, then give me the value of this brand new empty TextField".
Instead of being inside Step2 and working backwards to get the TextField, try to be inside Step1 and pass the value to Step2.
Related
I am creating a model and then adding that model to an array. However, once I add more than one item, some of the properties in my model ended up being duplicated.I have the following properties of type DrawnLayerModel:
model.overlay
model.fillcolor
model.linecolor
model.overlayString
OverlayString is the property that I'm most concerned with at the moment. Here is where I create the model object and add it to my array:
-(void)saveOverlay {
DrawnLayerModel *model = [self.drawnLayerModel initWithOverlay:self.mapView.overlays.lastObject fillColor:self.customFillColor lineColor:self.customLineColor overlayTitle:self.layerName];
[self.overlaysArray addObject:model];
for (DrawnLayerModel *model in self.overlaysArray) {
NSLog(#"Model ====> %#.", model);
NSLog(#"Title ====> %#.", model.overlayTitle);
}
}
Every time this button is pushed it adds a new model object:
- (IBAction)saveButtonPressed:(id)sender {
UITextField *textfield = alertController.textFields.firstObject;
self.layerName = textfield.text;
[self.helpers createSuccessAlertContoller:self mapView:self.mapView title:#"Layer Successfully Saved!" message:#"Choose the layers button in the navigation bar to access saved layers."];
[self saveOverlay];
}
I get the following output:
2018-02-05 13:47:12.387032-0800 prism[4910:1739598] Model ====> <DrawnLayerModel: 0x1c424d2c0>
2018-02-05 13:47:12.387166-0800 prism[4910:1739598] Title ====> Blue.
2018-02-05 13:47:12.387204-0800 prism[4910:1739598] Model ====> <DrawnLayerModel: 0x1c424d2c0>
2018-02-05 13:47:12.387235-0800 prism[4910:1739598] Title ====> Blue.
Now if you look at the DrawnLayerModel output these numbers are suspiciously the same:
0x1c424d2c0
Is that an address where the object was saved? Why are my properties being duplicated?
Once I add multiple models to my array
The problem is with the code that does that:
DrawnLayerModel *model = [self.drawnLayerModel initWithOverlay:self.mapView.overlays.lastObject fillColor:self.customFillColor lineColor:self.customLineColor overlayTitle:self.layerName];
[self.overlaysArray addObject:model];
You are just reinitializing the same persistent object over and over (self.drawnLayerModel). Thus, you are adding the same object to the array twice (or more). Adding an object to an array doesn't copy it, and an object pointer is merely a reference, so you are able to add multiple references to one object to an array.
The real problem here is that you have broken the most basic law of instantiation in Objective-C: Never say init without having said alloc in the very same set of square brackets. And vice versa: never say alloc without saying init in the same line.
So I have this problem in Objective-C. Let me set the stage of the problem.
I have a constraint, that doesn't allow me to modify the properties of an object. As it will assert that I am modifying that object without putting it between a write and commit transaction
ObjectA* constrainedObject = ...; // Retrieved from source with constraint applied.
constrainedObject.name = #"John"; // Assert tripped
[db writeTransaction];
constrainedObject.name = #"John"; // Does not assert
[db commitTransaction];
However if I create a new object, I can work around this limitation and modify the object by assigning the references to the unconstrainedObject.
ObjectA* constrainedObject = ...; // Retrieved from source with constraint applied.
ObjectA* unconstrainedObject = [[ObjectA alloc] init];
unconstrainedObject.id = contrainedObject.id;
// Change name here
unconstrainedObject.name = #"John";
unconstrainedObject.home = #"Mansion";
unconstrainedObject.age = constrainedObject.age; // Keep old property
// This illustrates the problem.
// I still want to keep some of the properties of the old
// object but have to manually type it in.
So my question is how do retrieve all the property references from the constrainedObject without manually typing that all out?
Is there a way to inspect and map the key value properties of an NSObject over to another NSObject of the same type ?
Related: https://github.com/realm/realm-cocoa/issues/1992
i try to add new object to my nsmutablearray but every time it replace all object
-(void)addToStack:(Coordinate *)coord{
Coordinate*c = [[Coordinate alloc] init];
c.x=coord.x;
c.y = coord.y;
if (coord.x==0 && coord.y==0) {
c.x=coord.x+1;
[_stack addObject:c];
c.x=coord.x;
c.y=coord.y+1;
[_stack addObject:c];
c.y=coord.y;
}
}
You are not adding a new object but you are changing the old object where the reference will remain the same.
NSMutableArray addObject will not add it because it already exists in the array.
So, when trying to add a new object, first create a copy of the one that you want to change, like this:
Coordinate *newCoordinate = [Coordinate mutableCopy];
// change attributes
// add it to the array
Everybody who said that adding the same object twice deletes the first instance and replaces it, is wrong.
Arrays can contain duplicate references to the same object. However, it's more like saving the same street address in an rolodex twice. If you look up the address in the first entry, go break all the windows in that house, then go back, look up the address in the second slot in your rolodex, and drive to THAT address, you'll find the house has broken windows (Because both addresses point to the same house.)
Similarly, when you add the same object to an array twice, it's two pointers to the same object. When you change values of the object at index 0, you see those changes reflected in the object in index 1 because it's a second pointer to the same object.
Despite saying the wrong thing about what goes wrong with your code, #Shashi3456643 gave you the correct solution, which is to create a new, unique object for every entry in your array.
Make sure to initiate the array:
NSMutableArray *stack=[[NSMutableArray alloc] init];
This is because every time you init the array. Initialize the array once.
For example:
in .h
Coordinate*c;
in .m
- (void)viewDidLoad
{
c = [[Coordinate alloc] init];
}
-(void)addToStack:(Coordinate *)coord{
c.x=coord.x;
c.y = coord.y;
if (coord.x==0 && coord.y==0) {
c.x=coord.x+1;
[_stack addObject:c];
c.x=coord.x;
c.y=coord.y+1;
[_stack addObject:c];
c.y=coord.y;
}
}
I've added a view controller as child like this:
UIViewController *sendViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"send"];
[self addChildViewController:sendViewController];
In the sendViewController I got this property:
#property (strong, nonatomic) IBOutlet StringInputTableViewCell *nameCell;
and in that class I can do something like self.nameCell.textField.text = #"test"; to set the textField to test
But how can I get this text thats filled in the textField in the parent class?
You are mixing model and view, thus breaking the MVC design pattern.
You should not try to read what is the content of a UI element. Rather you should have all the data (i.e. model) and the view (i.e. the UI, such as text fields) managed by a controller.
There are (easy) ways to get to this information, but I strongly advise you not to go down that road!
Basic inheritance between the parent and child class should allow you to pass the property forward.
You'll need to create a child object of the class say obj. Then to get the text value of the field you'll use (in the parent class)
id obj = [[ChildClassName alloc] init];
NSString *myChildsText = obj.nameCell.textField.text; // will get the value #"test" as assigned in the childclass.
Or of course, you can create a getter and setter in the Child Class for your #property. For example ::
- (IBOutlet)nameCell {
// returns the value
}
- (IBOutlet)setNameCell :(StringInputTableViewCell)newValue {
//set the value to the #synth value hereā¦
}
then you can call the child objects getters/setters as below ::
NSString *text = [obj nameCell]; //etc etc
You can use 4 approaches in here
a) keep reference to you childviewcontroller -> get the value directly
b) use delegate method ( best for observing changes in your textfield )
c) send NSNotification -> this comes with overhead, well at certain points it can help you a lot
d) KVO
I have a ViewController with a UITextField. The user enters a string of characters into the textField, clicks a done button and then this value should be passed to a method in the entity class. I know I need to pass this value as a parameter but I'm getting stuck.
I've tried to pass this value by adding a parameter to the end of the clickDone IBAction for the done button with no luck. Thank you for even the smallest bit of help or point into the right direction.
- (IBAction)doneClicked:(NSString*) name {
...
}
I've tried creating an ivar for ViewController in my entity class h file but Xcode asks "Unknown type name 'ViewController'; did you mean UIViewController?
#interface EntityClass : NSManagedObject{
ViewController* refVC;
UITextField* textBox;
}
and then use
self.name = self.refVC.textBox.text;
in my method in entity class m file to return the NSString self.name
Don't pass the ViewController to the Entity Object. Instead, update the entity object's property in your doneClicked action.
- (IBAction)doneClicked:(NSString *)name {
myObject.name = name;
}
I figured it out. This is my final code. It works. Help is no longer needed.
Thanks!
- (IBAction)doneClicked:(NSString*) name {
...
superClass.name = headingText.text; //headingText is UITextField on ViewController
[superClass doSomething];
...
}