2017-06-18 1 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点間に作成する必要があります:私はCGPointを見つけfindEndPointsと呼ばれる関数を書いた

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

ビュー内でtouchPointと指定された適切な線の終点の座標。私は仕事のほとんどをタイプDoubleとして、それとCGFloatとの間の変換について心配する必要がないようにしました。

私はまた、あなたが一度だけとdrawが複数回呼び出されることができることをやりたいので、init sから呼び出されたsetupルーチンにtouchGestureRecognizerのセットアップを動かしました。

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

それは、Uに感謝動作します。) – RosS

関連する問題