1

我正在开发一个在屏幕上绘制井字游戏网格的项目。

问题是,对于“瓷砖”的底行,UITapGestureRecognizer无法正常工作。对于网格的前两行,当UIImageView识别器分配给的任何部分被点击时,适当的函数被调用。但是,对于底行,它仅在UIImageView点击最顶部时才有效。

这是代码:

func drawTiles() {
    for view in subviews {
        if (view as? UIImageView != nil) {
            view.removeFromSuperview()
        }
    }

    // Upper Left Tile [0][0]
    var view = UIImageView(image: battleGround.tiles[0][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX, y: frame.minY, width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Upper Middle Tile [0][1]
    view = UIImageView(image: battleGround.tiles[0][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + frame.width / 3, y: frame.minY, width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Upper Right Tile [0][2]
    view = UIImageView(image: battleGround.tiles[0][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + ((frame.width / 3) * 2), y: frame.minY, width: frame.width / 3, height: frame.height / 3)
    addSubview(view)



    // Middle Left Tile [1][0]
    view = UIImageView(image: battleGround.tiles[1][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX, y: frame.minY + ((frame.height / 3)), width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Middle Center Tile [1][1]
    view = UIImageView(image: battleGround.tiles[1][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + ((frame.width / 3)), y: frame.minY + ((frame.height / 3)), width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Middle Center Tile [1][2]
    view = UIImageView(image: battleGround.tiles[1][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + ((frame.width / 3) * 2), y: frame.minY + ((frame.height / 3)), width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // FIXME: Only clicking the top of the next 3 views works

    // Lower Left Tile [2][0]
    view = UIImageView(image: battleGround.tiles[2][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX, y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Lower Center Tile [2][1]
    view = UIImageView(image: battleGround.tiles[2][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + ((frame.width / 3)), y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height: frame.height / 3)
    addSubview(view)

    // Lower Right Tile [2][2]
    view = UIImageView(image: battleGround.tiles[2][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: frame.minX + ((frame.width / 3) * 2), y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height:frame.height / 3)
    addSubview(view)
}

func upperLeftTapped() {
    tapped(row: 0, column: 0)
}

func upperCenterTapped(){
    tapped(row: 0, column: 1)
}

func upperRightTapped() {
    tapped(row: 0, column: 2)
}

func middleLeftTapped() {
    tapped(row: 1, column: 0)
}

func middleCenterTapped() {
    tapped(row: 1, column: 1)
}
func middleRightTapped() {
    tapped(row: 1, column: 2)
}

func lowerLeftTapped() {
    tapped(row: 2, column: 0)
}

func lowerCenterTapped() {
    tapped(row: 2, column: 1)
}

func lowerRightTapped() {
    tapped(row: 2, column: 2)
}

func tapped(row: Int, column: Int) {
    if (battleGround.tiles[row][column] == .empty) {
        battleGround.tiles[row][column] = currentPlayer

        drawTiles()
    }
}

这是需要注意的代码(绘制网格的下一行)

// Lower Left Tile [2][0]
view = UIImageView(image: battleGround.tiles[2][0].image)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerLeftTapped)))
view.isUserInteractionEnabled = true
view.frame = CGRect(x: frame.minX, y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height: frame.height / 3)
addSubview(view)

// Lower Center Tile [2][1]
view = UIImageView(image: battleGround.tiles[2][1].image)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerCenterTapped)))
view.isUserInteractionEnabled = true
view.frame = CGRect(x: frame.minX + ((frame.width / 3)), y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height: frame.height / 3)
addSubview(view)

// Lower Right Tile [2][2]
view = UIImageView(image: battleGround.tiles[2][2].image)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerRightTapped)))
view.isUserInteractionEnabled = true
view.frame = CGRect(x: frame.minX + ((frame.width / 3) * 2), y: frame.minY + ((frame.height / 3) * 2), width: frame.width / 3, height:frame.height / 3)
addSubview(view)

编辑:以下是应用程序运行的一些屏幕截图,以便更好地了解问题所在。

图像1

此屏幕截图显示了空网格的外观。

图2

此屏幕截图显示了我单击网格的顶部中间和中间左图后的网格。如您所见,图像已正确添加。

但是,如果我点击网格的底行,什么也不会发生。看看这个GIF:

gif1

我在底部中间多次敲击,没有任何反应。然而,在中心敲击工作正常。

这是有趣的部分:点击同一底部中间图块的顶部会导致图像出现。看一看:

在此处输入图像描述

任何帮助将不胜感激!

4

3 回答 3

2

使用 Debug -> View Debugging -> Capture View Hierarchy,并检查您将所有这些图块插入到的视图是否实际延伸到您假设的范围。

还可以使用一个简单的测试self.clipsToBounds = YES; 如果您看不到所有图块,则说明您的包含视图不够大,这意味着手势将无法正确转发到手势识别器。

于 2016-11-16T15:55:02.893 回答
0

您的视图可以与其他视图重叠。Nailer 是对的,只要使用 View 调试这个问题,你就可以看到哪个视图与你的视图重叠并修复它。

于 2016-11-16T16:17:00.810 回答
0

@Nailer 的clipToBounds方法帮助我找到了解决方案,但没有直接透露。经过几周的深思熟虑后,事实证明用替换大部分内容frame.可以bounds.解决问题。这是新代码。

func drawTiles() {
    for view in subviews {
        if (view as? UIImageView != nil) {
            view.removeFromSuperview()
        }
    }

    // Upper Left Tile [0][0]
    var view = UIImageView(image: battleGround.tiles[0][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX, y: bounds.minY, width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Upper Middle Tile [0][1]
    view = UIImageView(image: battleGround.tiles[0][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + bounds.width / 3, y: bounds.minY, width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Upper Right Tile [0][2]
    view = UIImageView(image: battleGround.tiles[0][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(upperRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + ((bounds.width / 3) * 2), y: bounds.minY, width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)



    // Middle Left Tile [1][0]
    view = UIImageView(image: battleGround.tiles[1][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX, y: bounds.minY + ((bounds.height / 3)), width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Middle Center Tile [1][1]
    view = UIImageView(image: battleGround.tiles[1][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + ((bounds.width / 3)), y: bounds.minY + ((bounds.height / 3)), width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Middle Center Tile [1][2]
    view = UIImageView(image: battleGround.tiles[1][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(middleRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + ((bounds.width / 3) * 2), y: bounds.minY + ((bounds.height / 3)), width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // FIXME: Only clicking the top of the next 3 views works

    // Lower Left Tile [2][0]
    view = UIImageView(image: battleGround.tiles[2][0].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerLeftTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX, y: bounds.minY + ((bounds.height / 3) * 2), width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Lower Center Tile [2][1]
    view = UIImageView(image: battleGround.tiles[2][1].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerCenterTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + ((bounds.width / 3)), y: bounds.minY + ((bounds.height / 3) * 2), width: bounds.width / 3, height: bounds.height / 3)
    addSubview(view)

    // Lower Right Tile [2][2]
    view = UIImageView(image: battleGround.tiles[2][2].image)
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(lowerRightTapped)))
    view.isUserInteractionEnabled = true
    view.frame = CGRect(x: bounds.minX + ((bounds.width / 3) * 2), y: bounds.minY + ((bounds.height / 3) * 2), width: bounds.width / 3, height:bounds.height / 3)
    addSubview(view)
}
于 2016-11-30T14:52:49.047 回答