如何在 UIView 中引用 BezierPath
How to reference BezierPath in a UIView
我正在尝试检测 UIView 中 BezierPaths 内的 Taps,并发现了很多对 containsPoint 方法的引用。但是我似乎无法找到如何从我的 ViewController.
中实际引用 BezierPaths
我已经设置:
class func drawSA(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 69, height: 107), resizing: ResizingBehavior = .aspectFit, SACountries: [String: ViewController.CountryStruct])
{
let myPath = UIBezierPath()
myPath.move(to: CGPoint(x: 32.24, y: 8.61))
myPath.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath.close()
}
贝塞尔曲线在此函数中绘制,调用者:
override func draw(_ rect: CGRect)
在主要 ViewController 中,我有以下功能用于检测 UIView 上的点击:
@objc func SATap(sender: UITapGestureRecognizer)
{
let location = sender.location(in: self.SAView)
// how do I call containsPoint from here?
}
如何从这里调用 containsPoint?
bezierPaths 在运行时正确绘制。
由于路径是在单独的 Class 中的 Class 函数中创建的,我无法将它们直接保存到视图中。
我通过将 UIBezierPaths 放入字典然后 return 字典解决了这个问题。数组也可以,但这样我可以轻松访问特定路径。
class func drawSA(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 71, height: 120), resizing: ResizingBehavior = .aspectFit, SACountries: [String: ViewController.CountryStruct]) -> ([String: UIBezierPath])
{
var Paths = [String: UIBezierPath]()
let myPath = UIBezierPath()
myPath.move(to: CGPoint(x: 32.24, y: 8.61))
myPath.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath.close()
Paths["mP"] = myPath
let myPath2 = UIBezierPath()
myPath2.move(to: CGPoint(x: 32.24, y: 8.61))
myPath2.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath2.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath2.close()
Paths["mP2"] = myPath2
return Paths
}
然后我使用 View.addLayer
在视图中创建图层,并在字典中使用 For In Loop 创建图层时将 Layer.name
属性 添加到每个图层:
for path in Paths.keys.sorted()
{
self.layer.addSublayer(CreateLayer(path)) // The Function simply creates a CAShapeLayer
}
然后我在手势功能中使用了词典:
@objc func ATap(sender: UITapGestureRecognizer)
{
let location = sender.location(in: self.SAView)
// You need to Scale Location if your CAShapeLayers are Scaled
for path in SAView.Paths
{
let value = path.value
value.contains(location)
if value.contains(location)
{
for (index, layer) in SAView.layer.sublayers!.enumerated()
{
if layer.name == path.key
{
// Do something when specific layer is Tapped
}
}
}
}
}
可能有更好的方法来做到这一点,但它都有效并且表现良好。
我正在尝试检测 UIView 中 BezierPaths 内的 Taps,并发现了很多对 containsPoint 方法的引用。但是我似乎无法找到如何从我的 ViewController.
中实际引用 BezierPaths我已经设置:
class func drawSA(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 69, height: 107), resizing: ResizingBehavior = .aspectFit, SACountries: [String: ViewController.CountryStruct])
{
let myPath = UIBezierPath()
myPath.move(to: CGPoint(x: 32.24, y: 8.61))
myPath.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath.close()
}
贝塞尔曲线在此函数中绘制,调用者:
override func draw(_ rect: CGRect)
在主要 ViewController 中,我有以下功能用于检测 UIView 上的点击:
@objc func SATap(sender: UITapGestureRecognizer)
{
let location = sender.location(in: self.SAView)
// how do I call containsPoint from here?
}
如何从这里调用 containsPoint?
bezierPaths 在运行时正确绘制。
由于路径是在单独的 Class 中的 Class 函数中创建的,我无法将它们直接保存到视图中。
我通过将 UIBezierPaths 放入字典然后 return 字典解决了这个问题。数组也可以,但这样我可以轻松访问特定路径。
class func drawSA(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 71, height: 120), resizing: ResizingBehavior = .aspectFit, SACountries: [String: ViewController.CountryStruct]) -> ([String: UIBezierPath])
{
var Paths = [String: UIBezierPath]()
let myPath = UIBezierPath()
myPath.move(to: CGPoint(x: 32.24, y: 8.61))
myPath.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath.close()
Paths["mP"] = myPath
let myPath2 = UIBezierPath()
myPath2.move(to: CGPoint(x: 32.24, y: 8.61))
myPath2.addLine(to: CGPoint(x: 31.99, y: 8.29))
myPath2.addLine(to: CGPoint(x: 31.78, y: 8.19))
myPath2.close()
Paths["mP2"] = myPath2
return Paths
}
然后我使用 View.addLayer
在视图中创建图层,并在字典中使用 For In Loop 创建图层时将 Layer.name
属性 添加到每个图层:
for path in Paths.keys.sorted()
{
self.layer.addSublayer(CreateLayer(path)) // The Function simply creates a CAShapeLayer
}
然后我在手势功能中使用了词典:
@objc func ATap(sender: UITapGestureRecognizer)
{
let location = sender.location(in: self.SAView)
// You need to Scale Location if your CAShapeLayers are Scaled
for path in SAView.Paths
{
let value = path.value
value.contains(location)
if value.contains(location)
{
for (index, layer) in SAView.layer.sublayers!.enumerated()
{
if layer.name == path.key
{
// Do something when specific layer is Tapped
}
}
}
}
}
可能有更好的方法来做到这一点,但它都有效并且表现良好。