我的应用程序是在商店中显示员工时间表。
我的设计是,左侧有一个表格视图,每个单元格中都有员工姓名,右侧有一个带有存储操作时间的标题,而下方则是一个从员工的开始时间到结束时间的彩色条时间。
表格的右侧必须水平滚动到,以便用户可以滚动并查看一天中任何时间的时间表。我通过将times标头和右侧表放入scrollview中来实现这种效果。
在heightForRowAt函数中,
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if tableView.accessibilityIdentifier == "SecondaryTable" {
var height = tblView.rowHeight
if let nameCell = tblView.cellForRow(at: indexPath) {
height = nameCell.frame.height
} else {
height = tblView.rowHeight
}
return height
}
else {
return UITableView.automaticDimension
}
}
其中名称表返回UITableView.automaticDimension
,小时表(可访问性标识符“ SecondaryTable”)应返回名称表上相应单元格的高度,以确保它们正确对齐。
问题是由于名称表尚未加载相应的单元格而正在为调度表调用heightForRowAt
,因此它返回了不正确的高度tblView.rowHeight
。您可以在上图的倒数第二行中看到它。我通过检查计划表正在加载哪个indexPath以及该索引不在名称表的可见单元格列表中来验证了这一点。
现在仅在viewWillAppear
中重新加载这些表:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
self.tblView.reloadData()
self.secondTblView.reloadData()
}
}
这仅在最初加载时影响表中的最后一行,但是当名称表确实加载到单元格中时,该行与计划不一致。看起来此方法稍后会自行纠正,但不会重新加载该单元格,因为该单元格中的信息不会更改以填充该单元格,但下一个单元格将从正确的位置开始,并且分隔线正确对齐。
如果有帮助,这是我的cellForRow:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "scheduleCell") as? ScheduleCell ?? ScheduleCell()
let cellSchedule = schedule[indexPath.row]
if tableView.accessibilityIdentifier == "SecondaryTable" {
let coloredLabel = UILabel()
coloredLabel.text = " " + cellSchedule.role
coloredLabel.backgroundColor = UIColor.green.darker(by: 35)
coloredLabel.textColor = UIColor.white
timesHeader.layoutSubviews()
var drawStartOnHalfHour = false
var drawEndOnHalfHour = false
var clockFormat = ClockFormat.TwentyFourHour
for hour in self.timesHeader.arrangedSubviews{
let lineLayer = CAShapeLayer()
let x = hour.center.x
switch indexPath.row % 2 {
case 0:
lineLayer.strokeColor = UIColor.lightGray.cgColor
break
default:
lineLayer.strokeColor = UIColor.white.cgColor
break
}
lineLayer.lineWidth = 2
let path = CGMutablePath()
if let header = hour as? UILabel, header.text != nil {
lineLayer.lineDashPattern = [1,5]
path.addLines(between: [CGPoint(x: x, y: 5),
CGPoint(x: x, y: cell.contentView.frame.maxY - 5)])
} else {
path.addLines(between: [CGPoint(x: x, y: cell.contentView.frame.maxY/2 - 2),
CGPoint(x: x, y: cell.contentView.frame.maxY/2 + 2)])
}
lineLayer.path = path
DispatchQueue.main.async {
cell.contentView.layer.addSublayer(lineLayer)
}
if let header = hour as? UILabel {
if header.text != nil {
var afterNoon = false
//On the hour logic
var formatCheck = ""
if header.text!.split(separator: ":").count == 1 {
clockFormat = .TwelveHour
formatCheck = String(describing: header.text!.split(separator: " ")[1] )
}
var headerTime = 0
if clockFormat == .TwentyFourHour {
headerTime = Int(String(describing: header.text!.split(separator: ":")[0])) ?? 0
} else {
headerTime = Int(String(describing: header.text!.split(separator: " ")[0])) ?? 0
}
var UTCCalendar = Calendar.current
UTCCalendar.timeZone = TimeZone(abbreviation: "UTC")!
var t = UTCCalendar.component(.hour, from: cellSchedule.StartTime)
if clockFormat == .TwelveHour && t >= 12{
if t > 12 {
t = t-12
}
afterNoon = true
}
if headerTime == t {
let m = UTCCalendar.component(.minute, from: cellSchedule.StartTime)
if clockFormat == .TwentyFourHour || ((afterNoon && formatCheck.contains("p")) || (!afterNoon && formatCheck.contains("a"))) {
if m == 0 {
//Logic for start times on the hour
coloredLabel.frame = CGRect(x: x, y: cell.contentView.frame.maxY/4,
width: 5, height: cell.contentView.frame.maxY/2)
} else {
//Logic for handling start times on half-hour
drawStartOnHalfHour = true
}
}
}
var e = UTCCalendar.component(.hour, from: cellSchedule.EndTime)
if clockFormat == .TwelveHour && e >= 12{
if e > 12 {
e = e - 12
}
afterNoon = true
}
if headerTime == e {
let m = UTCCalendar.component(.minute, from: cellSchedule.EndTime)
if clockFormat == .TwentyFourHour || ((afterNoon && formatCheck.contains("p")) || (!afterNoon && formatCheck.contains("a"))) {
if m == 0 {
//Logic for end time on the hour
let width = x - coloredLabel.frame.minX
coloredLabel.frame = CGRect(x: coloredLabel.frame.minX,
y: coloredLabel.frame.minY,
width: width, height: coloredLabel.frame.height)
} else {
//Logic for end time on the half-hour
drawEndOnHalfHour = true
}
}
}
} else {
//Half-hour logic
if drawStartOnHalfHour {
drawStartOnHalfHour = false
coloredLabel.frame = CGRect(x: x, y: cell.contentView.frame.maxY/4,
width: 5, height: cell.contentView.frame.maxY/2)
} else if drawEndOnHalfHour {
drawEndOnHalfHour = false
let width = x - coloredLabel.frame.minX
coloredLabel.frame = CGRect(x: coloredLabel.frame.minX,
y: coloredLabel.frame.minY,
width: width, height: coloredLabel.frame.height)
}
}
}
}
DispatchQueue.main.async {
cell.contentView.addSubview(coloredLabel)
}
switch indexPath.row % 2 {
case 0:
let backGround = CALayer()
backGround.frame = cell.contentView.frame
backGround.backgroundColor = UIColor.white.cgColor
cell.contentView.layer.addSublayer(backGround)
break
default:
let backGround = CALayer()
backGround.frame = CGRect(x: 0,
y: 0,
width: self.timesHeader.frame.width,
height: cell.contentView.frame.height)
backGround.backgroundColor = UIColor.lightGray.cgColor
cell.contentView.layer.addSublayer(backGround)
break
}
} else {
cell.textLabel?.numberOfLines = 2
let firstName = String(describing: cellSchedule.FirstName!.prefix(35))
let lastName = String(describing: cellSchedule.LastName!.prefix(35))
cell.textLabel?.text = firstName.trimmingCharacters(in: CharacterSet(charactersIn: " ")) + "\n" + lastName.trimmingCharacters(in: CharacterSet(charactersIn: " "))
cell.textLabel?.sizeToFit()
switch indexPath.row % 2 {
case 0:
cell.textLabel?.textColor = UIColor.black
cell.contentView.backgroundColor = UIColor.white
break
default:
cell.textLabel?.textColor = UIColor.white
cell.contentView.backgroundColor = UIColor.lightGray
break
}
}
return cell
}
有什么干净的方法可以实现这一目标吗?