#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:.
Related
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.
I subclassed my navigation bar, making the title view clickable. When clicked, it will present another view controller. I am creating a protocol in the navigation bar, that will tell the navigation controller that the title view has been clicked. Here is how my navigation bar is defined:
NavigationBar.h:
#protocol NavigationBarDelegate;
#interface NavigationBar : UINavigationBar
{
id <NavigationBarDelegate> delegate;
BOOL _titleClicked;
}
#property (nonatomic, assign) id <NavigationBarDelegate> delegate;
#end
#protocol NavigationBarDelegate
#optional
- (void)titleButtonClicked:(BOOL)titleClicked;
#end
The delegate implements one optional method. The .m file is as follows:
NavigationBar.m:
#implementation NavigationBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_titleClicked = 0;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
self.tintColor = [UIColor colorWithRed:(111/255.f) green:(158/255.f) blue:(54/255.f) alpha:(255/255.f)];
UIImage *image = [UIImage imageNamed:#"titlelogo.png"];
UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
titleButton.backgroundColor = [UIColor colorWithPatternImage:image];
[titleButton addTarget:self action:#selector(titleButton:) forControlEvents:UIControlEventTouchUpInside];
// self.navigationController.delegate = self;
[self.topItem setTitleView:titleButton];
[super drawRect:rect];
}
- (void)titleButton:(UIButton *)sender
{
_titleClicked = !_titleClicked;
[self.delegate titleButtonClicked:_titleClicked];
}
This creates a navbar with a logo and calls the titleButton method when the title button has been clicked. Everything is fine up till here and the navigation bar displays nicely.
In my RootViewController:
NavigationBar *navigationBar = [[NavigationBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 44.0f)];
navigationBar.delegate = self;
[self.navigationController setValue:navigationBar forKey:#"navigationBar"];
An implementation of titleButtonClicked is also there. When I click on the title view however, I get the following error: -[UINavigationController titleButtonClicked:]: unrecognized selector sent to instance
Why am I getting titleButtonClicked sent to UINavigationController? Is there something I need to do in my navigation controller? I am just using plain old UINavigationController. Do I need to subclass that too? If so, why?
EDIT:
Calling po self.delegate on line [self.delegate titleViewClicked:_titleClicked]; in NavigationBar.m yields the result below. How did the delegate change its type? How can I fix that?
(lldb) po self.delegate
(objc_object *) $1 = 0x07550170 <UINavigationController: 0x7550170>
As #idz said, the problem is with your:
#property (nonatomic, assign) delegete;
Don't you see that it's weird that you don't even have a:
#synthesize delegete;
That's because UINavigationBar already defines a delegate variable as idz said.
change your declaration to:
// use unsafe_unretained in ARC, not assign
#property (nonatomic, unsafe_unretained) myDelegete;
and of course
#synthesize myDelegate;
You have a clash/ambiguity between your delegate and UINavigationBar's delegate property. Rename your delegate to disambiguate them.
I have two properties setup properly in Objective-C:
#property (nonatomic, retain) IBOutlet UILabel *label;
#property (nonatomic, retain) IBOutlet UITextView *textView;
I have synthesised them and linked them in the NIB file however when I come to use them like:
if (row==0) {
NSLog(#"First text");
[self.label setText:#"LABEL 1"];
[self.textView setText:#"LABEL 1"];
}
else if (row==1) {
NSLog(#"Second text");
[self.label setText:#"LABEL 2"];
[self.textView setText:#"LABEL 2"];
}
The text is not changing however the NSLog is being called and not the setText: and I was wondering why...
It should be a IBOutlet for you to link them in xib.
Now that you updated your question, the problem may be you have not connected it to your viewcontroller's property. Hence the result. Add more details to your question.
Make sure that Xib and IBOutlet were correct linked.
Make sure that your label and testView are visible. You can set their background color red or other any color different with bg to check their visibility.
Make sure that the line "[self.label setText:#"LABEL 1"];" had ran. you can check the NSLog.
Make sure that the line "[self.label setText:#"LABEL 1"];" was running in main thread.
If your properties are outlets you should declare them as follows:
#property (nonatomic, retain) IBOutlet UILabel *label;
#property (nonatomic, retain) IBOutlet UITextView *textView;
The behaviour you are seeing suggests that you haven't set up the outlet correctly.
FIRST METHOD:
It should be declared as an IBOutlet and you should link it to a label and textView in XIB as Praveen S has said.
SECOND METHOD:
Other option if it is not a label in XIB then you need to allocate and initialize the label to set its text i.e. to access its properties/methods/attributes.
UILabel *label = [[UILabel alloc] init];
[label setText:#"Text"];
label.frame = CGRectMake(0,0,20,20);
Hope this helps.
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.