点网格外的线
Lines outside the point grid
我 "bug" 在网格中设置点之间的线。如果我在网格外单击,我可以使行变为 "nowhere" 。我必须只在网格中的 2 个点(水平和垂直)之间设置线。我试图找到问题所在,但无法找出问题所在,解决它
func setup() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMoreActions(touch:)))
tapGestureRecognizer.numberOfTapsRequired = 1
addGestureRecognizer(tapGestureRecognizer)
}
//draw line
func addLine(start: CGPoint,end:CGPoint) {
let line = CAShapeLayer()
let linePath = UIBezierPath()
linePath.move(to: start)
linePath.addLine(to: end)
line.path = linePath.cgPath
line.strokeColor = UIColor.black.cgColor
line.lineWidth = 2
line.lineJoin = kCALineJoinRound
layer.addSublayer(line)
}
// draw line between points
func showMoreActions(touch: UITapGestureRecognizer) {
let touchPoint = touch.location(in: self)
let (start, end) = findEndPoints(touchPt: touchPoint)
addLine(start: start, end: end)
}
func findEndPoints(touchPt: CGPoint) -> (pt1: CGPoint, pt2: CGPoint) {
//calculate where the touch is done
let viewWidth = self.bounds.width
let viewHeight = self.bounds.height
let gridRowWidth: CGFloat = viewWidth - diameter/4
let gridColumnHeight: CGFloat = viewHeight - diameter/4
let cellWidth: CGFloat = gridRowWidth / CGFloat(pointsOnRow)
let cellHeight: CGFloat = gridColumnHeight / CGFloat(pointsOnColumn)
// convert touch point to grid coordinates
let gridX = ( CGFloat(touchPt.x) / CGFloat(cellWidth) ) - 0.5
let gridY = ( CGFloat(touchPt.y) / CGFloat(cellHeight) ) - 0.5
// snap to nearest point in the grid
let snapX = round(gridX)
let snapY = round(gridY)
// find distance from touch to snap point
let distX = abs(gridX - snapX)
let distY = abs(gridY - snapY)
// start second point on top of first
var secondX = snapX
var secondY = snapY
if distX < distY {
// this is a vertical line
if secondY > gridY {
secondY -= 1
} else {
secondY += 1
}
} else {
//this is a horizontal line
if secondX > gridX {
secondX -= 1
} else {
secondX += 1
}
}
let halfdot = CGFloat(diameter) / 2
// convert line points to view coordinates
let pt1 = CGPoint(x: (snapX + 0.5) * CGFloat(cellWidth) + halfdot, y: (snapY + 0.5) * CGFloat(cellHeight) + halfdot)
let pt2 = CGPoint(x: (secondX + 0.5) * CGFloat(cellWidth) + halfdot, y: (secondY + 0.5) * CGFloat(cellHeight) + halfdot)
return (pt1, pt2)
}
重新设计了网格功能:
let squareSide = self.bounds.width
let distanceBetweenPointsOnRow = ( squareSide - 2 * pointStartPosition ) / (pointsOnRow - 1)
let distanceBetweenPointsOnColumn = ( squareSide - 2 * pointStartPosition ) / (pointsOnColumn - 1)
for n in 0..<self.pointsOnRow {
for m in 0..<self.pointsOnColumn {
let circleX: CGFloat = pointStartPosition + (CGFloat(n) * distanceBetweenPointsOnRow - diameter/2)
let circleY: CGFloat = pointStartPosition + (CGFloat(m) * distanceBetweenPointsOnColumn - diameter/2)
现在计算行放在哪里的函数是:
let squareSide = self.bounds.width
let distanceBetweenPoints = ( squareSide - 2 * pointStartPosition ) / (CGFloat(pointsOnColumn) - 1)
// convert touch point to grid coordinates
let gridX = (touchPt.x - pointStartPosition)/distanceBetweenPoints
let gridY = (touchPt.y - pointStartPosition)/distanceBetweenPoints
支票:
// check if the user is clicked outside the point grid
if secondX < 0 || secondY < 0 || secondY > (CGFloat(pointsOnColumn) - 1) || secondX > (CGFloat(pointsOnRow) - 1) || snapX < 0 || snapY < 0 || snapY > (CGFloat(pointsOnColumn) - 1) || snapX > (CGFloat(pointsOnRow) - 1) {
return nil
}
我 "bug" 在网格中设置点之间的线。如果我在网格外单击,我可以使行变为 "nowhere" 。我必须只在网格中的 2 个点(水平和垂直)之间设置线。我试图找到问题所在,但无法找出问题所在,解决它
func setup() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMoreActions(touch:)))
tapGestureRecognizer.numberOfTapsRequired = 1
addGestureRecognizer(tapGestureRecognizer)
}
//draw line
func addLine(start: CGPoint,end:CGPoint) {
let line = CAShapeLayer()
let linePath = UIBezierPath()
linePath.move(to: start)
linePath.addLine(to: end)
line.path = linePath.cgPath
line.strokeColor = UIColor.black.cgColor
line.lineWidth = 2
line.lineJoin = kCALineJoinRound
layer.addSublayer(line)
}
// draw line between points
func showMoreActions(touch: UITapGestureRecognizer) {
let touchPoint = touch.location(in: self)
let (start, end) = findEndPoints(touchPt: touchPoint)
addLine(start: start, end: end)
}
func findEndPoints(touchPt: CGPoint) -> (pt1: CGPoint, pt2: CGPoint) {
//calculate where the touch is done
let viewWidth = self.bounds.width
let viewHeight = self.bounds.height
let gridRowWidth: CGFloat = viewWidth - diameter/4
let gridColumnHeight: CGFloat = viewHeight - diameter/4
let cellWidth: CGFloat = gridRowWidth / CGFloat(pointsOnRow)
let cellHeight: CGFloat = gridColumnHeight / CGFloat(pointsOnColumn)
// convert touch point to grid coordinates
let gridX = ( CGFloat(touchPt.x) / CGFloat(cellWidth) ) - 0.5
let gridY = ( CGFloat(touchPt.y) / CGFloat(cellHeight) ) - 0.5
// snap to nearest point in the grid
let snapX = round(gridX)
let snapY = round(gridY)
// find distance from touch to snap point
let distX = abs(gridX - snapX)
let distY = abs(gridY - snapY)
// start second point on top of first
var secondX = snapX
var secondY = snapY
if distX < distY {
// this is a vertical line
if secondY > gridY {
secondY -= 1
} else {
secondY += 1
}
} else {
//this is a horizontal line
if secondX > gridX {
secondX -= 1
} else {
secondX += 1
}
}
let halfdot = CGFloat(diameter) / 2
// convert line points to view coordinates
let pt1 = CGPoint(x: (snapX + 0.5) * CGFloat(cellWidth) + halfdot, y: (snapY + 0.5) * CGFloat(cellHeight) + halfdot)
let pt2 = CGPoint(x: (secondX + 0.5) * CGFloat(cellWidth) + halfdot, y: (secondY + 0.5) * CGFloat(cellHeight) + halfdot)
return (pt1, pt2)
}
重新设计了网格功能:
let squareSide = self.bounds.width
let distanceBetweenPointsOnRow = ( squareSide - 2 * pointStartPosition ) / (pointsOnRow - 1)
let distanceBetweenPointsOnColumn = ( squareSide - 2 * pointStartPosition ) / (pointsOnColumn - 1)
for n in 0..<self.pointsOnRow {
for m in 0..<self.pointsOnColumn {
let circleX: CGFloat = pointStartPosition + (CGFloat(n) * distanceBetweenPointsOnRow - diameter/2)
let circleY: CGFloat = pointStartPosition + (CGFloat(m) * distanceBetweenPointsOnColumn - diameter/2)
现在计算行放在哪里的函数是:
let squareSide = self.bounds.width
let distanceBetweenPoints = ( squareSide - 2 * pointStartPosition ) / (CGFloat(pointsOnColumn) - 1)
// convert touch point to grid coordinates
let gridX = (touchPt.x - pointStartPosition)/distanceBetweenPoints
let gridY = (touchPt.y - pointStartPosition)/distanceBetweenPoints
支票:
// check if the user is clicked outside the point grid
if secondX < 0 || secondY < 0 || secondY > (CGFloat(pointsOnColumn) - 1) || secondX > (CGFloat(pointsOnRow) - 1) || snapX < 0 || snapY < 0 || snapY > (CGFloat(pointsOnColumn) - 1) || snapX > (CGFloat(pointsOnRow) - 1) {
return nil
}