Hiding/ Showing UIPickerView

后端 未结 8 580
广开言路
广开言路 2020-12-05 11:09

I Have an a touchesEnded event that checks for when a UITextField is pressed. What I would like it to do is is hide/show a UIPickerView. How can this be done?



        
相关标签:
8条回答
  • 2020-12-05 11:18

    I am using a dummy UITextField for showing / hiding the UIPickerView

    First, add a UITextField as a @property on your UIViewController. Optionally, add the UIPickerView, as well

    @property (strong, nonatomic) UITextField *dummyTextField;
    

    Second, assign a UIPickerView as inputView for the UITextField. Assign yourself as the dataSource and the delegate for the UIPickerView. UITextField needs to be added as a subview on your UIViewController's view.

    - (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];
    }
    

    Finally, add a mechanism to show and hide the UIPickerView. Since I am using a dummy UITextField, I have decided to add a UIBarButtonItem named "Filter" with the following IBAction:

    - (IBAction)tappedFilterButton:(UIBarButtonItem *)sender {
    
        if (self.dummyTextField.isFirstResponder) {
    
            [self.dummyTextField resignFirstResponder];
        }
        else {
    
            [self.dummyTextField becomeFirstResponder];
        }
    }
    
    0 讨论(0)
  • 2020-12-05 11:20

    Below is the sample code to hide and show of UIPickerView with animation:-

    //For Displaying

    -(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:^{
        }];
    
    }
    

    //For hiding

    -(void)hidePickerView{
        [self.pickerSheet dismissViewControllerAnimated:YES completion:^{
        }];
    }
    
    0 讨论(0)
  • 2020-12-05 11:23

    In a scrollView based application, showing and hiding UIPickerView could be a tough issue as it is relatively hard to pin it to the bottom of the visible screen rectangle. You can do it easily with the following code.

    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)
    

    To summarize, you create an UIAlertController with an empty message. In order to make the alertController to have the size of your pickerView, you give the message neccessary number of line breaks. And lastly you add your pickerView as a subview of alertController.view

    You then follow the selected pickerView rows with the UIPickerViewDelegate methods.

    0 讨论(0)
  • 2020-12-05 11:25

    So I have used many references on trying to figure this out and then my best reference (believe it or not), was from the apple docs on UIView Class reference.

    I built a mini View ("_pickerView" on top of my main view that held a UIToolBar, UIToolButton (With IBAction "closePicker"), and the UIPicker.

    ***please note that is only works for iOS 4.0 and up

    the code for closing and displaying the UIView ("_pickerView") is:

    -(IBAction)closePicker:(id)sender
    {
        [UIView animateWithDuration:0.3 animations:^{ 
            _pickerView.frame = CGRectMake(_pickerView.frame.origin.x,
                                           460, //Displays the view off the screen
                                           _pickerView.frame.size.width,
                                           _pickerView.frame.size.height);
        }];
    }
    
    -(IBAction)showPicker:(id)sender
    {
        [UIView animateWithDuration:0.3 animations:^{ 
            _pickerView.frame = CGRectMake(_pickerView.frame.origin.x,
                                           107, //Displays the view a little past the
                                                //center ling of the screen
                                           _pickerView.frame.size.width,
                                           _pickerView.frame.size.height);
        }];
    }
    

    And for your viewDidLoad just call "closePicker" to have the view hidden on load

    0 讨论(0)
  • 2020-12-05 11:27

    Because I saw a comment about these solutions not working on iOS 7 I will assume this thread is still relevant and being searched for.

    The best way I have found to do this is by attaching the UIPickerView to a (hidden)UITextField as the input view like:

    _myPicker = [[UIPickerView alloc] init];
    _myPicker.delegate = self;
    _myPicker.showsSelectionIndicator = YES;
    myTextField.inputView = _myPicker;
    

    You can always hide the text field if desired. Then you can show/hide the UIPickerView by activating the textfield as first responder like:

    [myTextField becomeFirstResponder];
    [myTextField resignFirstResponder];
    

    I have verified this works on iOS 7 and I have had it working as far back as iOS 5.

    0 讨论(0)
  • 2020-12-05 11:28

    I looked everywhere for a clean way to hide and show (toggle) UIPickerView using a single button item and only found bits and pieces. For those looking to do the same, here's my working result via a basic conditional statement.

    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";
            }
        }
    

    So here's what's going on here: I've got a button item called "userSelection" with a title of "Select" and a hidden UIPickerView called "userPicker" (to hide, just copy the bit about "_userPicker.hidden", paste it in your picker declaration, and set the boolean to YES). The button item is connected to the above action. On load (i.e. when the button's title says "Select"), it unhides the picker and animates it into view. You can use the animateWithDuration and delay options to control that function, but these settings seem pretty natural to me.

    Then I've got this method changing the button's title to "Done" when something's been selected. I'm positive there's a cleaner way to do this bit, but the switch method gives me some freedom in case I want to make UI changes later.

    - (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;
        }
    }
    

    Finally, the action closes with an "else if" that says when the button says "Done", hide the picker with the reverse animation (same code, but with "pvHeight * -2") and then sets the button's title back to "Select" which serves to complete the loop of the whole action.

    Probably an easier way for the pros out there, but for the folks who are new to this stuff, like me, this made the most logical sense. Plus it works, so that's always a bonus!

    0 讨论(0)
提交回复
热议问题