使用UIScrollViewKeyboardDismissModeInteractive移动一个栏

liv*_*124 21 uiscrollview ios

我有一个文本字段,我锚定到键盘的顶部.我不能使用inputAccessoryView,因为它总是显示.我能够观察键盘隐藏/显示的通知,使用键盘上下移动它,但这似乎不适用于UIScrollViewKeyboardDismissModeInteractive.有没有办法获得键盘位置的持续反馈以同步动画?

Mal*_*vis 17

编辑:看起来这在iOS 8中不起作用,伙计们 - 对不起!我也在寻找新的解决方案

我通过创建一个不可见的inputAccessoryView解决了这个问题.

textView.inputAccessoryView = [[MJXObservingInputAccessoryView alloc] init];
Run Code Online (Sandbox Code Playgroud)

accessoryView观察其superview的框架并发布您可以匹配的通知.

static NSString * const MJXObservingInputAccessoryViewSuperviewFrameDidChangeNotification = @"MJXObservingInputAccessoryViewSuperviewFrameDidChangeNotification";

@interface MJXObservingInputAccessoryView : UIView @end

@implementation MJXObservingInputAccessoryView

- (void)willMoveToSuperview:(UIView *)newSuperview
{
    if (self.superview)
    {
        [self.superview removeObserver:self
                            forKeyPath:@"frame"];
    }

    [newSuperview addObserver:self
                   forKeyPath:@"frame"
                      options:0
                      context:NULL];

    [super willMoveToSuperview:newSuperview];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (object == self.superview && [keyPath isEqualToString:@"frame"])
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:MJXObservingInputAccessoryViewSuperviewFrameDidChangeNotification
                                                            object:self];
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

  • 啊,没关系,这似乎可以解决问题:`UIView*activeKeyboard = observingInputAccessoryView.superview;`然后你可以从那个视图中获取帧. (4认同)
  • 再次问好.我找到了iOS 8的解决方案:你只能观察"中心"而不是"框架" (4认同)

Jor*_*anC 13

我找到了一个解决方案(虽然有点像黑客),我实现了scrollViewDidScroll来监听UITableView中内置的panGestureRecognizer.事实证明,键盘的顶部在整个手势中都能保持完美均匀,因此您可以不断更新文本字段,使其保持在平移手指上方.

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {

    CGPoint fingerLocation = [scrollView.panGestureRecognizer locationInView:scrollView];
    CGPoint absoluteFingerLocation = [scrollView convertPoint:fingerLocation toView:self.view];

    if (_keyboardIsOpen && scrollView.panGestureRecognizer.state == UIGestureRecognizerStateChanged && absoluteFingerLocation.y >= (self.view.frame.size.height - _keyboardFrame.size.height)) {

        [UIView animateWithDuration:.05 animations:^{
            //This is an autolayout constraint that needs to be set to the distance between the top of the keyboard and the bottom of the screen (with a buffer of 3)
            _bottomViewVerticalSpacingConstraint.constant = [[UIScreen mainScreen] bounds].size.height - absoluteFingerLocation.y - 3;
            [self.view layoutIfNeeded];
        }];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我也注册了通知

 [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShown:)
                                             name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillChangeFrame:)
                                             name:UIKeyboardWillChangeFrame object:nil];
Run Code Online (Sandbox Code Playgroud)

并像这样处理它们

-(void)keyboardWillShown:(NSNotification*)aNotification
{
    _keyboardIsOpen = YES;
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    [UIView animateWithDuration:.05 animations:^{
        _bottomViewVerticalSpacingConstraint.constant = kbSize.height;
        [self.view layoutIfNeeded];
    }];
}


-(void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    _keyboardIsOpen = NO;
    [UIView animateWithDuration:.3 animations:^{
        _bottomViewVerticalSpacingConstraint.constant = 0;
        [self.view layoutIfNeeded];
    }];
}

-(void)keyboardWillChangeFrame:(NSNotification*)aNotification {
    NSDictionary* info = [aNotification userInfo];
    _keyboardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
}
Run Code Online (Sandbox Code Playgroud)


小智 7

Malcolm的答案适用于iOS 8和7,只需稍作调整即可.我没有足够的声誉来评论他的帖子,所以这被添加为社区维基,供需要适用于iOS 7和8的解决方案的人们使用.

#import <UIKit/UIKit.h>

static NSString *const SSObservingInputAccessoryViewFrameDidChangeNotification = @"SSObservingInputAccessoryViewFrameDidChangeNotification";

@interface SSObservingInputAccessoryView : UIView

@end
Run Code Online (Sandbox Code Playgroud)

履行

#import "SSObservingInputAccessoryView.h"

@implementation SSObservingInputAccessoryView

- (void)willMoveToSuperview:(UIView *)newSuperview {
    if (self.superview) {
        [self.superview removeObserver:self
                            forKeyPath:@"center"];

        [self.superview removeObserver:self
                            forKeyPath:@"frame"];
    }

    [newSuperview addObserver:self
                   forKeyPath:@"center"
                      options:0
                      context:nil];

    [newSuperview addObserver:self
                   forKeyPath:@"frame"
                      options:0
                      context:nil];

    [super willMoveToSuperview:newSuperview];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (object == self.superview
        && ([keyPath isEqualToString:@"center"] || [keyPath isEqualToString:@"frame"])) {
        [[NSNotificationCenter defaultCenter] postNotificationName:SSObservingInputAccessoryViewFrameDidChangeNotification
                                                            object:self];
    }
}

@end
Run Code Online (Sandbox Code Playgroud)


AlK*_*zin 0

您尝试过DAKeyboardControl吗?

   UIView *addCommentContainer = self.addCommentContainer;
   [self.view addKeyboardPanningWithActionHandler:^(CGRect keyboardFrameInView) {
      [addCommentContainer setY:keyboardFrameInView.origin.y - addCommentContainer.frame.size.height];
   }];
Run Code Online (Sandbox Code Playgroud)

您可以在此控件上查看处理键盘框架的源代码。

  • 这个控制太糟糕了:( (8认同)