首页 > 解决方案 > 我将如何在 iOS 中制作可拖动的自定义形状瓷砖网格?

问题描述

对于一个游戏,我想制作一个相邻(彼此很好地接壤)并且可拖动/可交换的形状网格。例如六边形或三角形的网格。我不知道该怎么做。我可以用collectionView 做到这一点还是我需要使用spriteKit 或其他东西?任何有关前进方向的想法将不胜感激。

更新:所以在使用 UIBezierPaths 绘制三角形网格和 UIBezierPath.contains(CGPoint) 函数进行一些谷歌搜索后,我做了一种概念证明。我创建了一个 UIView 子类 TriangleView 来绘制三角形,但是我遇到了一个问题。形成正方形的两个相邻三角形具有相同的框架,因此一个的透明部分总是在另一个三角形的顶部。因此,平移/轻击手势击中的是透明部分而不是下面的可见三角形,任何想法如何忽略透明部分并击中下面的三角形。现在基本上我不会在手势碰到透明部分时采取行动(所以它只会在触摸实际形状时移动)

这一切看起来像什么

平移手势识别器的代码:

@objc func draggedView(_ sender:UIPanGestureRecognizer){
    var shouldDrag:Bool = false

    let tapLocation = sender.location(in: (sender.view! as! TriangleView))
    shouldDrag = (sender.view! as! TriangleView).hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y)) //returns whether tap is in UIBezierPath portion of UIView and not transparent part

    if shouldDrag{
        self.view.bringSubview(toFront: (sender.view! as! TriangleView))
        let translation = sender.translation(in: self.view)
        (sender.view! as! TriangleView).center = CGPoint(x: (sender.view! as! TriangleView).center.x + translation.x, y: (sender.view! as! TriangleView).center.y + translation.y)
        sender.setTranslation(CGPoint.zero, in: self.view)
    }
}

再次更新:所以经过一番搜索,我发现更好的选择是在我的 UIView 子类中覆盖此方法:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    if triangleBezierPath.contains(point){
        return true
    }
    return false
}

所以现在我什至不需要在手势过程中检查这个,三角形外部的透明/部分被完全忽略。这种方式似乎也更顺畅一些。您认为使用 SpriteKit 或 CollectionView 会更好吗?我仍然需要弄清楚如何在重叠拖动时交换形状

标签: iosswiftsprite-kituicollectionviewuicollectionviewcell

解决方案


推荐阅读