I have subclassed UITextField so I can create some custom behaviours for it. Here are my classes:
DataboundTextField.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "TestEntities.h"
#interface DataboundTextField : UITextField <UITextFieldDelegate> {
NSString *valueMember;
NSString *displayValueMember;
ODataObject *boundEntity;
}
#property (nonatomic, retain) NSString *valueMember;
#property (nonatomic, retain) NSString *displayValueMember;
#property (nonatomic, retain) ODataObject *boundEntity;
-(void)SetupDataBinding:(ODataObject*)oDataEntity ValueMember:(NSString*)valMemberID DisplayValueMember:(NSString*)disValMember;
#end
DataboundTextField.m
#import "DataboundTextField.h"
#implementation DataboundTextField
#synthesize valueMember;
#synthesize displayValueMember;
#synthesize boundEntity;
-(id) initWithCoder:(NSCoder *)aDecoder{
if ((self = [super initWithCoder:aDecoder]))
{
self.delegate = self;
}
return self;
}
-(void)SetupDataBinding:(ODataObject*)oDataEntity ValueMember:(NSString*)valMemberID DisplayValueMember:(NSString*)disValMember{
}
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return YES;
}
#end
How do I go about overriding the ValueChanged event? I cannot seem to catch it however I try. All I want to do is wack one of these subclassed Textfields on a view and catch that event and handle it.
Please help.
Thanks in advance
According to the documentation for UITextFieldDelegate, you can use
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.
Make sure you set the delegate property of your UITextField:
- (id)init
{
if ((self = [super init]))
{
self.delegate = self;
}
}
This is what I have used to allow only certain characters, as well as how many characters are allowed for a textField:
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
/* allow only these characters in the textField */
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890|:.#~_-+#!{}%*"];
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c]) {
return NO;
}
}
/* choose how many characters the textField can have */
NSUInteger newLength = [theTextField.text length] + [string length] - range.length;
return (newLength > 28) ? NO : YES;
}
Related
I'm trying to set the delegate to be my UITextfield collection so that I can call resignFirstResponder on all of my textfields. What I've tried has not responded.
#property (nonatomic, weak) IBOutletCollection(UITextField) NSMutableArray *textFields;
- (void)viewDidLoad
{
[_textFields enumerateObjectsUsingBlock:^(UITextField *textfield, NSUInteger idx, BOOL *stop)
{
textfield.delegate=self;
}];
}
- (BOOL) textFieldShouldReturn:(UITextField *)textFields
{
NSLog(#"textFieldShouldReturn Fired :)");
[_textFields enumerateObjectsUsingBlock:^(UITextField *textfield, NSUInteger idx, BOOL *stop)
{
[textfield resignFirstResponder];
}];
return YES;
}
Did you add UITextFieldDelegate in the .h?
#interface MyVC : UIViewController <UITextFieldDelegate>
Also maybe try:
for (UITextField __strong *field in self.textFields)
field.delegate = self;
I want to subclass UITextField and have a method that sets the maximum number of characters. allowed. In the init method of this subclass I try setting the inputDelegate to self but the callbacks aren't triggered. Also this is an iOS 5 thing only. My question is what protocol or notification would allow me to fire an event when a key is tapped so that I don't have to implement the UITextField delegate in my view controller to achieve this limit.
Thanks.
You could do it like this, create a delegate class for you textfield
.m file
#implementation LimitedTextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.text.length >= 5 && ![string isEqualToString:#""])
return NO;
return YES;
}
#end
.h file
#interface LimitedTextFieldDelegate : UITextField<UITextFieldDelegate>
#end
in the UITextField subclass do the following
- (id)init
{
self = [super init];
if (self) {
//limitedDelegate is a property of your textfield subclass
self.limitedDelegate = [[LimitedTextFieldDelegate alloc] init];
self.delegate = self.limitedDelegate;
}
return self;
}
i am new to the iPhone development, i am developing an app were i have tableview with custom-cell,my custom-cell contains label and textfiled. this is my registration screen,How to save the data of my textfields and,how to do validations for the text. In the textfield endediting we can save the data. but if the user on the first filed enter name and then he click done button it will show please enter first name, because i am saving data in didendediting. i want to save the data when ever user is on the textfield.
you can use this method to trace your current textfield text, with the help of the model class objects to store your text.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *characterSet = nil;
switch (theTextField.tag)
{
case 1:
characterSet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
[sharedInstance.registrationDetails setFirstName:theTextField.text];
default:
characterSet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?/!##$&*.,-:; _";
break;
}
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:characterSet];
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
return NO;
}
}
return YES;
}
Make the controller the delegate of the cell's textField and then implement these methods in your controller.
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSInteger tag = [textField tag];
if(tag == 0) {
//save first name text value
}
else if (tag == 1){
//save last name text value
}
else if etc....
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Just make sure you set the tag appropriately when you return the cell in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You could also do some research on how to get the keyboard to act like a form handler with the next/previous buttons
Register.h
#interface Register : NSObject {
NSString *_firstNameTxt;
NSString *_lastNameTxt;
NSString *_emailTxt;
NSString *_passwordTxt;
}
#property (nonatomic, retain) NSString * firstNameTxt;
#property (nonatomic, retain) NSString * lastNameTxt;
#property (nonatomic, retain) NSString * emailTxt;
#property (nonatomic, retain) NSString * passwordTxt;
#end
Register.m
#implementation Register
#synthesize firstNameTxt=_firstNameTxt;
#synthesize lastNameTxt =_lastNameTxt ;
#synthesize emailTxt=_emailTxt;
#synthesize passwordTxt= _passwordTxt;
- (void)dealloc{
[super dealloc];
[_firstNameTxt release];
[_lastNameTxt release];
[_emailTxt release];
[_passwordTxt release];
}
#end
RegisterViewController.h
#class Register;
#interface RegisterViewController : UIViewController {
Register *objRegister;
}
RegisterViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
objRegister = [[Register alloc] init];
}
tableview delegates
[txtFirstName setText:objRegister.firstNameTxt];
[txtLastName setText:objRegister.lastNameTxt];
-(void) textFieldDidEndEditing:(UITextField *)textField{
// do the same code as Warren Burton Post
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Assign a method for didEndOnExit event of UITextField
How can I add didEndOnExit to a UITextField in pure code rather than IB?
Thanks!
Assuming your talking about textFieldDidEndEditing: or textFieldShouldReturn:. You would implement the method in your view controller, and set the text fields delegate to self like so:
- (void)viewDidLoad {
[super viewDidLoad];
// ....
myTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 50, 25)];
myTextField.delegate = self;
[self.view addSubview:myTextField];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == myTextField) {
// Do stuff...
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == myTextField) {
return YES;
}
return NO;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ((myTextField.text.length + string.length) < 5) {
return YES;
}
return NO;
}
Then, in your header file in the #interface you can specify that you are a UITextFieldDelegate like this:
#interface MyViewController : UIViewController <UITextFieldDelegate> {
// ....
UITextField *myTextField;
// ....
}
// Optionally, to make myTextField a property:
#property (nonatomic, retain) UITextField *myTextField;
#end
UITextField Reference
UITextFieldDelegate Reference
Edit (as per your comment, this should work):
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ((myTextField.text.length + string.length) < 5) {
return YES;
}
return NO;
}
Is there a way to make a UITextField non-editable by the user and provide only a copy menu without subclassing? I.e when the text field is touched it automatically selects all the text and only shows the copy menu.
If possible to do this without subclassing what are the interface builder options that need to be selected?
Thanks in advance.
simply do:
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return NO;
}
and also:
yourTextField.inputView = [[UIView alloc] init];
You can disable editing by setting the enabled property of UITextField to NO.
textField.enabled = NO;
Note that doing this will also disable the copy/paste options.
What you are asking for has been discussed before in this solution: Enable copy and paste on UITextField without making it editable
Without subclassing, but also without auto-selection, i.e the user can select, keyboard shows up, but the user cannot input data:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return NO;
}
Items required to make a UITextField (in this case, outputTextField)
able to accept touch and allow Select, Select All, Copy, Paste, but
NOT edit the area and also DISABLE popup keyboard:
Put "UITextFieldDelegate" in angle brackets after ViewController declaration in #interface
In the -(void)viewDidLoad{} method add the following two lines:
self.outputTextField.delegate = self;
self.outputTextField.inputView = [[UIView alloc] init];
Add delegate method (see actual method below):
textField: shouldChangeCharactersInRange:replacementString: { }
// ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
// ViewController.m
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *inputTextField;
#property (weak, nonatomic) IBOutlet UITextField *outputTextField;
- (IBAction)copyButton:(UIButton *)sender;
#end
#implementation ViewController
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
NSLog(#"inside shouldChangeCharactersInRange");
if (textField == _outputTextField)
{
[_outputTextField resignFirstResponder];
}
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.outputTextField.delegate = self; // delegate methods won't be called without this
self.outputTextField.inputView = [[UIView alloc] init]; // UIView replaces keyboard
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)copyButton:(UIButton *)sender {
self.outputTextField.text = self.inputTextField.text;
[_inputTextField resignFirstResponder];
[_outputTextField resignFirstResponder];
}
#end
This worked for me to have UITextField non Editable and only allow copy. Just change your UITextField Class to CopyAbleTF from XIB and you are set.
#implementation CopyAbleTF
- (void)awakeFromNib{
self.inputView= [[UIView alloc] init];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == #selector(copy:))
{
return true;
}
return false;
}
- (void)copy:(id)sender {
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board setString:self.text];
self.highlighted = NO;
[self resignFirstResponder];
}
#end