我有一个受限于superview的UITableView。所以第一个单元格位于superview的顶部。这意味着在iPhone X上,第一个细胞在缺口下流血,并进入状态栏区域。哪个是完全正确的。我希望细胞在缺口下流入状态栏区域,这是当前的结果。
问题是,我还想在该表视图上进行刷新控制,以便用户可以拉动来刷新内容。但是当您在iPhone X上进行刷新时,刷新控制将被切入。我不希望刷新控制被切入。
所以基本上我想要做的是将表视图限制在superview,但是将刷新控制限制在安全区域。
我已经浏览过,看起来Apple并没有提供许多属性或方法来自定义刷新控件的行为。
我考虑过使用某种类型的自定义解决方案,但是我想到的每个自定义解决方案都会丢失刷新控件和表格视图滚动等所有预构建的物理。幕后的逻辑非常多,我真的不想牺牲刷新的感觉以及用户的感受,因为它在iOS中变得如此普遍。
关于如何让第一个细胞在缺口下出血(约束到超视图)的任何想法,但确保刷新控制不会被缺口切断(限制在安全区域)?
我还在下面附上了屏幕截图,了解了细胞如何渗入状态栏,以及如何通过缺口切断刷新控制。
编辑:我还向GitHub here发布了一个示例项目。
但是与刷新控制相关的基本代码如下。
private lazy var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
tableView.refreshControl = refreshControl
}
@objc func handleRefresh() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.refreshControl.endRefreshing()
}
}
你可以利用UIScrollView
。使用你的github示例,你可以获得所需的一切,所以如果你扩展它:
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 {
topConstraint.constant = -scrollView.contentOffset.y/2
} else {
topConstraint.constant = 0
}
}
}
什么反应每次contentOffset
开始低于0
并使你的tableView
移动到底部,每当关闭或向下滚动它将被设置为默认值 - 在你的情况下0
。
这样,您将最终获得与拖动力/距离相关的平滑动画,如下所示
解决方案很简单,您可以在viewDidLoad中设置刷新控件的边界。使用您需要的y偏移值(例如50)
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
y: 50,
width: refreshControl.bounds.size.width,
height: refreshControl.bounds.size.height)
tableView.refreshControl = refreshControl
更新:
您可以在刷新开始时添加内容插入,并在结束时将其恢复。
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
y: -100,
width: refreshControl.bounds.size.width,
height: refreshControl.bounds.size.height);
tableView.refreshControl = refreshControl
}
@objc func handleRefresh() {
self.tableView.contentInset = UIEdgeInsets(top: 200, left: 0, bottom: 0, right: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.refreshControl.endRefreshing()
self.tableView.contentInset = UIEdgeInsets.zero
self.tableView.setContentOffset(.zero, animated: true)
}
}