在Swift中更新视图

时间:2015-03-10 15:49:26

标签: ios swift uiview

我正在创建一个应用程序,我通过从阵列中读取CGPoint并相应地设置图像的中心,以编程方式在屏幕上移动图像。最简单的形式就是这样:

for point in array {
     image.center = point
     sleep(1)
}

按下按钮后会发生这种情况,因此for循环位于按钮的@IBAction func ...内。

问题是在image.center更改后屏幕没有更新,但只有在整个for循环完成后才会更新,因此当图像位于数组的最后一个点时。如何强制视图更新?或者一般来说处理这个问题的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

我会使用关键帧动画。 让我们假设这是你的观点:

let val: [CGPoint] = [CGPoint(x:10, y:20), CGPoint(x:100, y:80), CGPoint(x:200, y:80), CGPoint(x:200, y:400), CGPoint(x:30, y:400), CGPoint(x:30, y:100)]

按下按钮后,您可以调用动画:

       let duration = NSTimeInterval(2)

        UIView.animateKeyframesWithDuration(duration, delay: 0.0, options: nil, animations: {

            self.myView.center = CGPoint(x: 10, y: 20)

            for (index, point) in enumerate(self.val) {
                UIView.addKeyframeWithRelativeStartTime(Double(index) *  1.0 / Double(self.val.count), relativeDuration: 1.0 / Double(self.val.count), animations: {
                    self.myView.center = point
                })
            }
        }, completion: nil)

当然,您可以自定义动画持续时间,延迟等。 请记住

UIView.addKeyframeWithRelativeStartTime relativeDuration...

有相对值,所以例如持续时间应该在0-1之间,其中1是你在

中指定的总持续时间
UIView.animateKeyframesWithDuration...

答案 1 :(得分:0)

删除@matt建议的睡眠,并尝试在图像的父视图而不是睡眠中调用方法layoutifneeded。视图需要重新绘制,所以我认为这可以成为诀窍......

答案 2 :(得分:0)

另一种方法是使用animateWithDuration:delay:options:animations:completion:并使用delay参数为您提供移动之间的延迟。以下代码立即开始第一个移动,然后在一秒之后开始每个后续移动。

class ViewController: UIViewController {

    var block = UIView()
    var pointArray = [CGPoint(x: 30, y: 30), CGPoint(x: 100, y: 30), CGPoint(x: 50, y: 300), CGPoint(x: 300, y: 170)]
    var counter = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        block.frame = CGRect(origin: CGPointZero, size: CGSize(width: 50, height: 50))
        block.center = pointArray[0]
        block.backgroundColor = UIColor.redColor()
        view.addSubview(block)
        moveView()
    }

    func moveView() {
        var delay = counter == 1 ? Double(0) : Double(1)
        UIView.animateWithDuration(0.3, delay: delay, options: .CurveLinear, animations: { () -> Void in
            self.block.center = self.pointArray[self.counter]
        }) { (finished) -> Void in
            self.counter++
            if self.counter < self.pointArray.count {
                self.moveView()
            }
        }
    }
}