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 作为弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章

iOS:UIPickerView 默认尺寸

UIActionSheet 中的 UIPickerView:UI 冻结

UI框架搭建DAY1

装饰器作为弹出窗口不起作用

在 iOS 8 中使用 UIPickerview 作为 UITextfield 的输入视图时崩溃

iOS开发之基础视图—— UIPickerView