如何使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?