这个问题曾被问过几次,但我真的无法找到答案......
在iOS6中,每当键盘出现时,我都会使用以下内容调整UITextView的大小。在iOS7下,行为不是应该的(在我的情况下,似乎没有任何东西正在调整大小)。我怀疑原因是iOS7的自动布局/约束行为。有什么建议? (" notePad"是我的UITextView)?
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//NSLog(@"KeyboardSize: %f.%f", kbSize.width, kbSize.height);
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, (kbSize.width > kbSize.height ?
kbSize.height : kbSize.width), 0);
self.notePad.contentInset = contentInsets;
self.notePad.scrollIndicatorInsets = contentInsets;
}
答案 0 :(得分:15)
如果您在视图中使用自动布局,则以下方法可能会对您有所帮助。
首先为底部布局指南约束定义IBOutlet并与storyboard元素链接。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewBottomConst;
第二次添加键盘通知的观察者。
- (void)observeKeyboard {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
最后处理键盘更改的方法。
- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [kbFrame CGRectValue];
CGRect finalKeyboardFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];
int kbHeight = finalKeyboardFrame.size.height;
int height = kbHeight + self.textViewBottomConst.constant;
self.textViewBottomConst.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
self.textViewBottomConst.constant = 10;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
此方法支持方向更改和不同的键盘大小。希望它有所帮助。
答案 1 :(得分:4)
您的代码在逻辑上是正确的。当键盘出现时,您几乎不应该使用scrollview行为更改对象的框架,但是您应该只更改insets。 插件应相对于当前版本更改,因为iOS7负责调整导航栏。如果你提供一个新的插图可能你会破坏UI中的东西。 你的代码在iOS7上被破坏了两个主要原因:
以下是正确配置文本视图的步骤:
注册键盘通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
在keyboardWillShow
和keyboardWillHide
中,不要更改框架,而是将插图相对于现有框架更改。
- (void)keyboardWillShow:(NSNotification *)notification
{
// Take frame with key: UIKeyboardFrameEndUserInfoKey because we want the final frame not the begin one
NSValue *keyboardFrameValue = [notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
UIEdgeInsets contentInsets = self.textView.contentInset;
contentInsets.bottom = CGRectGetHeight(keyboardFrame);
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillHide:(NSNotification *)notification
{
UIEdgeInsets contentInsets = self.textView.contentInset;
contentInsets.bottom = .0;
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
}
答案 2 :(得分:3)
@BoranA有正确的答案,但需要调整所有键盘的全部功能。
请遵循以下代码:
将以下内容附加到Vertical Space - Bottom Layout Guide - TextField
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewBottomConst;
第二次添加键盘通知的观察者。
- (void)observeKeyboard {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
将此添加到viewDidLoad
[self observeKeyboard];
最后处理键盘更改的方法。
- (void)keyboardWillShow:(NSNotification *)notification {
//THIS WILL MAKE SURE KEYBOARD DOESNT JUMP WHEN OPENING QUICKTYPE/EMOJI OR OTHER KEYBOARDS.
kbHeight = 0;
height = 0;
self.textViewBottomConst.constant = height;
self.btnViewBottomConst.constant = height;
NSDictionary *info = [notification userInfo];
NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [kbFrame CGRectValue];
CGRect finalKeyboardFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];
int kbHeight = finalKeyboardFrame.size.height;
int height = kbHeight + self.textViewBottomConst.constant;
self.textViewBottomConst.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
self.textViewBottomConst.constant = 10;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
}
答案 3 :(得分:1)
我发现我必须拨打[self layoutIfNeeded]
才能让我的插图生效。
我的键盘通知方法如下所示(我更喜欢为更改设置动画):
-(void)keyboardWillShow:(NSNotification*)notification;
{
NSDictionary *userInfo = [notification userInfo];
NSValue *keyboardBoundsValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat keyboardHeight = [keyboardBoundsValue CGRectValue].size.width;
CGFloat duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
NSInteger animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
[UIView animateWithDuration:duration delay:0. options:animationCurve animations:^{
[[self textView] setContentInset:UIEdgeInsetsMake(0., 0., keyboardHeight, 0.)];
[[self view] layoutIfNeeded];
} completion:nil];
}
答案 4 :(得分:0)
键盘出现时需要调整UITextView的大小。 因此,请查看我之前的回答here。 您需要调用以下方法来调整UITextView的大小,具体取决于键盘的宽度和文本:
- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
{
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
您的代码使用我的方法:
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// Get your text to NSAttributedString
NSAttributedString *as = [[NSAttributedString alloc] initWithString:self.notePad.text];
// Resize UITextView
self.notePad.frame = CGRectMake(0, 0, CGRectGetWidth(self.notePad.frame), [self textViewHeightForAttributedText:as andWidth:kbSize.width)]);
}
答案 5 :(得分:0)
我一直在与这个争斗一个星期,我发现将键盘大小的高度添加到底部contentInset
不起作用。
有效的方法是从顶部减去它,如下:
UIEdgeInsets insets = UIEdgeInsetsMake(-(kbSize.height), 0.0, 0.0, 0.0);
[self.textView setContentInset:insets];