Question

iOS unfortunately doesn't have a dropdown picker like html does with the tag. I decided that I was finally going to create one for my app, and it looks and works great. My dropdown object is a subclass of UITextField. However, I changed something and now it only works some of the time.

User interaction is enabled, but I don't want the textfield to be editable. The class in which my dropdown subclass resides is UITextField delegate, and should receive delegate methods for UITextField.

I have - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ where I check to see if the textfield in question is a dropdown menu, and if it is, I call a method to instantiate a popover and disable editing, but the dropdown only appears on every other tap.

For example, i'll tap the "textfield" and my popover displays. I tap out so the popover goes away, then I tap on the "textfield" and nothing happens. I tap on the textfield once again and the popover appears. No idea why this is happening, here is what i'm doing:

.h

subclass : UIViewController<UITextFieldDelegate>

.m

dropdownTextField.delegate = self;
...
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    if(textField == self.measurementSelect){
        NSLog(@"IM CALLED");
        [self showPopover:textField];
        return NO;
    }
    return YES;
}

-(void)showPopover:(id)sender{
    if (_measurementPicker == nil) {
        _measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
        _measurementPicker.delegate = self;
    }

    if (_measurementPopover == nil) {
        _measurementPopover = [[UIPopoverController alloc] initWithContentViewController:_measurementPicker];
        [_measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

    }
    else {
        [_measurementPopover dismissPopoverAnimated:YES];
        _measurementPopover = nil;
    }
}

Every tap gets nslogged, so I assume my popover method is the culprit of this problem. Any ideas?

Was it helpful?

Solution

Let's rewrite by teasing apart existence of the UI elements and the visible state of the popover:

// canonical lazy getters for UI elements

- (iPadMeasurementSelect *)measurementPicker {
    if (!_measurementPicker) {
        _measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
        _measurementPicker.delegate = self;
    }
    return _measurementPicker;
}

- (UIPopoverController *)measurementPopover {
    if (!_measurementPopover) {
        _measurementPopover = [[UIPopoverController alloc] initWithContentViewController:self.measurementPicker];
    }
    return _measurementPopover;
}

// now the show/hide method makes sense.  it can take a bool about whether to show or hide
-(void)showPopover:(BOOL)show {

    if (show) {
        [self.measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
    } else {
        [self.measurementPopover dismissPopoverAnimated:NO];
        // if you want/need to create a new one each time it is shown, nil the popover here, like this:
        // self.measurementPopover = nil;
    }
}

When the textField begins editing, show the popover like this:

[self showPopover:YES];

And when the delegate gets the didEndEditing message:

[self showPopover:NO];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top