简体   繁体   English

UITableViewCell对齐列以适合内容

[英]UITableViewCell aligning columns to fit content

I am creating an UITableView using auto layout and prototype cells. 我正在使用自动布局和原型单元创建一个UITableView。 I would like it to act more like a web HTML table. 我希望它更像一个Web HTML表。 Each cell has four "columns", each with one label in it, see here . 每个单元格有四个“列”,每个列中都有一个标签, 请参见此处 Ultimately, each column should adjust its width to the widest column of all the other rows. 最终,每列应调整其宽度到所有其他行的最宽列。 This seems like a common case but I am unable to find any info about it. 这似乎是一个常见的情况,但我无法找到任何有关它的信息。 Am I missing something obvious here? 我错过了一些明显的东西吗?

What result I have right now: 我现在有什么结果:

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

What I would like: 我想要的是什么:

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

I hope this makes any sense, otherwise let me know. 我希望这有任何意义,否则请告诉我。 Thanks! 谢谢!

You can build a "grid" of labels using embedded UIStackView s 您可以使用嵌入式UIStackView构建标签的“网格”

Use an "outer" horizontal stack view to hold 4 "inner" stack views, which are used as the 4 "columns". 使用“外部”水平堆栈视图来保存4个“内部”堆栈视图,这些视图用作4“列”。

Embed the outer stack view in a UIScrollView in case the content exceeds the available area. 如果内容超出可用区域,则将外部堆栈视图嵌入UIScrollView中。

The result looks like this: 结果如下:

在此输入图像描述

The first two "column" stack views have .alignment = .leading and the 3rd and 4th have .alignment = .trailing . 前两个“列”堆栈视图有.alignment = .leading ,第三个和第四个有.alignment = .trailing As you can see, each "column" stack view stretches its width to fit the widest label. 如您所见,每个“列”堆栈视图都会拉伸其宽度以适合最宽的标签。

Here is some code to produce that example: 以下是生成该示例的一些代码:

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),
            ])

    }

}

Creating 2 dimensional tables was always PiTA on iOS. 在iOS上创建二维表总是PiTA。 I would strongly recommend you find already existing solution and save a lot time for yourself. 我强烈建议您找到现有的解决方案并为自己节省大量时间。
Unless you doing it for yourself (aka learning), in this case you need to: 除非你自己做(也就是学习), 否则你需要:

  1. Precalculate cell sizes somewhere in background and use it everywhere 在背景中的某处预先计算单元格大小,并在任何地方使用它
  2. Or add width constraint (greater or equal) on first cell in row. 或者在行中的第一个单元格上添加宽度约束(大于或等于)。 Let UIKit handle layout for you. 让UIKit为您处理布局。 Each time UIKit update width of cell, check that it same big as constraint, if it bigger you need to update constrain of all rows with new biggest width. 每次UIKit更新单元格的宽度时,检查它是否与约束相同,如果它更大,则需要更新具有新的最大宽度的所有行的约束。

1st approach is cleanest and probably only right solution, but if your app can exchange little of performances for development time, you can try second approach. 第一种方法是最干净的,可能只是正确的解决方案,但如果您的应用程序可以在开发时间内交换很少的性能,您可以尝试第二种方法。

EDIT: I just checked your image. 编辑:我刚检查了你的图像。 Why do you ever need 2d table here? 为什么你在这里需要2d表?

All you need is: 所有你需要的是:
|-amount-name-iDunnoWhatIsIt-price-|

Where: 哪里:
name label aligned left name标签左对齐
iDunnoWhatIsIt label aligned right iDunnoWhatIsIt标签对齐
price and amount has fixed width priceamount有固定的宽度

Now you need to decide what is more important name or iDunnoWhatIsIt . 现在你需要决定什么是更重要的nameiDunnoWhatIsIt And based on it update their compression resistance , so important one will be not trimmed (I assume it will be iDunnoWhatIsIt ) 并且基于它更新它们的compression resistance ,所以重要的一个将不会被修剪(我假设它将是iDunnoWhatIsIt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM