[英]scrolling/resizing UITableView
我会讲到重点。
我有一个UIViewController,其中有两个子视图。 顶部的是一个自定义的UIView(下面将其称为HeaderView),而底部的是一个UITableView。
我已经在InterfaceBuilder中对其进行了设置,以便HeaderView的左侧,顶部和右侧的边距为0,并且其高度固定。 UITableView在所有面的正下方,且页边距为0。
我的目标是实现一种行为,当我开始滚动UITableView的内容时,HeaderView将开始缩小,并且UITableView会变得更高而无需滚动。 这应该一直进行到HeaderView达到最小高度为止。 之后,UITableView应该开始正常滚动。 向下滚动时,效果应相反。
我最初是使用UIScrollView而不是UITableView来开始的,并且已经达到了预期的结果。 方法如下:
将UIScrollView连接到插座
@IBOutlet weak var scrollView: UIScrollView!
在控制器的viewDidLoad()
方法中设置UIScrollViewDelegate self.scrollView.delegate = self
并声明UIViewController符合协议
在UIScrollView滚动时进行拦截:
func scrollViewDidScroll(_ scrollView: UIScrollView) { self.adjustScrolling(offset: scrollView.contentOffset.y, scrollView: scrollView) }
在我的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
}
如果我没有忘记任何内容,这应该足以实现所需的效果。 让我分解一下:
actualOffset
0之间结合它self.MaxHeaderScroll
这仅仅是67(我认为,它是动态计算的,但这并不重要) actualOffset
并没有发生变化,那么我就不会麻烦地进行任何更改。 这避免了一些无用的计算。 CATransform3DTranslate
沿y轴actualOffset
,而负的actualOffset
。 self.header.didScrollBy(actualOffset)
以便HeaderView可以在内部应用一些可视更改。 但这并没有掩盖问题。 actualOffset
量相同,以对比滚动。 对于我想要实现的正确视觉效果而言,这是必不可少的。 如果我不这样做,scrollView仍会正确调整大小,但是内容将立即开始滚动,这是我不希望的。 仅应在HeaderView达到最小高度后才开始滚动。 actualOffset
供以后比较 正如我所说,这很好。 当我从UIScrollView切换到UITableView时出现问题。 由于UITableView继承自UIScrollView,因此我认为它会起作用。
唯一不起作用的代码是数字6。我真的不知道出了什么问题,所以我只列出我发现和/或注意到的所有内容。 希望有人能够帮助我。
scrollView.subviews[0]
引用一个视图,其中包含所有内容。 当我更改为UITableView时,此子视图似乎是UITableViewWrapperView
类型,找不到任何文档,XCode也不将其识别为有效类。 这已经令人沮丧。 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.