如何解决仅使UIBezierPath按钮内的点可选
我的快速代码具有一个由UIBezierPath制成的自定义形状按钮。如果用户触摸绿色部分,则该代码仅应调用功能键,如果用户触摸红色部分,则不应调用功能键。现在,如果您触摸绿色部分,该功能仍会被调用。
import UIKit
class ViewController: UIViewController {
let customButton = UIButton(frame: CGRect(x: 100.0,y: 100.0,width: 200.0,height: 140.0))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
customButton.backgroundColor = UIColor.green
let aPath = UIBezierPath()
aPath.move(to: CGPoint(x: 50,y: 0))
aPath.addLine(to: CGPoint(x: 200.0,y: 40.0))
aPath.addLine(to: CGPoint(x: 160,y: 140))
aPath.addLine(to: CGPoint(x: 40.0,y: 140))
aPath.addLine(to: CGPoint(x: 0.0,y: 40.0))
aPath.close()
let layer = CAShapeLayer()
layer.fillColor = UIColor.red.cgColor
layer.strokeColor = UIColor.red.cgColor
layer.path = aPath.cgPath
customButton.layer.addSublayer(layer)
self.view.addSubview(customButton)
customButton.addTarget(self,action: #selector(press),for: .touchDown)
}
@objc func press(){
print("hit")
}
}
解决方法
首先,首先要为自定义按钮添加约束,以便尝试解决问题的社区可以轻松识别您的问题。例如;
customButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
customButton.widthAnchor.constraint(equalToConstant: 250),customButton.heightAnchor.constraint(equalToConstant: 100),customButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),customButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
])
您的问题出在您的代码中,您要在按钮本身已存在的图层上添加填充到图层。因此无法识别事件响应者,因此您的功能自然无法正常工作。
yourGreenPartWhichYouClickable.isUserInteractionEnabled = false
yourRedPartWhichYouClickable.isUserInteractionEnabled = false
,
我对这个问题的解决方案是将UIButton
子类化为FunkyButton
。该按钮包含路径信息。 FunkyButton重写hitTest(_:event:)
方法,并检查路径中是否包含该点。
旋转一下:
class ViewController: UIViewController {
let customButton = FunkyButton(frame: CGRect(x: 100.0,y: 100.0,width: 200.0,height: 140.0))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
customButton.backgroundColor = UIColor.green
self.view.addSubview(customButton)
customButton.addTarget(self,action: #selector(press),for: .touchDown)
}
@objc func press(){
print("hit")
}
}
class FunkyButton: UIButton {
let aPath = UIBezierPath()
override init (frame : CGRect) {
super.init(frame : frame)
aPath.move(to: CGPoint(x: 50,y: 0))
aPath.addLine(to: CGPoint(x: 200.0,y: 40.0))
aPath.addLine(to: CGPoint(x: 160,y: 140))
aPath.addLine(to: CGPoint(x: 40.0,y: 140))
aPath.addLine(to: CGPoint(x: 0.0,y: 40.0))
aPath.close()
let shapedLayer = CAShapeLayer()
shapedLayer.fillColor = UIColor.red.cgColor
shapedLayer.strokeColor = UIColor.red.cgColor
shapedLayer.path = aPath.cgPath
layer.addSublayer(shapedLayer)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func hitTest(_ point: CGPoint,with event: UIEvent?) -> UIView? {
if self.isHidden == true || self.alpha < 0.1 || self.isUserInteractionEnabled == false {
return nil
}
if aPath.contains(point) {
return self
}
return nil
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。