View
4.585
Download
1
Category
Preview:
DESCRIPTION
2013/9/12 Retty株式会社,株式会社VASILYのエンジニアで技術勉強会を行いました。
Citation preview
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以上のViewController13年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で作られている
Table View Cellを各ViewController
で再利用する
13年9月13日金曜日
TableViewの構成
storyboardにViewControoler設置
Table View 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に実装する
• 画面更新をすべて請け負ったメソッド(Table Viewのリロード、ボタンの更新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日金曜日
layoutSubViewsViewクラスのLayoutSubViewsメソッドをオーバライドして、レイアウト設定をおこなう。ViewController側では情報をセットしsetNeedsLayoutを読んで適宜レイアウト調整を行う。
- (void)layoutSubviews{ [super layoutSubviews]; // 画像の設定処理 // 画像を角丸にする処理 // Labelにテキストを設定する処理 // etc...}
// データ更新処理など[hogeCell setNeedsLayout];
HogeCell
HogeViewController
13年9月13日金曜日
まとめ• Viewの再利用を可能な限り意識する
• ボタンやフォントはルールを決め統一
• ある程度のコーディング規約を設ける- ViewとControllerの役割- 認識が統一されたメソッドの実装- 画像命名規則- Action命名規則
13年9月13日金曜日
Recommended