问题
So I got this code for my simple iOS app. When I press the touchPressed button, the button should get a new random location on the screen and the labelScore should update itself with the number of button touches. A friend of mine tried this in Objective-C and it works.
The problem is: I have the newScore() in touchedPressed and the button doesn't get a new location. If I comment newScore(), the random location action works.
Thanks in advance.
// 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.
}
}
回答1:
Now that @matt has identified the problem, I have another suggestion about how to handle it:
1) Add two new vars to your ViewController
:
var newButtonX: CGFloat?
var newButtonY: CGFloat?
2) Set these in touchPressed()
when updating the button's location.
// 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) Add an IBOutlet
for the button to your ViewController
:
@IBOutlet weak var button: UIButton!
and wire it up in Interface Builder.
4) Then override viewDidLayoutSubviews
like so:
override func viewDidLayoutSubviews() {
if let buttonX = newButtonX {
button.center.x = buttonX
}
if let buttonY = newButtonY {
button.center.y = buttonY
}
}
回答2:
It's because of the way the drawing/layout system works. You have a small timing problem, that's all. What's really happening is that the button is moving, but layout is taking place immediately afterwards and putting it back again. One solution is to wrap everything except the call to newScore
in a short delay, like this:
@IBAction func touchPressed(button: UIButton) {
delay(0) {
// Find the button's width and height
var buttonWidth = button.frame.width
// ...
}
self.newScore()
}
Alternatively, turn off Auto Layout in this storyboard / xib file. That solves it too (though this may be unacceptable for other reasons).
来源:https://stackoverflow.com/questions/26077229/strange-ibaction-conflict-or-bug-swift