ios - scrollView的ContentInset

原文 标签 ios swift user-interface uiscrollview keyboard-events

这是我的观点,左边是未显示键盘时的视图,右边是我想要显示键盘时的视图。

enter image description here

我所有的字段都添加到了scrollView中,然后我像这样设置了约束,field1 topConstraint设置为scrollView top,field4 bottomConstraint设置为scrollView bottom。其他所有字段都附在下面的字段中。

从最右边的模型中可以看到,当显示键盘时,我想像这样重新调整视图。所以我现在正在做的是:

func keyboardWillShow(notification: NSNotification) {
       self.field2.snp_updateConstraints { make -> Void in
          make.bottom.equalTo(self.field3.snp_top).offset(8)
       }

到目前为止,我调整了field2和field3之间的大空间。然后,我继续设置contentInset:
    let contentInset = UIEdgeInsetsMake(0, 0,getKeyboardSize(notification).height, 0)

    self.scrollView.contentInset = contentInset
    self.scrollView.scrollIndicatorInsets = contentInset

但是scrollView不能调整我想要的方式,因为field3仍然隐藏在键盘的一半后面。

撰写此文章的原因是,我显然不了解contentInsets如何与scrollView一起使用,并且即使可能,我也希望避免手动设置contentOffset。

我设置的约束似乎有问题。当前对field4的约束是我将其设置为绑定到视图,而不是scrollView底部,并且将scrollView的每个边缘设置为绑定到视图。

更新:
如果我将field4底部约束设置为与scrollView绑定,则scrollViews的高度为0,如果我刚刚将scrollView设置为与视图本身一样大,怎么会不知道应该是什么大小?这真让我感到困惑。

更新2
我正在像这样设置scrollView约束:
    self.scrollView.snp_makeConstraints { make -> Void in
        make.top.equalTo(self.snp_topLayoutGuideBottom)
        make.left.right.equalTo(self.view)
        make.bottom.equalTo(self.snp_bottomLayoutGuideBottom)
    }

从UIDebugger中,我可以看到scrollView的高度是相同的,但是Y坐标已更改为20,但是我仍然无法在其中滚动?另外,在调试时,我可以将scrollViews contentSize设置为大于框架,这意味着它应该是可滚动的,但不是。

更新3
现在我已经了解到,Field1和Field4都需要连接到scrollViews的顶部和底部。因此,scrollViews框架和scrollViews contentSize之间是有区别的,因为当contentSize> frame时,scrollView是可滚动的,这是按预期工作的。
因此,这对我来说是一大进步,现在唯一奇怪的是contentInset。

我对contentInset的理解是,您可以指定视图在任一方向上的缩小程度。因此,现在我正在使用scrollView底部的键盘高度进行插入,但是它没有滚动,但是当我将顶部contentInset设置为一些随机负数(例如-100)时,它会滚动,为什么调整底部插图时无法实现此行为吗?

最佳答案

所以我用以下方法解决了这个问题:

我确保将Field1和Field4约束设置为scrollview,这样,scrollView可以自动计算高度,如果某些内容不在视图中,则还可以进行滚动。然后,我从键盘顶部和框架计算了可见的框架。

   func keyboardWillShow(notification: NSNotification) {

    self.Field2.snp_updateConstraints { make -> Void in
         make.bottom.equalTo(self.Field3.snp_top)
    }

    self.Field3.snp_updateConstraints { make -> Void in
         make.bottom.equalTo(self.Field4.snp_top)
    }

    self.view.layoutIfNeeded()

    let contentInset = UIEdgeInsetsMake(0, 0,getKeyboardSize(notification).height + 4, 0)
    let visibleRect = UIEdgeInsetsInsetRect(self.scrollView.frame, contentInset)
    let scrollToOffset = max(0,self.Field4.frame.maxY - visibleRect.height)
    self.scrollView.setContentOffset(CGPoint(x: 0, y: scrollToOffset), animated: true)
 }

关键是在更改约束之后,我需要使当前布局无效并再次对视图进行布局,这样我们才能计算出可以正确完成更新约束的位置。

关于ios - scrollView的ContentInset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38832770/

相关文章:

objective-c - 在文档的ArrayController中访问appdelegate的managedObjectContext

ios - iOS 中的 GPS 导航

c# - 如何防止异步方法阻止UI?

java - 想要在用户使用按钮之前暂停代码

matlab - 制作一个对话框,用户可以在其中选择文件或文件夹

ios - 在Xcode 4.5中执行分析后,iOS应用程序内存泄漏

ios - 如何从Web服务获取数据?

ios - 如何在Swift Struct中存储多个回溯日期?

ios - 我使用 objective-c 在xcode上编写了一个程序。我可以在Windows机器上运行它吗?

ios - 调度组不适用于完成块