繁体   English   中英

滚动/调整UITableView的大小

[英]scrolling/resizing UITableView

我会讲到重点。

我有一个UIViewController,其中有两个子视图。 顶部的是一个自定义的UIView(下面将其称为HeaderView),而底部的是一个UITableView。
我已经在InterfaceBuilder中对其进行了设置,以便HeaderView的左侧,顶部和右侧的边距为0,并且其高度固定。 UITableView在所有面的正下方,且页边距为0。

我的目标是实现一种行为,当我开始滚动UITableView的内容时,HeaderView将开始缩小,并且UITableView会变得更高而无需滚动。 这应该一直进行到HeaderView达到最小高度为止。 之后,UITableView应该开始正常滚动。 向下滚动时,效果应相反。

我最初是使用UIScrollView而不是UITableView来开始的,并且已经达到了预期的结果。 方法如下:

  1. 将UIScrollView连接到插座
    @IBOutlet weak var scrollView: UIScrollView!

  2. 在控制器的viewDidLoad()方法中设置UIScrollViewDelegate self.scrollView.delegate = self并声明UIViewController符合协议

  3. 在UIScrollView滚动时进行拦截:
    func scrollViewDidScroll(_ scrollView: UIScrollView) { self.adjustScrolling(offset: scrollView.contentOffset.y, scrollView: scrollView) }

  4. 在我的adjustScrolling(offset:scrollView:)方法中,“魔术”发生了

现在让我们看看这种方法会发生什么。

    private func adjustScrolling(offset: CGFloat, scrollView: UIScrollView) {

        // bind value between 0 and max header scroll
        let actualOffset: CGFloat = offset < 0 ? 0 : (offset >= self.maxHeaderScroll ? self.maxHeaderScroll : offset)

        // avoid useless calculations
        if (actualOffset == self.currentOffset) {
            return
        }

        /**
         * Apply the vertical scrolling to the header
         */
        // Translate the header up to give more space to the scrollView
        let headerTransform = CATransform3DTranslate(CATransform3DIdentity, 0, -(actualOffset), 0)
        self.header.layer.transform = headerTransform
        // Adjust header's subviews to new size
        self.header.didScrollBy(actualOffset)

        /**
         * Apply the corrected vertical scrolling to the scrollView
         */
        // Resize the scrollView to fill all empty space
        let newScrollViewY = self.header.frame.origin.y + self.header.frame.height
        scrollView.frame = CGRect(
            x: 0,
            y: newScrollViewY,
            width: scrollView.frame.width,
            height: scrollView.frame.height + (scrollView.frame.origin.y - newScrollViewY)
        )
        // Translate the scrollView's content view down to contrast scrolling
        let scrollTransform = CATransform3DTranslate(CATransform3DIdentity, 0, (actualOffset), 0)
        scrollView.subviews[0].layer.transform = scrollTransform
        // Set bottom inset to show content hidden by translation
        scrollView.contentInset = UIEdgeInsets(
            top: 0,
            left: 0,
            bottom: actualOffset,
            right: 0
        )

        self.currentOffset = actualOffset
    }

如果我没有忘记任何内容,这应该足以实现所需的效果。 让我分解一下:

  1. 我计算actualOffset 0之间结合它self.MaxHeaderScroll这仅仅是67(我认为,它是动态计算的,但这并不重要)
  2. 如果我发现自从上次调用此函数以来, actualOffset并没有发生变化,那么我就不会麻烦地进行任何更改。 这避免了一些无用的计算。
  3. 我将滚动应用于标题,方法是将CATransform3DTranslate沿y轴actualOffset ,而负的actualOffset
  4. 我调用self.header.didScrollBy(actualOffset)以便HeaderView可以在内部应用一些可视更改。 但这并没有掩盖问题。
  5. 我调整了scrollView的大小,以使HeaderView的高度在顶部和底部保持0页边距。
  6. 我向下滚动scrollView的内容时,实际的actualOffset量相同,以对比滚动。 对于我想要实现的正确视觉效果而言,这是必不可少的。 如果我不这样做,scrollView仍会正确调整大小,但是内容将立即开始滚动,这是我不希望的。 仅应在HeaderView达到最小高度后才开始滚动。
  7. 现在,我在scrollView中设置一个底部插图,以便能够一直滚动到最后。 否则,scrollView的最后一部分将被剪切掉,因为scrollView本身会认为它到达了其内容的末尾。
  8. 最后,我存储了actualOffset供以后比较

正如我所说,这很好。 当我从UIScrollView切换到UITableView时出现问题。 由于UITableView继承自UIScrollView,因此我认为它会起作用。
唯一不起作用的代码是数字6。我真的不知道出了什么问题,所以我只列出我发现和/或注意到的所有内容。 希望有人能够帮助我。

  • 对于UIScrollView,在点6中, scrollView.subviews[0]引用一个视图,其中包含所有内容。 当我更改为UITableView时,此子视图似乎是UITableViewWrapperView类型,找不到任何文档,XCode也不将其识别为有效类。 这已经令人沮丧。
  • 如果在第6点中,我还在x轴上进行了一些平移(比方说50),则可以看到初始的非常快速的平移立即变为0。这仅在UITableView开始滚动时才会发生,并且不会继续滚动时。
  • 我尝试在第6点更改子视图的框架以实现所需的结果。 尽管滚动是正确的,但是当我滚动UITableView时,顶部的单元格开始消失。 我之所以稀疏是因为我正在使用dequeueReusableCell(withIdentifier:for:)实例化单元格,并且UITableView认为顶部的单元格实际上并不可见。 我无法解决此问题。
  • 我尝试将self.tableView.tableHeaderView设置为actualOffset高度的UIView进行对比度滚动,但这产生了怪异的效果,即单元格无法正确滚动,并且当UITableView返回初始位置时,会出现间隙在上面。 也没有任何线索。

我知道这里有很多东西,所以请随时询问更多详细信息。 先感谢您。

我最近做了这样的事情,所以这是我如何实现的:

使一个具有高度约束常量的UIView并将其链接到您的视图/ VC,将UITableview约束到UIView后面的VC全屏视图。

现在,将UITableViews contentInset顶部设置为“ headerView”的起始高度,在scrollViewDidScroll中,调整常量,直到标题的高度最小为止。

这是一个演示

如果只运行它,则蓝色区域是您的“标题”,而彩色行则是任何单元格。 您可以在蓝色区域中自动布局任何内容,它应该会自动调整大小和所有内容

暂无
暂无

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

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