swift UIButton的UIStack根据标题动态调整大小/高度

h5qlskok  于 2023-04-10  发布在  Swift
关注(0)|答案(1)|浏览(141)

我有UITableview自定义单元格。在每个单元格的一边,我有一个垂直的UIButtons的UIStack视图。每个堆栈的按钮数量因单元格而异。
作为单元格代码的一部分,我创建了一个UIButtons数组,每个UIButtons都有不同的标题,然后通过addArrangedSubview()将它们添加到UIStack。UIButtons仅在代码中创建,而UIStack是在脚本上创建的,代码中有一些覆盖。
一切都很好。
但是,如果标题在按钮上大于1行,UIButton不会调整大小以适应。在图像上,注意意识旁边的第二个按钮上的重叠文本。

代码(全部在UITableview cellatrow函数中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: FormVerticalCell.reuseIdentifier, for: indexPath) as? FormVerticalCell else {
            fatalError("Unexpected Index Path")
        }

        for arrangedSubview in cell.buttonStack.arrangedSubviews {
            cell.buttonStack.removeArrangedSubview(arrangedSubview)
        }
        
        let tempOptions = formArray[indexPath.row][1]
        let optionsArray = tempOptions.components(separatedBy: ",")
        
        var btnArray = [UIButton]()
        for i in 0..<optionsArray.count {

            let button = UIButton()
            button.changesSelectionAsPrimaryAction = true
        
            button.setTitle(optionsArray[i], for: .normal)
            button.titleLabel?.numberOfLines = 0
            button.titleLabel?.lineBreakMode = .byWordWrapping
            button.titleLabel?.textAlignment = .left
            button.setTitleColor(.black, for: .normal)
            button.setTitleColor(.white, for: .selected)
            button.setTitleColor(.white, for: .highlighted)
            
            button.tag = i
            button.setBackgroundColor(UIColor(red:0.9, green:0.9, blue:0.9, alpha:1.0), forState: .normal)
            button.setBackgroundColor(UIColor(red:0.8, green:0.6, blue:0.0, alpha:1.0), forState: .highlighted)
            button.setBackgroundColor(UIColor(red:0.8, green:0.6, blue:0.0, alpha:1.0), forState: .selected)

            btnArray.append(button)
           
            let tempOptionsScores = formArray[indexPath.row][2]
 
            
            button.addAction { [self] in
                    
                    let optionsScoresArray = tempOptionsScores.components(separatedBy: ",")
                    let tempScore = optionsScoresArray[button.tag]
                    scoreArray[indexPath.row] = Int(tempScore)!
                    updateScore()
                    
                    for i in 0..<btnArray.count
                        {
                            if (i != button.tag) {
                            btnArray[i].isSelected = false
                        }
                        
                    }
                }
            }

        for i in 0..<btnArray.count {
            cell.buttonStack.addArrangedSubview(btnArray[i])
            }
   
        cell.buttonStack.axis = .vertical
        cell.buttonStack.alignment = .fill
        cell.buttonStack.distribution = .fillProportionally
        cell.buttonStack.spacing = 2.0
        cell.buttonStack.translatesAutoresizingMaskIntoConstraints = false

        cell.label.text = formArray[indexPath.row][0]
        
        // WHY NOT BLACK!!!
        cell.label.textColor = .black

        return cell
    }

已经看了几个问题-没有最新的答案,我可以找到。任何建议的步骤,我需要采取:
1.动态增加UIButton的高度以完全容纳标题。
1.理想情况下,在标题周围添加一点填充,这样文本就不会紧靠边缘。

33qvvth1

33qvvth11#

如果您不想使用自动处理多行标题的较新样式的按钮,可以使用像这样的子类按钮:

class MultilineTitleButton: UIButton {
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    func commonInit() -> Void {
        self.titleLabel?.numberOfLines = 0
        self.titleLabel?.textAlignment = .center
    }
    
    override var intrinsicContentSize: CGSize {
        let size = self.titleLabel!.intrinsicContentSize
        return CGSize(width: size.width + contentEdgeInsets.left + contentEdgeInsets.right, height: size.height + contentEdgeInsets.top + contentEdgeInsets.bottom)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        titleLabel?.preferredMaxLayoutWidth = self.titleLabel!.frame.size.width
    }
    
}

一个示例视图控制器,在垂直堆栈视图中添加4个按钮,宽度为200点:

class MultilineButtonVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 8
        // do NOT use .fillEqually
        stackView.distribution = .fill
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            stackView.widthAnchor.constraint(equalToConstant: 200.0),
        ])
        
        let titles: [String] = [
            "Short.",
            "A little longer.",
            "This title is long enough to wrap onto multiple lines.",
            "A fourth button in the stackView.",
        ]
        
        titles.forEach { str in
            let b = MultilineTitleButton()
            b.setTitle(str, for: [])
            b.setTitleColor(.black, for: .normal)
            b.setTitleColor(.lightGray, for: .highlighted)
            b.backgroundColor = .yellow
            b.contentEdgeInsets = .init(top: 6.0, left: 8.0, bottom: 6.0, right: 8.0)
            stackView.addArrangedSubview(b)
        }
        
    }
    
}

看起来像这样:

相关问题