Search code examples
ios7uitextfielduiinterfaceorientation

iOS - hidden accessory becomes visible after orientation change


In my case I'm using a UITextField as the accessory that I don't need to show all the time. I've confirmed the change happens after the orientation notification events fire. I guess a hack would be to resize the accessory to zero height, but I'm reticent to do this.

Wondering if anyone has encountered this and found a solution?

Have entered a bug report and provided a sample project. For those with higher privileges, it is searchable on bugreport.apple.com as ID 16771757. I have also copied it to a Dropbox account accessible as https://www.dropbox.com/s/o28vo04ig3yhgz6/ID16771757.zip.

Thank you for reading.


Solution

  • iOS calls such methods for input accessory view instance:

    1. [inputAccessoryView setAlpha:1]; when owner of accessory view becomes first responder (internal method call -[UIPeripheralHost(UIKitInternal) executeTransition:]);
    2. [inputAccessoryView setHidden:NO]; when interface rotation finished (internal method call -[UIPeripheralHost finishRotationOfKeyboard:]);

    That's why your input accessory view becomes visible after interface rotation event.

    Solution depends on behaviour that you expect:
    Let's imagine that input accessory view height = 44 ->
    Now you hide input accessory view and set owner as first responder:
    If you expect inputAccessoryView.frame.size.height equals 0 then solution for hiding input accessory view is set it to nil: inputAccessoryView = nil;

    If you expect inputAccessoryView.frame.size.height equals 44 then solution for hiding input accessory view is override setHidden: method for it:

    - (void)setHidden:(BOOL)hidden {
        [super setHidden:self.customIsHiddenFlag];
    }  
    

    where customIsHiddenFlag property that you need use for implementing logic of showing/hiding accessory view;

    or override setAlpha: method:

    - (void)setAlpha:(CGFloat)alpha {
        [super setAlpha:(self.customIsHiddenFlag ? 0 : 1)];
    }
    

    These solutions work for iOS 7.

    For iOS 6 you could use your base solution inputAccessoryView.hidden = YES and it works because iOS doesn't call setHidden:NO automatically when interface rotation is fired.

    It seems that you are right and it's a bug cause of different behaviour on iOS6 and iOS7. If Apple wants to show input accessory view forcedly then they should call setHidden:NO not only after interface rotation but also when owner becomes first responder.