I'm new in iphone development.now, I'm facing one warning in my project.while,setting the delegate of UITextfield in ios 6 I'm getting the warning that
"**incompatible pointer types sending 'class' to parameter of type '<uitextfielddelegate>'**"
+(UITextField*)tableLabelForText:(NSString *)txt frame:(CGRect)frm isEditable:(BOOL)isEditable
{
UITextField *txtField = [[UITextField alloc] initWithFrame:frm];
[txtField setEnabled:isEditable];
[txtField setText:txt];
[txtField setTextColor:[UIColor blackColor]];
[txtField setDelegate:self];
return txtField;
}
You are trying to assign the delegate in a class method which has no idea of the initialised object. Hence the warning. What you need to do is setDelegate to the initialised object.
[txtField setDelegate:<MyObject>];
Or you can as one of the answers suggests change the class methods to instance method.
-(UITextField*)tableLabelForText:(NSString *)txt frame:(CGRect)frm isEditable:(BOOL)isEditable
You are using a Class level method "+" to return a text field instance, change it to Instance Level Method "-". i.e:
-(UITextField*)tableLabelForText:(NSString *)txt frame:(CGRect)frm isEditable:(BOOL)isEditable
If I am not wrong , you are setting Delegate for an NSObject class ,
as NSObject class does not have any views , so UITextFieldDelegate does not confirms to the class. Instead use UIView
#interface ClassName : UIView <UITextFieldDelegate>
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.
So please forgive me as I am very new to stackoverflow and to ios programming in general.
I am attempting to change the text of a button i have, replacing current text with a date string (dateStringForInput) I am passing in from another class. The button is called myTodayButton and is declared in my .h file for my class inputMilesViewController...
#property (strong, nonatomic) IBOutlet UIButton *myTodayButton;
Below is the code from my .m.
+(void) changeButtonText:(NSString*) dateStringForInput{
NSLog(#"we got to changebuttontext");
[_myTodayButton setTitle:dateStringForInput forState:UIControlStateNormal];
}
I am getting the following error "Instance variable "_myTodayButton" accessed in class method.
I understand that this is written in a class method rather than an instance method but i cant figure out how to get this change to happen. the button which prompts this call to changeButtonText is in the other class which is creating dateStringForInput.
Try like this...
For (+) instance.
+ (void) changeButtonText: Only have access to the self object.
--Step 1: Remove follwing line from header file
#property (strong, nonatomic) IBOutlet UIButton *myTodayButton;
--Step 2:
Add UIButton *myTodayButton in your class file globally..
That means declare before #implementation
Eg: In .m File
#import "Controller.h"
UIButton *myTodayButton // Add like this before #implementation
#implementation Controller
For (-) instance
- (void) changeButtonText: Only have access to the instance methods
Class methods do not have access to instance variables, that's why you're getting the error you're seeing.
You need to change the method to an instance method:
- (void)changeButtonText:(NSString *)dateStringForInput;
Then you will need to pass or obtain a reference to the instance of the class containing the method to the class calling the method.
I hope that makes sense... Add a comment if you need any clarification!
change method to an instance method instead of a class method ("-" instead of "+") create an instance of the class and then simply call it like so:
MyClass *classInstance = [[MyClass alloc] init];
[classInstance changeButtonText:#"stringText"];
Also its recommended to have weak properties for IBOutlets.
#property (nonatomic, weak) IBOutlet UIButton *myButton;
[EDIT]
Regarding your second issue with segues. Firstly do you really need a different view controller for simply displaying a UIDatePicker? I normally display them in the same UIViewController using an actionSheet, its a little work to get just right but solves this problem. I can post the code if you like?
Anyway if you want to keep your current setup I would do the following:
In the ViewController that contains the button create a new public NSString property in the .h file.
#property (nonatomic, strong) NSString *dateString;
In the View Controller that contains the date picker, after the user has selected the date override the perpareForSegue method. In here get the destination view controller (which is the one with the button and new string property created in point one above) and set the dateString.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
MyViewController *todayViewController = (MyViewController*)[segue destinationViewController];
[todayViewController setDateString:#"valueYouRequire"];
}
In the ViewController with the button set the button's title in the viewDidLoad to be the dateString.
(void)viewDidLoad
{
[super viewDidLoad];
if (self.dateString) [self.myTodayButton setTitle:self.dateString forState:UIControlStateNormal];
}
[EDIT]
If you want to go down the actionSheet route then add this method to the ViewController with the button and play around with the frame sizes to fit your needs. The method below creates a date picker, adds it to an actionSheet and displays the actionSheet.
- (IBAction) datePressed:(id)sender {
if (!_actionSheet) {
_actionSheetFrame = CGRectMake(0, self.view.frame.size.height - 373, 320, 403);
_actionSheetBtnFrameOk = CGRectMake(20, 330, 280, 50);
_actionSheetBtnFreameCancel = CGRectMake(20, 275, 280, 50);
_pickerFrame = CGRectMake(0, 50, 320, 216);
_actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select Date" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"OK", nil];
_datePicker = [[UIDatePicker alloc] init];
[_datePicker setDatePickerMode:UIDatePickerModeDate];
[_actionSheet addSubview:_datePicker];
}
[_datePicker setMaximumDate:[NSDate date]];
[_actionSheet showInView:self.view.superview];
[[[_actionSheet subviews] objectAtIndex:kActionBtnIndexOk] setFrame:_actionSheetBtnFrameOk];
[[[_actionSheet subviews] objectAtIndex:kActionBtnIndexCancel] setFrame:_actionSheetBtnFreameCancel];
[_actionSheet setFrame:_actionSheetFrame];
[_datePicker setFrame:_pickerFrame];
}
You will also have to implement the UIActionSheetDelegate method to set the button's text once the user has selected his desired date.
#pragma mark - UIActionSheet Delegate Methods
- (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[self.myTodayButton setTitle:self.dateStringFromSelectedDate forState:UIControlStateNormal];
}
}
I have a view controller class with the following code:
-(void) awakeFromNib{
RootModel *rm = [RootModel sharedModel];
for(NSString *title in rm.rLevels) {
[self addNewButtonWithTitle:title];
}
}
// add a new button with the given title to the bottom of the list
- (void)addNewButtonWithTitle:(NSString *)title
{
// create a new button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
}
the statement
[self addNewButtonWithTitle:title];
generates a warning:
method addNewButtonWithTitle not found.
Con't figure it out.
Thanks
You have 3 options to get rid of the warning:
Declare the method in the #interface block.
If you do not want to expose the method in your interface:
Declare the method in a class extension.
Implement the method above the first call to it.
Have you added method in .h file ?
You need to declare that method in your header file and if not then the method definition should be above the place where you call it.
So in your header file of whereever you have written #interface add the line :
- (void)addNewButtonWithTitle:(NSString *)title
I have a class which is an NSObject type, and in a view it won't let me put:
[self.view addSubview:nsObject];
because it's an incompatible type. How can i get this to work?
The addSubview: method only takes instances of UIView. It won't work with NSObject.
Check out the method specification in the Apple Docs
You need the object you're adding to be of the type UIView or inherit from it. In your class declaration, simply put:
#interface MyClasS : UIView {
I assume that nsSubview is a subclass of UIView and just by typing, arg passing the compiler is seeing it as an NSObject? Or is it some kind of wrapper object that contains a UIView? You could try:
UIView *v = (UIView *)nsSubview ;
[ self.view addSubview:v] ;
I'm reasonably new at the iPhone SDK, so please forgive me if this answer's ridiculously obvious.
I have a ViewController connected to a .xib file (they are called FirstViewController)
I also have a custom class called MyCustomClass. In this class, I have a method like this:
- (void)setTheText {
[myLabel setText:#"foo"];
}
I want to call this method to set the text in a label in FirstViewController.xib
So far, I have done this:
Dragged in an "Object" into Interface Builder, and set the class to: MyCustomClass
Connected up the IBOutlet 'myLabel' from MyCustomClass to a UILabel in the view.
However, when I run the program, and press the button to set the label (which is in FirstViewController.m), something like:
- (IBAction)doSomething:(id)sender {
MyCustomClass *customClass = [MyCustomClass alloc] init];
[customClass setTheText];
}
This doesn't set though. NSLog(#"%#",[myLabel text]); returns (null)
Xcode shows no errors or warnings, what could be wrong?
Thanks,
Michael
Additional Info:
Interface to MyCustomClass.h:
#import <UIKit/UIKit.h>
#interface MyCustomClass : NSObject {
UILabel *myLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
- (void)setTheText;
#end
You don't want to create a new instance of your custom class in your action method.
There are a couple of ways to do what you want.
Option 1 is to give your view controller a reference to your custom object. To do this, create an outlet of type MyCustomClass * in your view controller, connect that outlet to the new object that you created in your XIB file, and then get rid of the allocation in your action method:
- (IBAction)doSomething:(id)sender {
[customClass setTheText];
}
Option 2 is to let your CustomClass handle both the label and the action method. To do this, you can simplify things even further. Put an outlet for the UILabel into your CustomClass, and then simply convert your setTheText method into an action:
- (IBAction)setTheText:(id)sender {
[myLabel setText:#"foo"];
}
Now, connect that action up to your button, and everything should work like a charm.
Note: You should probably use a method name that does not start with "set", since those are commonly used for property setters as part of Cocoa's KVC/KVO system. Instead, I would call it something like changeLabel, or equivalent.
Your instance of customClass here is completely unrelated to the NIB. You've instantiated a new object using +alloc. If you want to modify the specific MyCustomClass in your NIB, then FirstViewController needs an IBOutlet that points to it.
UILabel also have a property called text to set the value, you might find that easier.
myObject.myLabel.text = #"Your text";
well you called your label two things, first a non-ibaction then an ibaction in the property.