I have a very simple application. I have a button and a label in IB. I have an IBAction for onClick that calls setText on the label. There's an outlet for the label. Everything is connected in IB. It crashes the app the first time in the simulator. When I launch it again, it sets the text. Then crashes again next time. It always crashes on the actual device. This should be simple, but I'm not sure what I'm doing wrong.
Thanks.
in my .h file :
#import <UIKit/UIKit.h>
#interface UntitledViewController : UIViewController {
IBOutlet UILabel *label;
IBOutlet UIButton *button;
}
#property (nonatomic, retain) UILabel *label;
-(IBAction) onClick1: (id) sender;
#end
and in the .m:
- (IBAction) onClick1: (id) sender
{
//[label setText:#"Hello World!"];
label.text = #"Hello World!";
//[button setTitle:#"Clicked" forState:UIControlStateNormal];
}
Sorry, I'm new to the site. How do I get the crash log and the stack? Thanks.
EDIT : While this answer is technically correct, it doesn't answer the question at all :( Sorry
< warning - this is a guess >
If you're getting a crash setting the label's text then it tells me that you have set a value to label in the past but it's not been retained correctly.
I'm guessing you have code like this :
label = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,10,10)] autorelease];
when you should have code like
// Option 1
self.label = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,10,10)] autorelease];
or
// Option 2
label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,10,10)];
( the first one uses the property to retain to label. The second one doesn't autorelease it. The first one is the recommended way )
Double check you set connection for label in IB.
Put breakpoint in debugger on line label.text = #"Hello World!";
And make sure label is not nil here.
If it is nil you didn't set connection in IB for it.
Related
I have two views, and i'm trying to show text that i getting from first view in UITextField of another . Second view shown by - (source) so methods ViewWillAppear and ViewDidLoad won't work. And viewDidLoad method of second view is runs when app is started.
I'm tried to make method of second class
secondClass.h:
#property (strong, nonatomic) IBOutlet UITextField *itemName;//all hooked up in storyboard
-(void)SetName:(NSString *)name;
secondClass.m:
-(void)SetName:(NSString *)name{
NSLog(#"%#",name);
itemName.text = name;//itemName - textField
}
and use it in first one:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
[secondView SetName:#"Bill"];
NSlog shows "Bill" but textField.text won't change anything.
My guess that app shows UITextField without changes because it shows second view that it gets from viewDidLoad method and i need to update it somehow
My question: What is the best approach to change attributes of UI elements from different classes?
Easiest way:
secondViewConroller.h :
#property NSString * conversationName;
secondViewConroller.m :
#synthesize conversationName;
-(void)SetName:(NSString *)name{
NSLog(#"%#",name);
itemName.text = conversationName
}
On alloc:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
conversationName = #"Set this text";
[secondView SetName:#"Bill"];
I would suggest you to read about Protocols after that.
Easiest way:
in
secondViewConroller.h :
#property (nonatomic, retain) NSString *stringName;
secondViewConroller.m :
#synthesize stringName;
and in viewDidLoad method you write this line
itemName.text = stringName
On alloc:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
secondView.stringName = #"Set this text";
guess there is something wrong with your itemName variable if it appears to get to the nslog.
did you create a referencing outlet in the interface builder for the textfield?
otherwise you can get the right textfield by tag, in IB put for instance tag 1 on the textfield and do in code:
UITextField *tf=(UITextField*)[self.view viewWithTag:1];
tf.text=name;
(replace self.view for the view holding the textfield, if not directly in the main view)
So i found a solution: There's was something wrong with calling method SetName: with parameters that i getting from first UIViewController.
Basically the solution is : create NSObject and put in there value from first UIViewConroller and then use it in second.
This TUTORIAL helped me to resolve the problem.
having a little issue in an ARC environment. Creating an NSObject that adds a view to a parent view - it's basically a 'popup class' that can handle some text and display it.
In a view controller it's instantiated..
CBHintPopup *popup = [[CBHintPopup alloc]init];
[popup showPopupWithText:#"test text" inView:self.view];
And the actual class files..
CBHintPopup.h
#interface CBHintPopup : NSObject {
}
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view;
-(IBAction)closePopup;
#property (nonatomic, strong) UIView *popupView;
#property (nonatomic, strong) UIImageView *blackImageView;
#property (nonatomic, strong) UIButton *closeButton;
#end
CBHintPopup.m
#implementation CBHintPopup
#synthesize popupView,blackImageView, closeButton;
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view {
//CREATE CONTAINER VIEW
self.popupView = [[UIView alloc]initWithFrame:CGRectMake((view.frame.size.width/2)-(225/2),-146,225,146)];
self.popupView.alpha = 0;
self.popupView.backgroundColor = [UIColor clearColor];
//CREATE AND ADD BACKGROUND
UIImageView *popupBackground = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,225,146)];
popupBackground.image = [UIImage imageNamed:#"hintbackground.png"];
[self.popupView addSubview:popupBackground];
//CREATE AND ADD BUTTON
self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.closeButton addTarget:self action:#selector(closePopup) forControlEvents:UIControlEventTouchUpInside];
[self.popupView addSubview:self.closeButton];
//CREATE AND ADD LABEL
UILabel *popupTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(22,25,176,93)];
popupTextLabel.text = text;
[self.popupView addSubview:popupTextLabel];
[view addSubview:self.popupView];
}
-(void)closePopup {
NSLog(#"HI");
}
Recieving the following once closePopup is called via pressing the button ('HI' is not printed)..
-[CBHintPopup performSelector:withObject:withObject:]: message sent to deallocated instance 0x246b2fe0
I've tried retaining the button in non-ARC and a load of other methods but simply having no luck. Probably something real simple but i can't nail it. I've removed all the setting up of the labels and images etc to save some space, so ignore alpha's etc.
Any help will be much appreciated, thanks for your time.
Have you implemented the constructor for CBHintPopup,since you have called the constructor
[[CBHintPopup alloc]init];
you have to implement the constructor method like this
in .m file of CBHintPopup
-(id)init{
if(self == [super init]){
// do some initialization here
}
return self;
}
I tried your code and found the crash you mentioned. I found a solution for fixing the crash.
I declared the CBHintPopup *popup; in the viewController's interface. And changed this line
CBHintPopup *popup = [[CBHintPopup alloc]init];
to
popup = [[CBHintPopup alloc]init];
Everything worked fine for me. But I couldn't find the reason behind this. Hope this will help you.
Found a fix for it - instead of CBHintPopup being an NSObject, i simply made it a sub-class of UIView and added self to the parent view (instead of self.popupView). I wouldn't really call this a 'fix' though - more of an alternative method. Surely an NSObject can add a UIView (with a UIBUtton) to a parent view with no problems? Is this a bug?
Make sure you are retaining the object for class CBHintPopup.
I think the crash is coming because object of CBHintPopup deallocates. And hence the action method is not found.
I am developing an IPhone application and trying to create a custom TextField with caption on it like image below.
As you can see from image Label is changed by the value that user enters or read from database. Also there are other textfields other than name.
I couldn't be sure how should i implement this custom textfield?
One way i think placing an image with "Name:" text to background of textfield and placing "Label" value on it, other way is placing an image with only borders and inserting "Name: Label" text on it.
Are these ways suitable or is there any other best approach available?
Edit: Borders on image are textfield's border; also "Name: Label" is above on textfield.
Simply put another label with the desired text behind or beside the label or text field that is going to be filled. You can set the font and textColor and even the alpha according to your taste.
Make sure that if they overlap (which they should not!) the backgroundColor property of the label is set to [UIColor clearColor].
You could subclass UITextField like this:
#interface LabeledTextField : UIView
#property (nonatomic, strong) UILabel *label;
#property (nonatomic, strong) UITextField *textField;
#end
#define kPercentWidth 0.5
#implementation LabeledTextField
-initWithCoder:(NSCoder)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
CGRect f = self.frame;
_label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,
f.size.width*kPercentWidth,f.size.height)];
_textField = [[UITextField alloc] initWithFrame:CGRectMake(0,0,
f.size.width*(1-kPercentWidth),f.size.height)];
[self addSubView:_label];
[self addSubView:_textField];
}
return self;
}
#end
You could then use it like this: insert a UIView into your storyboard view controller and change the class to your LabeledTextField. This would ensure initWithCoder is called. Otherwise, you might have to put the init code into its own setup function and call it from your override of initWithFrame. Make sure you wire up the view with your outlet
// .h
#include LabeledTextField.h
//...
#property (nonatomic, strong) IBOutlet LabeledTextField *labeledTextField;
// .m, in some method
labeledTextField.textField.text = #"editable text";
labeledTextField.label.text = #"non-editable text";
Similarly, you could modify all properties of the label and text field, including colors, fonts etc.
#interface SomeViewController : UIViewController <UITextViewDelegate>
#property (retain, nonatomic) IBOutlet UIImageView *imageView;
#property (nonatomic, retain) UIImage *image;
#property (nonatomic, retain) IBOutlet UITextView *textView;
I need textview(editable) in my view controller.
so I set protocol ,
and also, IB to the file's owner, too. (I don't know, is it unnecessary?)
And my .m file.... viewDidLoad..
_textView = [[UITextView alloc]init];
[_textView setFrame:CGRectMake(8, 110, 304, 82)];
[_textView setFont:[UIFont boldSystemFontOfSize:12]];
_textView.editable = YES;
//[textView setText:#"hdgffgsfgsfgds"];// if uncommented, this actually visible...
[self.view insertSubview:_textView atIndex:2];
So far, it's working. But I want these methods to run...
- (void)textViewDidChange:(UITextView *)textView
{
if([_textView.text length] == 0)
{
_textView.text = #"Foobar placeholder";
_textView.textColor = [UIColor lightGrayColor];
_textView.tag = 0;
}
}
But after build, my textview is still empty.
What did I wrong?
You need to add the delegate to your textview, try with this:
_textView.delegate = self;
On the other hand,
textViewDidChange
Will only work when you change your text, if you want to place a text in the textview, you can do:
_textView.text = #"Foobar placeholder";
_textView.textColor = [UIColor lightGrayColor];
_textView.tag = 0;
In your ViewdidLoad
When synthesizing the textView, do you do it like #synthesize textView = _textView so that you can use the underscored name? Usually the underscored one is used only in the setter/getter methods (for instance when overriding them).
Note that
The text view calls this method in response to user-initiated changes to the text. This method is not called in response to programmatically initiated changes.
This is from Apple's documentation for the method you are using. This means if you are changing the text through the code, the method will not get fired.
Are you expecting [textView setText:#"hdgffgsfgsfgds"] to in turn invoke textViewDidChange:? Calling setText will not automatically invoke the textViewDidChange:.
I am new to objective C and I have a c++ background. I want to display a value in the label on the screen. I am calling the label value from the MainView.m. However, the label becomes blank after I click a button instead of printing a value. What is the problem? Here is the code.
MainView.h
#interface MainView : UIView {
int a;
}
-(int) vr;
#end
MainView.m
-(int) vr
{
return 100;
}
#end
MainViewController.h
#interface MainViewController : UIViewController {
IBOutlet UILabel *myLabel;
NSMutableString *displayString;
MainView *view1;
}
#property (nonatomic, retain) UILabel *myLabel;
#property (nonatomic, retain) NSMutableString *displayString;
(IBAction)showInfo;
(IBAction) pressButton:(id) sender;
#end
MainViewController.m
#synthesize myLabel, displayString;
-(IBAction) pressButton:(id) sender{
[displayString appendFormat:#"%i", view1.vr];
myLabel.text = displayString;}
- (void)viewDidLoad {
view1 = [[MainView alloc] init];
[super viewDidLoad];}
- (void)dealloc {
[view1 dealloc];
[super dealloc];}
I have not mentioned code that had been auto generated. This is enough to get the whole picture. I tried a lot to debug this thing. I believe that IBAction carries out direct command such that
myLabel.text = #"string";
but it does not invoke any method or class. Any subtle ideas? Thanks.
Few issues:
1
In MainView.h you declare -(id) vr;
And in MainView.m it returns int.
2
Maybe pressButton is not connected to the right event in Interface Builder (it is usually touch up inside).
Try to write to log in this method.
3
Maybe myLabel is not connected to the label in the Interface Builder.
Try to set tome hard-coded string to label's text property.
4
Do you initiate view1 in some place?
Can you post this piece of code too?
5
You can use [displayString appendFormat:#"%i", view1.vr];...
EDIT (due to changes in question):
6
The line [super viewDidLoad]; should be the first line inside viewDidLoad.
7
[view1 dealloc]; - never call dealloc directly on objects. Call release instead. The only place, where you can and should use dealloc is the line [super dealloc]; inside dealloc method.
8
When you format your question/answer in Stack Overflow, remember that each code line should start with at least 4 spaces (or tab). Try reformatting you question by adding 4 spaces in the beginning of each code line.
9
I think that displayString is not initiated. Add the next line in the viewDidLoad: displayString = [NSMutableString new];