简体   繁体   English

出现键盘时如何使滚动视图在缩小的视图区域中滚动

[英]How to make the scrollview scrollable in reduced view area when keyboard appears

I have embedded all my views in a UIScrollView from xib. 我已经将所有视图嵌入到xib的UIScrollView中。 The scrollview contents cover all screen below status bar. 滚动视图内容覆盖状态栏下方的所有屏幕。 Now when the textfield is tapped, I am able to move the scrollview little up. 现在,当点击文本字段时,我可以将scrollview稍微向上移动。 But I want it to be completely scrollable till the bottom most view is also visible above the keyboard. 但我希望它可以完全滚动,直到在键盘上方也可以看到最底部的视图。 Also when the scrollview is scrolled till top , it should come to normal original positions. 同样,当scrollview滚动到top时,它应该到达正常的原始位置。 Hence, Overall I want a completely scrollable functionality like mentioned above for my scrollview. 因此,总的来说,我想要一个完全可滚动的功能,就像上面为我的滚动视图所提到的那样。

I am done with following tricks but with no luck: 我已经完成了以下技巧,但没有运气:

Trick 1: Change the height of the scrollview so that the content is more than scrollview height and hence the view is scrollable: 技巧1:更改scrollview的高度,以使内容大于scrollview的高度,因此该视图可滚动:

-(void)keyboardWillAppear:(NSNotification *)sender
{
CGFloat y_offset=0;

if([UIScreen mainScreen].bounds.size.height == 480){
    y_offset = 80;
} else {
    y_offset = 70;
}
NSDictionary* userInfo = [sender userInfo];

CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
keyboardHeight = keyboardEndFrame.size.height;

[UIView animateWithDuration:0.5f animations:^{
    [self.view setFrame:CGRectMake(0, - y_offset, self.view.frame.size.width, self.view.frame.size.height)];
}];


[self.loginScrollView setFrame:CGRectMake(self.loginScrollView.frame.origin.x, self.loginScrollView.frame.origin.y, self.loginScrollView.frame.size.width, [UIScreen mainScreen].bounds.size.height - keyboardHeight)];
}

-(void)keyboardWillDisappear:(NSNotification *)sender
{
[UIView animateWithDuration:0.5f animations:^{
    [self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
}];
[self.loginScrollView setFrame:CGRectMake(self.loginScrollView.frame.origin.x, self.loginScrollView.frame.origin.y, self.loginScrollView.frame.size.width, [UIScreen mainScreen].bounds.size.height)];
}

Trick 2: As per other suggestions, I changed the contentInset of the UIScrollView. 技巧2:根据其他建议,我更改了UIScrollView的contentInset。

In keyboardWillAppear method I added following code: 在keyboardWillAppear方法中,我添加了以下代码:

  CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
  UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height+100, 0.0);
  self.loginScrollView.contentInset = contentInsets;
  self.loginScrollView.scrollIndicatorInsets = contentInsets;

and in keyboardWillDisappear method I set the contentInset back to zero values. 并在keyboardWillDisappear方法中将contentInset设置回零值。

Hence, let me know if there needs to be any other way to sort this out or any other possible changes I need to make in scrollview frame. 因此,请告诉我是否需要其他任何方法来解决此问题,或者需要在滚动视图框架中进行任何其他可能的更改。 Moreover , if I turn on the bouncesVertically functionality it is able to bounce even when complete subviews are visible onscreen which I don't want. 而且,如果我打开了bouncesVertically功能,即使在屏幕上看到了我不想要的完整子视图,它也可以反弹。 So basically I want it to freeze when keyboard is not there and scrollable till viewable area when it is up. 因此,基本上,我希望它在键盘不存在时冻结,并且在其向上滚动时可滚动到可见区域。 Hence, give me any other suggestions? 因此,还有其他建议吗? Thanks in advance. 提前致谢。

-(void)textFieldDidBeginEditing:(UITextField *)textField -(void)textFieldDidBeginEditing:(UITextField *)textField

{ {

[self animateTextField:textField up:YES];

} }

-(void)textFieldDidEndEditing:(UITextField *)textField -(void)textFieldDidEndEditing:(UITextField *)textField

{ {

[self animateTextField:textField up:NO];

} }

-(void)animateTextField:(UITextField*)textField up:(BOOL)up { -(void)animateTextField:(UITextField *)textField up:(BOOL)up {

    const int movementDistance = -60; // change this size if you need
    const float movementDuration = 0.3f; // change this size if you need

    int movement = (up ? movementDistance : -movementDistance);

    [UIView beginAnimations: @"animateTextField" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

it is useful for me 对我有用

I can really recommend this library: https://github.com/michaeltyson/TPKeyboardAvoiding 我真的可以推荐这个库: https : //github.com/michaeltyson/TPKeyboardAvoiding

It's very very easy to use, and works for ScrollView, TableView and CollectionView! 它非常易于使用,并且适用于ScrollView,TableView和CollectionView!

From a conceptual point of view when " scrollView Size == scrollView ContentSize ", it does not scroll. 从概念上讲,当“ scrollView Size == scrollView ContentSize ”时,它不会滚动。 To make it scrollable we need to increase the contentSize . 为了使其可滚动,我们需要增加contentSize In your problem you need to adjust the contentSize of scrollView along with frame. 在您的问题中,您需要调整scrollView的contentSize和框架。 This can be done in your first approach. 这可以用您的第一种方法来完成。

As for the second approach, changing the edge insets will create a sort of padding for the content drawable area. 对于第二种方法,更改边缘插图将为内容可绘制区域创建一种填充。 This can make the bottom content visible, but it won't affect the contentSize , hence view will not be scrollable. 这样可以使底部的内容可见,但不会影响contentSize ,因此视图将无法滚动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM