iQONのView構成
2013/09/12 荒井勇輔
13年9月13日金曜日
自己紹介
• 名前:荒井 勇輔 (あらい ゆうすけ)
• Facebook:ararajp
13年9月13日金曜日
本日の流れ
• iQONのView事情
• View実装ポリシーとTips
13年9月13日金曜日
iQONのView事情
13年9月13日金曜日
画面から見るiQON
常に存在する
Menu/Navigation/FeedBack
紹介しきれない多くの画面
13年9月13日金曜日
Storyboardから見るiQON
100以上のViewController
13年9月13日金曜日
デザインから見るiQON
• 女性のためのカワイイデザインにするため
に、UIKitで用意されているパーツを使う
事がほぼ無く、独自のViewをたくさん持
っている
• 見通し、仕様変更への対応速度を考えxib
で作成している
13年9月13日金曜日
状態から見るIQON
• ユーザ(機能権限、公式ユーザ、フォロー関係、プロフィール状況)
• アイテム(在庫状況、割引状況、お気に入り)
• 期間(コンテスト開催状況)
• etc...
これらの条件によってボタン、ラベル、
アイコンなどすべて出し分け
13年9月13日金曜日
このような複雑な画面を効率良く作成
するためにVASILY iOSチームが実践して
いるポリシー/Tipsを紹介します。
13年9月13日金曜日
View実装ポリシーとTips
13年9月13日金曜日
Viewクラスの役割を明確にする
• Viewは出来る限り再利用し開発を減らす
• Viewに画面遷移などの動作責任は持たせない
• Viewの高さ計算、ラベル変更などはViewがすべて処理する
• ViewControllerには画面表示に関わる責任は持たせない
13年9月13日金曜日
具体例
画像が2つ並ぶViewを作成
画像をタップすると詳細ページに飛ぶようなView
ImageViewが2つ置かれたViewが
ありViewControllerがこのView
を使用するとします
13年9月13日金曜日
for (int i = 0; i < self.imageViews.count; i++) {
Set *set = self.sets[i]; // コーディネートのオブジェクト
UIImageView *imageView = self.imageViews[i];
imageView.imageURL = set.imageUrlMedium;
imageView.tag = set.setId.intValue;
// ここがダメ Viewに画像タップ時の画面遷移が記述されている
[imageView setImageViewPressedBlock:^(int setId) { //UIImageViewの拡張
SetDetailViewController *vc = [VCFactory create:@"SetDetailViewController"];
[IQONAPPDELEGATE.navigationController pushViewController:vc animated:YES];
}];
}
悪い例
Viewのコード
画像タップ時の画面遷移が記述されていると、このViewの再
利用が著しく低下する
もしかしたら他の画面では画像タップでポップアップが求め
られるかもしれない
13年9月13日金曜日
良い例
for (int i = 0; i < self.imageViews.count; i++) {
Set *set = self.sets[i]; // コーディネートのオブジェクト
UIImageView *imageView = self.imageViews[i];
imageView.imageURL = set.imageUrlMedium;
imageView.tag = set.setId.intValue;
// ViewControllerで設定したActionを実行
if (self.imageViewPressedBlock) {
imageView.imageViewPressedBlock = self.imageViewPressedBlock;
}
}
View Controllerのコード
Viewのコード
setCell.imageViewPressedBlock =^(int setId) {
SetDetailViewController *vc = [VCFactory create:@"SetDetailViewController"];
vc.filter.setId = @(setId);
[vc updateDataController];
[IQONAPPDELEGATE.currentNavigationController pushViewController:vc animated:NO];
};
ViewにpublicなBlockのプロパティを持ち、ViewController側で動作を設定
13年9月13日金曜日
TableViewの利用
要素の有無、高さ計算などが多数
存在するためiQONのほとんどが
TableViewで作られている
TableView Cellを各ViewController
で再利用する
13年9月13日金曜日
TableViewの構成
storyboardにViewControoler設置
TableView Cell
TableViewのcellForRowAtIndexPathデリゲート
にて必要なTableViewCellを設定
if (indexPath.section == 0) {
cellName = @"UserDetailInformationAndCoverCell";
}
else {
if (indexPath.row == 0) {
cellName = @"UserDetailProfileCell";
}
else if (indexPath.row == 1) {
cellName = @"UserDetailBirthdayCell";
}
else if (indexPath.row == 2) {
cellName = @"UserDetailOccupationCell";
}
....
}
13年9月13日金曜日
チームとして共通認識のメソッドを用意
することで可読性を高める
13年9月13日金曜日
updateOutletsAll
• ViewControllerに実装する
• 画面更新をすべて請け負ったメソッド
(TableViewのリロード、ボタンの更新etc)
• このメソッドを呼べば画面に必要な再描写がすべてされる
- (void)updateOutletsAll
{
[self.tableView reloadData]; // TableViewのリロード
[self updateOutletsOfLikeButton]; // LikeButtonの更新
…
}
13年9月13日金曜日
configureCell
• cellの設定を行うメソッド
• cellForRowAtIndexPathで必ず呼ばれる
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if ([cell isKindOfClass:ItemDetailCell.class]) {
[self configureItemDetailCell:(ItemDetailCell *)cell atIndexPath:indexPath];
}
else if ([cell isKindOfClass:ItemDetailRelatedItemsCell.class]) {
[self configureItemDetailRelatedItemsCell:(ItemDetailRelatedItemsCell *)cell atIndexPath:indexPath];
}
else if ([cell isKindOfClass:ItemDetailItemSetsCell.class]) {
[self configureItemDetailItemSetsCell:(ItemDetailItemSetsCell *)cell atIndexPath:indexPath];
}
}
13年9月13日金曜日
layoutSubViews
ViewクラスのLayoutSubViewsメソッドをオーバライドして、レイ
アウト設定をおこなう。ViewController側では情報をセットし
setNeedsLayoutを読んで適宜レイアウト調整を行う。
- (void)layoutSubviews
{
[super layoutSubviews];
// 画像の設定処理
// 画像を角丸にする処理
// Labelにテキストを設定する処理
// etc...
}
// データ更新処理など
[hogeCell setNeedsLayout];
HogeCell
HogeViewController
13年9月13日金曜日
まとめ
• Viewの再利用を可能な限り意識する
• ボタンやフォントはルールを決め統一
• ある程度のコーディング規約を設ける
-ViewとControllerの役割
- 認識が統一されたメソッドの実装
- 画像命名規則
- Action命名規則
13年9月13日金曜日

iQONのVIew構成紹介