我会说得对.
我有一个UIViewController,里面有两个子视图.最上面的一个(我们从现在开始称它为HeaderView)是一个自定义的UIView,底部的是一个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
}
Run Code Online (Sandbox Code Playgroud)
如果我没有忘记任何事情,这应该足以达到预期的效果.让我分解一下:
actualOffset它在0和self.MaxHeaderScroll只有67 之间的绑定(我想,它是动态计算的,但这并不重要)actualOffset自上次调用此函数以来没有改变,我不打算任何改变.这避免了一些无用的计算.CATransform3DTranslate为y轴上的负数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的UIView actualOffset来对比滚动,但是这给出了一个奇怪的效果,其中单元格无法正确滚动,当UITableView被带回初始位置时,顶部会有一个间隙.对此也没有任何线索.我知道这里有很多,所以请不要犹豫,询问更多细节.先感谢您.
| 归档时间: |
|
| 查看次数: |
1249 次 |
| 最近记录: |