ios UIPickerView 作为弹出窗口
Posted
技术标签:
【中文标题】ios UIPickerView 作为弹出窗口【英文标题】:ios UIPickerView as popup 【发布时间】:2014-04-04 07:33:40 【问题描述】:我为每个表行记录都有一个 UIPickerView。这是函数下的
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
这是里面的代码部分
picker = [[UIPickerView alloc]initWithFrame:CGRectMake(280, -45, 30, 20)];
[picker setDelegate:self];
arrayColors = [[NSMutableArray alloc] init];
[arrayColors addObject:@"1"];
[arrayColors addObject:@"2"];
[arrayColors addObject:@"3"];
[arrayColors addObject:@"4"];
[arrayColors addObject:@"5"];
[arrayColors addObject:@"6"];
[arrayColors addObject:@"7"];
[arrayColors addObject:@"8"];
[arrayColors addObject:@"9"];
[arrayColors addObject:@"10"];
[cell addSubview:picker];
我希望在单击它们时弹出(作为模态视图)选择器。当我选择它应该关闭的值时。有可能吗?
【问题讨论】:
【参考方案1】:是的,这是可能的。您需要创建一个包含UIPickerView
和2 个UIButton
的视图控制器类,OK 和Cancel。并以模态方式呈现。当用户点击 OK 按钮时,您可以通过委托将带有 UIPickerView
上选定值的事件发送到表视图控制器并关闭视图控制器。
【讨论】:
【参考方案2】:这里有多个问题。
为数据源中的每一行设置一个单独的选取器实例是没有意义的。更好的设计是让您将选择器数据与行相关联,并在选择时将该数据加载到公共选择器中。
例如,如果您正在制作一个应用程序来接受食品订单,您将让每一行代表一个类别(例如饮料、主餐、配菜、甜点等),并将每个类别与一系列选项相关联那个类别。 NSDictionary 将是一个很好的内部数据存储选择:您的键将是类别(可能是常量 NSStrings),值将是不同选项的 NSArrays。您的表格将由这些常量 NSString 类别的数组填充,因此当一个单元格被点击时,您可以查找它所代表的类别并使用它来获取可能的选项数组。
然后您将在单个 UIPickerView 上设置这些选项。选择器很昂贵——它们会占用大量内存并且有很多子视图。为选择器可能显示的每组选项创建不同的选择器是非常糟糕的做法。
当用户选择一个值时关闭 UIPickerView 是个坏主意。用户可能会在选择另一项(他们真正想要的)的途中停在一项上。在这种情况下,您的应用程序将难以使用并惹恼他们。另外,如果他们想选择列表中的第一个(默认)选项,您会怎么做?
可以以模态方式呈现 UIPickerViews。最好的方法可能是将选择器作为 inputView 添加到单元格中。不幸的是, UITableViewCell 本身不采用 inputView。您可以通过巧妙地使用 UIResponder 并创建一个允许您分配 inputView 并允许自己捕获输入焦点的子类来解决此问题:
@interface InputViewCell : UITableViewCell
@property ( nonatomic, strong, readwrite ) UIView * inputView;
@end
@implementation InputViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if( selected && !self.isFirstResponder )
[self becomeFirstResponder];
else
[self resignFirstResponder];
- (BOOL)canBecomeFirstResponder return YES;
@end
【讨论】:
【参考方案3】:重写 UITextField 并实现以下方法。然后将您的数字选择器插入单元格,将其附加到您尝试修改的值(使用 UITextFieldDelegate 或更改事件),您就完成了。
- (UIView *)inputAccessoryView
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(resignFirstResponder)];
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
toolbar.items = @[spacer, item];
return toolbar;
- (UIView *)inputView
if ((self.minimumNumber == 0) && (self.maximumNumber == 0))
self.minimumNumber = 0;
self.maximumNumber = 9;
UIPickerView *pickerView = [[UIPickerView alloc] init];
pickerView.backgroundColor = [UIColor whiteColor];
pickerView.dataSource = self;
pickerView.delegate = self;
[pickerView selectRow:(self.number - self.minimumNumber) inComponent:0 animated:NO];
return pickerView;
- (NSInteger)number
return [self.text integerValue];
- (void)setNumber:(NSInteger)number
self.text = [NSString stringWithFormat:@"%d", (int)number];
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
return 1;
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
return self.maximumNumber - self.minimumNumber + 1;
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
return [NSString stringWithFormat:@"%d", (int)(row + self.minimumNumber)];
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
self.number = (row + self.minimumNumber);
【讨论】:
以上是关于ios UIPickerView 作为弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章
UIActionSheet 中的 UIPickerView:UI 冻结