I have a barcode scanner on one view, and after the user has scanned the barcode, the app takes them to another view (BoilerDetails) where the barcode text field has been pre-filled.
I understand that the viewcontroller is null when it hasn't come into view and I can'tchange the UITextField text directly. This so far has given me an error.. How can I fix this?
BarcodeScannerViewController.m
BoilerDetailsViewController *viewCtrl = [[BoilerDetailsViewController alloc] initWithNibName:nil bundle:nil];
[viewCtrl setBarcode:strBarcode];
[self.navigationController pushViewController:viewCtrl animated:YES];
BoilerDetailsViewController.h
#interface BoilerDetailsViewController : SubViewControllerBase
#property (retain, nonatomic) NSString *barcode;
#property (retain, nonatomic) IBOutlet UITextField *barcodeField;
- (void)setBarcode:(NSString*)strBarcode;
#end
BoilerDetailsViewController.m
-(void)setBarcode:(NSString *)strBarcode
{
self.barcode = strBarcode;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[_barcodeField setText:self.barcode];
// Do any additional setup after loading the view from its nib.
}
-(void)setBarcode:(NSString *)strBarcode
{
self.barcode = strBarcode;
}
I think that these strings give you infinite loop. According to your logic you should use:
-(void)setBarcode:(NSString *)strBarcode
{
self.barcodeField.text = strBarcode;
}
or
#syntesize barcode = _barcode;
-(void)setBarcode:(NSString *)strBarcode
{
[_barcode autorelease];
_barcode = [strBarcode retain] //in case of no ARC
}
Depends on what you want (store a string or set a label).
you just have to synthesize the barcode and in ViewDidload just write this code [_barcodeField setText:barcode]; and good to Go.
First of all, this is wrong
-(void)setBarcode:(NSString *)strBarcode
{
self.barcode = strBarcode;
}
self.barcode = strBarcode; itself calls the setter.
depending on your ios version you shud write:
//for ARC environment
-(void)setBarcode:(NSString *)strBarcode
{
_barcode = strBarcode;
}
//since default association in ARC is strong
before this do #synthesize barcode = _barcode;
//and for non-ARC environment, since your property is retain type
-(void)setBarcode:(NSString *)strBarcode
{
if (_barcode != barcode) {
[_barcode release];
_barcode = [barcode retain];
}
}
And you will be OK.
Related
Ok so I am trying to pass data from one view controller to another via the following code but its not working and I have no idea why.
In my ViewController.m I have imported ViewControllerTwo.h and declared ViewControllerTwo:
#import "ViewController.h"
#import "ViewControllerTwo.h"
#interface ViewController ()
#end
#implementation ViewController
{
ViewControllerTwo *settings;
}
#synthesize blockSizeLB;
#synthesize wpmLB;
#synthesize textTV;
#synthesize slider;
#synthesize stepper;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//sets label to corresponding value
wpmLB.text = [NSString stringWithFormat:#"WPM: %#", [[NSNumber numberWithInt:slider.value] stringValue]];
//configure stepper and its label to default values of 1
stepper.value = 1;
blockSizeLB.text = [NSString stringWithFormat:#"Block Size: %#", [[NSNumber numberWithInt:stepper.value] stringValue]];
//sets properties for next ViewController
settings = [[ViewControllerTwo alloc] init];
settings.timerValue = 60 / slider.value;
settings.text = textTV.text;
settings.blockCount = stepper.value;
}
In ViewControllerTwo.h I have:
#property (nonatomic) float timerValue;
#property (nonatomic) NSString * text;
#property (nonatomic) int blockCount;
Later on in the ViewController.m I need to change the properties defined in ViewControllerTwo:
Method from ViewController.m. This is also done earlier in my viewDidLoad to set the default values of the properties:
- (IBAction)sliderSlide:(id)sender
{
//event when the slider value is changed
//rounds value to nearest increment of 5
int increment = 5 * floor(((int)slider.value/5)+0.5);
[slider setValue:increment animated:YES];
//changes WPM: 0 label text
wpmLB.text = [NSString stringWithFormat:#"WPM: %#", [[NSNumber numberWithInt:increment] stringValue]];
//sets properties for next ViewController
settings.timerValue = 60 / slider.value;
}
I try to test if this is successful by calling a method in ViewControllerTwo.m that logs its property blockCount via NSLog. The output however is (null) meaning I was unsuccesful in passing the data from ViewController.m to ViewControllerTwo
If you are using segues, you should be doing this inside of:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Then name your segue, then do something like this:
if([segue.identifier isEqual: #"segue_From_1_To_2"])
{
ViewControllerTwo *vc2 = segue.destinationViewController;
vc2.timerValue = 123.45;
vc2.text = #"whatever";
vc2.blockCount = 1;
}
You can create a custom initializer in your viewControllerTwo. name it initWithTimerValue:
- (id)initWithTimerValue:(CGFloat)timerValue
{
self = [super init];
if (self) {
self.timerValue = timerValue;
}
return self;
}
I am creating a custom table-view cell generator and I want to pass in a reference to an Object created in a base class which will be mutated in a separate VC while the originating object class will reflect these changes:
//MutableTableViewObjects.h
#interface MutableTableViewObjects : NSObject
#property (retain, atomic) NSDate *startDate;
//MutableTableViewObjects.m
- (id) init {
self = [super init];
if (self) {
self.startDate = [[NSDate alloc] init];
}
return self;
}
then I want a call in a separate view controller to change the value of startDate
self.objectClass = [[MutableTableViewObjects alloc] init];
DateOptionCellInput *startDateCell = [[DateOptionCellInput alloc] initDateInputForObject:self.objectClass.startDate withDefault:[NSDate date] withTitle:#"start date" inSection:#"Dates"];
From here I want startDateCell to modify the value of startDate and have self.objectClass.startDate reflect the changes happening to its value in other classes/threads
Is this even possible or should I seriously reconsider the architecture?
Currently the value changes in the VC but it is never updated in the base object class. Is there some property parameters I can pass in to allow this?
edit: here is how date cell will
#interface BaseOptionCellInput : NSObject
#property (atomic) NSObject* observedObject;
- (id) initType:(NSString*) optionType withTitle:(NSString*) titleString inSection:(NSString*) sectionHeaderString {
self = [super init];
if (self) {
self.title = titleString;
self.sectionHeader = sectionHeaderString;
self.identifier = optionType;
}
return self;
}
- (void) setManagedObject:(NSObject*) managedObject withDefaultValue:(NSObject*) defaultvalue {
self.observedObject = managedObject;
self.defaultValue = defaultvalue;
}
- (void) updateContextWithValue:(NSObject*) newValue {
if ([self.observedObject class] == [newValue class]) {
self.observedObject = newValue;
}
}
and then DateCell is a subclass of BaseCell and calls updateContextWithValue from a delegate method triggered in the VC.
I know I can accomplish this if I used a dictionary to pass the values of objects back and forth but I was hoping it was possible just passing a pointer to the object?
I imagine in initDateInputForObject function you are just using the value from the passed in object and assigning it to startDateCell's member variables.
What you want to do is probably keep a pointer to the MutableTableViewObjects object so you can directly modify the date value in there.
If you can add the code for MutableTableViewObjects I can elaborate with better clarity rather than shoot arrows in the dark :)
But hopefully you get the idea of what I am saying. Point being that no where in your code the orig MutableTableViewObjects object values are being updated.. Just because you used it to initialize another object doesn't mean it will stay updated when you change second object.
EDIT:
Lets say I have an class A with NSDate*
A.h
#interface A : NSObject
#property NSDate *startDate;
}
with A.m
- (id) init {
self = [super init];
if (self) {
self.startDate = [[NSDate alloc] init];
}
return self;
}
Now there is a class B as follows that contains an object of A.
B.h
#interface B : UITableViewController
#property (strong, nonatomic) A *aObject;
#end
and B.m
- (void) some function {
self.aObject = [[A alloc] init];
}
Now if you change self.aObject.startDate, you should be able to change the value of data in A directly.
If its not working as expected, tell me exactly what it is and where it is happening
thx
So I got this for loop in a function, but it never gets entered,
for (Window *window in _app.windows) {
NSLog(#"test.");
}
I'm a beginner so where do I start to debug this and see where it goes wrong?
EDIT
This is in another class
(its in a function (loadApp) that I call in my ViewController, like this: self.app = [MyClass loadApp]; , the above code is also in my ViewController.
Window *window = [[Window alloc] initWithName:title subtitle:subtitle number:number ident:ident type:type chapternumber:chapternumber icon:icon text:text img:img question:question answerFormat:answerFormat answerLength:answerLength tip1:tip1 tip2:tip2 tip3:tip3 tip1Answer:tip1Answer tip2Answer:tip2Answer tip3Answer:tip3Answer];
[app.windows addObject:window];
}
return app;
Try the following
if(!_app) {
NSLog(#"app is nil");
}
else if(!_app.windows) {
NSLog(#"windows is nil");
}
else {
NSLog(#"there are %d windows", [_app.windows count]);
}
I suspect you'll see there are 0 windows
You have to make sure you are accessing the same variable. That is the gist of all the other comments and answers you are getting. It needs to be setup something like this. Keep in mind, your app may not be setup exactly like this. This is just a general structure to follow:
//myViewController.h
#import "WindowClass.h"
#import "AppClass.h"
#property (strong, nonatomic) AppClass *app;
//myViewController.m
#import "myViewController.h"
#synthesize app;
(id)init....{
//...init code here
//Synthesized objects must be initialized before they are accessed!
self.app = [[AppClass alloc] init];
return self;
}
(void)loadApp {
WindowClass *aWindow = [[WindowClass alloc] init];
[self.app.windowArray addObject:aWindow];
return;
}
(void)loopFunction {
for (WindowClass *window in self.app.windowArray) {
NSLog(#"test.");
}
return;
}
//AppClass.h
#property (strong, nonatomic) NSArray *windowArray;
//AppClass.m
#import "AppClass.h"
#synthesize windowArray;
I have two UIViews. One UIView, called SelectText has an ivar of NSMutableArray which is populated after performing a certain function.
Here is a snippet code:
- (void)fillDrawPoints
{
//the codes....
[self.drawnPoints addObject:[NSValue valueWithCGPoint:currPoint]];
}
NOTE: The drawnPoints array is initialized in the initWithFrame of SelectText. Also, I always check if the array is actually populated inside the view by putting a log in the function.
Now what I want to do is to access this array from another view. This is what I do:
TextView.h
#import "SelectText.h"
#interface TextView : UIView
{
SelectText *txtSel;
}
#property (nonatomic, retain) SelectText *txtSel;
TextView.m
#synthesize txtSel;
- (void)getDrawingPoints:(NSMutableArray *)pointArray
{
self.pointArray = pointArray;
NSLog(#"Array count: %d", [self.pointArray count]);
}
As you can see from the above code, I am trying to pass the data inside txtSel.drawnPoints to the textView.pointArray for later use. The problem is, the txtSel.drawnPoints always returns empty when I try to access it from another view. What am I doing wrong here?
ADDITIONAL:
This is how I instatiate SelectText
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
txtSel = [[SelectText alloc]init];
[self addSubView:txtSel];
//rest of code...
}
change TextView class init method as below
- (id)initWithClassSelectText:(SelectText *)selectText {
if ((self = [super init])) {
txtSel = selectText;
}
return self;
}
And when you make an instance of TextView you use this:
TextView textView = [[TextView alloc] initWithClassSelectText:self];
now you can access all properties of SelectText class using txtSel object
I am new to iPhone development, I have a program that has 7 UITextFields visableenter code here. When the user picks a number on the UIPicker View (1-5) that many UITextFields become hidden and unusable. That program works well. I want to have the same number that was picked from that .m file and transfered to another .m file so that 1-5 UITextFields are hidden and unusable. If it matters, the first .m file is abc.m and the second one is bca.m
if it matters I use [textfield sethidden= YES]
Thanks
You need to keep references to all those objects in the class, and define properties to them so that you can refer to them in the second .m file.
So assuming you have a classes, abc.m
#interface abc {
UITextField *text1;
}
#property (nonatomic, retain) UITextField *text1;
#end
#implementation abc
#synthesize text1;
- (id) init {
if (self = [super init]) {
text1 = [[UITextField alloc] initWithFrame:CGRectMake(0,0,150,10)];
}
return self;
}
- (void)dealloc {
[text1 release];
[super dealloc];
}
Then you can use the text1 property to refer to that text field, given that you have instantiated the object in the second class, or hold a reference to it.
[[MyClass alloc] initWithFrame: CGRectZero andSomeString: #"Hello World!"];
MyClass
- (id)initWithFrame:(CGRect)frame andSomeString:(NSString*)aString
{
if (self = [super initWithFrame:frame])
{
someString = aString;
}
return self;
}
You could try making a BOOL or several BOOL variables and set it equal to YES or NO then put that into your text fields.
BOOL isVisible = YES;
[textfield setHidden:isVisible];
and then if you use a pushViewController you can set the isVisible from bca.m equal to the isVisible in abc.m
viewController.isVisible = isVisible;