如何以编程方式正确自动布局自定义tableviewcell的子视图[iOS9]

时间:2016-01-15 10:31:33

标签: ios swift uitableview autolayout

我创建了自己的UITableViewCell子类。有几个子视图(2x imageview,2x UILabel)。我以编程方式做了所有事情也限制了但是在某些单元格上,autolayout没有正确计算,我不知道为什么。这里是我提到的问题screenshot

感谢您的任何建议。

这是我的手机来源

//menu list cell
class TableMenuViewCell:  UITableViewCell{

    var stripe:UIView?
    var separatorTop:UIView?
    var separatorBottom:UIView?
    var imageBox:UIView?
    var img:UIImageView?
    var dateBox:UIImageView?
    var date:UILabel?
    var label:UILabel?
    var desc:UILabel?
    var foreground:UIView?
    var multiplier:CGFloat = 1
    var didSetupConstraints:Bool = false

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.backgroundColor = Constants.grayColor

        if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
            multiplier = 1.3
        }

        //stripe
        stripe = UIView()
        stripe!.backgroundColor = Constants.light2GrayColor
        stripe!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(stripe!)

        //image box
        imageBox = UIView()
        imageBox!.backgroundColor = UIColor.clearColor()
        imageBox!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imageBox!)

        //image view
        img = UIImageView()
        img!.backgroundColor = UIColor.clearColor()
        img!.contentMode = UIViewContentMode.ScaleAspectFill
        img!.clipsToBounds = true;
        img!.translatesAutoresizingMaskIntoConstraints  = false
        imageBox!.addSubview(img!)

        //constraints
        imageBox!.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[img]-0-|", options: [], metrics: nil, views: ["img" : img! ]))
        imageBox!.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[img]-0-|", options: [], metrics: nil, views: ["img" : img! ]))

        //label
        label = UILabel()
        label!.numberOfLines = 0
        label!.backgroundColor = UIColor.clearColor()
        label!.textColor = UIColor.whiteColor()
        label!.textAlignment = NSTextAlignment.Left
        label!.font = UIFont(name: Constants.FONT_MEDIUM, size: Constants.MENU_LABEL_FONT_SIZE * multiplier)
        label!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(label!)
        label!.sizeToFit()

        //desc
        desc = UILabel()
        desc!.numberOfLines = 0
        desc!.backgroundColor = UIColor.clearColor()
        desc!.textColor = Constants.turquoiseColor
        desc!.textAlignment = NSTextAlignment.Left
        desc!.font = UIFont(name: Constants.FONT_THIN, size: Constants.MENU_DESC_FONT_SIZE * multiplier)
        desc!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(desc!)
        desc!.sizeToFit()

        //separator top
        separatorTop = UIView()
        separatorTop!.backgroundColor = Constants.lightGrayColor
        separatorTop!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(separatorTop!)

        //separator bottom
        separatorBottom = UIView()
        separatorBottom!.backgroundColor = Constants.lightGrayColor
        separatorBottom!.translatesAutoresizingMaskIntoConstraints = false
        addSubview(separatorBottom!)

        //foreground
        foreground = UIView()
        foreground!.backgroundColor = Constants.light2GrayHoverColor
        foreground!.alpha = 0.5
        foreground!.opaque = false

        self.selectedBackgroundView = foreground!

    }

    //set layout
    func setLayout(rowIndex : Int){

        if didSetupConstraints{
            return
        }
        else{
            didSetupConstraints = true
        }


        let views:[String:AnyObject] = ["stripe" : stripe!, "imageBox" : imageBox!, "label" : label!, "desc" : desc!, "separatorTop" : separatorTop!, "separatorBottom" : separatorBottom!]

        let metrics:[String:AnyObject] = ["hMargin" : Constants.HORIZONTAL_MARGIN, "vMargin" : Constants.VERTICAL_MARGIN, "stripeWidth" : Constants.STRIPE_WIDTH, "separatorHeight" : Constants.SEPARATOR_HEIGHT]

        var constraintsArr:[NSLayoutConstraint] = []

        //horizontal constraints
        constraintsArr.appendContentsOf( NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[separatorTop]-0-|", options: [], metrics: metrics, views: views) )

        constraintsArr.appendContentsOf( NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[separatorBottom]-0-|", options: [], metrics: metrics, views: views) )

        constraintsArr.appendContentsOf( NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[stripe(==stripeWidth)]-(hMargin)-[imageBox]-(hMargin)-[label]-0-|", options: [], metrics: metrics, views: views) )

        constraintsArr.appendContentsOf( NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[stripe(==stripeWidth)]-(hMargin)-[imageBox]-(hMargin)-[desc]-0-|", options: [], metrics: metrics, views: views) )

        constraintsArr.append(NSLayoutConstraint(item: imageBox!, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.height - 4*Constants.VERTICAL_MARGIN))

        //vertical constraints
        constraintsArr.append(NSLayoutConstraint(item: stripe!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.height))

        constraintsArr.append(NSLayoutConstraint(item: stripe!, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: separatorTop!, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0))

        constraintsArr.append(NSLayoutConstraint(item: stripe!, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: separatorBottom!, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0))

        constraintsArr.append(NSLayoutConstraint(item: imageBox!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))

        constraintsArr.append(NSLayoutConstraint(item: imageBox!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.height - 4*Constants.VERTICAL_MARGIN))

        if desc!.text!.isEmpty {

            constraintsArr.append(NSLayoutConstraint(item: label!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))

        }else{

            constraintsArr.append(NSLayoutConstraint(item: label!, attribute: NSLayoutAttribute.CenterYWithinMargins, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterYWithinMargins, multiplier: 1, constant: -label!.bounds.height*0.5))

            constraintsArr.append(NSLayoutConstraint(item: desc!, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: label!, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: Constants.VERTICAL_MARGIN + Constants.VERTICAL_MARGIN * multiplier ))

        }

        constraintsArr.append(NSLayoutConstraint(item: separatorTop!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: rowIndex != 0 ? 0 : Constants.SEPARATOR_HEIGHT))

        constraintsArr.append(NSLayoutConstraint(item: separatorBottom!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: Constants.SEPARATOR_HEIGHT))


        self.addConstraints(constraintsArr)
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        imageView!.image = nil
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

表视图控制器的来源

    import UIKit

class MenuViewController: UITableViewController {

    var cellHeight:CGFloat = 50

    override func viewDidLoad() {
        super.viewDidLoad()

        initTableView()

    }

    override func viewDidAppear(animated: Bool) {
        super.viewWillAppear(animated)

        tableView.reloadData()
    }

    func initTableView(){

        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        tableView.backgroundColor = Constants.grayColor
        tableView.delegate = self
        tableView.dataSource = self
        tableView.estimatedRowHeight = cellHeight
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.registerClass(TableMenuViewCell.self, forCellReuseIdentifier: NSStringFromClass(TableMenuViewCell))

    }

    override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0.001
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
            return cellHeight * 1.2
        }
        return cellHeight
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 16
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier( NSStringFromClass(TableMenuViewCell), forIndexPath: indexPath) as! TableMenuViewCell


        //stripe
        cell.stripe!.backgroundColor = Constants.turquoiseColor

        //image
        cell.img!.image = UIImage(named: "placeholder")
        cell.img!.sizeToFit()

        //image box
        cell.imageBox!.sizeToFit()

        //label
        cell.label!.text = "Main Label"
        cell.label!.sizeToFit()

        //desc
        cell.desc!.text = "Description Text"
        cell.desc!.sizeToFit()

        cell.setLayout(indexPath.row)
        cell.setNeedsLayout()
        cell.layoutIfNeeded()

        return cell
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

0 个答案:

没有答案