rubymotion/BubbleWrap

View on GitHub
samples/gesture/app/views/drawing/gesture_view.rb

Summary

Maintainability
A
2 hrs
Test Coverage
class GestureView < UIView
  attr_accessor :rotation, :scale, :translation

  def initWithCoder(coder)
    super
    setup
    self
  end

  def initWithFrame(coder)
    super
    setup
    self
  end

  ## UIGestureRecognizerDelegate

  #  Note: this method allow rotate and pinch gesture happen at the same time
  def gestureRecognizer(recognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer:other_recognizer)
    case recognizer
    when @rotated_recognizer
      if other_recognizer == @pinch_recognizer
        return true
      end
    when @pinch_recognizer
      if other_recognizer == @rotated_recognizer
        return true
      end
    end
    return false
  end

  private

  def setup
    self.layer.shouldRasterize = true
    self.rotation = 0
    self.scale = 1
    setup_gesture
  end

  def setup_gesture
    @panned_recognizer = self.whenPanned do |recognizer|
      case(recognizer.state)
      when UIGestureRecognizerStateBegan
        @last_position = self.position
      when UIGestureRecognizerStateChanged
        self.translation = recognizer.translationInView(self.superview)
        self.position = [@last_position.x + self.translation.x, @last_position.y + self.translation.y]
      when UIGestureRecognizerStateEnded
        @last_position = nil
      end
    end
    @panned_recognizer.maximumNumberOfTouches = 1
    @panned_recognizer.minimumNumberOfTouches = 1
    @panned_recognizer.delegate = self

    @rotated_recognizer = self.whenRotated do |recognizer|
      case(recognizer.state)
      when UIGestureRecognizerStateBegan
        @last_rotation = self.rotation
      when UIGestureRecognizerStateChanged
        self.rotation = @last_rotation + recognizer.rotation
        reset_transformation
      when UIGestureRecognizerStateEnded
        @last_rotation = nil
      end
    end
    @rotated_recognizer.delegate = self

    @pinch_recognizer = self.whenPinched do |recognizer|
      case(recognizer.state)
      when UIGestureRecognizerStateBegan
        @last_scale = self.scale
      when UIGestureRecognizerStateChanged
        self.scale = @last_scale * recognizer.scale
        reset_transformation
      when UIGestureRecognizerStateEnded
        @last_scale = nil
      end
    end
    @pinch_recognizer.delegate = self
  end

  def reset_transformation
    transform = CATransform3DIdentity
    transform = CATransform3DRotate(transform, -1 * self.rotation, 0.0, 0.0, -1.0)
    transform = CATransform3DScale(transform, self.scale, self.scale, 1.0)
    self.layer.transform = transform
  end

end