Iphone 隐藏/显示UIPickerView

Iphone 隐藏/显示UIPickerView,iphone,uipickerview,Iphone,Uipickerview,我有一个touchesEnded事件,该事件在按下UITextField时进行检查。我希望它做的是隐藏/显示UIPickerView。如何做到这一点 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [[event allTouches] anyObject]; if (CGRectContainsPoint([self.textField frame], [tou

我有一个touchesEnded事件,该事件在按下UITextField时进行检查。我希望它做的是隐藏/显示UIPickerView。如何做到这一点

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [[event allTouches] anyObject];
    if (CGRectContainsPoint([self.textField frame], [touch locationInView:self.view]))
    {
        NSString * error = @"Touched the TextField";
        UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Selection!" message:error delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [errorAlert show];
        //Want to show or hide UIPickerView
    }
}
当发生接触时,我已经有一个分配的UIPickerView

@interface ThirdViewController : UIViewController <UITextFieldDelegate,UIPickerViewDelegate> {
    IBOutlet UIPickerView *pickerView;
}
@interface ThirdViewController:UIViewController{
IBUIPickerView*pickerView;
}

UIPickerView继承自UIView,因此您应该能够切换其“隐藏”属性:

if (pickerView) pickerView.hidden = !pickerView.hidden;
切换“隐藏”属性就可以了,但也会给出一个非常突然的结果

避免这种情况的一种方法是将选择器嵌入UIActionSheet中,使其从屏幕底部向上滑动

下面是一个例子:

    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil 
delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];

    CGRect pickerFrame = CGRectMake(0, 0, 0, 0);
    UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
    pickerView.showsSelectionIndicator = YES;
    pickerView.dataSource = self;
    pickerView.delegate = self;
    [sheet addSubview:pickerView];
    [pickerView release];

    [sheet showInView:view];
    [sheet setBounds:CGRectMake(0, 0, 320, 415)];
    self.actionSheet = sheet; // assuming you have setup a property to hold the action sheet
    [sheet release];
完成拾取后,请将其关闭:

[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];

这种方法也可以用于将按钮合并到选择器上方的一个栏中(“完成”、“上一步”、“下一步”等)-对如何操作有很好的解释。

因此,我使用了许多参考资料来尝试解决这一问题,然后我最好的参考资料(信不信由你)来自UIView类参考上的apple文档

我在主视图的顶部构建了一个小视图(“pickerView”),其中包含一个UIToolBar、UIToolButton(带有iAction“closePicker”)和UIPicker

***请注意,它仅适用于iOS 4.0及以上版本

关闭和显示UIView(“\u pickerView”)的代码为:


对于您的viewDidLoad,只需调用“closePicker”即可在加载时隐藏视图

,因为我看到了一条关于这些解决方案在iOS 7上不起作用的评论,我将假设此线程仍然相关并正在搜索

我发现最好的方法是将UIPickerView作为输入视图附加到(隐藏的)UITextField,如:

_myPicker = [[UIPickerView alloc] init];
_myPicker.delegate = self;
_myPicker.showsSelectionIndicator = YES;
myTextField.inputView = _myPicker;
如果需要,您可以始终隐藏文本字段。然后,您可以通过作为第一响应者激活文本字段来显示/隐藏UIPickerView,如:

[myTextField becomeFirstResponder];
[myTextField resignFirstResponder];

我已经在iOS 7上验证了这一点,并且我已经让它在iOS 5上运行了。

我到处寻找一种使用单个按钮项隐藏和显示(切换)UIPickerView的干净方法,但只找到了一些零碎的部分。对于那些希望这样做的人,下面是我通过基本条件语句得到的工作结果

ViewController.m

- (IBAction)animatePicker {
    if ([self.userSelection.title isEqualToString: (NSString *)@"Select"]) {
        _userPicker.hidden = NO;
        UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
        float pvHeight = pickerView.frame.size.height;
        float y = [[UIScreen mainScreen] bounds].size.height - (pvHeight); // the root view of view controller
        [UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
            self.userPicker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
        } completion:nil];
    } else if ([self.userSelection.title isEqualToString: (NSString *)@"Done"]) {
            UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
            float pvHeight = pickerView.frame.size.height;
            float y = [[UIScreen mainScreen] bounds].size.height - (pvHeight * -2); // the root view of view controller
            [UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                self.userPicker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
            } completion:nil];
        self.userSelection.title = @"Select";
        }
    }
这里是这样的:我有一个名为“userSelection”的按钮项,标题为“Select”,还有一个名为“userPicker”的隐藏UIPickerView(要隐藏,只需复制关于“\u userPicker.hidden”的位,将其粘贴到你的picker声明中,并将布尔值设置为YES)。按钮项连接到上述操作。加载时(即,当按钮标题显示“选择”时),它将取消隐藏选取器并将其设置为视图中的动画。您可以使用animateWithDuration和delay选项来控制该功能,但这些设置对我来说非常自然

