7

UIScrollView当键盘隐藏 a 时,我试图UITextField通过使用显示的更改大小来移动 a contentInsets

但是,它不适用于键盘高度。键盘高度为 216,但如果我将底部插图设置为 iPhone 纵向模式的 515 和 iPhone 横向模式的 310,它只会在正确的位置停止滚动。为什么这些维度会如此不同?我不想硬编码这些任意值。

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.frame = self.parentViewController.view.frame;

    [self.textView becomeFirstResponder];

    NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width);

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification
                                           object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

- (void)keyboardWasShown:(NSNotification *)notification
{
    if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone) {

        // Step 1: Get the size of the keyboard.
        CGFloat keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;

        // Step 2: Adjust the bottom content inset of your scroll view by the keyboard height.
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardHeight, 0.0);
        ((UIScrollView*)self.view).contentInset = contentInsets;
        ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets;

        // Step 3: Scroll the target text field into view.
        CGRect aRect = self.view.frame;
        aRect.size.height = aRect.size.height - keyboardHeight;
        if (!CGRectContainsPoint(aRect, self.textView.frame.origin) ) {
            CGPoint scrollPoint = CGPointMake(0.0, self.textView.frame.origin.y - keyboardHeight);
            [((UIScrollView*)self.view) setContentOffset:scrollPoint animated:YES];
        }
    }
}

- (void) keyboardWillHide:(NSNotification *)notification {
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    ((UIScrollView*)self.view).contentInset = contentInsets;
    ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets;
}

编辑:

在键盘打开之前,我打印出来:

NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width);

它打印这个:

scrollview: 431.000000,320.000000, parent: 431.000000,320.000000
4

2 回答 2

23

我认为主要问题是您需要使用UIKeyboardFrameEndUserInfoKey而不是UIKeyboardFrameBeginUserInfoKey.

话虽这么说,我已经编写了这个方法的不同版本,即使滚动视图没有放在屏幕底部,它也可以工作,并且可能对你更有效:

请注意,我使用self.activeTextField而不是self.textField.

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    // Calculate the frame of the scrollview, in self.view's coordinate system
    UIScrollView *scrollView    = self.scrollView;
    CGRect scrollViewRect       = [self.view convertRect:scrollView.frame fromView:scrollView.superview];

    // Calculate the frame of the keyboard, in self.view's coordinate system
    NSDictionary* info          = [aNotification userInfo];
    CGRect kbRect               = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    kbRect                      = [self.view convertRect:kbRect fromView:nil];

    // Figure out where the two frames overlap, and set the content offset of the scrollview appropriately
    CGRect hiddenScrollViewRect = CGRectIntersection(scrollViewRect, kbRect);
    if (!CGRectIsNull(hiddenScrollViewRect))
    {
        UIEdgeInsets contentInsets       = UIEdgeInsetsMake(0.0,  0.0, hiddenScrollViewRect.size.height,  0.0);
        scrollView.contentInset          = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

    [self scrollToActiveTextField];
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.scrollView.contentInset          = UIEdgeInsetsZero;
    self.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

- (void)scrollToActiveTextField
{
    if (self.activeTextField)
    {
        CGRect visibleRect = self.activeTextField.frame;
        visibleRect        = [self.scrollView convertRect:visibleRect fromView:self.activeTextField.superview];
        visibleRect        = CGRectInset(visibleRect, 0.0f, -5.0f);
        [self.scrollView scrollRectToVisible:visibleRect animated:YES];
    }
}
于 2013-05-29T06:14:46.100 回答
0

无论您在代码中创建滚动视图,都将您的滚动视图的委托设置为自我

 ((UIScrollView*)self.view).delegate=self;

然后

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.frame = self.parentViewController.view.frame;

    [self.textView becomeFirstResponder];

    NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width);

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification
                                           object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

- (void)keyboardWasShown:(NSNotification *)notification
{
    if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone) {

        // Step 1: Get the size of the keyboard.
        CGFloat keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;

        // Step 2: Adjust the bottom content inset of your scroll view by the keyboard height.
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardHeight, 0.0);
        ((UIScrollView*)self.view).contentInset = contentInsets;
        ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets;

        ((UIScrollView*)self.view).scrollEnabled=YES;
    }
}

- (void) keyboardWillHide:(NSNotification *)notification {
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    ((UIScrollView*)self.view).contentInset = contentInsets;
    ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets;
    [((UIScrollView*)self.view) setContentOffset:CGPointMake(0.0f, 0.0f) animated:TRUE];
    ((UIScrollView*)self.view).contentSize = CGSizeMake(((UIScrollView*)self.view).contentSize.width, ((UIScrollView*)self.view).contentSize.height);
    ((UIScrollView*)self.view).scrollEnabled=NO;

}

#pragma mark - set scrollView content position
-(void)scrollViewToCenterOfScreen:(UIView *)theView
{
    CGFloat theViewY = theView.center.y;
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
    CGFloat avaliableHeight = applicationFrame.size.height - 300;
    CGFloat y = theViewY - avaliableHeight / 2.0;
    if(y<0)
        y = 0;
    [((UIScrollView*)self.view) setContentOffset:CGPointMake(0,y) animated:YES];
}

#pragma -mark UITextField Delegate methods

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    [self scrollViewToCenterOfScreen:textField];
    return YES;
}

现在设置您的文本字段的委托。每当 textFieldShouldBeginEditing: 你的滚动视图自动移动。scrollViewToCenterOfScreen: 方法将您的滚动视图位置设置在文本文件位置。

它肯定会设置您的滚动视图内容插图以及 setContentOffset。如果您仍然面临这个问题,请告诉我。谢谢

于 2013-05-23T07:34:59.413 回答