【问题标题】:View that moves along with keyboard随键盘移动的视图
【发布时间】:2013-11-08 06:01:10
【问题描述】:

我有一个带有UIScrollView 的 iOS 应用程序,它基本上看起来像 Messages.app:屏幕上的内容和底部的文本视图和添加更多内容的按钮。当键盘出现时,文本视图和按钮正确向上移动。

我设置了keyboardDismissMode,以便向下拖动键盘使其消失,但在拖动过程中,随着键盘向下移动,我如何更新我的视图在屏幕上的位置以保持连接?在此过程中似乎没有触发键盘将更改框架通知。

这样做的“正确”方法是什么?

编辑:我有一种预感,使用输入视图/附件视图可能是可行的,但不确定这是正确的方向。

【问题讨论】:

  • 抱歉,您想更改键盘位置。如果您想观察它,我更新了我的答案,以展示如何按照其他人的建议使用 KVO 进行操作。
  • 你找到解决这个问题的方法了吗??

标签: ios iphone uiscrollview ios7 autolayout


【解决方案1】:

很确定这种行为需要 SPI。但是:您可以遍历视图/窗口层次结构,找到键盘窗口,然后对其应用变换以在交互过程中移动它。 (window.transform=)

不确定当您的交互结束时该怎么做 - 可能手动动画键盘离开(使用上述技术)以完成键盘隐藏,然后当它被隐藏时,辞去第一响应者而不制作动画。

编辑:

对不起,我以为你想移动键盘,但如果你想观察键盘的位置,你可以使用 KVO(正如@KudoCC 建议的那样)

static void * __keyboardCenterKVOContext = & __keyboardCenterKVOContext ;

-(void)setUpKeyboardObserver
{
    UIView * keyboardView = ...?
    [ keyboardView addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:__keyboardCenterKVOContext ] ;
}

然后实现KVO观察者:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ( context == __keyboardCenterKVOContext )
    {
        CGPoint newKeyboardCenter = [ [ change valueForKey:NSKeyValueChangeNewKey ] pointValue ] ;
        // .. handle new keyboard position here ...
    }
    else
    {
        [ super observeValueForKeyPath:keyPath ofObject:object change:change context:context ] ;
    }
}

每次键盘视图更改其中心属性时,都会运行您的 KVO 观察器。您也可以尝试观察键盘窗口的frame 和/或transform 属性。

我有一些代码可以帮助您在这里观察 KVO,这可能会对您有所帮助:https://gist.github.com/nielsbot/6873377

(您可能想要使用我的帮助代码的原因是因为它会自动从正在释放的对象中删除 KVO 观察。这需要一些运行时摆弄,但在您的情况下,您并不真正知道键盘窗口何时会被释放。虽然也许你可以在你的keyboardWillHide处理程序中拆除KVO)

【讨论】:

  • 我不知道 SPI 是什么意思 :) 并且很想听听“更清洁”的解决方案
  • 我也不知道SPI,你是说系统私有接口吗?
  • SPI = 系统编程接口。 IE。如果您使用私有 API,您的应用程序将被 App Store 拒绝。此外,您的应用可能会在未来的操作系统中停止工作,因为不保证 SPI 不会在没有通知的情况下更改
  • 嗯,如果有办法获得键盘视图,这可能会起作用
  • 可能有一种方法不是 hacky。例如,您可以创建一个 0x0 的辅助键盘视图,覆盖它的 -didMoveToSuperview 并查看您所在的窗口。
【解决方案2】:

您可以尝试在键盘消失和出现时通知移动您的内容:

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(keyboardDisappeared) name:UIKeyboardWillHideNotification object:nil];
    [center addObserver:self selector:@selector(keyboardAppeared) name:UIKeyboardWillShowNotification object:nil];


    -(void) keyboardDisappeared
    {
     [UIView animateWithDuration:1.0 delay:0 options:yourAnimationOption  animations:^
            {
                   self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+100(same as you do in keyboardAppeared), self.view.frame.size.width, self.view.frame.size.height);

            } completion::^(BOOL finished) 
                 {
               }];
    }

 -(void) keyboardAppeared
    {
     [UIView animateWithDuration:1.0 delay:0 options:yourAnimationOption  animations:^
            {
                   self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y-(as much you want), self.view.frame.size.width, self.view.frame.size.height);

            } completion::^(BOOL finished) 
                 {
               }];
    }

【讨论】:

  • 这就是整个问题,keyboardDismissMode 拖动发生时不会触发这些事件
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 2014-06-13
  • 2023-03-22
  • 2015-12-14
  • 2010-12-19
  • 2021-09-12
  • 2018-01-12
  • 2020-01-16
相关资源
最近更新 更多