I created a subclass of UITextField to override the method rightViewRectForBounds.
Here is my custom class CustomTextField
#interface CustomTextField : UITextField
#end
#implementation CustomTextField
// override rightViewRectForBounds method:
- (CGRect)rightViewRectForBounds:(CGRect)bounds{
NSLog(#"rightViewRectForBounds");
CGRect rightBounds = CGRectMake(bounds.origin.x + 10, 0, 30, 44);
return rightBounds ;
}
#end
Now I set up my ViewController to call the custom class instead of UITextField.
#import "OutputViewController.h"
#import "CustomTextField.h"
#interface OutputViewController () <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet CustomTextField *field1;
#property (strong, nonatomic) IBOutlet UILabel *label1;
- (void)methodName
{
self.field1.rightView = self.label1;
}
The property rightView should call my method override according to Apple's Documentation: "The right overlay view is placed in the rectangle returned by the rightViewRectForBounds: method of the receiver". Why isn't my override working?
Sorry if this is a bad question. I've only been programming for a month.
The problem is most likely that field1 is not in fact a CustomTextField. It is easy to confirm this with a breakpoint or some logging.
Remember, it is not enough to declare the class of something. That thing must actually be that class (polymorphism). An instance has a class, quite without regard for how you may cast or declare a variable that refers to it.
Related
The clear answer to detecting a backspace is by creating a subclass of UITextField and overriding the deleteBackward property.
I've created a subclass a UITextField subclass, but am getting this error:
'NSInvalidArgumentException', reason: '-[UITextField setMyDelegate:]: unrecognized selector sent to instance
This is my subclass code:
My TextField.h:
#protocol MyTextFieldDelegate <NSObject>
#optional
- (void)textFieldDidDelete;
#end
#interface MyTextField : UITextField<UIKeyInput>
//create "myDelegate"
#property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate;
#end
My TextField.m:
- (void)deleteBackward {
[super deleteBackward];
if ([_myDelegate respondsToSelector:#selector(textFieldDidDelete)]){
[_myDelegate textFieldDidDelete];
}
}
In my ViewController that I would like to access the UITextField subclass I do the following:
#import "MyTextField.h"
<MyTextFieldDelegate>
#property (nonatomic, strong) IBOutlet MyTextField *passcode1;
self.passcode1.myDelegate = self;
Any ideas as to why I am getting the unrecognized selector error? It looks to me like I have done everything correctly in subclassing UITextField.
The problem is with your outlet. The property is defined with your custom class but in a Interface Builder you added a plain old UITextField. Hence the error at runtime. In Interface Buldier, update the text field's class to be your custom class.
I made a custom UIView object customView
The main initializer i used during prototyping was:
public init(textString: String, frame: CGRect) {
Once I want to add this little guy to the IB I'm not sure how to get it working. I understand that once I add the function to the Interface builder it calls:
required public init(coder aDecoder: NSCoder)
I'm at a loss at this point how to get my custom textString passed into the initializer
Is there a process to do this?
Your Custom UIView has two init methods which are :
initWithFrame:frame
initWithCoder:aDecoder
You do not use this two methods to pass data like your textString. Instead textString should be a property of your view. This property will be initialized via a View Controller that owns your custom view.
#interface CustomView : UIView
#property (strong, nonatomic) NSString *textString;
#end
Then you set the textString property's value in the View Controller, for instance in its viewDidLoad method.
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet CustomView *myCustomView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.myCustomView.textString = #"There's my textString";
}
#end
Hope this could help.
Make your custom view #IBDesignable, and the text property #IBInspectable, then you can set the text from inside the storyboard/xib file.
Just when you think you understand something, you don't! :)
I understand that if I make a variable a property, I can access it anywhere in the Class and even set it from outside that class.
I thought if I didnt need it I could just make it an ivar. So I have a viewcontroller with about 5 UILabels. So in its viewDidLoad I say:
pharmacyName.text = self.receivedLocation.name;
pharmacyTel1.text = #"556-7843";
pharmacyTel2.text = #"991-2345";
pharmacyTel3.text = #"800-0001";
When I have declared them like so in the .h file:
#interface DetailViewController : UIViewController{
IBOutlet UILabel *pharmacyName;
IBOutlet UILabel *pharmacyTel1;
IBOutlet UILabel *pharmacyTel2;
IBOutlet UILabel *pharmacyTel3;
}
#property (nonatomic,strong) MyLocation *receivedLocation;
#end
No. Its not mandatory to create ivar as property. If you don't want to access it outside of class just use as it is. In ARC you can also declare your IBOutlet as below:
#interface DetailViewController : UIViewController{
__weak IBOutlet UILabel *pharmacyName;
__weak IBOutlet UILabel *pharmacyTel1;
__weak IBOutlet UILabel *pharmacyTel2;
__weak IBOutlet UILabel *pharmacyTel3;
}
This will keep a week reference of outlets. Here is detail of __weak and strong
There are always many ways you can approach programming tasks and standards. Our group has started using a few coding standards. We like to put our instance variables that are NOT accessed from outside the class (and protocol statements) in the private interface in the .m file like this:
#interface DetailViewController() {
NSString *value_;
}
#end
We also like to use #property for our instance ivars and declare those in the private interface as well like this:
#interface DetailViewController() {
}
#property (nonatomic, strong) IBOutlet UIlabel *pharmacyName;
#end
and then in your code, you would refer to this as self.pharmacyName. It seems to work pretty well with autocomplete, and with getting and setting. Also when you have thread safety issues, the nonatomic, strong behavior comes in handy.
I have a view controller alertForNeedsClassification as a property in another class, as such:
#interface SCAAppDelegate()
{
HomeScreenViewController * _homeScreenViewController;
NSInteger SCAStatus;
}
#property (strong, nonatomic) PromptClassifyViewController * alertForNeedsClassification;
#end
#implementation SCAAppDelegate
#synthesize alertForNeedsClassification;
#synthesize window = _window;
PromptClassifyViewController's interface looks like this:
#interface PromptClassifyViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *headerTitle;
#property (weak, nonatomic) IBOutlet UITextView *message;
#property (weak, nonatomic) IBOutlet UIButton *notNowButton;
#property (weak, nonatomic) IBOutlet UIButton *classifyButton;
#property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;
#property (weak, nonatomic) IBOutlet UIView *alertView;
#property NSUInteger tag;
#property (weak, nonatomic) IBOutlet id<PromptClassifyViewControllerDelegate> delegate;
- (void)show;
- (void)showFromView:(UIView *)view;
- (IBAction)show:(id)sender;
- (IBAction)dismiss:(id)sender;
- (IBAction)buttonWasPressed:(id)sender;
- (void)setHeaderTitleWithText:(NSString *)text;
#end
I am trying to change the values of IBOutlets message and headerTitle text, like this:
alertForNeedsClassification = [[PromptClassifyViewController alloc] initWithNibName:#"PromptClassifyViewController" bundle:nil];
//[alertForNeedsClassification setDelegate:self];
self.alertForNeedsClassification.headerTitle.text = #"A title";
alertForNeedsClassification.message.text = #"A message";
Then I show alertForNeedsClassification calling a show method (it's like a custom uialertview, but it doesn't subclass from uialertview).
Thing is, no matter how I change it, the text on alertForNeedsClassification.view is always that which is defined in the nib, ie. I can't change it programmatically.
My custom alert view is based on Jeff LaMarche's design: http://iphonedevelopment.blogspot.com/2010/05/custom-alert-views.html
Any ideas what might be going on?
Please be careful when you allocate and initialize the UIView object, especially if you trying to mix using Nib and dynamically generating objects. The best place is within -(void)awakeFromNib or -(void)viewDidLoad
Also, make sure these methods are called. By using -(id)initWithNibName:bundle: only cannot make sure your view to be loaded. Try -(void)addChildViewController and -(void)addSubview: on parentViewController's view to make sure view is loaded after being initialized.
If the text had to be prepared before being loaded, assign it to separate NSString property within PromptClassifyViewController class. Since this property is independent from view being loaded, you can change it's value BEFORE view is appeared. Make sure this text is used and applied to the headerTitle within -(void)show method.
Since you allocate PromptClassifyViewController and access weak referenced headerTitle from self. alertForNeedsClassification, make sure it's not deallocated right afterward.
Usually, weak option is not used for IBOutlet properties. Though it is used when generating outlet connection code by dragging objects from Interface Builder. Try testing your code using strong.
I was assigning values to the IBOutlets before they were alloc'd/initialized. The solution I implemented was to set the values I needed to non-IBOutlet properties (NSStrings in this case) and assign those where needed, in Prompt...Controller's viewDidLoad;
For example one, I declare an object inside the interface brace {} like:
#interface testViewController : UIViewController {
IBOutlet UILabel * myLabel;
}
#property (retain, nonatomic) UILabel *myLabel;
#end
and example two, I declare an object outside the inferface brace {} like:
#interface testViewController : UIViewController {
}
#property (retain, nonatomic) IBOutlet UILabel *myLabel;
#end
I run the code and the result is the same, so I want to ask what is the different for decalare an object inside or outside the interface brace {}?
Thanks
The modern Objective-C runtimes (64-bit Mac OS X and iOS) will generate the backing store for your declared properties when you #synthesize them. So you don't need to declare them within the braces.
If you are declaring an iVar that is not a property and will only be used by the class, then they need to be declared. It's a good idea to mark these #private e.g
#interface MyClass : NSObject {
#private
NSString *privateString;
}
#property (nonatomic, copy) NSString *publicString; // be sure to #synthesize this
#end
In the second example you only declare a property. Xcode will declare object automatically.