iOS - 当文本字段在子视图内时,键盘上的 UIScroll 弹出到文本字段
Posted
技术标签:
【中文标题】iOS - 当文本字段在子视图内时,键盘上的 UIScroll 弹出到文本字段【英文标题】:iOS - UIScroll on Keyboard popup to textfield on when textfield is inside subview 【发布时间】:2013-07-12 23:26:45 【问题描述】:当键盘覆盖文本字段时,我使用代码使屏幕滚动。
我有一个文本字段列表,为了样式和组织目的,我开始将每个文本字段放在自己的 uiview 中。
现在我的代码仅在我开始实际输入文本字段时才有效。这是我从苹果复制的怪物。注意:我添加了一个参数 registerForKeyboardNotifications 以便我可以将其包含在父类中并从任何地方调用它
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications:(UIScrollView *)scroll
_scroller = scroll;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
NSLog(@"hey");
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, _activeField.frame.origin) )
CGPoint scrollPoint = CGPointMake(0.0, _activeField.frame.origin.y-kbSize.height);
[_scroller setContentOffset:scrollPoint animated:YES];
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
- (void)textFieldDidBeginEditing:(UITextField *)textField
_activeField = textField;
- (void)textFieldDidEndEditing:(UITextField *)textField
_activeField = nil;
我已将问题缩小到视图控制器中的这一部分
for (id subView in _tpnScroll.subviews)
if ([subView isKindOfClass:[UIView class]])
UIView *thisView = subView;
for(id textfield in thisView.subviews)
if([textfield isKindOfClass:[UITextField class]])
[textfield setDelegate:self];
原来的代码是
for (id subView in _tpnScroll.subviews)
if ([subView isKindOfClass:[UITextField class]])
[subView setDelegate:self];
在第一个例子中。我循环遍历我的 UIViews,找到 UITextfields,并将委托设置为 self(这部分我不完全理解,仍在尝试理解委托的概念)
在第二个例子中,文本字段直接位于滚动视图上,所以我直接循环遍历它们。
对不起,如果这太罗嗦了。
【问题讨论】:
【参考方案1】:尝试用这个替换keyboardWasShown。
- (void)keyboardWasShown:(NSNotification*)aNotification
NSLog(@"hey");
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
// the scroll view will only scroll if the text field is not fully visible
// no need to check if it is actually covered
[_scroller scrollRectToVisible:[_scroller convertRect:_activeField.bounds fromView:_activeField]
animated:YES];
将文本字段的边界转换为滚动视图的坐标系可确保即使文本字段不在滚动视图内部,它也能正常工作。
【讨论】:
这不起作用。我不确定你是否理解我的结构。我有一个视图->滚动视图->许多视图->许多文本字段,当它是视图时工作正常->滚动视图->文本字段 @hamobi 我理解结构。原始代码的问题在于,您在包含它们的视图中获取文本字段的框架,而不是在滚动视图的坐标中。你在哪里设置内容大小?另外,请确保正在调用 textFieldDidBeginEditing:。 该方法被调用我注意到这个值 _activeField.frame.origin.y-kbSize.height 最终为负数。这可能是什么原因。我怎样才能得到文本字段相对于滚动视图的坐标,而不是它所在的 uiview? 我最终厌倦了用头撞墙并改用它github.com/michaeltyson/TPKeyboardAvoiding 很高兴您找到了解决方案。在我发布的代码中,[_scroller convertRect:_activeField.bounds fromView:_activeField] 是计算滚动视图中文本字段坐标的部分。以上是关于iOS - 当文本字段在子视图内时,键盘上的 UIScroll 弹出到文本字段的主要内容,如果未能解决你的问题,请参考以下文章
当我在显示的键盘上单击文本字段两次时,iOS UIScrollView 无法滚动