gpt4 book ai didi

ios - 我应该如何实现点(在 :with:)? 内

转载 作者:行者123 更新时间:2023-11-28 14:05:26 25 4
gpt4 key购买 nike

我正在尝试创建一个非矩形的 UIView,它有一个非矩形的触摸区域。我已经知道如何使用贝塞尔曲线绘制形状。

根据 this comment ,我需要覆盖 point(inside:with:) 以创建自定义形状的触摸区域。

所以我尝试了这个:

class MyView: UIView {
override func draw(_ rect: CGRect) {
let path = UIBezierPath()
path.move(to: .zero)
path.addLine(to: CGPoint(x: 0, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: 0))
path.addLine(to: CGPoint(x: 0, y: 0))
UIColor.red.setFill()
path.fill()
}

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
print("point(inside:with:) called")

func isInRegion(_ point: CGPoint) -> Bool {
return (0...bounds.midX).contains(point.x) || (bounds.midY...bounds.maxY).contains(point.y)
}

guard let touches = event?.touches(for: self) else { return false }
guard !touches.isEmpty else { return false }

print("passed all the guards")
let first = touches.first!
print("first touch: \(first.location(in: self))")

return touches.map { $0.location(in: self) }.contains(where: isInRegion)
}
}

draw 方法绘制一个红色的 L 形。我尝试只在 L 形内部启用触摸。

我创建了一个名为 blueViewMyView,将其背景设置为蓝色,以便触摸区域为红色,非触摸区域为蓝色。

我还在蓝色部分下面添加了一个普通的绿色UIView,像这样:

enter image description here

我为这两个 View 启用了用户交互并添加了 UITapGestureRecogniser,这样如果红色区域被点击,蓝色 View 被点击 将被打印出来。如果绿色 View 被点击,green view tapped 将被打印。

override func viewDidLoad() {
super.viewDidLoad()

blueView.isUserInteractionEnabled = true
greenView.isUserInteractionEnabled = true

blueView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(blueViewTapped)))
greenView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(greenViewTapped)))
}

@objc func blueViewTapped() {
print("Blue view tapped")
}

@objc func greenViewTapped() {
print("Green view tapped")
}

当我运行应用程序并点击红色位时,只有 point(inside:with:) called 被打印两次,没有其他任何内容。我希望 blue view tapedpoint(inside:with:) 中的所有其他打印语句也能运行。如果我点击蓝色位,相同的消息会再次打印两次。如果我点击被蓝色位覆盖的绿色位,Green view tappedpoint(inside:with:) called 打印两次后打印。

为什么 blue view taped 没有打印出来?我一定是错误地实现了 point(inside:with:),对吧?

编辑:

经过一番调试,我发现point(inside:with:)不返回true的原因是event.allTouches为空。这很奇怪,因为我 100% 确定我触摸了 View !

最佳答案

由于您正在使用 UIBezierPath 绘制要点击的区域,因此您可以通过保存对路径的引用并使用 .contains(_ :):

class MyView: UIView {

var path: UIBezierPath!

override func draw(_ rect: CGRect) {
path = UIBezierPath()
path.move(to: .zero)
path.addLine(to: CGPoint(x: 0, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: 0))
path.addLine(to: CGPoint(x: 0, y: 0))
UIColor.red.setFill()
path.fill()
}

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {

print("path containsPoint?", path.contains(point))

return path.contains(point)

}
}

关于ios - 我应该如何实现点(在 :with:)? 内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53041776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com