如何检测 2 个手指点击以及在哪些视图中点击 Swift

How to detect 2 fingers tap and which views are tap in Swift

我正在制作掉落的方块游戏。当您点击(单个)时,我已经实现了普通磁贴,它将被删除。接下来,当您同时点击 2 个图块时,我想制作双图块,这些图块将被删除。但是我不知道要检测 "whether you tap 2 double tiles at the same time".

双砖从屏幕底部从屏幕顶部掉落。如果瓷砖到达底部,新的瓷砖将从屏幕顶部出现。 现在我可以检测到单击和同时用 2 个手指点击。

如何制作双层瓷砖?

更新:

到目前为止,我可以通过 GestureRecognizer 检测到 2 个手指触摸。但是检测不到"which views you touched"。 "gesture.view" 的日志即使你触摸了 2 个瓷砖也只有一个视图。我想要做的就像下面的代码:

if gesture.view.count == 2 && gesture.view is GameTileDouble {
    print("touched 2 doubleTiles at the same time")
}

瓷砖Class

class GameTile: UIImageView {

    init(named: String, frame: CGRect) {
        super.init(frame: frame)
        super.image = (UIImage(named: named))
        super.isUserInteractionEnabled = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

普通瓷砖Class

class GameTileNormal: GameTile {

    let namedDefault: String
    var frameDefault: CGRect
    let isHiddenDefault: Bool
    var isUserInteractionEnabledDefault: Bool
    let colorName: UIColor
    var tileLane: Int

    init(
        named: String,
        frame: CGRect,
        isHidden: Bool = false,
        isUserInteractionEnabled: Bool = true,
        color: UIColor = UIColor.blue,
        lane: Int) {
        namedDefault = named
        isHiddenDefault = isHidden
        frameDefault = frame
        isUserInteractionEnabledDefault = isUserInteractionEnabled
        colorName = color
        tileLane = lane

        super.init(named: named, frame: frame)
        super.isHidden = isHiddenDefault
        super.isUserInteractionEnabled = isUserInteractionEnabledDefault
        super.backgroundColor = colorName

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

双层瓷砖Class

class GameTileDouble: GameTile {
    let namedDefault: String
    var frameDefault: CGRect
    let isHiddenDefault: Bool
    let isUserInteractionEnabledDefault: Bool
    let colorName: UIColor
    var tileLane: Int

    init(
        named: String,
        frame: CGRect,
        isHidden: Bool = false,
        isUserInteractionEnabled: Bool = true,
        color: UIColor = UIColor.yellow,
        lane: Int) {
        namedDefault = named
        frameDefault = frame
        isHiddenDefault = isHidden
        isUserInteractionEnabledDefault = isUserInteractionEnabled
        colorName = color
        tileLane = lane

        super.init(named: named, frame: frame)
        super.isHidden = isHiddenDefault
        super.isUserInteractionEnabled = isUserInteractionEnabledDefault
        super.backgroundColor = colorName

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

ViewController.swift

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let tileNormal = GameTileNormal.init(named: "normal.png",frame: CGRect(x: 0, y:0, width: 50, height: 50),isUserInteractionEnabled: true, lane: 1)
        self.view.addSubview(tileNormal)

        let tileDouble1 = GameTileDouble.init(named: "black.png",frame: CGRect(x:150, y: 0, width: 50, height: 50),isUserInteractionEnabled: true, lane: 2)
        self.view.addSubview(tileDouble1)

        let tileDouble2 = GameTileDouble.init(named: "black.png",frame: CGRect(x: 200, y: 0, width: 50, height: 50),isUserInteractionEnabled: true, lane: 3)
        self.view.addSubview(tileDouble2)

        //detect single tap
        let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(StandardGameViewController.handleSingleTapGesture(_:)))
        singleTapGesture.numberOfTapsRequired = 1
        singleTapGesture.numberOfTouchesRequired = 1
        view.addGestureRecognizer(singleTapGesture)

        //detect tap at the same time by 2 fingers
        let doubleTapGesture = UITapGestureRecognizer(target: self , action: #selector(StandardGameViewController.handleDoubleTapGesture(_:)))
        doubleTapGesture.numberOfTouchesRequired = 2
        view.addGestureRecognizer(doubleTapGesture)

    }

    //something function to move tiles...

    @objc func handleSingleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("single tap")
        //if tapped tileNormal, the normalTile is deleted (removeFromSuperview)
    }

    @objc func handleDoubleTapGesture(_ gesture: UITapGestureRecognizer) {
        print("tap at the same time by 2 fingers")

        //if tapped doubleTile1 and tileDouble1 and tileDouble2, these tiles will be deleted (this is the point I don't have any idea
    }

您只需要在添加了磁贴的view上启用多点触控

//Assuming it's on self.view
self.view.isMultipleTouchEnabled = true

注意:这样做将支持 N 次触摸。


那你就凑合着用handleSingleTapGesture:.
不需要 handleDoubleTapGesture:.

只需确保在每个图块上添加一个点击手势并将点击操作分配给 handleSingleTapGesture:,这样您点击的每个图块都会调用它。

然后像这样简单地删除磁贴:

gesture.view?.removeFromSuperview()

示例:

@IBAction func handleSingleTapGesture(_ gesture: UITapGestureRecognizer) {
    guard let view = gesture.view else { return }

    print("Current view tapped: ", terminator: "")
    if view.isKind(of: GameTileNormal.self) {
        print("Normal Tile")
    }
    else if view.isKind(of: GameTileDouble.self) {
        print("Double Tile")
    }

    view.removeFromSuperview()
}