iOS中SnapKit动画的实现

在做项目的过程中突然遇到要在keywindow上添加一个全屏View来实现一个ViewController从底部present出来的一个效果,当然只是把View添加到keywindow上很简单,但我现在布局用的是自动布局,这个动画就不好实现了。

我突然想到了用SnapKit这个自动布局库来实现一下试试,经历了好几个版本的实验都以失败而告终,不是没有动画就是动画效果不对,总结了一下失败的原因主要有两个,如下:
- 使用动画的方法不对,代码如下

UIView.animate(withDuration: 0.5, animations: { [weak self] in
            self.mRootView.snp.updateConstraints {[weak self] (make) in
            guard let aSelf = self else { return }
            make.bottom.equalTo(aSelf).offset(0)
        }
        }) { (complete) in
        }

只是简单调用了一下在UIView的Animation的block里边,这样完全没有效果的。

  • 布局的初始化做的不到位
    只进行了初始化,让整个View移动到底部不可见,代码如下
 mRootView.snp.updateConstraints {[weak self] (make) in
            let height = UIScreen.main.bounds.size.height
            make.height.equalTo(height)
            guard let aSelf = self else { return }
            make.bottom.equalTo(aSelf.snp.bottom).offset(height)
        }

这样做完全不够,我们需要对UI强制刷新,应该调用

self.layoutIfNeeded() //对View的初始化进行强制刷新

然而上边第一个问题,我们用下面代码来解决

        self.mRootView.snp.updateConstraints {[weak self] (make) in
            guard let aSelf = self else { return }
            make.bottom.equalTo(aSelf).offset(0)
        }

        UIView.animate(withDuration: 0.5, animations: { [weak self] in
            self?.layoutIfNeeded()
        }) { (complete) in
        }

这种写法就是把动画SnapKit操作View的代码放到UIView的Animation Block外部,然后强制刷新UI的代码放到UIView的动画block内部这样动画效果就出来了,完整的代码如下:

    func show()
    {
        UIApplication.shared.keyWindow?.addSubview(self)
        mRootView.snp.updateConstraints {[weak self] (make) in
            let height = UIScreen.main.bounds.size.height
            make.height.equalTo(height)
            guard let aSelf = self else { return }
            make.bottom.equalTo(aSelf.snp.bottom).offset(height)
        }
        self.layoutIfNeeded()

        self.mRootView.snp.updateConstraints {[weak self] (make) in
            guard let aSelf = self else { return }
            make.bottom.equalTo(aSelf).offset(0)
        }

        UIView.animate(withDuration: 0.5, animations: { [weak self] in
            self?.layoutIfNeeded()
        }) { (complete) in
        }
    }

注意在xib里边做View(动画容器)的约束的时候一定要定义正确了,做底部向上滑动的动画需要只定义左右距离父View的间距,底部距父View的间距,还有动画容器的高度,千万不能做顶部对父容器的间距。只要遵循我给出方式动画就能完美出来了,其他方向动画同理,希望这篇文档对你帮助!

1
说点什么

avatar
1 Comment threads
0 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
星辰皓月 Recent comment authors
  Subscribe  
最新 最旧 得票最多
提醒