带有 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 中的标签位置添加显式约束,然后为这些约束创建 @IBOutlets 并通过更改这些约束的 constant 属性 在代码中移动标签约束而不是改变它的框架(中心)。