【问题标题】:Strange @IBAction conflict or bug? (Swift)奇怪的@IBAction 冲突或错误? (迅速)
【发布时间】:2014-11-22 12:11:16
【问题描述】:

所以我得到了我的简单 iOS 应用程序的代码。当我按下 touchPressed 按钮时,该按钮应该在屏幕上获得一个新的随机位置,并且 labelScore 应该使用按钮触摸次数自行更新。我的一个朋友在 Objective-C 中尝试过这个,它可以工作。

问题是:我在 touchPressed 中有 newScore() 并且按钮没有获得新位置。如果我评论 newScore(),则随机位置操作有效。

提前致谢。

//  ViewController.swift


import UIKit
import SpriteKit

class ViewController: UIViewController {

@IBOutlet var backgroundImage: UIImageView!

@IBOutlet var scoreLabel: UILabel!



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

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}





// Initial score
var score:Int  = 0



// Update the actual score with the one matching th number of touches
func newScore() { 
    score = score + 1
    scoreLabel.text = "SCORE: \(score)"
}



// Get the random height for the button (with limits)
func randomButtonHeight(min: Float, max:Float) -> Float {
    return min + Float(arc4random_uniform(UInt32((max-90) - min + 1)))



}

@IBAction func touchPressed(button: UIButton) {



    // Find the button's width and height
    var buttonWidth = button.frame.width
    var buttonHeight = button.frame.height

    // Find the width and height of the enclosing view
    var viewWidth = button.superview!.bounds.width
    var viewHeight = button.superview!.bounds.height


    // Compute width and height of the area to contain the button's center
    var xwidth = viewWidth - buttonWidth
    var yheight = viewHeight - buttonHeight

    // Generate a random x and y offset
    var xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
    var yoffset = CGFloat(self.randomButtonHeight(100, max: Float(viewHeight)))

    // Offset the button's center by the random offsets.
    button.center.x = xoffset + buttonWidth / 2
    button.center.y = yoffset + buttonHeight / 2


    newScore() // this works but the action above this doesn't and if I comment this line, the action above works.

}



}

【问题讨论】:

  • 问得很好——我可以很容易地重现这个问题。
  • 也许有人找到了解决方法..

标签: ios xcode swift uikit xcode6


【解决方案1】:

既然@matt 已经确定了问题所在,我还有一个关于如何处理它的建议:

1) 向您的ViewController 添加两个新变量:

var newButtonX: CGFloat?
var newButtonY: CGFloat?

2) 更新按钮位置时在touchPressed() 中设置这些。

// Offset the button's center by the random offsets.
newButtonX = xoffset + buttonWidth / 2
newButtonY = yoffset + buttonHeight / 2
button.center.x = newButtonX!
button.center.y = newButtonY!

3) 将按钮的IBOutlet 添加到您的ViewController

@IBOutlet weak var button: UIButton!

并在 Interface Builder 中连接起来。

4) 然后像这样覆盖viewDidLayoutSubviews

override func viewDidLayoutSubviews() {
    if let buttonX = newButtonX {
        button.center.x = buttonX
    }
    if let buttonY = newButtonY {
        button.center.y = buttonY
    }
}

【讨论】:

  • 致命错误:在展开可选值 (lldb) 时意外发现 nil - button.center.x = buttonX
  • 确保将按钮连接到情节提要中的插座
  • 我应该创建另一个吗?我的按钮已经连接到 touchPressed
  • 是的。您需要添加一个IBOutlettouchPressed 是一个 IBAction 连接。以同样的方式进行操作,从按钮拖动到 class ViewController 下方,但这次从弹出窗口中选择 Outlet
  • 现在这比@matt 提供的解决方案效果更好。非常感谢!
【解决方案2】:

这是因为绘图/布局系统的工作方式。你有一个小的时间问题,仅此而已。真正发生的是按钮正在移动,但布局是在之后立即发生并再次放回。一种解决方案是在很短的延迟内包装除了对newScore 的调用之外的所有内容,如下所示:

@IBAction func touchPressed(button: UIButton) {
    delay(0) {
        // Find the button's width and height
        var buttonWidth = button.frame.width
        // ...
    }
    self.newScore()
}

或者,在这个故事板/xib 文件中关闭自动布局。这也解决了它(尽管由于其他原因这可能是不可接受的)。

【讨论】:

  • 对于delay 函数,请在此处查看我的答案:stackoverflow.com/a/24318861/341994
  • 使用延迟部分起作用,因为有时按钮仍然存在但关闭自动布局效果更好。
  • 是的,我也注意到了。使标签比需要的更大(更宽)可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
  • 2010-10-24
  • 2015-02-28
相关资源
最近更新 更多