Swift - tableviewcell 中的动态按钮数

Posted

技术标签:

【中文标题】Swift - tableviewcell 中的动态按钮数【英文标题】:Swift - Dynamic number of buttons in tableviewcell 【发布时间】:2018-02-16 17:02:24 【问题描述】:

实际上我在github 有一个项目。问题是我不明白为什么在滚动时,单元格中的按钮约束变得疯狂.. 我没有看到任何这样的项目,那么我有理由分享它,但我想为其他人提供一个很好的例子。 我将非常感谢任何驱使我解决此问题的帮助。 最好的祝福。 这是单元格的代码:

import UIKit

class BookTableViewCell: UITableViewCell 

let nameLabel = UILabel()
let detailLabel = UILabel()

var cellButton = UIButton()
var cellLabel = UILabel()
var book : Book!

// MARK: Initalizers
override init(style: UITableViewCellStyle, reuseIdentifier: String?) 
    super.init(style: style, reuseIdentifier: reuseIdentifier)


func configureCellCon(botones:Int, titulo:String, book:Book) 
    self.book = book
    let marginGuide = contentView.layoutMarginsGuide
    // configure titleLabel
    contentView.addSubview(nameLabel)
    nameLabel.translatesAutoresizingMaskIntoConstraints = false
    nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
    nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
    nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
    nameLabel.numberOfLines = 0
    nameLabel.font = UIFont(name: "AvenirNext-DemiBold", size: 16)
    nameLabel.text = book.name

    // configure authorLabel
    contentView.addSubview(detailLabel)
    detailLabel.translatesAutoresizingMaskIntoConstraints = false
    detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
    //        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
    detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
    detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor).isActive = true
    detailLabel.numberOfLines = 0
    detailLabel.font = UIFont(name: "Avenir-Book", size: 12)
    detailLabel.textColor = UIColor.lightGray
    detailLabel.text = book.details

    var lastButton = UIButton()
    if(book.buttonsAttibutes.count == 1) 
        let button = UIButton()
        button.tag = 0
        button.backgroundColor = UIColor.init(white: 0.9, alpha: 0.0)
        //            button.setBackgroundColor(color: UIColor.white, forState: .normal)
        //            button.setBackgroundColor(color: UIColor.blue, forState: .normal)
        button.setTitle(book.buttonsAttibutes[0].title, for: .normal)
        button.setTitleColor(UIColor.blue.withAlphaComponent(0.7), for: .normal)
        button.setTitleColor(UIColor.init(white: 0.8, alpha: 1), for: .highlighted)
        button.layer.borderWidth = 0
        button.layer.borderColor = UIColor.blue.cgColor
        contentView.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        contentView.addConstraints([
            NSLayoutConstraint(item: button, attribute: .leftMargin, relatedBy: .equal, toItem: contentView, attribute: .leftMargin, multiplier: 1.0, constant: 20),
            NSLayoutConstraint(item: button, attribute: .rightMargin, relatedBy: .equal, toItem: contentView, attribute: .rightMargin, multiplier: 1.0, constant: -20),
            ])
        button.topAnchor.constraint(equalTo: detailLabel.bottomAnchor).isActive = true
        button.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        button.addTarget(self, action:#selector(mostrarMensaje), for:.touchUpInside)
        return
    else if(book.buttonsAttibutes.count == 0) 
        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        return
    

    if(book.buttonsAttibutes.count > 0) 
        for x in 0...(book.buttonsAttibutes.count - 1) 
            let button = UIButton()
            button.tag = x
            button.backgroundColor = UIColor.init(white: 0.9, alpha: 0.0)
            //            button.setBackgroundColor(color: UIColor.white, forState: .normal)
            //            button.setBackgroundColor(color: UIColor.blue, forState: .normal)
            button.setTitle(book.buttonsAttibutes[x].title, for: .normal)
            button.setTitleColor(UIColor.blue.withAlphaComponent(0.7), for: .normal)
            button.setTitleColor(UIColor.init(white: 0.8, alpha: 1), for: .highlighted)
            button.layer.borderWidth = 0
            button.layer.borderColor = UIColor.blue.cgColor
            contentView.addSubview(button)
            button.translatesAutoresizingMaskIntoConstraints = false
            //            button.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
            //            button.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true

            contentView.addConstraints([
                NSLayoutConstraint(item: button, attribute: .leftMargin, relatedBy: .equal, toItem: contentView, attribute: .leftMargin, multiplier: 1.0, constant: 20),
                NSLayoutConstraint(item: button, attribute: .rightMargin, relatedBy: .equal, toItem: contentView, attribute: .rightMargin, multiplier: 1.0, constant: -20),
                ])

            if(x == 0)
                if #available(ios 11.0, *) 
                    button.layer.cornerRadius = 8
                    button.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
                 else 
                    button.layer.cornerRadius = 5
                
                button.topAnchor.constraint(equalTo: detailLabel.bottomAnchor).isActive = true
            else if(x == (book.buttonsAttibutes.count - 1))
                if #available(iOS 11.0, *) 
                    button.layer.cornerRadius = 8
                    button.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
                 else 
                    button.layer.cornerRadius = 5
                
                button.topAnchor.constraint(equalTo: lastButton.bottomAnchor).isActive = true
                button.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
            else
                button.topAnchor.constraint(equalTo: lastButton.bottomAnchor).isActive = true
            

            button.addTarget(self, action:#selector(mostrarMensaje), for:.touchUpInside)
            lastButton = button
        
    



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


@objc func mostrarMensaje(sender: UIButton)

    let message = self.book.buttonsAttibutes[sender.tag].message
    let alertController = UIAlertController(title: "\(self.book.name)", message: message, preferredStyle: UIAlertControllerStyle.alert)
    let okAction = UIAlertAction(title: "Cerrar", style: UIAlertActionStyle.default) 
        (result : UIAlertAction) -> Void in
    

    alertController.addAction(okAction)
    if let myViewController = parentViewController 
        print(myViewController.title ?? "ViewController without title.")
        myViewController.present(alertController, animated: true, completion: nil)
    
 

【问题讨论】:

有关完整代码示例,您可以在 GitHub 上查找该项目。 故事板?你可以试试吗? 我看不出它不应该发疯的原因。您几乎没有“共享”按钮和标签,可以同时添加到不同的单元格(平均视图),并为每个单元格添加约束。所以这些视图将在显示的最后一个单元格中解决。但是对每个细胞都有限制。然后,您为每个单元格创建特定视图并为它们添加约束。但是由于表格视图倾向于重用现有单元格,因此每次删除现有单元格时都会添加新视图。还有新的约束。 PS:好的,不共享,我以为你发布了视图控制器,因为通常控制器负责配置单元格。但是无论如何,您都会遇到很多相互矛盾的疯狂约束。尝试使用 InterfaceBuilder,它很有用的工具 :) 和 StackViews。 “发疯”是什么意思? 【参考方案1】:

好的,我选择了“InterfaceBuilder”并且做得很好。 但是,我将阅读更多有关编程方法的信息。 感谢大家的指导。

以编程方式创建按钮和约束时,它们会在相同单元格上生成更多约束,从而导致它们崩溃。

【讨论】:

以上是关于Swift - tableviewcell 中的动态按钮数的主要内容,如果未能解决你的问题,请参考以下文章

马尔可夫决策过程中的动规

微信中的动图如果发朋友圈

Apple官网的动效

Apple官网的动效

Apple官网的动效

java继承涉及的动/静态绑定及隐藏