一个 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
添加专用 UIViewController(例如 Monotouch 中的 UIPageViewController)的正确方法是啥?
ios 7中的UI Popover ViewController?
在 applicationDelegate 中初始化和分配视图控制器使 viewController 中的所有 UI 元素为零