自定义的UIButton触发IBAction为一次,然后再也

问题描述:

我有一个自定义的UIButton称为RippleButton宣布像这样自定义的UIButton触发IBAction为一次,然后再也

public class RippleButton: UIButton 

基本上它触摸时产生了连锁反应。我使用的是下面的IBAction为

@IBAction func toggleMic() { 
    if isMicrophoneOn { 
     print("Stopped recording") 
     micIcon.image = UIImage(named: "mic_off") 
     micLabel.text = "Start Recording" 
    } else { 
     print("Started recording") 
     micIcon.image = UIImage(named: "mic_on") 
     micLabel.text = "End Recording" 
    } 

    isMicrophoneOn = !isMicrophoneOn 
} 

的作用是通过对触摸的内心活动的设计编辑器分配给该按钮自定义按钮。

我RippleButton覆盖的touchesBegan像这样

override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    super.touchesBegan(touches, with: event) 
    ripple.animate(sender: self, location: touches.first!.location(in: self)) 
} 

当我触摸按钮,它第一次将触发IBAction为,并从我的课纹波

func animate(sender: UIView, location: CGPoint){   
    ripple?.transform = CGAffineTransform(scaleX: 1, y: 1) 
    let size = Double(sender.bounds.width) > Double(sender.bounds.height) ? sender.bounds.width : sender.bounds.height 
    ripple?.frame = CGRect(x: location.x - size/2, y: location.y - size/2, width: size, height: size) 
    ripple?.layer.cornerRadius = size/2.0 
    ripple?.alpha = CGFloat(opacity) 
    ripple?.backgroundColor = color 
    ripple?.transform = CGAffineTransform(scaleX: 0, y: 0) 
    container?.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height) 
    container?.layer.cornerRadius = sender.layer.cornerRadius 
    container?.clipsToBounds = true 

    UIView.animate(withDuration: TimeInterval(speed), 
        delay: 0.0, 
        options: .curveEaseOut, 
        animations: { 
        self.ripple?.transform = CGAffineTransform(scaleX: 2.5, y: 2.5) 
        self.ripple?.alpha = 0.0 
    }) 
} 

ripple扮演我的动画是一个子视图加入到container,container是添加到RippleButton

的视图当我碰它时首先触动动画,但IBAction不会触发。为什么它会触发一次,然后再也不会发生?

+0

而不是覆盖'touchesBegan',为什么不直接挂钩在Interface Builder中'touchDown'事件? –

+0

因为我不想为所有使用这个类的按钮做这件事。因为我计划在多个地方使用这个类,所以每次我实现这个类时,都会在IB中接触'touchDown'的大量重复工作。 – ChrisStillwell

+0

如果你只是使用'UIButton'它是否工作? – Alistra

你说“涟漪是添加到容器的子视图,容器是添加到RippleButton的视图”...你是否在“涟漪”效果后移除该容器?也许这就是触摸事件。

+0

这是问题所在。我正在添加容器来填充按钮,然后拦截触摸。通过添加'container?.isUserInteractionEnabled = false',我能够按预期工作。 – ChrisStillwell

通过调用self.sendActionsForControlEvents在touchesEnded中默认触发该操作。尝试覆盖touchesEnded和touchesCancelled(使用超级调用)并在两者中设置断点。也许该活动将在第二次被取消。在这种情况下,您的动画会以某种方式干扰内部按钮状态的实现。这很难解决,因为UIButton是一个黑匣子,甚至更糟糕的是它的内部实现可能会改变。那么你应该从UIControl派生出来。

看看到:4 different ways to handle tap