代码之家  ›  专栏  ›  技术社区  ›  PvDev

是否可以在iOS swift中通过在图像上画线对图像进行分组?

  •  0
  • PvDev  · 技术社区  · 7 年前

    例如,如果我在随机位置的视图上有多个图像。通过在图像上绘制线条来选择图像,并使用手势对图像进行分组。现在,我可以随机显示图像,但不能通过在图像上画线对图像进行分组。 这里截图1是我现在得到的结果: enter image description here

    截图2正是我想要的。 enter image description here

    1 回复  |  直到 7 年前
        1
  •  2
  •   Matic Oblak    7 年前

    对于您试图做的事情,我将首先创建一个能够处理手势和绘制路径的自定义视图(一个子类)。

    对于手势识别器,我将使用 UIPanGestureRecognizer 。您要做的是在处理手势的位置设置一组点,然后使用这些点绘制路径:

    private var currentPathPoints: [CGPoint] = []
    @objc private func onPan(_ sender: UIGestureRecognizer) {
        switch sender.state {
        case .began: currentPathPoints = [sender.location(in: self)] // Reset current array by only showing a current point. User just started his path
        case .changed: currentPathPoints.append(sender.location(in: self)) // Just append a new point
        case .cancelled, .ended: endPath() // Will need to report that user lifted his finger
        default: break // These extra states are her just to annoy us
        }
    }
    

    所以,如果平移手势识别器使用这种方法,它应该跟踪用户拖动的点。现在这些都是最好的 drawRect 需要在视图中覆盖,如:

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    
        // Generate path
        let path: UIBezierPath = {
            let path = UIBezierPath()
            var pointsToDistribute = currentPathPoints
            if let first = pointsToDistribute.first {
                path.move(to: first)
                pointsToDistribute.remove(at: 0)
            }
            pointsToDistribute.forEach { point in
                path.addLine(to: point)
            }
            return path
        }()
    
        let color = UIColor.red // TODO: user your true color
    
        color.setStroke()
        path.lineWidth = 3.0
        path.stroke()
    }
    

    现在,当您通过调用 setNeedsDisplay .在您的情况下,最好在路径点设置器上进行:

    private var currentPathPoints: [CGPoint] = [] {
        didSet {
            setNeedsDisplay()
        }
    }
    

    由于此视图应作为整个场景的覆盖,因此您需要某种方式来报告事件。应创建一个委托过程来实现以下方法:

    func endPath() {
        delegate?.myLineView(self, finishedPath: currentPathPoints)
    }
    

    因此,现在如果视图控制器是委托,它可以检查路径中选择了哪些图像视图。对于第一个版本,只需检查任何点是否在任何图像视图内即可:

    func myLineView(sender: MyLineView, finishedPath pathPoints: [CGPoint]) {
        let convertedPoints: [CGPoint] = pathPoints.map { sender.convert($0, to: viewThatContainsImages) }
    
        let imageViewsHitByPath = allImageViews.filter { imageView in
           return convertedPoints.contains(where: { imageView.frame.contains($0) })
        }
    
    // Use imageViewsHitByPath
    }
    

    现在,在这个基本实现之后,您可以通过绘制一条更好的线(曲线)开始玩游戏,在这种情况下,您不会检查点是否在图像视图内,而是检查任何两个相邻点之间的线是否与图像视图相交。