ios - UILabels 两列多行 iOS 的复杂动态集合

标签 ios swift uistackview

我一直在思考如何在我的 tableViewCell 中设置这种布局。见照片:

更多信息:

  1. 数据是动态的。可能还有其他日子,每一天可能包含多组时间。
  2. 我的单元格的动态/响应高度当然需要自动布局。

我已经做了:

  1. 我确实尝试过使用 IB 来做到这一点。
  2. 我也以编程方式尝试过。
  3. 无论是在 IB 中还是以编程方式,我都使用了 UIStackView。但是有点难设置。
  4. 我正在考虑使用 UIViews 作为容器来设置它,就像 UIStackView 一样,但不那么复杂。

我正在逐行设置它。首先是垂直排列时间,然后将其 View 或堆栈 View 与日期水平配对。之后,对其他日子做同样的事情。

enter image description here

为了问题的正式性,这是我单元格中用于设置此布局的部分代码,我建议不要费力阅读它,我相信我知道我在做什么,我想我只需要你们的另一种方法。

var job: Job! {
    didSet {

        _ = self.subviews.map {
            if $0 is UIStackView {
                $0.removeFromSuperview()
            }
        }

        GPLog(classSender: self, log: "🎉Setting up stackview for JobShift")

        // Add the main vertical stackView

        let stackView_Vertical = UIStackView(frame: .zero)
        stackView_Vertical.translatesAutoresizingMaskIntoConstraints = false
        stackView_Vertical.alignment = .fill
        stackView_Vertical.distribution = .fillProportionally
        stackView_Vertical.axis = .vertical
        stackView_Vertical.spacing = 16.0
        self.addSubview(stackView_Vertical)

        // Add constraints

        stackView_Vertical.topAnchor.constraint(equalTo: self.topAnchor, constant: 15.0).isActive = true
        stackView_Vertical.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -15.0).isActive = true
        stackView_Vertical.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15.0).isActive = true
        stackView_Vertical.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -15.0).isActive = true

        if let dummyJson = self.readJson() {
            if let shiftsJsonArray = dummyJson.array {
                for shiftJson in shiftsJsonArray {

                    let newShift = DummyDataShift(json: shiftJson)

                    if let day = newShift.day,
                        let schedules = newShift.schedule {
                        let generatedStackView = self.generateDayScheduleStackView(day: day, schedules: schedules)
                        stackView_Vertical.addArrangedSubview(generatedStackView)
                    }
                }
            }
        }
    }
}

// MARK: - Functions

// Generate the full schedule stack view.
func generateDayScheduleStackView(day: String, schedules: [DummyDataSchedule]) -> UIStackView {

    // label day (e.g. MONDAY)
    let newLabel_Day = self.shiftLabel
    newLabel_Day.translatesAutoresizingMaskIntoConstraints = false
    newLabel_Day.text = day
    newLabel_Day.backgroundColor = .red
    newLabel_Day.heightAnchor.constraint(equalToConstant: 30.0).isActive = true

    // Prepare the vertical schedule stackView
    let stackView_Schedule = UIStackView(frame: .zero)
    stackView_Schedule.alignment = .fill
    stackView_Schedule.distribution = .fillEqually
    stackView_Schedule.axis = .vertical

    // Add the schedules to the stackView vertically
    for schedule in schedules {
        let newLabel_Time = self.shiftLabel
        newLabel_Time.text = "\(schedule.timeIn!) - \(schedule.timeOut!)"
        newLabel_Time.backgroundColor = self.getRandomColor()
        newLabel_Time.translatesAutoresizingMaskIntoConstraints = false
        newLabel_Time.heightAnchor.constraint(equalToConstant: 30.0).isActive = true

        stackView_Schedule.addArrangedSubview(newLabel_Time)
    }

    // Prepare the horizontal dayScheduleStackView
    let stackView_DaySchedule = UIStackView(frame: .zero)
    stackView_DaySchedule.alignment = .fill
    stackView_DaySchedule.distribution = .fillProportionally
    stackView_DaySchedule.axis = .horizontal

    // Add arranged subViews
    stackView_DaySchedule.addArrangedSubview(newLabel_Day)
    stackView_DaySchedule.addArrangedSubview(stackView_DaySchedule)


    return stackView_DaySchedule
}

问题是:很多关于破坏约束的警告,我知道如何设置和修复约束。但是当我修复它时,没有任何显示。我觉得我在浪费时间插入并努力继续这种方法。所以我认为如果我征求建议,我会很高兴吗?

最佳答案

有多种方法可以解决您的问题。我将尝试为您提供一种方法。

1) 使用 TableView,每个部分单元格都包含“星期几”标签以及用于时间标签的垂直 StackView(使用等间距)。

2) 如果你正确地设置了你的约束,你可以在 sizeForRow: delegate 上返回 UITableViewAutomaticDimension。

override func tableView(_ tableView: UITableView, heightForRowAt 
    indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

然后,在 cellForRowAt 方法中,您可以将标签附加到带有时间的垂直堆栈 View 。每个单元格的高度都是正确的,因为它来自约束条件。

关于ios - UILabels 两列多行 iOS 的复杂动态集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45679120/

相关文章:

ios - UIStackView宽度为 "wrap content"

ios - 具有执行功能和 UI 更新的重复动画

swift - 使用未解析的标识符 : kCGWindowImageDefault (and other Core Graphics constants)

ios - iMessage 扩展和 CoreData

swift - 如何根据用户输入更改其物理世界引力后重新加载场景?

ios - tableView 单元格内的 PickerView

ios - Swift 3 - 以编程方式构建带有图像和标签的按钮

swift - 从 UIStackView 中拖动和删除 UIView 但将其保留在其放置目的地

ios - Objective-C 对象文字的隐式 bool 转换总是计算为真 ios

ios - 设置 NSUserDefault 崩溃