一个 ViewController 中的三个 UIPickerViews

Posted

技术标签:

【中文标题】一个 ViewController 中的三个 UIPickerViews【英文标题】:Three UIPickerViews in one ViewController 【发布时间】:2014-11-10 22:26:37 【问题描述】:

我有三个 UIPickerView,我在一个 ViewController 中使用它们。它需要彼此独立,因为我需要保存每个结果,但是当我运行它时,它会看到三个pickerView,当你选择不同的 UIPickerView 时,它们也保存了相同的结果。 ViewController.m 文件:

 @interface ViewController ()
 NSArray *_pickerData;
 NSArray *_pickerData2;
 NSArray *_pickerData3;

__weak IBOutlet UITextField *max;
__weak IBOutlet UITextField *m2;
__weak IBOutlet UITextField *m3;
 
@end

@implementation ViewController


   - (void)viewDidLoad 
     [super viewDidLoad];
 _pickerData = @[@"Apple",@"Avocado",@"Asparagus",@"Grapefruit"];
    _pickerData2 = @[@"Apple",@"Avocado",@"Asparagus",@"Grapefruit"];
    _pickerData3 = @[@"Apple",@"Avocado",@"Asparagus",@"Grapefruit"];
// Do any additional setup after loading the view, typically from a nib.
self.picker.dataSource = self;
self.picker.delegate = self;
self.picker2.dataSource = self;
self.picker2.delegate = self;
self.picker3.dataSource = self;
self.picker3.delegate = self;


- (void)didReceiveMemoryWarning 
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.

// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
 
return 1;
 

 // The number of rows of data
 - (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
 
return _pickerData.count;
  
  - (int)picker2View:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
  
return _pickerData2.count;
  
  - (int)picker3View:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
  
return _pickerData3.count;
  
 - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:           (NSInteger)component                    
   
   self->max.text = [NSString stringWithFormat:@"%@", _pickerData[row]];

    return _pickerData[row];

    
   - (NSString*)pickerView2:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component
     
     self->m2.text = [NSString stringWithFormat:@"%@", _pickerData2[row]];
     return _pickerData2[row];
      
  - (NSString*)pickerView3:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:   (NSInteger)component
      
       self->m3.text = [NSString stringWithFormat:@"%@", _pickerData2[row]];
       return _pickerData3[row];
       
       @end

当我运行它时,三个 PickerView 就像一个.ViewController.h 文件一样工作:

       #import <UIKit/UIKit.h>

      @interface ViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
      @property (weak, nonatomic) IBOutlet UIPickerView *picker;
      @property (weak, nonatomic) IBOutlet UIPickerView *picker2;
      @property (weak, nonatomic) IBOutlet UIPickerView *picker3;
      @end

【问题讨论】:

【参考方案1】:

调用的委托和数据源方法对于所有选择器视图都是相同的。不同之处在于传递给方法的 pickerView 参数。因此,例如,而不是:

- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    return _pickerData.count;

- (int)picker2View:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    return _pickerData2.count;

- (int)picker3View:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    return _pickerData3.count;

你应该有:

- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    if (pickerView == self.picker) 
        return _pickerData.count;
     else if (pickerView == self.picker2) 
        return _pickerData2.count;
     else if (pickerView == self.picker3) 
        return _pickerData3.count;
    

对于所有其他委托/数据源方法,依此类推。

【讨论】:

【参考方案2】:

您不需要实现 3 个不同的 (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger) 组件。我假设您有 3 个文本字段,当用户点击 TextField 时应该显示 UIPickerView。你也不需要 3 个不同的 UIPickerViews

您将需要三个布尔值 Bool firstTextFieldActive、Bool secondTextFieldActive、Bool thirdTextFieldActive,在 viewDidLoad 中将所有这些设置为默认“NO”。

一旦用户点击特定的 TextField,将其相应的布尔值设置为“YES”

例如:假设用户点击“max”,然后编译器调用“(BOOL)textFieldShouldBeginEditing:(UITextField *)textField”,在这里您将使用以下代码检查正在编辑哪个文本字段

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField

    if([textField isEqual: max])

        //First textfield is being edited
        firstTextFieldActive = YES;
        //Make sure the other textfield actives are set to NO
        secondTextFieldActive = NO;
        thirdTextFieldActive = NO;
        //Now reload pickerView
        [picker reloadAllComponents];
    

在你的

之后
-(int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    if(firstTextFieldActive)
        return _pickerData.count;
    else if(secondTextFieldActive)
        return _pickerData2.count;
    else if(thirdTextFieldActive)
        return _pickerData3.count;
    

也只实现其中之一

-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component                    

    if(firstTextFieldActive)
        self->max.text = [NSString stringWithFormat:@"%@", _pickerData[row]];

        return _pickerData[row];
    else if(secondTextFieldActive)
        self->m2.text = [NSString stringWithFormat:@"%@", _pickerData2[row]];
        return _pickerData2[row];
    else if(thirdTextFieldActive)
        self->m3.text = [NSString stringWithFormat:@"%@", _pickerData2[row]];
        return _pickerData3[row];
    

希望对您有所帮助

【讨论】:

【参考方案3】:

您重复了委托方法 - 这不是委托方法的工作方式。 上述 6 种方法中唯一有效的方法将是每组中的第一种 - 这些是您的 UIPickerView 将调用的实际委托方法。其他人永远不会受到打击。这就是为什么他们的行为似乎都一样。

传递给委托方法的 pickerView 参数已经告诉您它是 3 个中的哪一个。 您需要通过将传入方法的选项与您在 viewController 的 .h 中声明的 @property 进行比较来获取 pickerView。此外,它们可能不需要在 .h 中。

 //The following is the only one of the 3 "titleForRow" methods that's working
 - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:           (NSInteger)component                    
   
   //...result is that they're all set to the same array value Don't use the following line.
   //self->max.text = [NSString stringWithFormat:@"%@", _pickerData[row]];

  //use this instead to determine which UIPicker the argument `pickerView` refers to
  if (pickerView == self.picker) 
    return _pickerData[row]; //this assumes the data array has an NSString value for this row. What if it doesn't?  
    else if ... //looks like pbasdf already mentioned this approach above... Account for the 3 options

   return nil; //after all the if/else branches, in case pickerView or row are nil, since you have to return something  



- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
 
     //check the "pickerView" argument against your @properties. @pbasdf beat me to it! 
    //Same if/else check as the other delegate methods
    //then return the correct _pickerData.count; //
  

【讨论】:

以上是关于一个 ViewController 中的三个 UIPickerViews的主要内容,如果未能解决你的问题,请参考以下文章

使用多个 ViewController、Xcode 将代码连接到情节提要中的 UI

故事板中的子类 viewController 并以编程方式从子类更改 UI

添加专用 UI​​ViewController(例如 Monotouch 中的 UIPageViewController)的正确方法是啥?

ios 7中的UI Popover ViewController?

在 applicationDelegate 中初始化和分配视图控制器使 viewController 中的所有 UI 元素为零

如何将rootviewcontroller更改为堆栈中的第三个viewcontroller