【问题标题】:Add shapes on top of created path在创建的路径上添加形状
【发布时间】:2021-08-21 03:26:04
【问题描述】:

拥有使用以下代码绘制自定义形状的代码:

struct ProgressPath: Shape {
    var numberOfPoints: Int = 2

    var animatableData: CGFloat {
        get { CGFloat(numberOfPoints) }
        set { numberOfPoints = Int(newValue) }
    }

    var sectionsByItems: [IndexPath] {
        var result: [IndexPath] = []
        for index in 0..<numberOfPoints {
            guard let lastItem = result.last?.row else {
                result.append(IndexPath(item: 0,
                                        section: 0))
                continue
            }

            let currentSection = Int(index / 2)

            if index % 2 == 0 {
                result.append(IndexPath(item: lastItem,
                                        section: currentSection))
            } else {
                result.append(IndexPath(item: lastItem == 1 ? 0 : 1,
                                        section: currentSection))
            }
        }

        return result
    }

    func point(indexPath: IndexPath,
               rect: CGRect)-> CGPoint {
        let distance = rect.width - 40
        return CGPoint(x: indexPath.row == 0 ? distance : 40,
                       y: (rect.height - 20) - 50 * (CGFloat(indexPath.section)))
    }

    func path(in rect: CGRect) -> Path {
        var path = Path()

        sectionsByItems
            .forEach { indexPath in
                let newPoint = point(indexPath: indexPath,
                                     rect: rect)

                if indexPath.section == 0 &&
                    indexPath.row == 0 {
                    path.move(to: newPoint)
                } else {
                    path.addLine(to: newPoint)
                }
            }

        return path
    }
}

如下所示:

我想在创建的路径上添加形状,理想情况下,我希望有一些看起来像这样的机制,路径顶部的圆圈可以交互:

在不修改原始路径的情况下如何实现这一点有点迷茫,也许有更优雅的解决方案可以在自定义路径上绘制形状?

类似问题 - How to create game map for iOS?

注意:虽然这是上面提供的自定义路径的一个特定问题 - 我正在尝试提出一种方法,通过遵循它们的路径在任何形状的顶部绘制自定义形状并使它们可交互。

【问题讨论】:

    标签: ios swift user-interface mobile swiftui


    【解决方案1】:

    在不修改原始路径的情况下如何实现这一点,

    在您给出的示例中,答案非常简单,因为您已经拥有所需的所有数据。您正在从一组点创建路径,这些点也是您的圈子的位置,因此您只需要保存这些位置。一种方法是将生成点的代码移到ProgressPath 的定义之外,并修改ProgressPath 使其只接受任何点数组。然后你可以生成一次数组,用它创建一个ProgressPath,然后用同一个数组创建你的circles

    路径顶部的圆圈可以交互

    目前尚不清楚您的想法是哪种互动。如果您只想单击/点击圆圈并进入相应的游戏关卡,您将需要创建一个可以绘制圆圈并存储您需要的数据或操作的新视图类型完成交互。例如,您可以创建一个struct LevelButton,它将自身绘制为一个圆圈并包含一个级别 ID。如果您希望能够使用像手柄这样的圆圈来拖动路径的一部分,或者可能像在绳子上的珠子一样沿着路径滑动圆圈,事情变得比我认为我们需要在这里介绍的要复杂。

    也许有更优雅的解决方案可以在自定义路径上绘制形状?

    Path 包含 CGPath,其中包含路径元素列表,因此可以编写代码遍历段列表并提取定位圆圈所需的点。但是,对于通用解决方案,您需要考虑几种不同类型的路径段:不仅是直线段,还包括曲线和移动。有关完整列表,请参阅 CGPathElementType。 CGPath 还提供了让您将自己的函数应用于每个元素的函数,因此您可以编写一个函数来收集每种元素类型的适当点,这样您就可以得到一个点列表,您可以使用这些点来定位您的圆。

    【讨论】:

      【解决方案2】:

      简单点,比如一个点就是一个imageView

      分而治之

      在创建的路径顶部添加形状,

      关键点是点的中心。

      如果你得到了点的中心,你就知道它们的框架大小相同,

      一旦你知道它们的框架,只需将点放在路径上方

      struct ProgressPath: Shape {
      
          func centers(in rect: CGRect) -> [CGPoint] {
              var ctrs = [CGPoint]()
      
              sectionsByItems
                  .forEach { indexPath in
                      let newPoint = point(indexPath: indexPath,
                                           rect: rect)
      
                      ctrs.append(newPoint)
                  }
      
              return ctrs
          }
      }
      

      在创建的路径顶部添加形状,

      使用上面的辅助方法

      您可以轻松获得两条路径,原始路径和点路径

      只要冷静一下,你就会明白的

      【讨论】:

        猜你喜欢
        • 2012-05-14
        • 2018-04-24
        • 1970-01-01
        • 2012-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-15
        • 2019-01-24
        相关资源
        最近更新 更多