Search code examples
iosobjective-cuipickerviewuibarbuttonitemuitoolbar

The action of UIBarbuttonItem on UIToolBar not called


I am having trouble as the action of UIBarbuttonItem on UIToolBar is not be called.
In the following code, although the doneBtn on toolBar is tapped, the action doneBtnAction: is not be called.
Do you have any idea to fix it?

- (void)viewDidLoad {
    UIPickerView *pickerView = [[UIPickerView alloc] init];

    UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, -44, 320, 44)];
    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneBtnAction:)];
    UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    toolBar.items = @[flex, doneBtn];
    [pickerView addSubview:toolBar];

    UITextField *textField = [[UITextField alloc] init];
    textField.inputView = pickerView;
}

- (void)doneBtnAction:(UIBarButtonItem *)sender {
    NSLog(@"%@", sender);
}

Solution

  • Don't add the toolbar as a subview of the picker view, especially with a negative y origin (No touches reach the toolbar because the taps are clipped to the picker view's frame).

    Instead, make the toolbar the inputAccessoryView of the text field.

    textField.inputAccessoryView = toolBar;
    

    Complete code:

    - (void)viewDidLoad {
        UIPickerView *pickerView = [[UIPickerView alloc] init];
    
        UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneBtnAction:)];
        UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
        toolBar.items = @[flex, doneBtn];
    
        UITextField *textField = [[UITextField alloc] init];
        textField.inputView = pickerView;
        textField.inputAccessoryView = toolBar;
    }
    

    One other note - Why not use the standard system Done type for the bar button item?