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

时间:2017-08-14 16:39:00

标签: ios swift uistackview

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

更多信息:

  1. 数据是动态的。可能还有其他日子,每天可能包含多组时间。
  2. 当然需要自动布局以获得我单元格的动态/响应高度。
  3. 我已经做了什么:

    1. 我确实尝试过使用IB。
    2. 我也是以编程方式尝试过的。
    3. 在IB和编程方面,我都使用了UIStackView。但有点难以设置它。
    4. 我正在考虑使用UIViews作为容器进行设置,就像UIStackView一样,但不那么复杂。
    5. 我要逐行设置。首先是垂直排列时间,然后将视图或堆栈视图与日期水平配对。在那之后,与其他日子一样。

      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
      }
      

      问题是:对于破坏约束的大量警告,我确实知道如何设置和修复约束。但是当我修复它时,没有任何东西在显示。我觉得我在浪费时间推动并努力继续这种方法。所以如果我提出建议,我认为这将是我的很多?

2 个答案:

答案 0 :(得分:2)

有多种方法可以解决您的问题。我会尝试给你一个方法。

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

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

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

然后,在cellForRowAt方法上,您可以使用时间将标签附加到垂直堆栈视图。每个单元格的高度都是正确的,因为它来自约束。

答案 1 :(得分:1)

实际上,我认为堆栈视图是一个非常好的方法。它们是关于按行和列排列的东西,这正是你想要做的。在Interface Builder中单独使用堆栈视图,我可以毫不费力地模仿您的规范:

enter image description here

关于堆栈视图的令人愉快的事情是,一旦它们被正确配置,它们就会在添加或删除排列的子视图时适应。所以他们的动态完全符合你的愿望。