如何使ScrollView内的TableView的滚动自然行为
我需要做这个有奇怪配置的应用程序。
如下图所示,主视图是一个UIScrollView。 然后在里面它应该有一个UIPageView,并且PageView的每个页面都应该有一个UITableView。
到目前为止我已经完成了所有这些。 但我的问题是,我希望滚动行为 自然 。
接下来就是我的意思。 目前,当我在其中一个UITableView上滚动时,它滚动tableview(而不是scrollview)。 但我希望它滚动ScrollView,除非scrollview无法滚动,因为它得到了它的顶部或底部(在这种情况下,我希望它滚动tableview)。
例如,假设我的滚动视图正在滚动到顶部。 然后,我将手指放在(正在显示的当前页面的)tableview上并开始向下滚动。 我这种情况下,我希望scrollview滚动(没有tableview)。 如果我一直向下滚动滚动视图并且到达底部,如果我从显示中删除手指并将其放回tebleview并再次向下滚动,我希望现在我的tableview向下滚动,因为滚动视图已到达底部,而不是能够保持滚动。
你们有没有关于如何实现这种滚动的想法?
我真的失去了这个。 任何帮助将不胜感激:(
谢谢!
同时处理滚动视图和表视图的解决方案围绕UIScrollViewDelegate
。 因此,让您的视图控制器符合该协议:
class ViewController: UIViewController, UIScrollViewDelegate {
我将以滚动视图和表格视图的形式表示出来:
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var tableView: UITableView!
我们还需要跟踪滚动视图内容的高度以及屏幕高度。 你会看到为什么以后。
let screenHeight = UIScreen.mainScreen().bounds.height
let scrollViewContentHeight = 1200 as CGFloat
viewDidLoad:
需要一点配置:
override func viewDidLoad() {
super.viewDidLoad()
scrollView.contentSize = CGSizeMake(scrollViewContentWidth, scrollViewContentHeight)
scrollView.delegate = self
tableView.delegate = self
scrollView.bounces = false
tableView.bounces = false
tableView.scrollEnabled = false
}
我已经关闭弹跳以保持简单。 关键设置是滚动视图和表视图的代表,并且首先关闭表视图滚动。
这些是必需的,以便scrollViewDidScroll:
delegate方法可以处理到达滚动视图的底部并到达表视图的顶部。 这是该方法:
func scrollViewDidScroll(scrollView: UIScrollView) {
let yOffset = scrollView.contentOffset.y
if scrollView == self.scrollView {
if yOffset >= scrollViewContentHeight - screenHeight {
scrollView.scrollEnabled = false
tableView.scrollEnabled = true
}
}
if scrollView == self.tableView {
if yOffset <= 0 {
self.scrollView.scrollEnabled = true
self.tableView.scrollEnabled = false
}
}
}
委托方法正在做的是检测滚动视图何时到达底部。 发生这种情况时,表格视图可以滚动。 它还检测表格视图何时到达滚动视图重新启用的顶部。
我创建了一个GIF来演示结果:
修改Daniel的答案,使其更高效和无bug。
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
//Set table height to cover entire view
//if navigation bar is not translucent, reduce navigation bar height from view height
tableHeight.constant = self.view.frame.height-64
self.tableView.isScrollEnabled = false
//no need to write following if checked in storyboard
self.scrollView.bounces = false
self.tableView.bounces = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 30))
label.text = "Section 1"
label.textAlignment = .center
label.backgroundColor = .yellow
return label
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Row: (indexPath.row+1)"
return cell
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.scrollView {
tableView.isScrollEnabled = (self.scrollView.contentOffset.y >= 200)
}
if scrollView == self.tableView {
self.tableView.isScrollEnabled = (tableView.contentOffset.y > 0)
}
}
完整的项目可以在这里看到:https://gitlab.com/vineetks/TableScroll.git
经过多次试验和错误之后,这对我来说最合适。 解决方案必须解决两个需求1)确定谁应该使用滚动属性; tableView或scrollView? 2)确保tableView不会对scrollView授予权限,直到它到达其表格/内容的顶部。
为了查看滚动视图是否应该用于滚动和tableview,我检查了我的tableview上方的UIView是否在框架内。 如果UIView在框架内,可以说scrollView应该有权滚动。 如果UIView不在框架内,这意味着tableView占据了整个窗口,因此应该有权滚动。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.bounds.intersects(UIView.frame) == true {
//the UIView is within frame, use the UIScrollView's scrolling.
if tableView.contentOffset.y == 0 {
//tableViews content is at the top of the tableView.
tableView.isUserInteractionEnabled = false
tableView.resignFirstResponder()
print("using scrollView scroll")
} else {
//UIView is in frame, but the tableView still has more content to scroll before resigning its scrolling over to ScrollView.
tableView.isUserInteractionEnabled = true
scrollView.resignFirstResponder()
print("using tableView scroll")
}
} else {
//UIView is not in frame. Use tableViews scroll.
tableView.isUserInteractionEnabled = true
scrollView.resignFirstResponder()
print("using tableView scroll")
}
}
希望这可以帮助别人!
链接地址: http://www.djcxy.com/p/75419.html上一篇: How to Make the scroll of a TableView inside ScrollView behave naturally
下一篇: How do you change the UIRefreshControl beginRefresh height?