UITableViewCell对齐列以适合内容

时间:2019-03-22 14:16:27

标签: ios swift uitableview interface-builder

我正在使用自动布局和原型单元创建UITableView。我希望它的行为更像一个Web HTML表。每个单元格都有四个“列”,每个列中都有一个标签, see here。最终,每列应将其宽度调整为所有其他行的最宽列。这似乎很普通,但是我找不到任何有关它的信息。我在这里想念一些明显的东西吗?

我现在有什么结果:

1|product name|11 xx|22 yy
1|longer product name|11 xxx|22 yy
1|short|1x|22 yy

我想要什么:

1|product name       |11 xx |22 yy
1|longer product name|11 xxx|22 yy
1|short              |1x    |22 yy

我希望这有任何意义,否则请告诉我。谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用嵌入的UIStackView s建立一个“网格”标签

使用“外部”水平堆栈视图保存4个“内部”堆栈视图,这些视图用作4个“列”。

将外部堆栈视图嵌入UIScrollView中,以防内容超出可用区域。

结果如下:

enter image description here

前两个“列”堆栈视图具有.alignment = .leading,第3和第4个堆栈视图具有.alignment = .trailing。如您所见,每个“列”堆栈视图都会扩展其宽度以适合最宽的标签。

以下是产生该示例的代码:

class StackGridViewController: UIViewController {

    var myData = [[String]]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // init 30 rows of data
        for i in 1...30 {
            myData.append(["\(i)", "Product Name", "12 xx", "34 xx"])
        }

        // make a few of the rows different
        for i in [2, 15, 21] {

            // longer "column B"
            myData[i][1] = "Longer Product Name"

            // longer "column C"
            myData[i+2][2] = "1234 xx"

            // longer "column D"
            myData[i+4][3] = "3456 xx"

        }

        // and one row with the longest values
        // longest "column B"
        myData[9][1] = "The Longest Product Name"

        // longest "column C"
        myData[9][2] = "123456 xx"

        // longest "column D"
        myData[9][3] = "345678 xx"


        // create a horizontal stack view
        let outerSV = UIStackView()
        outerSV.translatesAutoresizingMaskIntoConstraints = false
        outerSV.axis = .horizontal
        outerSV.distribution = .fill

        // "column" spacing
        outerSV.spacing = 12

        // add 4 "column" vertical stack views
        for col in 0..<4 {
            let columnSV = UIStackView()
            columnSV.translatesAutoresizingMaskIntoConstraints = false
            columnSV.axis = .vertical

            // align leading for first two columns, trailing for 3rd and 4th
            columnSV.alignment = col < 2 ? .leading : .trailing

            columnSV.distribution = .fill

            // "row" spacing
            columnSV.spacing = 8

            // add a label for each data "row"
            for row in 0..<myData.count {
                let v = UILabel()
                v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
                v.font = UIFont.systemFont(ofSize: 13.0, weight: .light)
                v.text = myData[row][col]
                columnSV.addArrangedSubview(v)
            }

            // add the "column" stack view to the outer stack view
            outerSV.addArrangedSubview(columnSV)
        }

        // create a scroll view
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(scrollView)

        // constrain it to all four sides with 20-pt padding on top/bottom, 8-pt padding leading/trailing
        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20.0),
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8.0),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8.0),
            ])

        // add the outer stack view to the scroll view
        scrollView.addSubview(outerSV)

        // constrain it to all four sides (which will also define .contentSize (the "scrollable area")
        NSLayoutConstraint.activate([
            outerSV.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0.0),
            outerSV.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0.0),
            outerSV.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0.0),
            outerSV.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0.0),
            ])

    }

}

答案 1 :(得分:0)

创建二维表始终是iOS上的PiTA。我强烈建议您找到已经存在的解决方案,并为自己节省很多时间。
除非,您需要自己做(也可以学习),在这种情况下,您需要:

  1. 在后台某处预先计算单元大小,并在各处使用
  2. 或在行的第一个单元格上添加宽度约束(大于或等于)。让UIKit为您处理布局。每次UIKit更新单元格的宽度时,请检查其是否与约束相同,如果更大,则需要更新具有新的最大宽度的所有行的约束。

第一种方法是最简洁的解决方案,可能仅是正确的解决方案,但是如果您的应用程序在开发时间上几乎不能交换性能,则可以尝试第二种方法。

编辑:我刚刚检查了您的图像。为什么这里需要2D表格?

您需要的是:
|-amount-name-iDunnoWhatIsIt-price-|

位置:
name标签向左对齐
iDunnoWhatIsIt标签右对齐
priceamount具有固定宽度

现在,您需要确定更重要的nameiDunnoWhatIsIt。并根据它更新其compression resistance,因此重要的将不会被修剪(我假设它将是iDunnoWhatIsIt