前回書いた「iOS 7から追加されたDynamic Typeを使ってみた」の続編です。
新しくわかったこと
前回は「UIFontDescriptor を使う必要がある」と書きましたが、その後の調査で
+ (UIFont *)preferredFontForTextStyle:(NSString *)style
メソッドを使えば Dynamic Type に対応できることがわかりました。
このメソッドではフォントのサイズではなく、スタイルを定義します。*1スタイルには次の値を指定できます。
- UIFontTextStyleHeadline
- UIFontTextStyleBody
- UIFontTextStyleSubheadline
- UIFontTextStyleFootnote
- UIFontTextStyleCaption1
- UIFontTextStyleCaption2
各スタイルがどのように表示されるか、いろいろ試してみると面白いです。
(c)Apple
今回作ったもの
前回は、UITextView を Dynamic Type に対応させるだけでしたが、今回は UITableView 全体のテキストを Dynamic Type に対応させ、さらに文字サイズに合わせて各セルの高さを自動調整するところまで試してみました。
実装方法
まずは、様々な長さのテキストを各セルに表示するだけのUITableViewを作成します。
高さの調整はしていないので、長いテキストは途中で省略されてしまいます。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
cell.textLabel.numberOfLines = 0;
cell.textLabel.text = [_textArray objectAtIndex:indexPath.row];
return cell;
}
セルのフォントサイズは preferredFontForTextStyle メソッドによって指定されているので、この時点で一応 Dynamic Type には対応しています。
高さの調整
今度は、テキストの長さによってセルの高さを調整してみます。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [_textArray objectAtIndex:indexPath.row];
UIFont *nameLabelFont = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
CGFloat PADDING_OUTER = 10;
CGRect totalRect = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:[NSDictionary dictionaryWithObject:nameLabelFont forKey:NSFontAttributeName]
context:nil];
return totalRect.size.height + PADDING_OUTER;
}
セルの高さは
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context;
(長い!^^;)メソッドを使って計算しています。
これまでよく使われていた sizeWithFont 系のメソッドは、iOS 7から Deprecated になったようです。
また、設定画面で文字サイズが変更された通知(UIContentSizeCategoryDidChangeNotification)を受け取り、UITableView全体をリロードするようにします。
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(preferredContentSizeChanged:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
}
- (void)preferredContentSizeChanged:(NSNotification *)aNotification
{
// refresh tableView
[self.tableView reloadData];
}
これでテキストに合わせてセルの高さを調整してくれるようになりました。
設定画面から文字サイズを大きくしても、ちゃんと高さを調整してくれます。
今回のサンプルソース
こちらに置いておきます。
https://github.com/koogawa/DynamicTypeDemo