简体   繁体   English

当滚动视图子视图不在屏幕上时,手势识别器不起作用

[英]Gesture recognizer not working when scrollview subview is off screen

I have a UIScrollView in my view controller with a UIView (called viewPreSeasonCard ) in it acting as the content view, all done in Interface Builder. 我的视图控制器中有一个UIScrollView ,其中有一个UIView (称为viewPreSeasonCard ),它充当内容视图,所有这些操作都在Interface Builder中完成。 I am then programmatically adding sub views to the container like this: 然后,我以编程方式将子视图添加到容器中,如下所示:

func displayPreSeason(preSeasons: [PreSeason]) {
    var yPos = 0
    let viewWidth = Int(viewPreSeasonCard.frame.width)
    for (index, preSeason) in preSeasons.enumerated() {
        yPos = 40 + index * 80
        let frame = CGRect(x: 0, y: yPos, width: viewWidth, height: 78)
        let preSeasonView = PreSeasonLineupView(frame: frame)
        preSeasonView.setPreSeason(preSeason: preSeason)
        preSeasonView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.preSeasonClicked)))

        viewPreSeasonCard.frame.size.height += frame.height
        viewPreSeasonCard.addSubview(preSeasonView)
    }

    let curSize = self.view.frame
    scrollView.contentSize = CGSize(width: curSize.width, height: curSize.height + CGFloat(yPos))
}

As you can see I am then adjusting scrollView.contentSize after adding the subviews. 如您scrollView.contentSize ,添加子视图后,我将调整scrollView.contentSize This all works properly, I can scroll the scrollview all the way down and see all the subviews. 这一切都可以正常工作,我可以将scrollview一直向下滚动并查看所有子视图。

The problem is with the UITapGestureRecognizer I am adding to the subviews. 问题是我要添加到子视图的UITapGestureRecognizer When the subview is initially visible on the device screen (ie the first 3 or 4 subviews) the gesture recognizer is working. 当子视图最初在设备屏幕上可见时(即前3或4个子视图),手势识别器正在工作。 But when I have to scroll to see subviews, the gesture recognizers on these subviews is not firing at all when I tap on them. 但是当我不得不滚动查看子视图时,当我点击它们时,这些子视图上的手势识别器根本不会触发。 It's as if because the lower subviews are not visible initially, the gesture recognizer is ignored. 好像是因为较低的子视图最初不可见,所以手势识别器将被忽略。

Here's the method for the gesture recognizer: 这是手势识别器的方法:

func preSeasonClicked(_ sender: UITapGestureRecognizer) {
    if let preSeasonView = gestureRecognizer.view as? PreSeasonLineupView, let constructorId = preSeasonView.constructorId {
        presenter.preSeasonClicked(constructorId: constructorId)
    }
}

I had the same problem, and the I had ContentView inside the Scroll View 我有同样的问题,并且在滚动视图中有ContentView

The problem I discovered that the ContentView I set its height equal to the ScrollView parent view. 我发现的问题是,我将ContentView设置为与ScrollView父视图相等的高度。 And I was calculating the ContentSize of ScrollView my self. 我正在自己计算ScrollView的ContentSize。

So the behavior was that the scrollview is scrolling correctly but any view is OFF screen in first show of ViewController cannot detect touch. 因此,行为是滚动视图正确滚动,但是ViewController的第一个节目中的任何视图都处于OFF屏幕无法检测到触摸。

After some debugging I tried to make ClipToBounds to be true for the ContentView. 经过一些调试后,我尝试使ClipToBounds对于ContentView为true。 and I saw what I was waiting for, the content view is just having the height of the screen (ScrollView parent) 并且我看到了我在等待的内容视图仅具有屏幕的高度(ScrollView父级)

I removed the constraint which made the content view equal height of the scrollview parent. 我删除了使内容视图与scrollview父级高度相等的约束。 than added new constraint to align the bottom of the container view to the bottom of the most view at the bottom, and didn't calculate the content size any more. 然后添加了新的约束,以将容器视图的底部与底部的大多数视图的底部对齐,并且不再计算内容大小。

Currently the scrolling is working correctly and the touch is working for all views. 当前,滚动正常工作,并且触摸对于所有视图均有效。

I had the same problem with the content view and I didn't have a constraint on the height. 我对内容视图也有同样的问题,但对高度没有任何限制。

What I ended up doing was removing the content view altogether and that fixed the problem. 我最终要做的是完全删除内容视图,从而解决了该问题。

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM