【问题标题】:Is it possible to group images by drawing lines on it in iOS swift?是否可以通过在 iOS swift 中绘制线条来对图像进行分组?
【发布时间】:2018-04-16 03:33:38
【问题描述】:

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

截图 2 这正是我想要的。

【问题讨论】:

  • 几乎一切皆有可能。这听起来也确实如此。在学习如何创建路径时查找“绘制路径”,您可以引用与路径共享坐标的每个 imageView
  • 谢谢@Jake 是否有任何示例代码可以分享。过去一周我一直在挣扎。
  • 我不知道。我从来没有做过。但从概念上讲,这就是我会尝试的。
  • 您可以检查用户的手势是否属于图像帧,获取它。

标签: ios swift xcode uiview uiimageview


【解决方案1】:

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

对于手势识别器,我会使用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
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2021-09-14
    • 2016-11-24
    • 2012-04-09
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多