How properly subclass UITextField in iOS?

╄→гoц情女王★ 提交于 2019-12-01 11:15:26

I wouldn't set the delegate to self within your custom UITextField, it is not really neat. What i would do is simply have a property or a method for edition that you can call in your controller when you receive delegates call.

Basically in your view controller somewhere :

- (void)viewDidLoad{
    ....
    self.textField = [[CustomTextField alloc] init];
    self.textField.delegate = self;

}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
     self.textField.editMode = YES;
}

And in your CustomTextField

-(void)setEditMode:(BOOL)edit{
    if(edit){
        self.layer.borderColor=[[UIColor redColor]CGColor];
        self.layer.borderWidth= 1.0f;
    }
}

I disagree with setting the delegate inside view controllers all the time. There are a couple obvious advantages using UITextField itself as the delegate such as cleaner code when a lot of different view controllers share the same text field behavior.

In iOS 8 the self delegate reference loop seems to be "fixed". But for those targeting iOS 7 and below, we used a proxy object to bypass the loop:

InputTextProxy.h:

@interface InputTextProxy : NSObject <UITextFieldDelegate>
@property (weak, nonatomic) id<UITextFieldDelegate> proxiedDelegate;
@end

InputTextProxy.m:

#import "InputTextProxy.h"

@implementation InputTextProxy

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return [self.proxiedDelegate textFieldShouldReturn:textField];
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    return [self.proxiedDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
}

@end

You can add more callbacks as necessary, we only use the above two.

Now create a property in your subclass MyCustomTextField.m:

@property (strong, nonatomic) InputTextProxy *inputProxy;

- (InputTextProxy *)inputProxy
{
    if (!_inputProxy)
        _inputProxy = [[InputTextProxy alloc] init];
    return _inputProxy;
}

Use this to set your delegate:

self.delegate = self.inputProxy;
self.inputProxy.proxiedDelegate = self;

For edit starts and ends you have becomeFirstResponder and resignFirstResponder. This is the best place for that. Override and don't forget to call super. For input manipulation you have to check documentation. There are two ways, via notifications and subclass. Both offer different level of flexibility.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!