[英]How do I check multiple UIView subviews displayed on top of each other for a touch event inside a bezier path?
我編寫了一些代碼,這些代碼可以在UIViews中生成輪子的楔形,將這些UIView存儲在一個數組中,並將這些UIView彼此重疊地顯示在容器UIView中。 這基本上畫了一個分段的輪子。
我現在想要的是讓每個UIView在其定義的貝塞爾曲線路徑內分別接收觸摸事件,並返回唯一的標識符。 實際上,這意味着滾輪的每個楔塊都是單獨的按鈕。
我現在遇到的問題是,只有添加到數組中的最后一個UIView會響應單個觸摸事件(我將其設置為現在打印貝塞爾曲線中的觸摸位置),然后在此之前添加UIView響應單個觸摸事件,直到我遍歷所有楔塊/ UIViews,再也沒有一個響應觸摸事件。
這是繪制楔形的課程。 我嘗試實現一些方法,這些方法應允許在代碼末尾將觸摸事件轉移到其他UIView,但是我無法使其正常工作。
import UIKit
class WedgeDraw: UIView {
var wedgeNumber:CGFloat = 4
var wedgeLocation: CGFloat = 2
var wedgeIdentifier = 0
var wedgePath = UIBezierPath()
var touchPosition = CGPoint()
override func draw(_ rect: CGRect) {
let startAngle = (360 / wedgeNumber - 360) * (wedgeLocation - 1) * CGFloat.pi / 180
let endangle = (360 / wedgeNumber - 360) * wedgeLocation * CGFloat.pi / 180
let center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
let outerRadius = self.bounds.midX - 3
let innerRadius = self.bounds.width / 8
//defines end points of simulated Bezier archs as a CGpoint
let endPointInner = UIBezierPath(arcCenter: center, radius: innerRadius, startAngle: startAngle, endAngle: endangle, clockwise: false).currentPoint
let endPointOuterCounterclockwise = UIBezierPath(arcCenter: center, radius: outerRadius, startAngle: endangle, endAngle: startAngle, clockwise: true).currentPoint
//defines bezier arch curves
let outerWedgeCurvePath = UIBezierPath(arcCenter: center, radius: outerRadius, startAngle: startAngle, endAngle: endangle, clockwise: true)
let innerWedgeCurvePath = UIBezierPath(arcCenter: center, radius: innerRadius, startAngle: endangle, endAngle: startAngle, clockwise: false)
//draw line path
wedgePath.append(outerWedgeCurvePath)
wedgePath.addLine(to: endPointInner)
wedgePath.append(innerWedgeCurvePath)
wedgePath.addLine(to: endPointOuterCounterclockwise)
//sets stroke and color properties and draws the bezierpath.
UIColor.black.setStroke()
UIColor.white.setFill()
wedgePath.lineWidth = 3
wedgePath.stroke()
wedgePath.fill()
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let view = super.hitTest(point, with: event)
if wedgePath.contains(touchPosition) {
return nil
} else {
return view
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
touchPosition = touch.location(in: self)
if wedgePath.contains(touchPosition){
print(touchPosition)
print(isUserInteractionEnabled)
} else {
}
}
}
}
這是創建數組並繪制輪子的Viewcontroller代碼:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var boardContainer: UIView!
@IBAction func checkButton(_ sender: UIButton) {
}
var wedgeViewConstructorArray = [WedgeDraw]()
override func viewDidLoad() {
super.viewDidLoad()
//creates array of UNIQUE wedgedraw objects
for _ in 1...6 {
wedgeViewConstructorArray.append(WedgeDraw())
}
drawBoard()
}
func drawBoard() {
for i in 0..<wedgeViewConstructorArray.count {
wedgeViewConstructorArray[i].wedgeIdentifier = i
wedgeViewConstructorArray[i].frame = CGRect(x: 0, y: 0, width: boardContainer.frame.width, height: boardContainer.frame.height)
wedgeViewConstructorArray[i].wedgeNumber = CGFloat(wedgeViewConstructorArray.count)
wedgeViewConstructorArray[i].wedgeLocation = CGFloat(i + wedgeViewConstructorArray.count + 1)
wedgeViewConstructorArray[i].backgroundColor = UIColor.clear
boardContainer.addSubview(wedgeViewConstructorArray[i])
}
}
}
這是轉輪的外觀以及視圖層次結構:
總體而言,我對Swift和編碼尚不陌生,我很高興能找到自己的位置,但是現在我真的很困,不知道如何進行。 希望我能弄清楚我的問題所在! 提前致謝!
好了,花了我一段時間才找到答案,但這實際上非常容易。 這就是我現在得到的,並且完全可以滿足我的需求。
// checks if point inside touch event is inside bezier path and passes on to next subview if false.
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let location = point
if wedgePath.contains(location) == true {
print("\(wedgeColor)")
return true
}
return false
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.