设定constraint后执行layoutIfNeeded()

这里写图片描述

通过设置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)

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值