菜鸟教程小白 发表于 2022-12-13 03:38:47

ios - UIScrollView 与 contentSize 的触摸拦截器来控制 subview


                                            <p><p>假设我有以下 View 层次结构;</p>

<p> <img src="/image/tpT7D.png" alt="enter image description here"/> </p>

<p>这些 View 实际上是 ShinobiCharts,它们是 UIView 的子类。 View1 充当用户可以触摸的主图表(捏合、平移、长按等)。该 View 反过来控制其他 View (View2、View3 等)关于特定的、与触摸相关的属性(用户平移 View1,因此 View2 和 3...必须相应地进行操作并平移)。
但是,一旦用户滚动 UIScrollView,View1 可能会从屏幕上消失,只留下 View2、3 等可见,它们没有相应的手势识别器,因此用户无法再与图表交互,糟糕用户体验。
我当然也可以将识别器添加到这些附加图表中,但是在捏合期间,这意味着两个手指都必须位于单个 View 中,用户不能再触摸他想要的位置以进行捏合和缩放,糟糕的用户体验。</p>

<p>为了简短起见,我需要某种触摸拦截器来覆盖 UIScrollView 的整个内容区域,以便当用户捏合或平移时,相应的触摸将被转发到主图表(View1),这反过来可以更新其他 subview 。
UIScrollView 应该始终可以垂直滚动。</p>

<p><strong>第一个实验:</strong></p>

<p>我尝试向覆盖 UIScrollView 的 ViewController 添加一个透明的 UIView。
但是,即使直接引用 View1,触摸也不会被转发。</p>

<pre><code>-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    ;
}
</code></pre>

<p>我不太确定这是否是实现这一目标的正确方法。</p>

<p><strong>第二次实验:</strong></p>

<p>在 UIScrollView 中的图表 subview 上禁用 userInteraction 并将我自己的捏合和平移手势(在 UIViewController 中)添加到 UIScrollView。 </p>

<p>问题;
1. UIScrollView 不再滚动。
2. 如何将这些手势转发给View1?</p>

<p>恐怕我现在无法提供更多示例代码,因为还没有太多相关的代码可以展示。</p>

<p><strong>编辑:</strong>
实验二的小笔记;
手势识别器已添加如下;</p>

<pre><code>UIPinchGestureRecognizer *pinchGestureRecognizer = [ initWithTarget:self action:@selector(pinchGesture:)];
pinchGestureRecognizer.cancelsTouchesInView = NO;
;
</code></pre>

<p>已启用 UIViewController 上的同时手势识别;</p>

<pre><code>- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
</code></pre>

<p>}</p>

<p><strong>编辑:</strong></p>

<p>实验 2 的问题 2 已解决。我没有为平移/捏合手势设置正确的代表。哦!</p>

<p>剩下的就是如何转发捏/平移手势。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您可以在其他 View 之上放置一个透明 View 。但是,您需要覆盖另外一种方法。 </p>

<p>您想在透明 View 上覆盖 hitTest:withEvent。在遍历响应者链以查看哪个 View 处理特定区域中的触摸时使用此方法。如果 View 处理了该触摸,它会返回它自己。如果它想将它传递给它下面的下一个 View ,它会返回 nil。如果它知道另一个 View 处理该触摸,它可以返回该 View 。 </p>

<p>因此,在您的情况下,如果该点位于顶部透明 View 的目标区域中,则返回 view1。然后应该调用 View1 的手势识别器。 </p>

<p><strong>示例</strong>:</p>

<p>InterceptorView 是一个位于 scrollView 顶部的透明 View 。 TargetView 是 scrollView 内部的一个 View ,并附加了一个 TapGestureRecognizer。</p>

<pre><code>class InterceptorView: UIView {

    required init(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
    }

    @IBOutlet weak var targetView1: UIView?

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -&gt; UIView? {
      print(&#34; Testing point: \(point) &#34;)
      if self.pointInside(point, withEvent: event) {
            println(&#34;Hit&#34;)
            return targetView1
      }
      else {
            println()
            return nil;
      }
    }
}
</code></pre>

<p>--</p>

<pre><code>class TargetView: UIView {

    required init(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
    }

   @IBAction func handleGesture(gestureRecognizer: UIGestureRecognizer) {
      let location = gestureRecognizer.locationInView(self)
      print(&#34; Got gesture.Location \(location) &#34;)
      if (pointInside(location, withEvent: nil)) {
            println(&#34;Inside&#34;);
      }
      else {
            println(&#34;Outside&#34;);
      }
    }
}
</code></pre>

<p>项目如下:
<a href="https://github.com/annabd351/GestureForwarding" rel="noreferrer noopener nofollow">https://github.com/annabd351/GestureForwarding</a> </p>

<p>(里面还有一些其他的东西,但它有效!)</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - UIScrollView 与 contentSize 的触摸拦截器来控制 subview ,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/27060966/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/27060966/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - UIScrollView 与 contentSize 的触摸拦截器来控制 subview