一、IB 约束
- 绑定约束 在 viewController 中定义
@IBOutlet weak var menuHeightConstraint: NSLayoutConstraint!复制代码
在 Interface Builder 中创建绑定。
找到对应的 Constraint ,并将其绑定到 IBOutlet 。操作如下所示:
绑定后,就可以使用进行约束控制了:
isMenuOpen = !isMenuOpenmenuHeightConstraint.constant = isMenuOpen ? 200.0 : 60.0titleLabel.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() }, completion: nil )复制代码
- 遍历约束并打印到控制台:
titleLabel.superview?.constraints.forEach { constraint in print(" -> \(constraint.description)\n") }复制代码
- NSLayoutConstraint 属性作用是这样的:
- 可以通过给约束添加 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() }) }}复制代码
效果如下:
附: