动画视图跳转到最终位置而不是慢速移动

时间:2017-04-21 12:05:57

标签: ios iphone swift swift2.3

我正在制作包含ImageView和Label的视图动画。 请参见图1.我正在尝试在下面的tableView上滚动时为上层视图设置动画。最终结果应如图2所示。其中imageView的高度和宽度减小,位于左侧角落,最小高度和标签位于imageView前面。动画工作正常,imageView平滑地从原始位置移动到最终位置,Label也是如此。但是,根据动画,upperView不起作用。

我尝试使用upperViews Height Constraint及其框架。

  1. 如果我用它的高度Constraint改变它,它很快就会到达最终位置。

  2. 如果我使用upperView.frame.size.height给出高度,那么视图会上升,但是表视图仍然在他们的位置。

  3. 这是我试过的

    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。

    图1。   enter image description here 图2。 enter image description here

2 个答案:

答案 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?

这不是你想要的,但我希望能帮到你。

enter image description here

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)
}