ios 当 UITextField 成为第一响应者时如何使 UIScrollView 自动滚动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13056004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a UIScrollView auto scroll when a UITextField becomes a first responder
提问by Nosrettap
I've seen posts around herethat suggest that UIScrollViews
should automatically scroll if a subview UITextField
becomes the first responder; however, I can't figure out how to get this to work.
我在这里看到的帖子表明,UIScrollViews
如果子视图UITextField
成为第一响应者,应该自动滚动;但是,我不知道如何让它发挥作用。
What I have is a UIViewController
that has a UIScrollView
and within the UIScrollView
there are multiple textfields.
我已经是一个UIViewController
具有UIScrollView
与内UIScrollView
有多个文本框。
I know how to do this manually if necessary; however, from what I've been reading, it seems possible to have it autoscroll. Help please.
如有必要,我知道如何手动执行此操作;但是,从我一直在阅读的内容来看,似乎可以让它自动滚动。请帮忙。
回答by Adeel Pervaiz
I hope this example will help you You can scroll to any point by this code.
我希望这个例子能帮助你你可以通过这段代码滚动到任何一点。
scrollView.contentOffset = CGPointMake(0,0);
So if you have textfield, it must have some x,y position on view, so you can use
所以如果你有文本框,它必须有一些 x,y 位置在视图中,所以你可以使用
CGPoint point = textfield.frame.origin ;
scrollView.contentOffset = point
This should do the trick,
这应该可以解决问题,
But if you don't know when to call this code, so you should learn UITextFieldDelegatemethods
但是如果你不知道什么时候调用这段代码,那么你应该学习UITextFieldDelegate方法
Implement this method in your code
在您的代码中实现此方法
- (void)textFieldDidBeginEditing:(UITextField *)textField {
// Place Scroll Code here
}
I hope you know how to use delegate methods.
我希望你知道如何使用委托方法。
回答by Supertecnoboff
I know this question has already been answered, but I thought I would share the code combination that I used from @Adeel and @Basil answer, as it seems to work perfectly for me on iOS 9.
我知道这个问题已经得到了回答,但我想我会分享我从 @Adeel 和 @Basil 答案中使用的代码组合,因为它在 iOS 9 上似乎对我来说非常适合。
-(void)textFieldDidBeginEditing:(UITextField *)textField {
// Scroll to the text field so that it is
// not hidden by the keyboard during editing.
[scroll setContentOffset:CGPointMake(0, (textField.superview.frame.origin.y + (textField.frame.origin.y))) animated:YES];
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
// Remove any content offset from the scroll
// view otherwise the scroll view will look odd.
[scroll setContentOffset:CGPointMake(0, 0) animated:YES];
}
I also used the animated method, it makes for a much smoother transition.
我还使用了动画方法,它可以实现更平滑的过渡。
回答by donmiller
Here is the Swift 4 update to @Supertecnoboff's answer. It worked great for me.
这是@Supertecnoboff 答案的 Swift 4 更新。它对我很有用。
func textFieldDidBeginEditing(_ textField: UITextField) {
scroll.setContentOffset(CGPoint(x: 0, y: (textField.superview?.frame.origin.y)!), animated: true)
}
func textFieldDidEndEditing(_ textField: UITextField) {
scroll.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
}
Make sure to extend UITextFieldDelegate and set the textfields' delegate to self.
确保扩展 UITextFieldDelegate 并将文本字段的委托设置为 self。
回答by Michael McGuire
There is nothing you have to do manually. It is the default behavior. There are two possibilities as to why you are not seeing the behavior
您无需手动执行任何操作。这是默认行为。关于为什么您没有看到该行为的原因有两种可能
- The most likely reason is that the keyboard is covering your
UITextField
. See below for solution - The other possibility is that you have another
UIScrollView
somewhere in the view hierarchy between theUITextField
and theUIScrollView
that you want to auto scroll. This is less likely but can still cause problems.
- 最可能的原因是键盘覆盖了您的
UITextField
. 解决办法见下文 - 另一种可能性是,你有其他
UIScrollView
的之间的视图层次的地方UITextField
和UIScrollView
要自动滚动。这不太可能,但仍然会导致问题。
For #1, you want to implement something similar to Apple's recommendations for Moving Content That Is Located Under the Keyboard. Note that the code provided by Apple does not account for rotation. For improvements on their code, check out this blog post'simplementation of the keyboardDidShow
method that properly translates the keyboard's frame using the window.
对于 #1,您想要实现类似于 Apple 的关于移动位于键盘下的内容的建议的内容。请注意,Apple 提供的代码不考虑轮换。要改进他们的代码,请查看此博客文章的实现keyboardDidShow
方法,该方法使用窗口正确转换键盘框架。
回答by George
- (void)textFieldDidBeginEditing:(UITextField *)textField {
CGRect rect = [textField bounds];
rect = [textField convertRect:rect toView:self.scrollView];
rect.origin.x = 0 ;
rect.origin.y -= 60 ;
rect.size.height = 400;
[self.scrollView scrollRectToVisible:rect animated:YES];
}
回答by Basil Mariano
You can use this function for autoScroll of UITextField
您可以将此功能用于 UITextField 的 autoScroll
on UITextFieldDelegate
在 UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self autoScrolTextField:textField onScrollView:self.scrollView];
}
- (void) autoScrolTextField: (UITextField *) textField onScrollView: (UIScrollView *) scrollView {
float slidePoint = 0.0f;
float keyBoard_Y_Origin = self.view.bounds.size.height - 216.0f;
float textFieldButtomPoint = textField.superview.frame.origin.y + (textField.frame.origin.y + textField.frame.size.height);
if (keyBoard_Y_Origin < textFieldButtomPoint - scrollView.contentOffset.y) {
slidePoint = textFieldButtomPoint - keyBoard_Y_Origin + 10.0f;
CGPoint point = CGPointMake(0.0f, slidePoint);
scrollView.contentOffset = point;
}
EDIT:
编辑:
Im now using IQKeyboardManagerKudos to the developer of this, you need to try this.
我现在使用IQKeyboardManagerKudos 向这个开发者致敬,你需要试试这个。
回答by Deep Batra
If you have multiple textfields say Textfield1
, Textfield2
, Textfield3
and you want to scroll the scrollview along the y-axis when textfield2 becomes first responder:
如果您有多个 textfields 说Textfield1
, Textfield2
,Textfield3
并且您想在 textfield2 成为第一响应者时沿 y 轴滚动滚动视图:
if([Textfield2 isFirstResponder])
{
scrollView.contentOffset = CGPointMake(0,yourY);
}
回答by jsbox
As Michael McGuire mentioned in his point #2 above, the system's default behavior misbehaves when the scroll view contains another scroll view between the text field and the scroll view. I've found that the misbehavior also occurs when there's a scroll view merely nextto the text field (both embedded in the scroll view that needs to be adjusted to bring the text field into view when the text field wants to start editing. This is on iOS 12.1.
正如 Michael McGuire 在上面的第 2 点中提到的那样,当滚动视图在文本字段和滚动视图之间包含另一个滚动视图时,系统的默认行为会出现错误。我发现当仅在文本字段旁边有滚动视图时也会发生不当行为(两者都嵌入在滚动视图中,当文本字段想要开始编辑时,需要进行调整以将文本字段带入视图中。这是在 iOS 12.1 上。
But my solution is different from the above. In my top-level scroll view, which is sub-classed so I can add properties and override methods, I override scrollRectToVisible:animated:
. It simply calls its [super scrollRectToVisible:animated:]
unless there's a property set that tells it to adjust the rect
passed in, which is the frame of the text field. When the property is non-nil, it is a reference to the UITextField
in question, and the rect
is adjusted so that the scroll view goes further than the system thought it would. So I put this in the UIScrollView
's sub-classed header file:
但我的解决方案与上述不同。在我的顶级滚动视图中,它是子类以便我可以添加属性和覆盖方法,我覆盖scrollRectToVisible:animated:
. 它只是调用它,[super scrollRectToVisible:animated:]
除非有一个属性集告诉它调整rect
传入的,这是文本字段的框架。当该属性为非 nil 时,它是对有UITextField
问题的引用,并且rect
会进行调整,以便滚动视图比系统预期的更远。所以我把它放在UIScrollView
子类的头文件中:
@property (nullable) UITextField *textFieldToBringIntoView;
(with appropriate @synthesize textFieldToBringIntoView;
in the implementation. Then I added this override method to the implementation:
(@synthesize textFieldToBringIntoView;
在实现中适当。然后我将这个覆盖方法添加到实现中:
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)how
{
if (textFieldToBringIntoView) {
// Do whatever mucking with `rect`'s origin needed to make it visible
// based on context or its spatial relationship with the other
// view that the system is getting confused by.
textFieldToBringIntoView = nil; // Go back to normal
}
[super scrollRectToVisible:rect animated:how];
}
In the delegate method for the UITextField
for when it's about to begin editing, just set textFieldToBringIntoView
to the textField
in question:
在 forUITextField
即将开始编辑时的委托方法中,只需设置textFieldToBringIntoView
为有textField
问题的:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Ensure it scrolls into view so that keyboard doesn't obscure it
// The system is about to call |scrollRectIntoView:| for the scrolling
// superview, but the system doesn't get things right in certain cases.
UIScrollView *parent = (UIScrollView *)textField.superview;
// (or figure out the parent UIScrollView some other way)
// Tell the override to do something special just once
// based on this text field's position in its parent's scroll view.
parent.textFieldToBringIntoView = textField;
// The override function will set this back to nil
return(YES);
}
It seems to work. And if Apple fixes their bug, it seems like it might still work (fingers crossed).
它似乎工作。如果 Apple 修复了他们的错误,它似乎仍然有效(手指交叉)。