动画约束更改UIViewController

时间:2019-05-27 08:25:57

标签: ios swift autolayout

我有“错误”视图,该视图位于导航栏上方并隐藏。发生错误时,我希望该视图从顶部平滑显示。我尝试过:

class AuthViewController: UIViewController {

  let error: ErrorView = {
    let error = ErrorView()
    error.setup()
    return error
  }()
  var topAnchor: NSLayoutConstraint!
  var botAnchor: NSLayoutConstraint!

  override func viewDidLoad() {
    setupErrorView()
  }

  private func setupErrorView(){
    view.addSubview(error)
    botAnchor = error.bottomAnchor.constraint(equalTo: view.topAnchor)
    botAnchor.isActive = true
    topAnchor = error.topAnchor.constraint(equalTo: view.topAnchor, constant: CGFloat(Offsets.navigationAndStatusBarHeight))
    topAnchor.isActive = false
    error.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    error.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
  }

  func showError(_ text: String){
    UIView.animate(withDuration: 2.0) {[weak self] in
      guard let weakSelf = self else { return }
      print("attempt to animate")
      weakSelf.error.show(text)
      weakSelf.botAnchor.isActive = false
      weakSelf.topAnchor.isActive = true
      weakSelf.view.setNeedsLayout()
    }
  }
}

class ErrorView: UIView {

  private var label: UILabel = {
    return LabelSL.regular()
  }()

  fileprivate func setup(){
    translatesAutoresizingMaskIntoConstraints = false
    backgroundColor = Theme.Color.orange.value
    addSubview(label)
  }

  fileprivate func show(_ text: String){
    let sideOffset: CGFloat = 10
    let verticalOffset: CGFloat = 10
    label.text = text
    label.topAnchor.constraint(equalTo: topAnchor, constant: verticalOffset).isActive = true
    label.leftAnchor.constraint(equalTo: leftAnchor, constant: sideOffset).isActive = true
    label.rightAnchor.constraint(equalTo: rightAnchor, constant: -sideOffset).isActive = true
    label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -verticalOffset).isActive = true
  }
}

应该在调用func showError(_ text: String){方法时进行动画处理,但不是。视图只是立即出现。

1 个答案:

答案 0 :(得分:1)

您正在尝试以错误的方式设置约束的动画。您应该在动画块之外设置约束,并且在动画中仅设置layoutIfNeeded

func showError(_ text: String){
    botAnchor.isActive = false
    topAnchor.isActive = true
    error.show(text)
    UIView.animate(withDuration: 2.0) {
        self.view.layoutIfNeeded()
    }
}