如何在自定义的ui表格视图单元快速中显示大量标签?

时间:2019-05-20 07:08:17

标签: swift uitableview for-in-loop

I Am displaying data as shown in this image我想显示用作标签的标记或分数。大约100个标签。

我将每个学生的详细信息作为1个单独的数组,例如:

student1 = [
    [test details, test1, test2, test3, test4],
    [subject1,100,98,56,78],
    [subject2,67,78,89,56],
    [subject3,67,56,34,78],
    [subject4,56,46,84,38]]
student2 = [[test details, test1, test2, test3, test4],[subject1,100,98,56,78],[subject2,67,78,89,56],[subject3,67,56,34,78],[subject4,56,46,84,38]]

以此类推。...

我想在UITableViewCell自定义单元格中显示这些详细信息。

我写了StudentCustomCell类,扩展了UITableViewCell

使用循环

  1. 创建滚动视图
  2. 创建分数的背景视图
  3. 根据我的要求创建标记标签

当我执行代码时,所有单元格中仅显示学生1的相同标签/标记。

因为我只在循环中使用学生1计数。

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "SCell", for: indexPath) as! StudentCustomCell

        cell.cricketerName.text = studentDetails[indexPath.row][0]
        cell.studentImage.image = UIImage(named: studentDetails[indexPath.row][0])

    }

    return cricketerCell

}
func scoreScrollView(){

    scView = UIScrollView(frame: CGRect(x: 0, y: 120, width: cricketView.frame.width, height: 220))

    scView.backgroundColor = .white
    self.addSubview(scView)

    var formatView:UIView!

for i in 0..<(student1[0] as AnyObject).count! {

     formatView = UIView()
     xAxis = 10
     formatView.frame = CGRect(x: 0, y: CGFloat(yAxis), width: 640, height: 40)

     if(i % 2 == 0){
     formatView.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.2132919521)
     }else{
     formatView.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.4010595034)
     }

     for j in 0..<student1.count {

     let label = UILabel()
     label.text = "\(student1[j][i])"
     label.frame = CGRect(x: xAxis, y: CGFloat(yAxis)+5, width: 60, height: 30)
     xAxis = xAxis + 65
     scView.addSubview(label)
     }
     yAxis = yAxis + 40
     scView.addSubview(formatView)
     scrolls.append(scView)
     }

     scView.contentSize = CGSize(width: xAxis, height: scView.frame.height)

}

test details     subject1    subject2    subject3   subject4                 

test1              100          67           67         56               

test2               98          78           56         46        

test3               56          89           34         84                 

test4               78          56           78         38                 

Am在表格视图的单元格/行中显示如上所述的结果。

2 个答案:

答案 0 :(得分:1)

对于这种复杂的布局要求,您应该考虑序列化布局逻辑。流行的方法是使用XIB / Storyboards来布局UITableViewCell派生的单元格。

然而,挑战在于如何根据更改的设备尺寸来放置元素。因此,您应该利用iOS的自动版式功能-只需执行一次,以后您将发现包含其他更改会更加容易。

相反-想象一下用代码编写框架设置布局逻辑的恐怖。 2周后,您将无法确定编写该代码的原因。确实存在用于在代码中编写此逻辑的有效情况(加载xib / storyboard的性能原因),但此处没有适用的情况。

为此,请参见thisthis之类的详细讨论。您不会获得直接的代码,但是您肯定会知道如何有效地执行它。

答案 1 :(得分:0)

据我了解,您担心测验分数太多,因而无法显示在屏幕上。

您可以像这样将ScrollView添加到单元格中:

import UIKit

// Instead of having matrices of Student data, it's better to have the logic divided in structs

struct Student {
    let subjects: [Subject]
    let tests: [Test]
}

struct Subject {
    let name: String
}

struct Test {
    let scores: [Int]
    let number: String
}

class ViewController: UIViewController {

    let tableView = UITableView()

    let student = Utils.makeMockStudent()

    override func viewDidLoad() {
        super.viewDidLoad()
        configureTableView()
    }

    private func configureTableView() {
        tableView.dataSource = self
        tableView.delegate = self
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(StudentTableViewCell.self, forCellReuseIdentifier: "studentCell")

        view.addSubview(tableView)
        Utils.constraintViewToSuperview(subview: tableView, superview: view)
    }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard !student.subjects.isEmpty else {
            return 0
        }
        // The +1 is because of the "Details" and "Test N" Cell at the beginning of every row.
        return student.tests.count + 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "studentCell") as! StudentTableViewCell
        if indexPath.row == 0 {
            cell.configure(with: student.subjects)
        } else {
            cell.configure(with: student.tests[indexPath.row - 1])
        }
        return cell
    }
}

class StudentTableViewCell: UITableViewCell {

    override var reuseIdentifier: String? {
        return "studentCell"
    }

    func configure(with subjects: [Subject]) {
        configure(firstLabelText: "Details", labels: subjects.map { Utils.makeLabel(text: $0.name) })
    }

    func configure(with test: Test) {
        let labels = test.scores.map { Utils.makeLabel(text: "\($0)", font: .monospacedDigitSystemFont(ofSize: 14, weight: .regular)) }
        configure(firstLabelText: "Test \(test.number)", labels: labels)
    }

    private func configure(firstLabelText: String, labels: [UILabel]) {
        let scrollView = UIScrollView()
        let stackView = Utils.makeStackView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false

        stackView.addArrangedSubview(Utils.makeLabel(text: firstLabelText))
        labels.forEach { stackView.addArrangedSubview($0) }

        contentView.addSubview(scrollView)
        scrollView.addSubview(stackView)

        Utils.constraintViewToSuperview(subview: stackView, superview: scrollView)
        Utils.constraintViewToSuperview(subview: scrollView, superview: contentView)
    }

}

class Utils {

    // MARK: - Factory Methods

    static func makeMockStudent() -> Student {
        return Student(
            subjects: [
                Subject(name: "Math"),
                Subject(name: "Biology"),
                Subject(name: "English"),
                Subject(name: "Math2"),
                Subject(name: "Biology2"),
                Subject(name: "English2"),
                Subject(name: "Math3"),
                Subject(name: "Biology3"),
                Subject(name: "English3"),
                Subject(name: "Math4"),
                Subject(name: "Biology4"),
                Subject(name: "English4")],

            tests: [
                Test(scores: [10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30], number: "1"),
                Test(scores: [10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30], number: "2"),
                Test(scores: [10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30], number: "3")
        ])
    }

    static func makeLabel(text: String, font: UIFont = .boldSystemFont(ofSize: 16)) -> UILabel {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = text
        label.font = font

        NSLayoutConstraint.activate([label.widthAnchor.constraint(equalToConstant: 100)])
        return label
    }

    static func makeStackView() -> UIStackView {
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.spacing = 5
        stackView.distribution = .fillEqually
        stackView.alignment = .fill

        return stackView
    }

    // MARK: - Autolayout Methods

    static func constraintViewToSuperview(subview: UIView, superview: UIView) {
        NSLayoutConstraint.activate(
            [subview.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
             subview.trailingAnchor.constraint(equalTo: superview.trailingAnchor),
             subview.topAnchor.constraint(equalTo: superview.topAnchor),
             subview.bottomAnchor.constraint(equalTo: superview.bottomAnchor)])
    }
}

Here,您可以看到使用该单元格的工作代码。我假设每个主题都进行相同数量的测试,但是如果没有测试,可以很容易地将其留空。