问题
I made an app for iOS 8 which uses grouped UITableView
for one of its page. There are multiple sections in it that uses CGFloat.leastNormalMagnitude
(or CGFloat.min
in Swift 2 and below) for section header and footer height to remove the "default" space. Everything went well until the app run in iOS 9 and 10, where it crashes with this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'section header height must not be negative - provided height for section 0 is -0.00000'
Somehow, any value under 1
(except the rounded 0
) is treated as a negative - and using 1
as return value will make the header / footer space appears again.
Is there any workaround to fix this?
Thanks in advance.
回答1:
I have tried several values for the tableView(_:heightForHeaderInSection:)
, and found out that:
leastNormalMagnitude
andleastNonzeroMagnitude
will be treated as minus (hence the crash).- Zero will make the TableView return the default height as header / footer.
- Anything between zero and one will be treated as a minus.
- One will make the TableView return the default height.
- Anything more than one (e.g 1.1) will set the header / footer to the actual height.
I ended up using 1.1
for solving my problem.
Hope this will help someone out there!
回答2:
We've experienced the same running on iOS 9 using Swift 5 running Xcode 10.2. It turns out if you return CGFloat.leastNormalMagnitude or CGFloat.leastNonzeroMagnitude in estimatedHeightForHeaderInSection / estimatedHeightForFooterInSection, it will crash on iOS 9 devices.
You can still return leastNormalMagnitude or leastNonzeroMagnitude in heightForHeaderInSection / heightForFooterInSection.
As edopelawi pointed out above, any value less than 1 will be treated as negative, and 1 will be treated as the default grouped section header/footer height. We ended up returning 1.000001 as the estimated height if devices are running iOS 10 or below:
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
if #available(iOS 11.0, *) {
return self.tableView(tableView, heightForHeaderInSection: section)
} else {
return max(1.000001, self.tableView(tableView, heightForHeaderInSection: section))
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return 10
}
return CGFloat.leastNonzeroMagnitude
}
回答3:
I have same issue if I set section header height with:
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = CGFloat.leastNormalMagnitude
But if I set my Controller as delegate (UITableViewDelegate) for my table view and implement:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
then it works
回答4:
Maybe CGFloat.leastNonzeroMagnitude
is what you need!
回答5:
If you implement viewForHeader and viewForFooter you don't have to make any cheat.
I personally return 0.1f when I want to hide the header and/or the footer for example. This example will completely hide header and footer with no space to fill, from that you can add your custom logic.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0.1f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.1f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return nil;
}
来源:https://stackoverflow.com/questions/42246153/returning-cgfloat-leastnormalmagnitude-for-uitableview-section-header-causes-cra