2017-06-18 67 views
0

我需要在網格中的每個點之間連接每2個點的連線,以便它們可以連接。我設法創建點網:用線連接網格中的點

func drawPointGrid() { 

    let points: CGFloat = 5 

    let cellWidth = bounds.width/points 

    let cellHeight = bounds.height/points 

    for i in 0..<Int(points) { 

     for j in 0..<Int(points) { 

      let circleX: CGFloat = ((CGFloat(i) + 0.5) * cellWidth) 

      let circleY: CGFloat = ((CGFloat(j) + 0.5) * cellHeight) 

      let centerCirclePath = UIBezierPath(ovalIn: CGRect(x: circleX, y: circleY, width: diameter, height: diameter)) 

      let customlayer = CAShapeLayer() 
      customlayer.path = centerCirclePath.cgPath 
      customlayer.fillColor = UIColor.black.cgColor 
      layer.addSublayer(customlayer) 
     } 
    } 
} 

這是我的視點網:enter image description here

我設法使上觀點一致,但只有當我點擊了起點,並再次點擊終點,所以要創建的行,但我需要這條線,每2個點之間創建水平和垂直當使用者開關之間:

override func draw(_ rect: CGRect) { 
    drawPointGrid() 
      tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMoreActions)) 
      tapGestureRecognizer.numberOfTapsRequired = 1 
      addGestureRecognizer(tapGestureRecognizer) 
} 


// draw line from point to point that are clicked 

var firstPoint: CGPoint? 

var secondPoint: CGPoint? 

    func showMoreActions(touch: UITapGestureRecognizer) { 

     let touchPoint = touch.location(in: self) 

     guard let _ = firstPoint else { 

      firstPoint = touchPoint 

      return 
     } 

     guard let _ = secondPoint else { 

      secondPoint = touchPoint 

      addLine(start: firstPoint!,end: secondPoint!) 

      firstPoint = nil 
      secondPoint = nil 

      return 
     } 
    } 


    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) 

    } 

回答

1

我寫了一個名爲findEndPoints功能找到CGPoint在視圖中給出touchPoint的適當線端點的座標。我做了大部分工作,類型爲Double,以免不必擔心在那個和CGFloat之間轉換。

我也感動了touchGestureRecognizer的設置到setup例程從init叫做因爲你只想做一次,draw可以被稱爲不止一次。

class DotsView: UIView { 

    let diameter = CGFloat(5) 

    func setup() { 
     let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMoreActions)) 
     tapGestureRecognizer.numberOfTapsRequired = 1 
     addGestureRecognizer(tapGestureRecognizer) 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setup() 
    } 

    override func draw(_ rect: CGRect) { 
     drawPointGrid()  
    } 

    // 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 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) 
    } 

    func drawPointGrid() { 

     let points: CGFloat = 5 
     let diameter: CGFloat = 5 

     let cellWidth = bounds.width/points 

     let cellHeight = bounds.height/points 

     for i in 0..<Int(points) { 

      for j in 0..<Int(points) { 

       let circleX: CGFloat = ((CGFloat(i) + 0.5) * cellWidth) 

       let circleY: CGFloat = ((CGFloat(j) + 0.5) * cellHeight) 

       let centerCirclePath = UIBezierPath(ovalIn: CGRect(x: circleX, y: circleY, width: diameter, height: diameter)) 

       let customlayer = CAShapeLayer() 
       customlayer.path = centerCirclePath.cgPath 
       customlayer.fillColor = UIColor.black.cgColor 
       layer.addSublayer(customlayer) 
      } 
     } 
    } 

    func findEndPoints(touchPt: CGPoint) -> (pt1: CGPoint, pt2: CGPoint) { 
     let points = 5.0 
     let cellWidth = Double(bounds.width)/points 
     let cellHeight = Double(bounds.height)/points 

     // convert touch point to grid coordinates 
     let gridX = Double(touchPt.x)/cellWidth - 0.5 
     let gridY = Double(touchPt.y)/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 = Double(diameter)/2 

     // convert line points to view coordinates 
     let pt1 = CGPoint(x: (snapX + 0.5) * cellWidth + halfdot, y: (snapY + 0.5) * cellHeight + halfdot) 
     let pt2 = CGPoint(x: (secondX + 0.5) * cellWidth + halfdot, y: (secondY + 0.5) * cellHeight + halfdot) 

     return (pt1, pt2) 
    } 

} 

Demo running in simulator

+0

它的工作原理感謝ü:) – RosS