键盘重叠时向上移动 UITextField
Posted
技术标签:
【中文标题】键盘重叠时向上移动 UITextField【英文标题】:Move UITextField up when keyboard is overlapped 【发布时间】:2017-05-22 18:54:16 【问题描述】:在 ViewA 上显示了一个 subView。请在下面找到屏幕布局。当键盘显示在选择 UITextField 时,即使它没有与 UITextField 重叠,视图也会向上滚动。
ViewA
-> UIButton
subView
-> UIScrollView
-> UITextField
-> UITextField
ViewA
-----------
| |
| |
| Button |
| |
| |
-----------
subView
--------------
| |
| |
| UITextField |
| UITextField |
| |
--------------
我已经注册了键盘通知
- (void) viewWillAppear:(BOOL)animated
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
- (void) keyboardDidShow:(NSNotification *)notification
NSDictionary* info = [notification userInfo];
CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0);
self.scrollViewIb.contentInset = contentInsets;
self.scrollViewIb.scrollIndicatorInsets = contentInsets;
CGRect aRect = self.viewSelf.frame;
aRect.size.height -= kbRect.size.height;
CGRect frame = [self.viewSelf convertRect:self.activeField.frame toView:self.viewSelf.superview];
if (!CGRectContainsPoint(aRect, frame.origin) )
[self.scrollViewIb scrollRectToVisible:self.activeField.frame animated:YES];
- (void) keyboardWillBeHidden:(NSNotification *)notification
self.scrollViewIb.scrollEnabled = true;
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.scrollViewIb.scrollIndicatorInsets = contentInsets;
[self.scrollViewIb setContentOffset:CGPointZero animated:false];
【问题讨论】:
最好使用这个库github.com/michaeltyson/TPKeyboardAvoiding它会在键盘弹出时自动管理你的视图。 【参考方案1】:坐标系转换有个小错误:convertRect:toView:从receiver的坐标系转换为传递的view的坐标。
如果self.activeField.frame
是self.scrollViewIb
坐标系中的一个矩形,正如代码所示,那么转换应该是这样的......
CGRect frame = [self.scrollViewIb convertRect:self.activeField.frame toView:self.view];
请注意,我还建议将 self.viewSelf.superview
更改为 self.view
。如果这段代码在包含所有这些子视图的视图控制器中运行,那么 self.view 应该是足够且正确的。
【讨论】:
建议的更改我仍然面临问题 嗯。很抱歉听到。我将在今天晚些时候自己构建这个,让你知道我出现了什么。同时,您可以记录所有视图的框架并将它们发布到这里吗?按钮、子视图、滚动视图及其两个文本视图? 请找项目github.com/dssandeep/ScrollTextField.git 嗯。不能运行它。我得到“无效的论点”。必须是构建设置中的某些内容。此外,超级不寻常和复杂的设置。您是否只是想在主视图上弹出“viewself”(带有两个文本字段)?推荐的方法是使用另一个视图控制器。 viewself 中还有一些 UI 元素。【参考方案2】:我认为问题在于您总是向上滚动,无论键盘是否与您的文本字段重叠。
您必须获取文本字段的框架,计算到屏幕底部的距离并检查键盘高度(加上其顶部可能的工具栏)是否会与您的文本字段重叠,然后才能向上滚动。
无论如何,我个人一次又一次地放弃了实现向上滚动的行为。我现在改用 IQKeyboardManager。只需将其作为 Pod 安装在您的项目中,然后在 application(didFinishLaunchingWithOptions) 中调用 IQKeyboardManager.sharedManager().enable = true
即可。
您甚至可以免费获得带有下一个/上一个和完成按钮的工具栏。
【讨论】:
【参考方案3】:当我们身处拥有大量开放图书馆的世界时,请不要担心。
通过将KeyboardLib Lib 添加到代码或通过 pod 来使用它。
只需构建它。在每次打开键盘时,都会显示带有完成按钮的下一个、上一个箭头的选项。 零代码行,具有自动事件处理功能。
这可能是解决问题和改进应用程序的解决方案。
【讨论】:
【参考方案4】:*Add this in your Controller or the other way is to create a category on UITextField. If you are creating a category on UITextfield just call below methods in delegate methods of UITextField.
static CGFloat const MINIMUM_SCROLL_FRACTION = 0.4;
static CGFloat const MAXIMUM_SCROLL_FRACTION = 0.8;
static CGFloat const PORTRAIT_KEYBOARD_HEIGHT = 185;
static CGFloat const PORTRAIT_KEYBOARD_HEIGHT1 = 230;
static CGFloat const LANDSCAPE_KEYBOARD_HEIGHT = 140;
static CGFloat const KEYBOARD_ANIMATION_DURATION = 0.3;
- (void)textFieldDidBeginEditing:(UITextField *)textField view:(UIView *)view
CGRect textFieldRect = [view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [view.window convertRect:view.bounds fromView:view];CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
heightFraction = 0.0;
else if (heightFraction > 1.0)
heightFraction = 1.0;
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if([[ UIScreen mainScreen ] bounds ].size.height == 568)
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
else
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
else
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction + 23);
else
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction + 23);
CGRect viewFrame = view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[view setFrame:viewFrame];
[UIView commitAnimations];
- (void)textFieldDidEndEditing:(UITextField *)textField view:(UIView *)view
CGRect viewFrame = view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCur rentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[view setFrame:viewFrame];
[UIView commitAnimations];
*
【讨论】:
以上是关于键盘重叠时向上移动 UITextField的主要内容,如果未能解决你的问题,请参考以下文章