質問

I have a Custom Scroll View, subclassing UIScrollView. I have added a scroll view in my viewcontroller nib file and changed its class to CustomScrollView. Now, this custom scroll view (made from xib) is added as a subview on self.view.

In this scroll view, I have 3 text fields and 1 UIImageView(named signImageView) added from xib. On clicking UIImageView (added a TapGestureRecogniser), a UIView named signView is added on the custom scroll view. I want to allow User to sign on this view, So I have created a class Signature.m and .h, subclassing UIView and implemented the touches methods (touchesBegan, touchesMoved and touchesEnded) and initialised the signView as follows:

signView = [[Signature alloc]initWithFrame:signImageView.frame];
    [customScrollView addSubview:signView];

But when I start signing on the signView, the view gets scrolled and hence the touches methods don't get called.

I have tried adding signView on self.view instead of custom scroll view, but in that case the view remains glued to a fixed position when I start scrolling. (Its frame remains fixed in this case)

役に立ちましたか?

解決

Try setting canCancelContentTouches of the scrollView to NO and delaysContentTouches to YES.

EDIT:

I see that similiar question was answered here Drag & sweep with Cocoa on iPhone (the answer is exactly the same).

If the user tap-n-holds the signView (for about 0.3-0.5 seconds) then view's touchesBegan: method gets fired and all events from that moment on go to the signView until touchesEnded: is called.

If user quickly swipes trough the signView then UIScrollView takes over.

Since you already have UIView subclassed with touchesBegan: method implemented maybe you could somehow indicate to user that your app is prepared for him to sign ('green light' equivalent).

You could also use touchesEnded: to turn off this green light.

It might be better if you add signImageView as as subView of signView (instead of to customScrollView) and hide it when touchesBegan: is fired). You would add signView to customScrollview at the same place where you add signImageView in existing code instead.

With this you achieve that there is effectively only one subView on that place (for better touch-passing efficiency. And you could achieve that green light effect by un-hiding signImageView in touchesBegan:/touchesEnded:

If this app-behaviour (0.3-0.5s delay) is unacceptable then you'd also need to subclass UIScrollView. There Vignesh's method of overriding UIScrollView's touchesShouldBegin: could come to the rescue. There you could possibly detect if the touch accoured in signView and pass it to that view immediately.

他のヒント

When ever you add a scrollview in your view hierarchy it swallows all touches.Hence you are not getting the touches began. So to get the touches in your signon view you will have to pass the touches to signon view. This is how you do it.

We achieved this with a UIScrollView subclass that disables the pan gesture recogniser for a list of views that you provide.

class PanGestureSelectiveScrollView: UIScrollView {

  var disablePanOnViews: [UIView]?

  override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    guard let disablePanOnViews = disablePanOnViews else {
      return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }

    let touchPoint = gestureRecognizer.location(in: self)
    let isTouchingAnyDisablingView = disablePanOnViews.first { $0.frame.contains(touchPoint) } != nil

    if gestureRecognizer === panGestureRecognizer && isTouchingAnyDisablingView {
      return false
    }
    return true
  }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top