iOS 8 broke UIPickerView in UIActionSheet

2019-04-10 05:35发布

问题:

I was presenting a picker in UIActionSheet very simply up until iOS 8. Now, it seems they have broken that capability with the latest update. It was never supported and the practice was discouraged in the docs all along.

Presumably the entire UIActionSheet capability is deprecated and will not be supported going forward. The documentation says to use UIAlertController instead.

I have tried switching to the UIAlertController and actually found what I initially expected would be a nicer solution than what I originally had presented.

My original code:

// Ask user for project to associate the new issue with a project
        UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Select Project", @"Title for Action Sheet")
                                                          delegate:self 
                                                 cancelButtonTitle:klocalized_CancelButtonTitle
                                            destructiveButtonTitle:nil 
                                                 otherButtonTitles:klocalized_SelectButtonTitle ,nil];

        [menu addSubview:self.projectPicker];
        [menu showFromTabBar:self.tabBarController.tabBar];
        [menu setBounds:CGRectMake(0, 0, 320, 700)];

Worked fine in iOS 7.

My new code. Looks nicer but for some reason I cannot get the UITextField to respect my setting of the inputView property. It shows my text field with standard keyboard, otherwise this would be an acceptable alternative, better even than the original in my opinion.

New, work in progress for iOS 8:

// is iOS 8, ActionSheet, newly deprecated, will not allow subviews. Use UIAlertController instead
        NSString *title = NSLocalizedString(@"Select Project", @"Title for Action Sheet");
        UIAlertController *projectSelector = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
        [projectSelector addAction:[UIAlertAction actionWithTitle:klocalized_CancelButtonTitle style:UIAlertActionStyleCancel handler:nil]];
        [projectSelector addAction:[UIAlertAction actionWithTitle:klocalized_SelectButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            // Do my button action stuff here

        }]];

        [projectSelector addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            // projectField is lazily created property.
            //My picker is set as its inputView but standard keyboard is always presented instead.
            textField = self.projectField;
        }];

        [self presentViewController:projectSelector animated:YES completion:^{
            // Do my final work here

        }];

Can anyone tell me why this is happening? Is inputView property of UITextfield unusable on the new UIAlertController view? Has anyone had success using UIPickerView in this manner?

I haven't included my code for the projectField or projectPicker properties but I have tested and checked. They do create valid objects. The picker is retained by my presenting VC and the text field is weak, owned by the AlertViewController I assume. I tried retaining it as well, that had no effect.

I do receive UITextField Delegate calls from the text field as well, so I know that it is the object that I created that is presented. I can think of no reason for the standard keyboard to show when I have clearly set the pickerView as its inputView.

See resulting view in screenshot:

回答1:

After banging my head on the desk for some time, I found the solution, well, I mean I found the dumb error I was making.

I was doing the textField configuration backwards. I thought the intent was to pass the textField parameter my text field, when I should have been setting the properties of the text field given.

Simply changing to

// is iOS 8, ActionSheet, newly deprecated, will not allow subviews. Use UIAlertController instead
        NSString *title = NSLocalizedString(@"Select Project", @"Title for Action Sheet");
        UIAlertController *projectSelector = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
        [projectSelector addAction:[UIAlertAction actionWithTitle:klocalized_CancelButtonTitle style:UIAlertActionStyleCancel handler:nil]];
        [projectSelector addAction:[UIAlertAction actionWithTitle:klocalized_SelectButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

        }]];

        [projectSelector addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            //Set the properties of the textField provided. DO NOT CREATE YOUR OWN.
            [textField setPlaceholder:NSLocalizedString(@"Make Selection", @"PlaceHolder for project field when awaiting picker choice")];
            [textField setInputView:self.projectPicker];
            [textField setDelegate:self];
            self.projectField = textField;
        }];

        [self presentViewController:projectSelector animated:YES completion:^{

        }];