使用动画更改CAShapeLayer的位置

时间:2017-06-19 17:33:08

标签: ios swift uiviewanimation cashapelayer

我在viewcontroller中居中UITextField。我在文本字段下面使用CAShapeLayer,文字在文本字段中输入时宽度增加。用户按下回车键后,隐藏在视图底部的UITableView会向上滑动。我可以通过更改约束来使tableview和textfield上滑。

func moveUp(){

    searchBarTopConstraint.constant = 0
    tableViewTopConstraint.constant = 0

    UIView.animate(withDuration: 2.0) {

        self.view.layoutSubviews()

    }
}

但是,我无法弄清楚如何让CAShapeLayer与文本字段一起向上滑动。我尝试创建一个移动线并将其放入带有完成处理程序的UIView动画的函数,但该线将在动画之后或之前向上移动。

    UIView.animate(withDuration: 2.00, delay: 0.0, options: [], animations: {

        self.view.layoutSubviews()
        self.moveLine()

    }, completion: { (finished: Bool) in

//            self.moveLine()

    })

该行的y位置由textfields位置决定(这是moveLine()的简洁版本):

    let y = searchField.frame.origin.y + searchField.frame.size.height + 6
    linePath.move(to: CGPoint(x:x1, y:y))
    linePath.addLine(to: CGPoint(x:x2, y:y))

1 个答案:

答案 0 :(得分:1)

有两个问题:

  1. 如果通过约束移动视图,则在动画块中调用layoutIfNeeded(),而不是layoutSubviews()

    正如layoutSubviews() documentation所说:

      

    您不应该直接调用此方法。如果要强制进行布局更新,请在下次绘图更新之前调用setNeedsLayout()方法。如果您想立即更新视图的布局,请调用layoutIfNeeded()方法。

    在您的情况下,请将layoutIfNeeded()放入animate封闭内,而不是layoutSubviews()

  2. 请注意,当您正确执行此操作时,会移动您拥有CAShapeLayer的视图,而不会移动CAShapeLayer本身。因此,如果您有要移动的形状图层,则可以将该形状图层放在带有约束的视图中,然后使用上述layoutIfNeeded()调用移动视图。

    从理论上讲,您实际上可以使用CAShapeLayer为视图中CABasicAnimation的移动设置动画:

    let position = CGPoint(...)                          // the new origin of the CAShapeLayer within its view
    
    let animation = CABasicAnimation(keyPath: "position")
    animation.fromValue = shapeLayer.position            // animate from current position ...
    animation.toValue = position                         // ... to whereever the new position is
    animation.duration = 2
    shapeLayer.position = position                       // set the shape's final position to be the new position so when the animation is done, it's at its new "home"
    shapeLayer.add(animation, forKey: nil)               // animate from `fromValue` to `toValue`
    

    就我个人而言,我认为在视图中移动形状图层有点混乱,我更喜欢将形状图层放在自己的视图中,在视图层次结构中添加具有相关约束的视图,然后设置动画该观点的约束。它使得使用Xcode视图调试器调试视图变得更加容易,恕我直言。