【Objective-C】UITableViewを Dynamic Type に対応する
UITableViewを文字サイズの変更 (Dynamic Type) に対応する方法です。
(環境: xcode 6.3, iOS8.3)
iOS7から設定アプリ > 一般 > アクセシビリティ から文字サイズを変更できます。
こちらの設定が変更された際に、設定変更の検知し、フォントサイズとセルの高さを動的に変更する方法を紹介します。
フォントサイズの指定
UITableViewのCellの表示内容を設定するメソッド、もしくはstoryboardなどでフォントサイズをDynamicTypeに対応しているスタイルに設定します。
下記はtableView:cellForRowAtIndexPath:メソッドで設定している例です。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil]; } cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping; cell.textLabel.numberOfLines = 0; // フォントサイズのスタイルを設定 cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; cell.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]; HogeItem* item = [self getItem:incexPath]; cell.textLabel.text = item.text; cell.detailTextLabel.text = item.subText; [cell.textLabel sizeToFit]; return cell; }
セルの高さを設定
セルの高さを動的にします。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { HogeItem* item = [self getItem:indexPath]; NSString *text = item.text; UIFont *labelFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; CGFloat padding = 40.0; CGRect totalRect = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width - 30, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:[NSDictionary dictionaryWithObject:labelFont forKey:NSFontAttributeName] context:nil]; return MAX(totalRect.size.height + padding, 60); }
フォントサイズ設定変更の検知
最後にDynamicTypeが変更されたことを検知し、設定を反映するようにします。
// viewDidLoadで通知センターにフォントサイズが変更された際に呼ばれるメソッドを登録 - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; } // フォントサイズが変更された際に呼ばれるメソッド - (void)preferredContentSizeChanged:(NSNotification *)aNotification { [self.tableView reloadData]; }
ヘッダーのサイズ
また、テーブルにヘッダーがある場合は、下記のようにしてヘッダーのサイズも動的に変更できます。
- (void)sizeHeaderToFit { self.headerLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; UIView *header = self.tableView.tableHeaderView; [header setNeedsLayout]; [header layoutIfNeeded]; CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; CGRect frame = header.frame; frame.size.height = height; header.frame = frame; self.tableView.tableHeaderView = header; } // tableViewをリロードするタイミングで... [self sizeHeaderToFit];
以上です。
参考:
iOSアプリで動的にフォントサイズを変更する「Dynamic Type」新機能の実装法 #ios7yahoo|CodeIQ MAGAZINE
ios - table header view height is wrong when using auto layout, IB, and font sizes - Stack Overflow