UIImageView的Touch up和Touch down动作

4

我希望实现的功能是当用户触摸UIImageView时,设置Image1;当用户抬起手指时,设置Image2。

通过这段代码,我只能获得UIGestureRecognizerState.Ended状态。

var tap = UITapGestureRecognizer(target: self, action: Selector("tappedMe:"))     
imageView.addGestureRecognizer(tap)
imageView.userInteractionEnabled = true
   
func tappedMe(gesture: UITapGestureRecognizer)
{
    
    if gesture.state == UIGestureRecognizerState.Began{
        imageView.image=originalImage
        dbgView.text="Began"
    }else if  gesture.state == UIGestureRecognizerState.Ended{
        imageView.image=filteredImage
        dbgView.text="Ended"
    }else if  gesture.state == UIGestureRecognizerState.Cancelled{
        imageView.image=filteredImage
        dbgView.text="Cancelled"
    }else if  gesture.state == UIGestureRecognizerState.Changed{
        imageView.image=filteredImage
        dbgView.text="Changed"
    }

}

1
我的错误。轻拍手势不支持“Began”状态。一旦它被识别,你只能得到“Ended”状态。 - rmaddy
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - rmaddy
使用UIButton会更好吗? - Zhang
我会选择一个手势识别器。 - Daij-Djan
3个回答

5

UITapGestureRecognizer不会改变其状态为.Began,但UILongPressGestureRecognizer会。如果出于某种原因,您不想直接覆盖touch回调,则可以使用UILongPressGestureRecognizer,并将非常短的minimumPressDuration设置为0.1以实现效果。

例子由@Daij-Djan提供:

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.

    var tap = UILongPressGestureRecognizer(target: self, action: Selector("pressedMe:"))
    tap.minimumPressDuration = 0
    self.view.addGestureRecognizer(tap)
    self.view.userInteractionEnabled = true
  }

  func pressedMe(gesture: UITapGestureRecognizer) {
    if gesture.state == .Began{
      self.view.backgroundColor = UIColor.blackColor()
    } else if  gesture.state == .Ended {
      self.view.backgroundColor = UIColor.whiteColor()
    }
  }
}

点赞了这个,因为为此子类化imageView会过度设计。 - Daij-Djan
@Daij-Djan 在我看来,添加事件监听器比子类化更加繁琐。 - Sentry.co
@eonist 子类化有许多其他问题,您应该避免。 - kiecodes
@Kie IMO 子类化有其优点和缺点,管理事件监听器也有其优点和缺点。可以说使用子类化并让苹果添加/删除监听器并不是一个坏主意。 - Sentry.co

4
这里是解决方案:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if touch.view == self {
            //began
        }
    }
    super.touchesBegan(touches, with: event)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if touch.view == self {
            //end
        }
    }
    super.touchesEnded(touches, with: event)
}

注意:将此代码放在一个UIView子类中,并在init块内添加:userInteractionEnabled = true


1
我给你点了个踩,因为你没有解释,只提供了一些随意的代码片段,甚至不是一个完整的代码块;)——如果使用UILongPressGestureRecognizer可以正常工作,那么为此子类化imageView就有些过度设计了。请让它更好看些。 - Daij-Djan
这个解决方案很好,因为它使父视图可滚动。 - Josselin

1
最好和最实用的解决方案是将你的 UIImageView 嵌入到一个 UIControl 的子类中。
默认情况下,UIImageView 启用了用户交互。如果你创建一个简单的 UIControl 子类,就可以轻松地将你的图像视图添加到其中,并使用以下方法来实现你想要的效果:
let control = CustomImageControl()
control.addTarget(self, action: "imageTouchedDown:", forControlEvents: .TouchDown)
control.addTarget(self, action: "imageTouchedUp:", forControlEvents: [ .TouchUpInside, .TouchUpOutside ])

这种方法的优点是您可以访问所有不同的触摸事件,节省了自己检测它们所需的时间。
根据您想要做什么,您还可以覆盖var highlighted: Boolvar selected: Bool以检测用户何时与图像交互。最好以这种方式进行操作,以便您的用户在应用中使用所有控件时具有一致的用户体验。
一个简单的实现看起来会像这样:
final class CustomImageControl: UIControl {

    let imageView: UIImageView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)

        // setup our image view
        imageView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imageView)
        imageView.leadingAnchor.constraintEqualToAnchor(leadingAnchor).active = true
        imageView.trailingAnchor.constraintEqualToAnchor(trailingAnchor).active = true
        imageView.topAnchor.constraintEqualToAnchor(topAnchor).active = true
        imageView.bottomAnchor.constraintEqualToAnchor(bottomAnchor).active = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

final class MyViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

        let control = CustomImageControl()
        control.translatesAutoresizingMaskIntoConstraints = false
        control.imageView.image = ... // set your image here.
        control.addTarget(self, action: "imageTouchedDown:", forControlEvents: .TouchDown)
        control.addTarget(self, action: "imageTouchedUp:", forControlEvents: [ .TouchUpInside, .TouchUpOutside ])

        view.addSubview(control)
        control.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
        control.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
    }

    @objc func imageTouchedDown(control: CustomImageControl) {
        // pressed down on the image
    }

    @objc func imageTouchedUp(control: CustomImageControl) {
        // released their finger off the image
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接