USTanGesture与NSTimer问题

时间:2016-03-05 14:42:41

标签: ios swift timer gesture

我正面临一个问题 我有一个视图控制器,包含一个Pan手势和一个NSTimer,它有一个每秒调用一次的选择器 问题是每次启动计时器时,我试图使用平移手势移动的标签会自动返回其原点位置。 可能是什么原因?

这是代码

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 Labels = UILabel

numbersLabels是使用storyboard添加的空标签,仅用于在以编程方式创建标签时进行定位。

问题是以编程方式创建并添加到labels数组的标签没有响应。

1 个答案:

答案 0 :(得分:2)

我认为你确实启用了自动布局(默认情况下它已启用)。如果没有为视图指定任何约束(例如标签),则Storyboard将在构建时为您创建它们。您可以通过查看标签的尺寸检查器设置来验证这一点。

调用updateTime()时,自动布局会根据故事板自动为其创建的约束将标签放回原位。

要解决此问题,您可以:

1)以编程方式创建标签,而不是在故事板中创建标签。

OR

2)在Storyboard中为标签位置添加显式约束,然后为这些约束创建@IBOutlet并通过更改这些约束的constant属性而不是更改其框架来在代码中移动标签(中心)。