How should I get my inputAccessoryView to resize when rotating device?

I'm attaching a UIToolbar to my UITextView as its inputAccessoryView in order to add a button to dismiss the keyboard. This works great and it looks correct when the device is in portrait mode. But I'm having trouble figuring out how to resize the toolbar to the lower height used for toolbars when the device is in landscape mode.

I'm adding the toolbar in my text view's delegate's -textViewShouldBeginEditing: method:

if (!textView.inputAccessoryView) {
    UIToolbar *keyboardBar = [[UIToolbar alloc] init];
    keyboardBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
    keyboardBar.barStyle = UIBarStyleBlackTranslucent;

    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard:)];
    [keyboardBar setItems:[NSArray arrayWithObjects:spaceItem, doneButton, nil]];
    [spaceItem release];
    [doneButton release];

    [keyboardBar sizeToFit];

    textView.inputAccessoryView = keyboardBar;
    [keyboardBar release];
}

I get strange behavior from this code in landscape mode, though. If I start editing in landscape mode, the toolbar has the landscape height but the Done button is drawn half off the screen. If I then rotate to Portrait mode, the Done button is drawn in the correct location, and it remains in the correct location when I rotate back to landscape mode.

If I start editing in portrait mode, the toolbar is drawn with portrait height, but the Done button is drawn in the correct location. If I then rotate to landscape mode, the toolbar remains portrait height, but the Done button is still drawn in the correct position at least.

Any suggestions for how to get this to resize when the device rotates? I'm really hoping there's a more automatic way than manually plugging in the height magic numbers in one of the view controller's rotation events.


That's a tough problem. I've solved this in the past by adjusting the frame when the accessory view gets laid out after rotating. Try something like this:

@interface RotatingTextInputToolbar : UIToolbar
@end

@implementation RotatingTextInputToolbar

- (void) layoutSubviews
{
    [super layoutSubviews];
    CGRect origFrame = self.frame;
    [self sizeToFit];
    CGRect newFrame = self.frame;
    newFrame.origin.y += origFrame.size.height - newFrame.size.height;
    self.frame = newFrame;

}
@end

And using the the RotatingTextInputToolbar instead of the UIToolbar in your code, above.


瞧:

@interface AccessoryToolbar : UIToolbar @end

@implementation AccessoryToolbar

-(id)init
{
    if (self = [super init])
    {
        [self updateSize];
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
        [nc addObserver:self selector:@selector(orientationDidChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:NULL];
    }
    return self;
}

-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

-(void)orientationDidChange:(NSNotification*)notification
{
    [self updateSize];
}

-(void)updateSize
{
    bool landscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
    CGSize size = UIScreen.mainScreen.bounds.size;
    if (landscape != size.width > size.height)
        std::swap(size.width, size.height);
    if (size.height <= 320)
        size.height = 32;
    else
        size.height = 44;
    self.frame = CGRectMake(0, 0, size.width, size.height);
}

@end
链接地址: http://www.djcxy.com/p/10012.html

上一篇: 如何将一个列表分割成没有重复元素的子集

下一篇: 旋转设备时,如何让我的inputAccessoryView调整大小?