これはなに
iOS10までは tableView の Header や Footer の高さを無くすために、0.1 やCGFloat.leastNormalMagnitudeをtableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloatに返していました`しかし、iOS11になるとそれでは高さが無くならないケースが出て困った-
こちらはtableViewのセクションヘッダーやフッターの高さを無くす方法が変わったのではなく、下記の条件が組み合わさると起きるバグでした。
-
estimatedSectionHeaderHeightが-1(おそらく、UITableViewAutomaticDimension)になっている -
tableView.tableHeaderView = UIView()など tableHeaderView に何かViewを設定している
-
自分のプロダクトでは、状態によって tableView.tableHeaderView が変更される画面だったため、ある状態のときに tableView.tableHeaderView = UIView() をして、tableHeaderViewに空のViewを設定しておりました。
OSごとのデフォルト値の違い
Xcode 9(iOS 11 SDK)でUITableViewのSelf-Sizing(Auto Layoutによる高さの自動調整)がデフォルトになりました。
したがって、それぞれのデフォルト値がiOS11で下記のように変更されています。
| コード (iOS10/iOS11) | Interface Builder | |
|---|---|---|
| estimatedSectionHeaderHeight | (0/-1) | 0 |
| estimatedSectionFooterHeight | (0/-1) | 0 |
iOS10とiOS11で、estimatedSectionHeader(Footer)Heightのデフォルト値が違います。
これにより、iOS10では無効であった、見積もりの高さがiOS11だと有効になることで今回のような余分な高さが、UITableViewに加算されて表示されてしまいます。
どうすればいいのか
- コードからUITableViewをAutoLayoutで組む場合、見積もりの高さが必要ない場合は、
tableView.estimatedSectionHeaderHeightやtableView.estimatedSectionFooterHeightに明示的に 0 を設定して見積もりを無効にしておく
スクショで比較
| before | after |
|---|---|
![]() |
![]() |

