从已定义的贝塞尔路径创建 UIbutton?
Posted
技术标签:
【中文标题】从已定义的贝塞尔路径创建 UIbutton?【英文标题】:Creating a UIbutton from an already defined Bezier Path? 【发布时间】:2019-03-02 14:39:31 【问题描述】:我在一个视图控制器(默认)中有一系列定义的贝塞尔路径。然而,具体来说,我想让其中一个成为 UIButton (它还不必引导到任何地方,但如果它可以在触摸时打印一些东西会很棒)。
通过查看一些类似的问题,我已经能够在模拟器上分别定义我想要的Bezier Path和UIButton,但无法将它们拼接在一起。
import UIKit
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: 200, y: 350), radius: CGFloat(150), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
//change the fill color
shapeLayer.fillColor = UIColor.clear.cgColor
//you can change the stroke color
shapeLayer.strokeColor = UIColor.gray.cgColor
//you can change the line width
shapeLayer.lineWidth = 7.5
view.layer.addSublayer(shapeLayer)
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = .green
button.setTitle("Test Button", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
@objc func buttonAction(sender: UIButton!)
print("Button tapped")
如何将 circlePath 作为 UIButton 传递?
【问题讨论】:
【参考方案1】:UIButton 是 UIView,因此您可以将创建的层添加到按钮中,方法与创建视图的方式相同:
button.layer.addSublayer(shapeLayer)
请注意,该层将覆盖 UIButton 的标签,但解决此问题的一种简单方法是更改该层的 z 位置:
shapeLayer.zPosition = -1
例如如果你想给一个按钮添加一个圆形层:
let circlePath = UIBezierPath(ovalIn: button.bounds)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.zPosition = -1
button.layer.addSublayer(shapeLayer)
或者,匹配示例中的圆圈,但在形状之前创建按钮:
// define circle parameters
let radius: CGFloat = 150
let center = CGPoint(x: 200, y: 350)
// create the button
let button = UIButton(frame: CGRect(origin: center.applying(CGAffineTransform(translationX: -radius, y: -radius)),
size: CGSize(width: 2 * radius, height: 2 * radius)))
// create the circle layer
let circlePath = UIBezierPath(ovalIn: button.bounds)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.zPosition = -1
// add the circle layer to the button
button.layer.addSublayer(shapeLayer)
view.addSubview(button)
【讨论】:
感谢您的回答。我不得不切换按钮的位置和路径以使其运行。但是,每当我点击原始按钮所在的位置而不是圆形层时,我只会收到“按下按钮”消息。我正在尝试使圆形图层成为视图上的唯一按钮 - 如果我不清楚,请见谅! 是的,按钮的框架和图层的框架可能不同。 UIBezierPath(ovalIn: button.bounds) 创建一个路径,当分配给按钮时,该路径位于按钮内部。您是否有特殊原因要先声明路径,然后声明按钮,而不是相反? 它是这样出来的,因为我不太了解。我更专注于(可能是不必要的)路径,因为我只希望路径的笔触响应触摸,而不是整个圆。我也希望设置,以便我以后可以将动画渐变应用到路径的笔划 啊,所以你想要一个响应触摸的路径? UIButton 真的不适合那个,这可能是导致混乱的原因。您应该寻找询问“如何检测 CGPath 上的触摸”的问题或自己创建一个。 正是这样 - 我的含糊不清。我会这样做的。谢谢普里贝以上是关于从已定义的贝塞尔路径创建 UIbutton?的主要内容,如果未能解决你的问题,请参考以下文章