我正在制作包含ImageView和Label的视图动画。 请参见图1.我正在尝试在下面的tableView上滚动时为上层视图设置动画。最终结果应如图2所示。其中imageView的高度和宽度减小,位于左侧角落,最小高度和标签位于imageView前面。动画工作正常,imageView平滑地从原始位置移动到最终位置,Label也是如此。但是,根据动画,upperView不起作用。
我尝试使用upperViews Height Constraint及其框架。
如果我用它的高度Constraint改变它,它很快就会到达最终位置。
如果我使用upperView.frame.size.height给出高度,那么视图会上升,但是表视图仍然在他们的位置。
这是我试过的
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y > 0
{
UIView.animateWithDuration(1.5, delay: 0.0, options: .CurveEaseOut, animations:
{
self.imageView.frame = CGRect(x: 5.0, y: 0.0, width: 30, height: 40)
}, completion: { finished in
UIView.animateWithDuration(1.5, delay: 1.0, options: UIViewAnimationOptions.AllowUserInteraction,animations: {
self.selectedProgramNameLabel.center = CGPoint(x: self.selectedProgramNameLabel.center.x, y: self.imageView.center.y)
}, completion: { finished in
UIView.animateWithDuration(1.5, delay: 2.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: {
self.upperViewHeightConstraint.constant = 50
}, completion: { finished in
})
})
})
}
else if scrollView.contentOffset.y == 0
{
UIView.animateWithDuration(1.5, delay: 0.0, options: .CurveEaseOut, animations:
{
self.selectedProgramNameLabel.center = CGPoint(x: self.selectedProgramNameLabel.center.x, y: self.imageView.center.y + self.imageView.frame.height - 45)
}, completion: { finished in
UIView.animateWithDuration(1.5, delay: 0.0, options: UIViewAnimationOptions.AllowUserInteraction,animations: {
self.imageView.frame = CGRect(x: self.upperView.frame.origin.x, y: self.upperView.frame.origin.y, width: 100.0, height: 134)
}, completion: { finished in
UIView.animateWithDuration(1.5, delay: 1.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: {
}, completion: { finished in
})
})
})
}
TIA。
答案 0 :(得分:0)
在设置任何布局约束的动画时,如果您想要所需的动画效果,必须在动画块中使用layoutIfNeeded
。所以只需在动画块中添加这个。
self.view.layoutIfNeeded()
self.upperViewHeightConstraint.constant = 50
还可以使用任何标志来检查视图是否已设置动画,否则您的动画块将执行多次。
答案 1 :(得分:0)
尝试使用:UIViewAnimationOptions.beginFromCurrentState,CABasicAnimation。 How to animate the frame of an layer with CABasicAnimation?
这不是你想要的,但我希望能帮到你。
var cntTopViewT: NSLayoutConstraint!
var cntTopViewH: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
let scrollView = UIScrollView()
scrollView.delegate = self
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
let topView = UIView()
topView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(topView)
let topViewBackgroundImageView = UIImageView()
topViewBackgroundImageView.translatesAutoresizingMaskIntoConstraints = false
topView.addSubview(topViewBackgroundImageView)
let bottomView = UIView()
bottomView.translatesAutoresizingMaskIntoConstraints = false
scrollView.insertSubview(bottomView, at: 0)
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
bottomView.addSubview(v)
let views: [String: Any] = ["view": view,
"scrollView": scrollView,
"topView": topView,
"topViewBackgroundImageView": topViewBackgroundImageView,
"bottomView": bottomView,
"v": v]
var cnts: [NSLayoutConstraint] = []
cnts += NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "H:[topView(scrollView)]", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:[scrollView]-0@1-[topView]", options: [.alignAllCenterX], metrics: nil, views: views)
cntTopViewT = NSLayoutConstraint(item: topView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1, constant: 0)
cntTopViewH = NSLayoutConstraint(item: topView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
cnts += [cntTopViewT, cntTopViewH]
cnts += NSLayoutConstraint.constraints(withVisualFormat: "H:|[topViewBackgroundImageView]|", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:|[topViewBackgroundImageView]|", options: [], metrics: nil, views: views)
cnts += [NSLayoutConstraint(item: bottomView, attribute: .width, relatedBy: .equal, toItem: scrollView, attribute: .width, multiplier: 0.9, constant: 0)]
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:[scrollView]-0@1-[bottomView]|", options: [.alignAllCenterX], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:|[bottomView(999)]|", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "H:|[v(50)]", options: [], metrics: nil, views: views)
cnts += NSLayoutConstraint.constraints(withVisualFormat: "V:|[v(50)]", options: [], metrics: nil, views: views)
NSLayoutConstraint.activate(cnts)
topView.backgroundColor = .red
bottomView.backgroundColor = .green
v.backgroundColor = .blue
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let minH = (navigationController?.navigationBar.frame.height ?? 0) + UIApplication.shared.statusBarFrame.height
let maxH = view.frame.height * 0.35
cntTopViewT.constant = scrollView.contentOffset.y
cntTopViewH.constant = max(-scrollView.contentOffset.y, minH)
scrollView.contentInset.top = maxH
scrollView.scrollIndicatorInsets.top = (cntTopViewH.constant - minH) + (minH * ((cntTopViewH.constant - minH) / (maxH - minH))) + 5
//let kTransform = min(max(cntTopViewH.constant / maxH + 0.1, 0.5), 1)
//topViewFioLabel.transform = CGAffineTransform(a: kTransform, b: 0, c: 0, d: kTransform, tx: 0, ty: 0)
}