gpt4 book ai didi

ios - Swift 3 手势识别器 path.boundingBox 是无限的

转载 作者:行者123 更新时间:2023-11-28 10:51:15 25 4
gpt4 key购买 nike

我想了解有关自定义手势识别器的更多信息,所以我正在阅读 Ray Wenderlich 教程,我计划对其进行修改以了解详细信息以及我可以轻松更改的内容以了解每个部分的工作原理,但它是在以前版本的 Swift。 Swift 更新了大部分代码,我能够手动修复其余代码,除了我无法在屏幕上绘制触摸手势,而且没有任何形状被识别为圆圈,我希望它们都与同样的问题。网址及代码片段如下:

https://www.raywenderlich.com/104744/uigesturerecognizer-tutorial-creating-custom-recognizers

import UIKit
import UIKit.UIGestureRecognizerSubclass

class CircleGestureRecognizer: UIGestureRecognizer {

fileprivate var touchedPoints = [CGPoint]() // point history
var fitResult = CircleResult() // information about how circle-like is the path
var tolerance: CGFloat = 0.2 // circle wiggle room, lower is more circle like higher is oval or other
var isCircle = false
var path = CGMutablePath() // running CGPath - helps with drawing

override func touchesBegan(_ touches: (Set<UITouch>!), with event: UIEvent) {

if touches.count != 1 {
state = .failed
}
state = .began

let window = view?.window
if let touches = touches, let loc = touches.first?.location(in: window) {
//print("path 1 \(path.currentPoint)")
path.move(to: CGPoint(x: loc.x, y: loc.y)) // start the path
print("path 2 \(path.currentPoint)")
}
//super.touchesBegan(touches, with: event)
}

override func touchesMoved(_ touches: (Set<UITouch>!), with event: UIEvent) {

// 1
if state == .failed {
return
}

// 2
let window = view?.window
if let touches = touches, let loc = touches.first?.location(in: window) {
// 3
touchedPoints.append(loc)

print("path 3 \(path.currentPoint)")
path.move(to: CGPoint(x: loc.x, y: loc.y))
print("path 4 \(path.currentPoint)")

// 4
state = .changed
}
}

override func touchesEnded(_ touches: (Set<UITouch>!), with event: UIEvent) {

print("path 5 \(path.currentPoint)")
// now that the user has stopped touching, figure out if the path was a circle
fitResult = fitCircle(touchedPoints)

// make sure there are no points in the middle of the circle
let hasInside = anyPointsInTheMiddle()

let percentOverlap = calculateBoundingOverlap()

isCircle = fitResult.error <= tolerance && !hasInside && percentOverlap > (1-tolerance)

state = isCircle ? .ended : .failed
}

override func reset() {
//super.reset()
touchedPoints.removeAll(keepingCapacity: true)
path = CGMutablePath()
isCircle = false
state = .possible
}

fileprivate func anyPointsInTheMiddle() -> Bool {
// 1
let fitInnerRadius = fitResult.radius / sqrt(2) * tolerance
// 2
let innerBox = CGRect(
x: fitResult.center.x - fitInnerRadius,
y: fitResult.center.y - fitInnerRadius,
width: 2 * fitInnerRadius,
height: 2 * fitInnerRadius)

// 3
var hasInside = false
for point in touchedPoints {
if innerBox.contains(point) {
hasInside = true
break
}
}

//print(hasInside)
return hasInside
}

fileprivate func calculateBoundingOverlap() -> CGFloat {
// 1
let fitBoundingBox = CGRect(
x: fitResult.center.x - fitResult.radius,
y: fitResult.center.y - fitResult.radius,
width: 2 * fitResult.radius,
height: 2 * fitResult.radius)
let pathBoundingBox = path.boundingBox

// 2
let overlapRect = fitBoundingBox.intersection(pathBoundingBox)

// 3
let overlapRectArea = overlapRect.width * overlapRect.height
let circleBoxArea = fitBoundingBox.height * fitBoundingBox.width

let percentOverlap = overlapRectArea / circleBoxArea
print("Percent Overlap \(percentOverlap)")
print("pathBoundingBox \(pathBoundingBox)")
print("path 6 \(path.currentPoint)")

return percentOverlap
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
state = .cancelled // forward the cancel state
}
}

如教程中所示,这段代码应该将路径的边界框与适合圆的框进行比较并比较重叠,但是当我打印 pathBoundingBox 时状态为:“pathBoundingBox (inf, inf , 0.0, 0.0)”,这可能就是 percentOverlap 为 0 的原因。我认为这是 path.move(to: loc),其中 loc 是第一个触摸位置,但 move(to:) 的文档说“此方法隐式结束当前子路径(如果有的话)并将当前点设置为点参数中的值。”所以我正在努力弄清楚为什么 path.boundingBox 是无限的......

最佳答案

这不是一个无限边界框,它恰恰相反——一个零边界框。问题是您的 path 是空的。

关于ios - Swift 3 手势识别器 path.boundingBox 是无限的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46010513/

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