Obj-C UIDownpicker 将在滚动期间用另一个值填充另一个文本字段
Posted
技术标签:
【中文标题】Obj-C UIDownpicker 将在滚动期间用另一个值填充另一个文本字段【英文标题】:Obj-C UIDownpicker will fill another textfield with another value during scrolls 【发布时间】:2018-11-19 03:26:30 【问题描述】:我下面的代码将从服务器获取国家名称和国家代码并存储到2 NSMutablleMArray
、countryMArray
和codeMArray
code。当用户点击txtCountry UITextField
时,它会调用down picker
,当用户选择国家并点击完成时,它将根据索引获取Country Code from codeMArray
并将代码放入txtCode UITexField
。
我想知道如何在滚动down picker
时立即填充txtCode UITextfield
,而不是这种方式。有点像下面的图片。而不是让用户完成。当用户滚动down picker Country Name
时,txtCode UITexField
将自动填充为Code
。有没有办法做到这一点。
在*中添加如下代码
我添加了 downpicker.m 和 downpicker.h 以及 * 中的代码,但它永远不会触发。请帮忙,谢谢。
RootViewController.h
#import <UIKit/UIKit.h>
#import "LoginViewController.h"
#import <DownPicker/UIDownPicker.h>
@protocol LoginViewProtocol <NSObject>
- (void)dismissAndLoginView;
@end
@interface RootViewController : UIViewController <UITextFieldDelegate,UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITextField *txtCountry;
@property (weak, nonatomic) IBOutlet UIDownPicker *downCountry;
@property (strong, nonatomic) IBOutlet UITextField *txtCode;
@property (strong, nonatomic) IBOutlet UITextField *txtPhone;
@property (strong, nonatomic) NSMutableArray *countryMArray;
@property (strong, nonatomic) NSMutableArray *codeMArray;
@property (nonatomic) DownPicker *pickerCountry;
@end
RootViewController.m
#import "RootViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface RootViewController ()
NSString *sURL,*sResponseData, *sRemaining;
NSString *sCode;
@end
@implementation RootViewController
@synthesize loginView;
@synthesize txtCountry,txtCode,txtPhone;
@synthesize countryMArray;
@synthesize codeMArray;
- (void)viewDidLoad
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
//=== Initiallize the Mutable Array
countryMArray = [[NSMutableArray alloc] init];
codeMArray = [[NSMutableArray alloc] init];
//=== Initialize the responseData Mutable Data
self.responseData = [NSMutableData data];
//=== Pass the string to server to get the return Country response.write
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
sURL = @"https://www.share-fitness.com";
sURL = [sURL stringByAppendingString:@"/apps/getcountry.asp?"];
NSURLRequest *requestCountry = [NSURLRequest requestWithURL:[NSURL URLWithString:sURL]];
(void) [[NSURLConnection alloc] initWithRequest:requestCountry delegate:self];
//=== Pass the string to server to get the return CountryCode
sURL = @"https://www.share-fitness.com";
sURL = [sURL stringByAppendingString:@"/apps/getctcode.asp?"];
NSURLRequest *requestCode = [NSURLRequest requestWithURL:[NSURL URLWithString:sURL]];
(void) [[NSURLConnection alloc] initWithRequest:requestCode delegate:self];
//=== Initialie the picker ====
self.pickerCountry = [[DownPicker alloc] initWithTextField:self.txtCountry withData:countryMArray];
[self.pickerCountry addTarget:self
action:@selector(pickerClicked:)
forControlEvents:UIControlEventValueChanged];
//**** ADDED the following but will never trigger ?
- (void)pickerView:(UIDownPicker *)pickerCountry didSelectRow:(NSInteger)row inComponent:(NSInteger)component
sCode = [codeMArray objectAtIndex:row];
txtCode.text = [@"+"stringByAppendingString:sCode];
//**********************
//=== Pick the countryCode, when Country is selected based on Array Index
-(void)pickerClicked:(id)dp
NSString* selectedValue = [self.pickerCountry text];
for ( int i = 0 ; i < countryMArray.count; i++)
NSString*item = [countryMArray objectAtIndex:i];
if([item isEqualToString:selectedValue])
sCode = [codeMArray objectAtIndex:i];
txtCode.text = [@"+"stringByAppendingString:sCode];
break;
Downpicker.h
#import <UIKit/UIKit.h>
@interface DownPicker : UIControl<UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
UIPickerView* pickerView;
IBOutlet UITextField* textField;
NSArray* dataArray;
NSString* placeholder;
NSString* placeholderWhileSelecting;
NSString* toolbarDoneButtonText;
NSString* toolbarCancelButtonText;
UIBarStyle toolbarStyle;
@property (nonatomic) NSString* text;
@property (nonatomic) NSInteger selectedIndex;
-(id)initWithTextField:(UITextField *)tf;
-(id)initWithTextField:(UITextField *)tf withData:(NSArray*) data;
@property (nonatomic) BOOL shouldDisplayCancelButton;
/**
Sets an alternative image to be show to the right part of the textbox (assuming that showArrowImage is set to TRUE).
@param image
A valid UIImage
*/
-(void) setArrowImage:(UIImage*)image;
-(void) setData:(NSArray*) data;
-(void) setPlaceholder:(NSString*)str;
-(void) setPlaceholderWhileSelecting:(NSString*)str;
-(void) setAttributedPlaceholder:(NSAttributedString *)attributedString;
-(void) setToolbarDoneButtonText:(NSString*)str;
-(void) setToolbarCancelButtonText:(NSString*)str;
-(void) setToolbarStyle:(UIBarStyle)style;
/**
TRUE to show the rightmost arrow image, FALSE to hide it.
@param b
TRUE to show the rightmost arrow image, FALSE to hide it.
*/
-(void) showArrowImage:(BOOL)b;
-(UIPickerView*) getPickerView;
-(UITextField*) getTextField;
/**
Retrieves the string value at the specified index.
@return
The value at the given index or NIL if nothing has been selected yet.
*/
-(NSString*) getValueAtIndex:(NSInteger)index;
/**
Sets the zero-based index of the selected item: -1 can be used to clear selection.
@return
The value at the given index or NIL if nothing has been selected yet.
*/
-(void) setValueAtIndex:(NSInteger)index;
@end
Downpicker.m
#import "DownPicker.h"
@implementation DownPicker
NSString* _previousSelectedString;
-(id)initWithTextField:(UITextField *)tf
return [self initWithTextField:tf withData:nil];
-(id)initWithTextField:(UITextField *)tf withData:(NSArray*) data
self = [super init];
if (self)
self->textField = tf;
self->textField.delegate = self;
// set UI defaults
self->toolbarStyle = UIBarStyleDefault;
// set language defaults
self->placeholder = @"Tap to choose...";
self->placeholderWhileSelecting = @"Pick an option...";
self->toolbarDoneButtonText = @"Done";
self->toolbarCancelButtonText = @"Cancel";
// hide the caret and its blinking
[[textField valueForKey:@"textInputTraits"]
setValue:[UIColor clearColor]
forKey:@"insertionPointColor"];
// set the placeholder
self->textField.placeholder = self->placeholder;
// setup the arrow image
UIImage* img = [UIImage imageNamed:@"downArrow.png"]; // non-CocoaPods
if (img == nil) img = [UIImage imageNamed:@"DownPicker.bundle/downArrow.png"]; // CocoaPods
if (img != nil) self->textField.rightView = [[UIImageView alloc] initWithImage:img];
self->textField.rightView.contentMode = UIViewContentModeScaleAspectFit;
self->textField.rightView.clipsToBounds = YES;
// show the arrow image by default
[self showArrowImage:YES];
// set the data array (if present)
if (data != nil)
[self setData: data];
self.shouldDisplayCancelButton = YES;
return self;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return (interfaceOrientation == UIInterfaceOrientationPortrait);
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
return 1;
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
self->textField.text = [dataArray objectAtIndex:row];
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
return [dataArray count];
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
return [dataArray objectAtIndex:row];
-(void)doneClicked:(id) sender
//hides the pickerView
[textField resignFirstResponder];
if (self->textField.text.length == 0 || ![self->dataArray containsObject:self->textField.text])
// self->textField.text = [dataArray objectAtIndex:0];
[self setValueAtIndex:-1];
self->textField.placeholder = self->placeholder;
/*
else
if (![self->textField.text isEqualToString:_previousSelectedString])
[self sendActionsForControlEvents:UIControlEventValueChanged];
*/
[self sendActionsForControlEvents:UIControlEventValueChanged];
-(void)cancelClicked:(id)sender
[textField resignFirstResponder]; //hides the pickerView
if (_previousSelectedString.length == 0 || ![self->dataArray containsObject:_previousSelectedString])
self->textField.placeholder = self->placeholder;
self->textField.text = _previousSelectedString;
- (IBAction)showPicker:(id)sender
_previousSelectedString = self->textField.text;
pickerView = [[UIPickerView alloc] init];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
//If the text field is empty show the place holder otherwise show the last selected option
if (self->textField.text.length == 0 || ![self->dataArray containsObject:self->textField.text])
if (self->placeholderWhileSelecting)
self->textField.placeholder = self->placeholderWhileSelecting;
// 0.1.31 patch: auto-select first item: it basically makes placeholderWhileSelecting useless, but
// it solves the "first item cannot be selected" bug due to how the pickerView works.
[self setSelectedIndex:0];
else
if ([self->dataArray containsObject:self->textField.text])
[self->pickerView selectRow:[self->dataArray indexOfObject:self->textField.text] inComponent:0 animated:YES];
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = self->toolbarStyle;
[toolbar sizeToFit];
//space between buttons
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]
initWithTitle:self->toolbarDoneButtonText
style:UIBarButtonItemStyleDone
target:self
action:@selector(doneClicked:)];
if (self.shouldDisplayCancelButton)
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
initWithTitle:self->toolbarCancelButtonText
style:UIBarButtonItemStylePlain
target:self
action:@selector(cancelClicked:)];
[toolbar setItems:[NSArray arrayWithObjects:cancelButton, flexibleSpace, doneButton, nil]];
else
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpace, doneButton, nil]];
//custom input view
textField.inputView = pickerView;
textField.inputAccessoryView = toolbar;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)aTextField
if ([self->dataArray count] > 0)
[self showPicker:aTextField];
return YES;
return NO;
- (void)textFieldDidEndEditing:(UITextField *)aTextField
// [self doneClicked:aTextField];
aTextField.userInteractionEnabled = YES;
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: (NSRange)range replacementString:(NSString *)string
return NO;
-(void) setData:(NSArray*) data
dataArray = data;
NSLog(@" This is the data : %@ ", dataArray);
-(void) showArrowImage:(BOOL)b
if (b == YES)
// set the DownPicker arrow to the right (you can replace it with any 32x24 px transparent image: changing size might give different results)
self->textField.rightViewMode = UITextFieldViewModeAlways;
else
self->textField.rightViewMode = UITextFieldViewModeNever;
-(void) setArrowImage:(UIImage*)image
[(UIImageView*)self->textField.rightView setImage:image];
-(void) setPlaceholder:(NSString*)str
self->placeholder = str;
self->textField.placeholder = self->placeholder;
-(void) setPlaceholderWhileSelecting:(NSString*)str
self->placeholderWhileSelecting = str;
-(void) setAttributedPlaceholder:(NSAttributedString *)attributedString
self->textField.attributedPlaceholder = attributedString;
-(void) setToolbarDoneButtonText:(NSString*)str
self->toolbarDoneButtonText = str;
-(void) setToolbarCancelButtonText:(NSString*)str
self->toolbarCancelButtonText = str;
-(void) setToolbarStyle:(UIBarStyle)style;
self->toolbarStyle = style;
-(UIPickerView*) getPickerView
return self->pickerView;
-(UITextField*) getTextField
return self->textField;
-(NSString*) getValueAtIndex:(NSInteger)index
return (self->dataArray.count > index) ? [self->dataArray objectAtIndex:index] : nil;
-(void) setValueAtIndex:(NSInteger)index
if (index >= 0) [self pickerView:nil didSelectRow:index inComponent:0];
else [self setText:nil];
/**
Getter for text property.
@return
The value of the selected item or NIL NIL if nothing has been selected yet.
*/
- (NSString*) text
return self->textField.text;
/**
Setter for text property.
@param txt
The value of the item to select or NIL to clear selection.
*/
- (void) setText:(NSString*)txt
if (txt != nil)
NSInteger index = [self->dataArray indexOfObject:txt];
if (index != NSNotFound) [self setValueAtIndex:index];
else
self->textField.text = txt;
/**
Getter for selectedIndex property.
@return
The zero-based index of the selected item or -1 if nothing has been selected yet.
*/
- (NSInteger)selectedIndex
NSInteger index = [self->dataArray indexOfObject:self->textField.text];
return (index != NSNotFound) ? (NSInteger)index : -1;
/**
Setter for selectedIndex property.
@param index
Sets the zero-based index of the selected item using the setValueAtIndex method: -1 can be used to clear selection.
*/
- (void)setSelectedIndex:(NSInteger)index
[self setValueAtIndex:(NSInteger)index];
@end
【问题讨论】:
【参考方案1】:也许你的 Downpicker 是 UIPickerView 的子类,你应该实现它的委托方法,命名为:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component __TVOS_PROHIBITED;
可以解决你的问题。
【讨论】:
【参考方案2】:首先我建议您使用 NSDictionary 而不是两个数组:您可以将字典的键设置为国家短,将值设置为电话并将其用作:
NSString *phoneCode = self.codeDict[@"en"];
其次,为 DownPicker 创建一个类别并覆盖 [pickerView:didSelectRow:inComponent]
。从那里您可以发布用于完成操作的相同通知,或者您可以为此创建协议。
【讨论】:
【参考方案3】:正如前面提到的其他答案,这里的关键应该在 pickerView:didSelectRow:inComponent 委托方法中。
您似乎已将其添加到您的 RootViewController,但 RootViewController 不是 UIPickerViewDelegate(您的 UIPickerView 的子类是)。为了解决这个问题,您需要将 RootViewController 调整为 UIPickerViewDelegate,并将您的 pickerView 代理实例设置为 RootViewController:
@interface RootViewController : UIViewController
@interface RootViewController : UIViewController <UITextFieldDelegate,UITableViewDelegate, UIPickerViewDelegate>
...
然后在 rootViewController 的 viewDidLoad 中将选取器视图的委托设置为 self:
self.pickerCountry.delegate = self
【讨论】:
以上是关于Obj-C UIDownpicker 将在滚动期间用另一个值填充另一个文本字段的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C:点击 UIDownPicker 并获取 UITextfield 的值
在swift或obj-c中的uitextview末尾添加一个视图