時間ができた時にコツコツと Xcode 6.4 + iOS 8.4 SDKを使って開発していたアプリをXcode 7.2でビルドが通るようにしていました。要するにSwift 1.2からSwift 2.1.1への移行です。
ある時、UICollectionViewのフッターの表示が崩れていることに気付きました。細かい部分は実際のコードとは異なりますが概ね下記のような感じです。
// フッターに文字列を表示させる処理... let font = UIFont.boldSystemFontOfSize(20) let style = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle style.lineBreakMode = .ByCharWrapping style.alignment = .Left style.minimumLineHeight = font.leading + 2 style.maximumLineHeight = font.leading + 2 let attributes = [ NSFontAttributeName: font, NSParagraphStyleAttributeName: style ] titleLabel.attributedText = NSAttributedString(string: "ぴよぴよ", attributes: attributes)
↑ここでtitleLabelが潰れて表示されていました。
他にも同一事象だと思われることが幾つか発生していました。
- UILabelで装飾付き文字列を設定した場合に表示が崩れている(UILabel#attributedText)
- NSAttributedString#boundingRectWithSizeで明らかに小さすぎる高さが返ってくる
minimumLineHeightとmaximumLineHeightを指定している部分をコメントアウトしたところ、ラベルが潰れずに表示されたのでよかったよかったと思っていたのですが、本質的にはそこが原因ではありませんでした。
結論を書くと、Xcode 7.2(iOS 9.2 SDK)を使うとUIFont#leadingプロパティ
が0を返すようになっていたためです。
iOS 8.4とiOS 9.2のシミュレーターでUIFontのleadingプロパティの値をログで出すようにしてみました。
iOS 9.2 SDK + iOS 8.4で実行した場合
leading: 13.123 lineHight: 13.123
フッターのサイズ: (0.0, 0.0, 347.666, 273.968)
iOS 9.2 SDK + iOS 9.2で実行した場合
leading: 0.0 lineHight: 13.126953125
フッターのサイズ: (0.0, 0.0, 346.9437106269, 56.0)
UIFont#leadingプロパティが0で返ってきてしまい、この値を1行あたりの高さとして固定してしまっていた為、表示が崩れてしまっていました。
結論
UIFont#leadingプロパティ
ではなくて、UIFont#lineHightプロパティ
を使わないといけません。
let style = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle style.lineBreakMode = .ByCharWrapping style.alignment = .Left style.minimumLineHeight = font.lineHeight + 2 style.maximumLineHeight = font.lineHeight + 2
ドキュメントには以下のように書かれているだけでした。
leading Property
The receiver’s leading information. (read-only)Use the lineHeight property instead.
iOS 9.0 SDKおよびiOS 9.1 SDKを使った場合でも同じような現象が発生するのかどうかは検証していません。
最初は、「Xcode 7.2(iOS 9.2 SDK)を使っている場合にNSParagraphStyle#minimumLineHeight、NSParagraphStyle#maximumLineHeightを指定すると表示が崩れてしまった」というタイトルでしたが途中で書き直しました。
以下、感想です。
iOS 9 SDK使うとUIFont#leadingが0で返ってくるのdeprecated扱いにして欲しかった(気付かなかった…)
— さくさん (@ch3cooh) January 18, 2016