在iOSswift中可以通过在图像上画线来对图像进行分组吗?

Is it possible to group images by drawing lines on it in iOS swift?

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

屏幕截图 2 这正是我想要的。

对于你想要做的事情,我将从创建一个能够处理手势和绘制路径的自定义视图(一个子类)开始。

对于手势识别器,我会使用 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使绘图无效时将调用此方法。在您的情况下,最好在 setter 个路径点上完成:

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([=14=], to: viewThatContainsImages) }

    let imageViewsHitByPath = allImageViews.filter { imageView in
       return convertedPoints.contains(where: { imageView.frame.contains([=14=]) })
    }

// Use imageViewsHitByPath
}

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