如何通过点击手势通过不在全屏UITableView的UIEdgeInsets中的屏幕上的点:

时间:2018-10-03 08:43:02

标签: ios swift uitableview uitapgesturerecognizer

我创建了一个具有全屏UITableView的屏幕,并为其设置了UIEdgeInsets,其配置如下:

categoriesTableView.contentInset = UIEdgeInsets.init(top: HEADER_VIEW_HEIGHT, left: 0, bottom: 0, right: 0)

其中HEADER_VIEW_HEIGHTCGFloat = 160

这使我可以向UITableView添加一个“标题视图”,当我开始滚动UITableView时它就会被覆盖(...并且不会卡在UITableView上方,作为真正的标题查看)。

问题:问题是我需要在标题视图中具有3个可单击的视图,因此我在情节提要中设计了3个视图,并在其上配置了Tap Gesture Recognizers。但是,当我尝试使用它们时,即使我在屏幕上看到了这些视图(由于contentInset配置的结果),也没有通过点击手势,而抛出了UITableView。我可以将它们设为可点击/可点击的唯一方法是,如果在User Interaction Enabled上将UITableView设置为false(这是我无法做的,因为我需要UITableView作为可拖动和可点击的对象)好)。

问题:当由于contentInset设置而未被UITableView覆盖时,如何将点击事件传递给较低的“标题视图”可点击部分? >

这是UI图像,您可以在其中看到全屏UITableView,其后有一个包含3个子视图的视图,其中包含3个收藏夹项,我可以将它们显示给用户,以便于使用访问。当屏幕开始时,UITableView有一个contentInset,因此用户可以看到那些易于访问的选项并按下它们(他现在不能执行)。当用户开始滚动时,UITableView进入具有3个视图的布局顶部,并且用户可以全屏滚动列表。有点像视差效果。

enter image description here

2 个答案:

答案 0 :(得分:1)

对此我有一个非常难看的解决方案。

现在您有了一个表格视图,下面有一个标题视图,对吗?在表格视图的顶部再添加一个视图,该视图中包含3个子视图,并且所有颜色均为透明。

将此新添加的子视图定位为与标题视图相同(通过以编程方式提供与标题视图相同的框架,或者通过将其顶部,左侧,底部和右侧约束连接到标题视图)。类似地,将此新视图的3个子视图与标题视图中的子视图相同。并为该新视图的子视图提供轻按手势。因此,我们的用户会认为他正在点击标题视图,而实际上是在这个不可见的视图中点击。

如果您想在表格视图中向上滚动并覆盖标题视图时进行触摸,则可以使用这两种方法之一。

  1. 在scrollView.contentOffset.y> = 160的情况下,调用UIScrollViewDelegate委托方法scrollViewDidScroll()并在内部,将为此新添加的视图的User Interaction Enabled设置为false,如果scrollView.contentOffset.y则将其还原为true <160。

  2. 或者从scrollViewDidScroll()内部分配outletOfTopConstraintOfYourNewView.constant = -(scrollView.contentOffset.y),以便新视图也将根据滚动向上移动,从而更改其可见的可点击区域。

另一个不太优雅的想法是。

在此表视图中的第0个索引处仅添加了一个高度为160的单元格,而不是给contentInset添加一个部分,启用的用户交互为false,颜色为透明。然后,您不必担心scrollViewDidScroll()中的逻辑。

答案 1 :(得分:1)

更新:

下面的解决方案并不完美,但它可能会为您提供一个入门指南。

A)将tableView的顶部约束放到headerview的底部约束。

B)在ViewController中创建headerview高度限制的IBOutlet

C)听着tableview的ScrollViewDidScroll并放置这样的代码

func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let y = scrollView.contentOffset.y
            if y > 50{
                if heightConstant.constant != 0{
                    view.layoutIfNeeded()
                    heightConstant.constant = 0
                    UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: {
                        self.view.layoutIfNeeded()
                    }, completion: nil)

                }
            }else{
                view.layoutIfNeeded()
                heightConstant.constant = 160
                UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: {
                    self.view.layoutIfNeeded()
                }, completion: nil)
            }
        }

此处50是应该开始动画的点形式。它有点类似于Android中的可折叠工具栏。只需确保headerView.isClipsToBounds = true。


将标题视图转换为UITableViewCell并将UITableViewDataSource更改为

extension ViewController: UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return section == 0 ? 1 : yourList.count
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0{
            // set your header view here
        }else{
            // Your normal cell configuration
        }
    }
}

有了这个,您的headerview将成为表视图的一部分,但是作为UITableViewCell,因此它的行为不会像普通的header那样。