然后我有了一个方法,当选择某项内容时,将按钮的标题更改为“完成”。我肯定有一个更干净的方法来完成这一点,但切换方法为我提供了一些自由,以防我以后想要更改UI

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

    NSLog(@"Selected Row %ld", (long)row);
    switch(row)
    {

        case 0:
            self.userSelection.title = @"Done";
            break;
        case 1:
            self.userSelection.title = @"Done";
            break;
        case 2:
            self.userSelection.title = @"Done";
            break;
        case 3:
            self.userSelection.title = @"Done";
            break;
        case 4:
            self.userSelection.title = @"Done";
            break;
        case 5:
            self.userSelection.title = @"Done";
            break;
    }
}
最后,该动作以“else-if”结束,当按钮显示“Done”时,用反向动画隐藏选择器(代码相同,但使用“pvHeight*-2”),然后将按钮标题设置回“Select”,以完成整个动作的循环


对于专业人士来说,这可能是一个更简单的方法,但对于像我这样的新手来说,这是最符合逻辑的。而且它很有效,所以这总是一个额外的奖励!

我使用一个虚拟的
UITextField
来显示/隐藏
UIPickerView

首先,在
UIViewController
上添加一个UITextField作为
@属性
。也可以选择添加
UIPickerView

@property (strong, nonatomic) UITextField *dummyTextField;
其次,为
UITextField
指定一个
UIPickerView
作为
UITextField
inputView
。为
UIPickerView
指定自己作为
UIViewController
视图的
子视图,需要添加
UIPickerView
委托

- (void)viewDidLoad {

    [super viewDidLoad];

    UIPickerView *picker = [[UIPickerView alloc] init];
    [picker setDataSource:self];
    [picker setDelegate:self];

    self.dummyTextField = [UITextField new];
    self.dummyTextField.inputView = picker;
    [self.dummyTextField setHidden:YES];
    [self.view addSubview:self.dummyTextField];
}
最后,添加一个机制来显示和隐藏
UIPickerView
。由于我使用了一个虚拟的
UITextField
,我决定添加一个名为“Filter”的
UIBarButtonItem
,并使用以下
iAction

- (IBAction)tappedFilterButton:(UIBarButtonItem *)sender {

    if (self.dummyTextField.isFirstResponder) {

        [self.dummyTextField resignFirstResponder];
    }
    else {

        [self.dummyTextField becomeFirstResponder];
    }
}

下面是使用动画隐藏和显示
UIPickerView
的示例代码:-

//展示

-(void)showPickerView{
    self.pickerSheet = [UIAlertController alertControllerWithTitle:@"Select font" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    self.pickerView = [[UIPickerView alloc]initWithFrame:CGRectZero];
    self.pickerView.dataSource = self;
    self.pickerView.delegate = self;
    self.pickerView.showsSelectionIndicator = YES;
    [self.pickerView selectRow:1 inComponent:0 animated:YES];
    [self.pickerSheet.view addSubview:self.pickerView];
    self.pickerView.translatesAutoresizingMaskIntoConstraints = NO;
    UIView *view = self.pickerView;
    [self.pickerSheet.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:|[view]|"
                               options:0l
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(view)]];

    [self.pickerSheet.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|[view]|"
                               options:0l
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(view)]];
    [self presentViewController:self.pickerSheet animated:YES completion:^{
    }];

}
//隐藏

-(void)hidePickerView{
    [self.pickerSheet dismissViewControllerAnimated:YES completion:^{
    }];
}

在基于scrollView的应用程序中,显示和隐藏UIPickerView可能是一个困难的问题,因为将其固定到可见屏幕矩形的底部相对比较困难

let alertController = UIAlertController(title: title, message: "\n\n\n\n\n\n\n\n\n\n", preferredStyle: .ActionSheet)
alertController.view.addSubview(pickerView)
alertController.addAction(UIAlertAction(title: "OK", style: .Cancel) { action in
})
self.presentViewController(alertController, animated: true, completion: nil)
总之,您创建了一个带有空消息的UIAlertController。为了使alertController具有pickerView的大小,您需要为消息提供必要的换行数。最后,您将pickerView添加为alertController.view的子视图


然后,使用UIPickerViewDeleteGate方法跟踪选定的pickerView行。

谢谢您的解释。这应该被标记为最佳答案。@jonathan Moffatt,谢谢您的回答,但我有一个问题。它很好地忽略了UIpickerView,但当我想调用它时,如果我要使用此代码,它将创建操作表和pickerView再次单击w并将pickerview添加到actionsheet上作为子视图。如果我这样做,内存管理会有问题吗?或者安全吗?ARC在btw上。谢谢。@Mani这在ios 7和8上不起作用。但您可以改为使用!下面是一个示例
let alertController = UIAlertController(title: title, message: "\n\n\n\n\n\n\n\n\n\n", preferredStyle: .ActionSheet)
alertController.view.addSubview(pickerView)
alertController.addAction(UIAlertAction(title: "OK", style: .Cancel) { action in
})
self.presentViewController(alertController, animated: true, completion: nil)