美文网首页iOS Developer适配
iOS 动画六:Animating Constraints

iOS 动画六:Animating Constraints

作者: _浅墨_ | 来源:发表于2018-06-28 23:41 被阅读171次
一、IB 约束
  1. 绑定约束
    在 viewController 中定义
@IBOutlet weak var menuHeightConstraint: NSLayoutConstraint!

在 Interface Builder 中创建绑定。

找到对应的 Constraint ,并将其绑定到 IBOutlet 。操作如下所示:

绑定后,就可以使用进行约束控制了:

isMenuOpen = !isMenuOpen
menuHeightConstraint.constant = isMenuOpen ? 200.0 : 60.0
titleLabel.text = isMenuOpen ? "Select Item" : "Packing List"

  1. 添加动画效果,表现更好:
UIView.animate(withDuration: 1.0, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 10.0, 
options: .curveEaseIn, animations: { 
     self.view.layoutIfNeeded() 
}, completion: nil )

  1. 遍历约束并打印到控制台:
titleLabel.superview?.constraints.forEach { constraint in 
     print(" -> \(constraint.description)\n") 
}
  1. NSLayoutConstraint 属性作用是这样的:
  1. 可以通过给约束添加 id , 进行特定控制。


if constraint.identifier == "TitleCenterY" {   
   constraint.isActive = false //add new constraint    
   return 
}

constraint.isActive = false 可以禁止该约束,约束效果失效。

二、代码控制 constraints
let newConstraint = NSLayoutConstraint( 
  item: titleLabel, 
  attribute: .centerY, 
  relatedBy: .equal, 
  toItem: titleLabel.superview!, 
  attribute: .centerY, 
  multiplier: isMenuOpen ? 0.67 : 1.0, 
  constant: 5.0) 
newConstraint.identifier = "TitleCenterY" 
newConstraint.isActive = true
三、本 demo 主要代码是这样的
@IBAction func actionToggleMenu(_ sender: AnyObject) {
    
    titleLabel.superview?.constraints.forEach { constraint in print(" -> \(constraint.description)\n")
    }
    
    isMenuOpen = !isMenuOpen
    titleLabel.superview?.constraints.forEach { constraint in
        if constraint.firstItem === titleLabel && constraint.firstAttribute == .centerX {
          constraint.constant = isMenuOpen ? -100.0 : 0.0
          return
        }
        if constraint.identifier == "TitleCenterY" {
            constraint.isActive = false //add new constraint return
            
            let newConstraint = NSLayoutConstraint(
                item: titleLabel,
                attribute: .centerY,
                relatedBy: .equal,
                toItem: titleLabel.superview!,
                attribute: .centerY,
                multiplier: isMenuOpen ? 0.67 : 1.0,
                constant: 5.0)
            newConstraint.identifier = "TitleCenterY"
            newConstraint.isActive = true
        }
    }
    
    menuHeightConstraint.constant = isMenuOpen ? 200.0 : 60.0
    titleLabel.text = isMenuOpen ? "Select Item" : "Packing List"
    
    UIView.animate(withDuration: 1.0, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 10.0, options: .curveEaseIn, animations: {
        self.view.layoutIfNeeded()
        let angle: CGFloat = self.isMenuOpen ? .pi / 4 : 0.0
        self.buttonMenu.transform = CGAffineTransform(rotationAngle: angle)
    }, completion: nil )
    
    if isMenuOpen {
        slider = HorizontalItemList(inView: view)
        slider.didSelectItem = {index in
        print("add \(index)")
        self.items.append(index)
        self.tableView.reloadData()
        self.actionToggleMenu(self) }
        self.titleLabel.superview!.addSubview(slider)
    } else {
        slider.removeFromSuperview()
    }
  }
  
  func showItem(_ index: Int) {
    print("tapped item \(index)")
    
    let imageView = UIImageView(image: UIImage(named: "summericons_100px_0\(index).png"))
    imageView.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
    imageView.layer.cornerRadius = 5.0
    imageView.layer.masksToBounds = true
    imageView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(imageView)
    
    let conX = imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    let conBottom = imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: imageView.frame.height)
    let conWidth = imageView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.33, constant: -50.0)
    let conHeight = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor)
    
    NSLayoutConstraint.activate([conX, conBottom, conWidth, conHeight])
    
    view.layoutIfNeeded()
    
    UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.0, animations: {
        conBottom.constant = -imageView.frame.size.height/2
        conWidth.constant = 0.0
        self.view.layoutIfNeeded()
    }, completion: nil )
    
    UIView.animate(withDuration: 0.8, delay: 1.0, usingSpringWithDamping: 0.4,initialSpringVelocity: 0.0,animations: {
        conBottom.constant = imageView.frame.size.height
        conWidth.constant = -50.0
        self.view.layoutIfNeeded()
    }, completion: { _ in
        imageView.removeFromSuperview()
    })
  }
}

效果如下:

附:demo下载地址

相关文章

网友评论

  • 笨鸟后飞了:最好能有OC版本的demo,不能把OC给抛弃了啊
    _浅墨_:@东海岸边 最近在学Swift,:smile:

本文标题:iOS 动画六:Animating Constraints

本文链接:https://www.haomeiwen.com/subject/odabyftx.html