Изменение размера представления при появлении клавиатуры (iOS)
Я понимаю, что существует много подобных решений, таких как TPKeyboardAvoiding, знаменитое решение Apple и различные предложения, связанные с использованием UIScrollView. В моем случае мне нужно изменить размер представления, чтобы разместить клавиатуру, а не прокручивать или перемещать ее. Это решение ближе всего к тому, чего я пытаюсь достичь, поэтому это была моя основа. Однако у меня проблема, в которой все работает в ландшафтном режиме. Мой метод, который изменяет размер представления при появлении клавиатуры, таков:
- (void)keyboardWillShow:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[self textField].superview convertRect:[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGRect statusBarFrame = [[self textField].superview convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil];
CGRect bounds = [self textField].superview.bounds;
CGRect newFrame = CGRectMake(0.0, 0.0, bounds.size.width, keyboardFrame.origin.y + statusBarFrame.size.height);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
[self textField].superview.frame = newFrame;
} completion:nil];
}
Это прекрасно работает в портретном режиме.
![enter image description here]()
Однако в ландшафтном режиме вид изменяется влево-вправо или справа налево в зависимости от того, в каком направлении было повернуто устройство, а не снизу вверх.
![enter image description here]()
Ясно, что что-то не так с тем, как я использую координаты, и какая-то система отсчета не то, что я думаю, когда она находится в ландшафтном режиме, но у меня есть время на то, как решить ее, Я попытался преобразовать всевозможные вещи с помощью -convertRect: но ничто из того, что я пытаюсь, никуда меня не доставит.
Я действительно надеюсь, что кто-то, кто меньше смущает все эти прямоугольники и как они меняются, когда изменения ориентации могут определить, что я делаю неправильно, и что мне нужно сделать, чтобы это исправить. Для справки, я создал проект, демонстрирующий простейший случай, который воспроизводит проблему, которую я имею.
Ответы
Ответ 1
Я не советую вам изменять размер корневого представления для вашего контроллера представлений, вы можете создать contentView и добавить в просмотр контроллера вида. Вы можете изменить размер этого contentView, как показано ниже (я не использую autolayouting):
- (void)keyboardWillShow:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
- (void)keyboardWillHide:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
Ответ 2
Виталий Б ответ быстро. Я получил представление под названием templateHeaderContentView, я создал функцию и настроил ее высоту. Вы используете свой собственный вид и соответственно изменяете его.
func keyboardWillShow(notification: NSNotification) {
keyboardShowOrHide(notification)
}
func keyboardWillHide(notification: NSNotification) {
keyboardShowOrHide(notification)
}
private func keyboardShowOrHide(notification: NSNotification) {
guard let userInfo = notification.userInfo else {return}
guard let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]else { return }
guard let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] else { return }
guard let keyboardFrameEnd = userInfo[UIKeyboardFrameEndUserInfoKey] else { return }
let curveOption = UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16))
let keyboardFrameEndRectFromView = view.convertRect(keyboardFrameEnd.CGRectValue, fromView: nil)
UIView.animateWithDuration(duration.doubleValue ?? 1.0,
delay: 0,
options: [curveOption, .BeginFromCurrentState],
animations: { () -> Void in
self.templateHeaderContentView.configureView(keyboardFrameEndRectFromView.origin.y)
}, completion: nil)
}
Ответ 3
Покрытый очень хорошо прямой рот лошади:
https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
Ответ 4
Я сделал это, надеюсь, этот код будет полезен для u.
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification*)notification
{
[self moveControls:notification up:YES];
}
- (void)keyboardWillBeHidden:(NSNotification*)notification
{
[self moveControls:notification up:NO];
}
- (void)moveControls:(NSNotification*)notification up:(BOOL)up
{
NSDictionary* userInfo = [notification userInfo];
CGRect newFrame = [self getNewControlsFrame:userInfo up:up];
[self animateControls:userInfo withFrame:newFrame];
}
- (CGRect)getNewControlsFrame:(NSDictionary*)userInfo up:(BOOL)up
{
CGRect kbFrame = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
kbFrame = [self.view convertRect:kbFrame fromView:nil];
CGRect newFrame = self.view.frame;
newFrame.origin.y += kbFrame.size.height * (up ? -1 : 1);
return newFrame;
}
- (void)animateControls:(NSDictionary*)userInfo withFrame:(CGRect)newFrame
{
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
[UIView animateWithDuration:duration
delay:0
options:animationOptionsWithCurve(animationCurve)
animations:^{
self.view.frame = newFrame;
}
completion:^(BOOL finished){}];
}
static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve)
{
return (UIViewAnimationOptions)curve << 16;
}
Ответ 5
Попробуйте эти методы. Отредактируйте его в соответствии с вашими требованиями.
#define kOFFSET_FOR_KEYBOARD 280.0
- (void)keyboardWillHide:(NSNotification *)notif {
[self setViewMoveUp:NO];
}
- (void)keyboardWillShow:(NSNotification *)notif{
[self setViewMoveUp:YES];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
stayup = YES;
[self setViewMoveUp:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
stayup = NO;
[self setViewMoveUp:NO];
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMoveUp:(BOOL)moveUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect rect = self.view.frame;
if (moveUp)
{
// 1. move the view origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
if (rect.origin.y == 0 ) {
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
//rect.size.height += kOFFSET_FOR_KEYBOARD;
}
}
else
{
if (stayup == NO) {
rect.origin.y += kOFFSET_FOR_KEYBOARD;
//rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
}
self.view.frame = rect;
[UIView commitAnimations];
}