根据 UICollectionView 内容大小高度更改 UITableViewCell 高度
Change UITableViewCell Height based UICollectionView content size height
我正在使用 UICollectionView
.
创建的日历
UICollectionView
位于 UITableViewCell
内
heightForRowAt
方法中的UITableViewCell
return UITableView.automaticDimension
用于创建日历的 UICollectionView
根据显示的天数更新其高度,例如 11 月 有其 第一天是星期天 所以要将这一天放在标签 "Sunday" 下 collectionView
必须添加一整行。
通常 每个月有 5 行(周),但是当 一个月的第一天 发生在 星期日 collectionview
returns 6
现在正如我所说,我可以根据行数 returns 更新 UICollectionView 的高度,但我无法动态更改 [=71= TableViewCell
的 ]height 包含 collectionView
如何根据其中 CollectionView
的高度调整 tableViewCell
的大小?
编辑
我的手机
我已将包含 CalendarView
的单元格的高度设置为 UITableView.automaticDimension
在classCalendarView: UIView
我创建了一个变量CGFloat calendarH来设置collectionView的默认高度
CollectionView 实现
我添加了一个观察器,它在 collctionView
发生变化时跟踪其高度
我目前可以更改 collectionView
的高度,但它的超级视图 (bookingCalendarView
) 和 tableView 单元格继续保持固定高度并且不适应 collectionView
您需要为集合视图的高度限制创建 @IBOutlet
。
设置一行的日历/月份数据时,判断需要5行还是6行。
如果是6,将高度限制上的.constant
设置为750
如果是5,将高度约束上的.constant
设置为675
编辑
首先,我建议您忘记使用“自动调整大小”的集合视图。 UICollectionView
旨在根据集合视图的大小 布局单元格 ,当单元格过多时提供自动滚动。
尝试“自我调整”可能在一个实例中工作,但在另一个实例中失败。在这种情况下它失败的原因是因为您的 table 视图布局单元格并计算其高度 在 之前填充集合视图,因此在它可以“自我调整大小”之前。
相反,因为您知道您的单元格高度是 75,所以您可以计算您的日历需要多少行,然后为您的集合视图设置 .constant
高度限制,或者(因为您已经在使用 heightForRowAt
) 计算那里的行高。
看这段代码:
let dateComponents = DateComponents(year: year, month: month)
// startDate will be the first date of the month (Jan 1, Feb 1, Mar 1, etc...)
guard let startDate = calendar.date(from: dateComponents) else {
fatalError("Something is wrong with the date!")
}
// get the range of days in the month
guard let range = calendar.range(of: .day, in: .month, for: startDate) else {
fatalError("Something is wrong with the date!")
}
// get number of days in the month
let numberOfDaysInMonth = range.count
// get the day of the week for the first date in the month
// this returns 1-based numbering
// Nov 1, 2020 was a Sunday, so this would return 1
let startDayOfWeek = Calendar.current.component(.weekday, from: startDate)
// add the "leading days to the start date"
// so, if startDayOfWeek == 3 (Tuesday)
// we need to add 2 "empty day cells" for Sunday and Monday
let totalCellsNeeded = numberOfDaysInMonth + (startDayOfWeek - 1)
// calculate number of rows needed -- this will be 4, 5 or 6
// the only time we get 4 is if Feb 1st in a non-leapYear falls on a Sunday
let numRows = Int(ceil(Double(totalCellsNeeded) / Double(7)))
// we now know the Height needed for the collection view
// you said your calendar cell height is 75, so...
// cvHeight = numRows * 75
我们可以把它放在一个循环中,然后 print()
像这样将信息发送到调试控制台:
override func viewDidLoad() {
super.viewDidLoad()
let calendar = Calendar.current
// 2026 is the next year where Feb starts on a Sunday
// so let's use that year to see that we get 4 rows for Feb
let year = 2026
for month in 1...12 {
let dateComponents = DateComponents(year: year, month: month)
// startDate will be the first date of the month (Jan 1, Feb 1, Mar 1, etc...)
guard let startDate = calendar.date(from: dateComponents) else {
fatalError("Something is wrong with the date!")
}
// get the range of days in the month
guard let range = calendar.range(of: .day, in: .month, for: startDate) else {
fatalError("Something is wrong with the date!")
}
// get number of days in the month
let numberOfDaysInMonth = range.count
// get the day of the week for the first date in the month
// this returns 1-based numbering
// Nov 1, 2020 was a Sunday, so this would return 1
let startDayOfWeek = Calendar.current.component(.weekday, from: startDate)
// add the "leading days to the start date"
// so, if startDayOfWeek == 3 (Tuesday)
// we need to add 2 "empty day cells" for Sunday and Monday
let totalCellsNeeded = numberOfDaysInMonth + (startDayOfWeek - 1)
// calculate number of rows needed -- this will be 4, 5 or 6
// the only time we get 4 is if Feb 1st in a non-leapYear falls on a Sunday
let numRows = Int(ceil(Double(totalCellsNeeded) / Double(7)))
// we now know the Height needed for the collection view
// you said your calendar cell height is 75, so...
// cvHeight = numRows * 75
// debug output
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
let dayName = dateFormatter.string(from: startDate)
dateFormatter.dateFormat = "LLLL y"
let dateString = dateFormatter.string(from: startDate)
let dayPadded = dayName.padding(toLength: 10, withPad: " ", startingAt: 0)
let datePadded = dateString.padding(toLength: 16, withPad: " ", startingAt: 0)
print("\(datePadded) has \(numberOfDaysInMonth) days, starting on \(dayPadded) requiring \(numRows) rows")
}
}
这是输出:
January 2026 has 31 days, starting on Thursday requiring 5 rows
February 2026 has 28 days, starting on Sunday requiring 4 rows
March 2026 has 31 days, starting on Sunday requiring 5 rows
April 2026 has 30 days, starting on Wednesday requiring 5 rows
May 2026 has 31 days, starting on Friday requiring 6 rows
June 2026 has 30 days, starting on Monday requiring 5 rows
July 2026 has 31 days, starting on Wednesday requiring 5 rows
August 2026 has 31 days, starting on Saturday requiring 6 rows
September 2026 has 30 days, starting on Tuesday requiring 5 rows
October 2026 has 31 days, starting on Thursday requiring 5 rows
November 2026 has 30 days, starting on Sunday requiring 5 rows
December 2026 has 31 days, starting on Tuesday requiring 5 rows
所以...要么在:
cellForRowAt
...计算出需要的高度并在单元格中设置CV高度,或者
heightForRowAt
... 计算并return 行所需的高度
旁注:我建议对所有单元格使用自动布局,而不是return设置各种行高。
我正在使用 UICollectionView
.
UICollectionView
位于 UITableViewCell
内
heightForRowAt
方法中的UITableViewCell
return UITableView.automaticDimension
用于创建日历的 UICollectionView
根据显示的天数更新其高度,例如 11 月 有其 第一天是星期天 所以要将这一天放在标签 "Sunday" 下 collectionView
必须添加一整行。
通常 每个月有 5 行(周),但是当 一个月的第一天 发生在 星期日 collectionview
returns 6
现在正如我所说,我可以根据行数 returns 更新 UICollectionView 的高度,但我无法动态更改 [=71= TableViewCell
的 ]height 包含 collectionView
如何根据其中 CollectionView
的高度调整 tableViewCell
的大小?
编辑
我的手机
我已将包含 CalendarView
UITableView.automaticDimension
在classCalendarView: UIView
我创建了一个变量CGFloat calendarH来设置collectionView的默认高度
CollectionView 实现
我添加了一个观察器,它在 collctionView
发生变化时跟踪其高度
我目前可以更改 collectionView
的高度,但它的超级视图 (bookingCalendarView
) 和 tableView 单元格继续保持固定高度并且不适应 collectionView
您需要为集合视图的高度限制创建 @IBOutlet
。
设置一行的日历/月份数据时,判断需要5行还是6行。
如果是6,将高度限制上的.constant
设置为750
如果是5,将高度约束上的.constant
设置为675
编辑
首先,我建议您忘记使用“自动调整大小”的集合视图。 UICollectionView
旨在根据集合视图的大小 布局单元格 ,当单元格过多时提供自动滚动。
尝试“自我调整”可能在一个实例中工作,但在另一个实例中失败。在这种情况下它失败的原因是因为您的 table 视图布局单元格并计算其高度 在 之前填充集合视图,因此在它可以“自我调整大小”之前。
相反,因为您知道您的单元格高度是 75,所以您可以计算您的日历需要多少行,然后为您的集合视图设置 .constant
高度限制,或者(因为您已经在使用 heightForRowAt
) 计算那里的行高。
看这段代码:
let dateComponents = DateComponents(year: year, month: month)
// startDate will be the first date of the month (Jan 1, Feb 1, Mar 1, etc...)
guard let startDate = calendar.date(from: dateComponents) else {
fatalError("Something is wrong with the date!")
}
// get the range of days in the month
guard let range = calendar.range(of: .day, in: .month, for: startDate) else {
fatalError("Something is wrong with the date!")
}
// get number of days in the month
let numberOfDaysInMonth = range.count
// get the day of the week for the first date in the month
// this returns 1-based numbering
// Nov 1, 2020 was a Sunday, so this would return 1
let startDayOfWeek = Calendar.current.component(.weekday, from: startDate)
// add the "leading days to the start date"
// so, if startDayOfWeek == 3 (Tuesday)
// we need to add 2 "empty day cells" for Sunday and Monday
let totalCellsNeeded = numberOfDaysInMonth + (startDayOfWeek - 1)
// calculate number of rows needed -- this will be 4, 5 or 6
// the only time we get 4 is if Feb 1st in a non-leapYear falls on a Sunday
let numRows = Int(ceil(Double(totalCellsNeeded) / Double(7)))
// we now know the Height needed for the collection view
// you said your calendar cell height is 75, so...
// cvHeight = numRows * 75
我们可以把它放在一个循环中,然后 print()
像这样将信息发送到调试控制台:
override func viewDidLoad() {
super.viewDidLoad()
let calendar = Calendar.current
// 2026 is the next year where Feb starts on a Sunday
// so let's use that year to see that we get 4 rows for Feb
let year = 2026
for month in 1...12 {
let dateComponents = DateComponents(year: year, month: month)
// startDate will be the first date of the month (Jan 1, Feb 1, Mar 1, etc...)
guard let startDate = calendar.date(from: dateComponents) else {
fatalError("Something is wrong with the date!")
}
// get the range of days in the month
guard let range = calendar.range(of: .day, in: .month, for: startDate) else {
fatalError("Something is wrong with the date!")
}
// get number of days in the month
let numberOfDaysInMonth = range.count
// get the day of the week for the first date in the month
// this returns 1-based numbering
// Nov 1, 2020 was a Sunday, so this would return 1
let startDayOfWeek = Calendar.current.component(.weekday, from: startDate)
// add the "leading days to the start date"
// so, if startDayOfWeek == 3 (Tuesday)
// we need to add 2 "empty day cells" for Sunday and Monday
let totalCellsNeeded = numberOfDaysInMonth + (startDayOfWeek - 1)
// calculate number of rows needed -- this will be 4, 5 or 6
// the only time we get 4 is if Feb 1st in a non-leapYear falls on a Sunday
let numRows = Int(ceil(Double(totalCellsNeeded) / Double(7)))
// we now know the Height needed for the collection view
// you said your calendar cell height is 75, so...
// cvHeight = numRows * 75
// debug output
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
let dayName = dateFormatter.string(from: startDate)
dateFormatter.dateFormat = "LLLL y"
let dateString = dateFormatter.string(from: startDate)
let dayPadded = dayName.padding(toLength: 10, withPad: " ", startingAt: 0)
let datePadded = dateString.padding(toLength: 16, withPad: " ", startingAt: 0)
print("\(datePadded) has \(numberOfDaysInMonth) days, starting on \(dayPadded) requiring \(numRows) rows")
}
}
这是输出:
January 2026 has 31 days, starting on Thursday requiring 5 rows
February 2026 has 28 days, starting on Sunday requiring 4 rows
March 2026 has 31 days, starting on Sunday requiring 5 rows
April 2026 has 30 days, starting on Wednesday requiring 5 rows
May 2026 has 31 days, starting on Friday requiring 6 rows
June 2026 has 30 days, starting on Monday requiring 5 rows
July 2026 has 31 days, starting on Wednesday requiring 5 rows
August 2026 has 31 days, starting on Saturday requiring 6 rows
September 2026 has 30 days, starting on Tuesday requiring 5 rows
October 2026 has 31 days, starting on Thursday requiring 5 rows
November 2026 has 30 days, starting on Sunday requiring 5 rows
December 2026 has 31 days, starting on Tuesday requiring 5 rows
所以...要么在:
cellForRowAt
...计算出需要的高度并在单元格中设置CV高度,或者heightForRowAt
... 计算并return 行所需的高度
旁注:我建议对所有单元格使用自动布局,而不是return设置各种行高。