Obj-C UIDownpicker заполнит другое текстовое поле другим значением во время прокрутки - PullRequest
0 голосов
/ 19 ноября 2018

Мой код, приведенный ниже, извлечет название страны и код страны с сервера и сохранит в коде 2 NSMutablleMArray, countryMArray и codeMArray. Когда пользователь нажимает txtCountry UITextField, он будет вызывать down picker, а когда пользователь выбирает страну и нажимает Готово, он будет на основе индекса и получать Country Code from codeMArray и вводить код в txtCode UITexField.

Вместо этого мне было интересно, как сразу заполнить txtCode UITextfield при прокрутке down picker. Что-то вроде картинки ниже. Вместо того, чтобы заставить пользователя нажать «Готово». Когда пользователь прокручивает down picker Country Name, txtCode UITexField будет автоматически заполнен Code. Есть ли способы сделать это.

Добавлен следующий код в *

Я добавил downpicker.m и downpicker.h, а также код в *, но он никогда не срабатывает. Пожалуйста, помогите, спасибо.

When scroll to Malaysia auto fill txtCode with Malaysia Country Code

When scroll to China auto fill txtCode with China Country Code

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

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Сначала я хотел бы предложить вам использовать NSDictionary вместо двух массивов: вы можете установить ключ словаря в качестве короткой страны и значение в качестве телефона и использовать его как:

NSString *phoneCode = self.codeDict[@"en"];

Во-вторых, создайте категорию для DownPicker и переопределите [pickerView:didSelectRow:inComponent]. Оттуда вы можете опубликовать то же уведомление, что и для действия Готово, либо создать протокол для этого.

0 голосов
/ 22 ноября 2018

Как уже упоминалось в других ответах, ключ здесь должен быть в методе pickerView: didSelectRow: inComponent.

Похоже, что вы добавили его в свой RootViewController, но RootViewController не является UIPickerViewDelegate(подкласс вашего UIPickerView есть).Чтобы исправить это, вы должны настроить свой RootViewController на UIPickerViewDelegate и установить экземпляр делегата вашего pickerView на RootViewController:

@ interface RootViewController: UIViewController

@interface RootViewController : UIViewController     <UITextFieldDelegate,UITableViewDelegate, UIPickerViewDelegate>

...

Затем в viewDidLoad вашего rootViewController установите делегат представления выбора в self:

self.pickerCountry.delegate = self
0 голосов
/ 19 ноября 2018

Возможно, ваш Downpicker является подклассом UIPickerView, вы должны реализовать его метод делегата с именем:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component __TVOS_PROHIBITED;

, которая может решить вашу проблему.

...