通过设置constraint后,在这种情况下,你已经更新了约束值,但iOS 一直没有机会真正更新布局,调用layoutIfNeeded()方法,让这个view参与到布局中
import UIKit
class IconListView: UIScrollView {
var didSelectItemBlock:((_ index:Int) -> ())?
let buttonWidth:CGFloat = 60.0
let padding:CGFloat = 10.0
var imgsArray = ["icon1","icon2","icon3","icon4","icon5","icon1","icon2"]
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func didTapImage(_ gesture:UITapGestureRecognizer){
didSelectItemBlock?(((gesture.view!.tag)))
}
convenience init(inView:UIView) {
let rect = CGRect(x: inView.bounds.width, y: 120, width: inView.frame.width, height: 80.0)
self.init(frame: rect)
self.alpha = 0.0
for i in 0 ..< imgsArray.count {
let image = UIImage(named: imgsArray[i])
let imageView = UIImageView(image: image)
imageView.center = CGPoint(x: (CGFloat(i) + 1/2) * buttonWidth, y: buttonWidth/2)
imageView.tag = i
imageView.isUserInteractionEnabled = true
addSubview(imageView)
let tap = UITapGestureRecognizer(target: self, action: #selector(IconListView.didTapImage(_:)))
imageView.addGestureRecognizer(tap)
}
contentSize = CGSize(width: CGFloat(imgsArray.count) * buttonWidth, height: buttonWidth + 2 * padding)
}
// 视图移动完成后调用
override func didMoveToSuperview() {
super.didMoveToSuperview()
UIView.animate(withDuration: 1.0, delay: 0.01, usingSpringWithDamping: 0.5, initialSpringVelocity: 10.0, options: .curveEaseIn, animations: {
self.alpha = 1.0
self.center.x -= self.frame.size.width
}, completion: nil)
}
}
执行addSubview(iconList)时,会调用iconList中的didMoveToSuperView方法
import UIKit
class LayoutViewController: UIViewController {
@IBOutlet weak var menuHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var btnMenu: UIButton!
@IBOutlet weak var tableView: UITableView!
var isMenuOpen = false
var iconList:IconListView!
var imageView:UIImageView!
var tb = ["icon1","icon2","icon3","icon5"]
var wz = ["图标一","图标二","图标三","图标四"]
var imgs = ["icon1","icon2","icon3","icon4","icon5","icon6","icon7"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.tableFooterView = UIView()
}
@IBAction func toggleMenu(_ sender: UIButton) {
isMenuOpen = !isMenuOpen
/*
(lldb) po sender.superview?.constraints
▿ Optional<Array<NSLayoutConstraint>>
▿ some : 5 elements
- 0 : <NSLayoutConstraint:0x60400028da20 UIView:0x7fe06bc1d3d0.height == 60 (active)>
- 1 : <NSLayoutConstraint:0x60400028d480 UILabel:0x7fe06bc0c800'测试列表'.centerX == UIView:0x7fe06bc1d3d0.centerX (active)>
- 2 : <NSLayoutConstraint:0x60400009bc60 UILabel:0x7fe06bc0c800'测试列表'.centerY == UIView:0x7fe06bc1d3d0.centerY (active)>
- 3 : <NSLayoutConstraint:0x60400028bb80 UIButton:0x7fe06bd1b4a0'+'.centerY == UILabel:0x7fe06bc0c800'测试列表'.centerY (active)>
- 4 : <NSLayoutConstraint:0x60400028cdf0 H:[UIButton:0x7fe06bd1b4a0'+']-(15)-| (active, names: '|':UIView:0x7fe06bc1d3d0 )>
*/
for constraint in titleLabel.superview!.constraints {
print("aaaaa")
// if constraint.firstItem as? NSObject == titleLabel && constraint.firstAttribute == .centerX {
// constraint.constant = isMenuOpen ? 100.0 : 0.0
// continue
// }
if constraint.secondItem as? NSObject == titleLabel &&
constraint.secondAttribute == .centerX {
constraint.constant = isMenuOpen ? 100.0 : 0.0
continue
}
if constraint.firstItem as? NSObject == titleLabel && constraint.firstAttribute == .centerY {
titleLabel.superview?.removeConstraint(constraint)
// 添加新的约束
let newConstraint = NSLayoutConstraint(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: titleLabel.superview, attribute: .centerY, multiplier:isMenuOpen ? 0.5 : 1 , constant: 5)
newConstraint.isActive = true
continue
}
if constraint.firstItem as? NSObject == btnMenu && constraint.firstAttribute == .centerY {
btnMenu.superview?.removeConstraint(constraint)
// 添加新的约束
let newConstraint = NSLayoutConstraint(item: btnMenu, attribute: .centerY, relatedBy: .equal, toItem: btnMenu.superview, attribute: .centerY, multiplier: isMenuOpen ? 0.5:1, constant: 5)
newConstraint.isActive = true
continue
}
}
menuHeightConstraint.constant = isMenuOpen ? 200.0 : 60
titleLabel.text = isMenuOpen ? "选择元素" : "测试列表"
let angel = isMenuOpen ? CGFloat(Double.pi/4) : 0.0
self.btnMenu.transform = CGAffineTransform(rotationAngle: angel)
// 在这种情况下,你已经更新了约束值,但iOS 一直没有机会真正更新布局,调用layoutIfNeeded()方法,让这个view参与到布局中
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 8.0, options: .curveEaseIn, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
if isMenuOpen {
iconList = IconListView(inView: view)
iconList.didSelectItemBlock = { index in
print("add \(index)")
self.wz.append("图标\(4+index)")
self.tb.append(self.imgs[index])
self.tableView.reloadData()
}
print(iconList)
// 执行addSubview(iconList)时,会调用iconList中的didMoveToSuperView方法
self.titleLabel.superview?.addSubview(iconList)
}else{
iconList.removeFromSuperview()
}
}
}
extension LayoutViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wz.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = wz[indexPath.row]
cell.imageView?.image = UIImage(named: tb[indexPath.row])
return cell
}
}
let storyboard = UIStoryboard(name: "Layout", bundle: nil)
let layoutVC = storyboard.instantiateViewController(withIdentifier: "LayoutViewController") as! LayoutViewController
self.present(layoutVC, animated: true, completion: nil)