带有 NSTimer 问题的 UIPanGesture
UIPanGesture With NSTimer Issue
我遇到了一个问题
我有一个视图控制器,它包含一个平移手势和一个 NSTimer,它有一个每秒调用的选择器
问题是每次激活计时器时,我都会尝试使用平移手势 return 自动将标签移动到其原始位置。
可能是什么原因?
这是代码
import UIKit
class gameViewController: UIViewController {
@IBOutlet weak var img1: UIImageView!
@IBOutlet weak var lbl1: UILabel!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var gameDifficultyLabel: UILabel!
var timer = NSTimer()
var timeManager = TimerManager()
override func viewDidLoad() {
super.viewDidLoad()
timerLabel.text = "\(timeManager.displayedTime(timeManager.time!))"
// Do any additional setup after loading the view.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let difficulty = timeManager.difficulties {
switch difficulty {
case .Easy:
gameDifficultyLabel.text = "Easy"
case .Medium:
gameDifficultyLabel.text = "Medium"
case .Hard:
gameDifficultyLabel.text = "Hard"
}
}
}
@IBAction func panGesture(sender: UIPanGestureRecognizer) {
let translation = sender.translationInView(self.view)
if let view = sender.view {
view.center = CGPoint(x:view.center.x + translation.x,
y:view.center.y + translation.y)
}
sender.setTranslation(CGPointZero, inView: self.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func updateTime() {
let shouldStop = timeManager.updateTime()
timerLabel.text = timeManager.displayedTime(timeManager.time)
if shouldStop {
timer.invalidate()
}
}
}
更新:
我已经更新了代码。
以编程方式添加标签解决了这个问题,但我有另一个问题
这是代码。
class gameViewController: UIViewController {
@IBOutlet var numbersContainers: [UIImageView]!
@IBOutlet var numbersLabel: [UILabel]!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var gameDifficultyLabel: UILabel!
var LabelsBackground = [UIImageView]()
var Labels = [UILabel]()
var timer = NSTimer()
var timeManager = TimerManager()
var panGesture : UIPanGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
timerLabel.text = "\(timeManager.displayedTime(timeManager.time!))"
self.createLabelsBackground()
self.setUpLabelsBackground()
self.addLabelsBackground()
self.createLabels()
self.setUpLabels()
self.addLabels()
panGesture = UIPanGestureRecognizer(target: self, action: "panAction:")
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
self.addPanGesture()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let difficulty = timeManager.difficulties {
switch difficulty {
case .Easy:
gameDifficultyLabel.text = "Easy"
case .Medium:
gameDifficultyLabel.text = "Medium"
case .Hard:
gameDifficultyLabel.text = "Hard"
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func updateTime() {
let shouldStop = timeManager.updateTime()
timerLabel.text = timeManager.displayedTime(timeManager.time)
if shouldStop {
timer.invalidate()
}
}
func createLabelsBackground() {
for _ in 0..<10 {
if let img = UIImage(named: "noContainer") {
LabelsBackground.append(UIImageView(image: img))
}
}
}
func setUpLabelsBackground() {
for i in 0..<10 {
LabelsBackground[i].frame = numbersContainers[i].frame
LabelsBackground[i].center = numbersContainers[i].center
}
}
func addLabelsBackground() {
for background in LabelsBackground {
self.view.addSubview(background)
}
}
func createLabels() {
for _ in 0..<10 {
Labels.append(UILabel())
}
}
func setUpLabels() {
for i in 0..<10 {
Labels[i].frame = numbersLabel[i].frame
Labels[i].center = numbersLabel[i].center
Labels[i].backgroundColor = UIColor.whiteColor()
Labels[i].userInteractionEnabled = true
}
}
func addLabels() {
for label in Labels {
self.view.addSubview(label)
}
}
func addPanGesture(){
for label in Labels {
label.text = "10"
label.addGestureRecognizer(panGesture)
}
}
func panAction(recognizer: UIPanGestureRecognizer) {
print("panAction")
let translation = recognizer.translationInView(self.view)
if let myView = recognizer.view {
myView.center = CGPoint(x: myView.center.x + translation.x, y: myView.center.y + translation.y)
}
recognizer.setTranslation(CGPointZero, inView: self.view)
}
}
澄清一下
@IBOutlet var numbersLabel:[UILabel]!
var 标签 = UILabel
numbersLabels 是使用故事板添加的空标签,仅在以编程方式创建标签时用于定位。
问题是以编程方式创建并添加到标签数组的标签没有响应。
我认为您启用了自动布局(默认情况下启用)。如果您没有为视图指定任何约束(例如您的标签),Storyboard 将在构建时为您创建它们。您可以通过查看标签的 Size Inspector 设置来验证这一点。
调用 updateTime()
时,自动布局会根据 Storyboard 自动为其创建的约束将您的标签放回其原始位置。
要解决此问题,您可以:
1) 以编程方式创建标签,而不是在 Storyboard 中创建标签。
或
2) 为 Storyboard 中的标签位置添加显式约束,然后为这些约束创建 @IBOutlet
s 并通过更改这些约束的 constant
属性 在代码中移动标签约束而不是改变它的框架(中心)。
我遇到了一个问题 我有一个视图控制器,它包含一个平移手势和一个 NSTimer,它有一个每秒调用的选择器 问题是每次激活计时器时,我都会尝试使用平移手势 return 自动将标签移动到其原始位置。 可能是什么原因?
这是代码
import UIKit
class gameViewController: UIViewController {
@IBOutlet weak var img1: UIImageView!
@IBOutlet weak var lbl1: UILabel!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var gameDifficultyLabel: UILabel!
var timer = NSTimer()
var timeManager = TimerManager()
override func viewDidLoad() {
super.viewDidLoad()
timerLabel.text = "\(timeManager.displayedTime(timeManager.time!))"
// Do any additional setup after loading the view.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let difficulty = timeManager.difficulties {
switch difficulty {
case .Easy:
gameDifficultyLabel.text = "Easy"
case .Medium:
gameDifficultyLabel.text = "Medium"
case .Hard:
gameDifficultyLabel.text = "Hard"
}
}
}
@IBAction func panGesture(sender: UIPanGestureRecognizer) {
let translation = sender.translationInView(self.view)
if let view = sender.view {
view.center = CGPoint(x:view.center.x + translation.x,
y:view.center.y + translation.y)
}
sender.setTranslation(CGPointZero, inView: self.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func updateTime() {
let shouldStop = timeManager.updateTime()
timerLabel.text = timeManager.displayedTime(timeManager.time)
if shouldStop {
timer.invalidate()
}
}
}
更新: 我已经更新了代码。 以编程方式添加标签解决了这个问题,但我有另一个问题 这是代码。
class gameViewController: UIViewController {
@IBOutlet var numbersContainers: [UIImageView]!
@IBOutlet var numbersLabel: [UILabel]!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var gameDifficultyLabel: UILabel!
var LabelsBackground = [UIImageView]()
var Labels = [UILabel]()
var timer = NSTimer()
var timeManager = TimerManager()
var panGesture : UIPanGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
timerLabel.text = "\(timeManager.displayedTime(timeManager.time!))"
self.createLabelsBackground()
self.setUpLabelsBackground()
self.addLabelsBackground()
self.createLabels()
self.setUpLabels()
self.addLabels()
panGesture = UIPanGestureRecognizer(target: self, action: "panAction:")
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
self.addPanGesture()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let difficulty = timeManager.difficulties {
switch difficulty {
case .Easy:
gameDifficultyLabel.text = "Easy"
case .Medium:
gameDifficultyLabel.text = "Medium"
case .Hard:
gameDifficultyLabel.text = "Hard"
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func updateTime() {
let shouldStop = timeManager.updateTime()
timerLabel.text = timeManager.displayedTime(timeManager.time)
if shouldStop {
timer.invalidate()
}
}
func createLabelsBackground() {
for _ in 0..<10 {
if let img = UIImage(named: "noContainer") {
LabelsBackground.append(UIImageView(image: img))
}
}
}
func setUpLabelsBackground() {
for i in 0..<10 {
LabelsBackground[i].frame = numbersContainers[i].frame
LabelsBackground[i].center = numbersContainers[i].center
}
}
func addLabelsBackground() {
for background in LabelsBackground {
self.view.addSubview(background)
}
}
func createLabels() {
for _ in 0..<10 {
Labels.append(UILabel())
}
}
func setUpLabels() {
for i in 0..<10 {
Labels[i].frame = numbersLabel[i].frame
Labels[i].center = numbersLabel[i].center
Labels[i].backgroundColor = UIColor.whiteColor()
Labels[i].userInteractionEnabled = true
}
}
func addLabels() {
for label in Labels {
self.view.addSubview(label)
}
}
func addPanGesture(){
for label in Labels {
label.text = "10"
label.addGestureRecognizer(panGesture)
}
}
func panAction(recognizer: UIPanGestureRecognizer) {
print("panAction")
let translation = recognizer.translationInView(self.view)
if let myView = recognizer.view {
myView.center = CGPoint(x: myView.center.x + translation.x, y: myView.center.y + translation.y)
}
recognizer.setTranslation(CGPointZero, inView: self.view)
}
}
澄清一下 @IBOutlet var numbersLabel:[UILabel]! var 标签 = UILabel
numbersLabels 是使用故事板添加的空标签,仅在以编程方式创建标签时用于定位。
问题是以编程方式创建并添加到标签数组的标签没有响应。
我认为您启用了自动布局(默认情况下启用)。如果您没有为视图指定任何约束(例如您的标签),Storyboard 将在构建时为您创建它们。您可以通过查看标签的 Size Inspector 设置来验证这一点。
调用 updateTime()
时,自动布局会根据 Storyboard 自动为其创建的约束将您的标签放回其原始位置。
要解决此问题,您可以:
1) 以编程方式创建标签,而不是在 Storyboard 中创建标签。
或
2) 为 Storyboard 中的标签位置添加显式约束,然后为这些约束创建 @IBOutlet
s 并通过更改这些约束的 constant
属性 在代码中移动标签约束而不是改变它的框架(中心)。