Is it possible to create inputAccessoryView above the keyboard for the full width of the screen in the split mode? System automatically resizes it to fit to the app frame. Is it a bug in iOS?

2

There are 2 answers

0
Pau Senabre On

You can use this method to detect if your keyboard is in split mode. Note: In order for this to work you need a UITextField/UITextView with a non-nil inputAccessoryView (you can just use an empty view for that).

NSArray *classPath = @[
  @"KeyboardAutomatic",
  @"KeyboardImpl",
  @"KeyboardLayoutStar",
  @"KBKeyplaneView",
  @"KBSplitImageView"
];
UIView *splitView = textField.inputAccessoryView.superview;
for (NSString *className in classPath) {
  for (UIView *subview in splitView.subviews) {
    if ([NSStringFromClass([subview class]) rangeOfString:className].location != NSNotFound) {
      splitView = subview;
      break;
    }
  }
}
BOOL isSplit = [splitView.subviews count] > 1;

Then you could use a custom inputAccessoryView and edit it's CGRectFrame depending if the keyboard is in split mode or not. Here a good example: https://github.com/bmancini55/iOSExamples-DockedKeyboardView

0
Rohit Wankhede On

Sharing accepted answer for same question Link

UIKit posts UIKeyboardWillShowNotification when it shows the keyboard, and UIKeyboardWillHideNotification when it hides the keyboard. These notifications contain everything you need to properly animate your UITextField.

Let's say your UITextField is in a property called called myTextField.

First, you need to register for the notifications somewhere. Where you register depends on what object is responsible for moving myTextField. In my project, the field's superview is responsible, and since I load my UI from a nib, I do it in the superview's awakeFromNib:

- (void)awakeFromNib {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}

If you use a UIViewController to move the field around, you'll probably want to do it in viewWillAppear:animated:.

You should unregister in your dealloc or viewWillDisappear:animated::

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

Of course the tricky bit is in the keyboardWillHideOrShow: method. First I extract the animation parameters from the notification:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

The keyboardFrame is in the global coordinate system. I need to convert the frame to the same coordinate system as myTextField.frame, and myTextField.frame is in the coordinate system of myTextField.superview:

CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

Next, I compute the frame that I want myTextField to move to. The bottom edge of the new frame should be equal to the top edge of the keyboard's frame:

CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

Finally, I animate myTextField to its new frame, using the same animation parameters that the keyboard is using:

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}

Here it is all put together:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

    CGRect newTextFieldFrame = self.myTextField.frame;
    newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}