Your SlideShare is downloading. ×
iOS Apps Development for Androider part2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

iOS Apps Development for Androider part2

2,224
views

Published on

Published in: Technology

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,224
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
31
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 第2回 AndroiderのためのiOS勉強会 【UI基本編】 2012年11月4日 木下 照章 @metal_presidentCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 1 1
  • 2. 自己紹介 • 岐阜県のソフトピアジャパンというところで、株式会社グルーヴシステム ズという会社をやっています。 • 制御系(C, VB, VC) 業務系(Java, PHP) アプリ系(Objective-C, Lua) • 2009年7月頃 iPhoneアプリ開発開始 • 2010年7月頃 Androidアプリ開発開始 • 最近イロイロなところで講師をやっています。 • Twiter ID : @metal_presidentCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 2 2
  • 3. 前回(第1回で)やったこと •プロジェクトの作成 •Xcodeの使い方 •シミュレータの使い方 •プロジェクトに含まれるファイルの構成 •ローカライズ •画面の作り方(IBでxibファイルを作る) •アウトレットとアクション •Objective-Cの基礎(クラス、メモリ管理、プロパティ など)Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 3 3
  • 4. Agenda 1. ジェスチャー 2. ナビゲーションコントローラ 3. タブメニュー(タブバー) 4. モーダルビュー 5. リスト 6. グリッドCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 4 4
  • 5. 1.ジェスチャーCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 5 5
  • 6. Androidでジェスチャーというと... こんな感じのやつですよね...使いやすいのかな?...Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 6 6
  • 7. iOSでジェスチャーとは •ユーザーによるタップ、パン(ドラッグ)、ピンチ、回 転、スワイプ、長押し等のことを指します。 •UIGestureRecognizer クラス(のサブクラス)を使うと簡単 に検出できます。 UITapGestureRecognizer タップ UIPanGestureRecognizer パン(ドラッグ) UIPinchGestureRecognizer ピンチイン/ピンチアウト UIRotationGestureRecognizer 回転 UISwipeGestureRecognizer スワイプ UILongPressGestureRecognizer 長押しCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 7 7
  • 8. プロジェクトを作成しようCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 8 8
  • 9. ジェスチャー検知用のViewを配置① ViewController.xib を編集する。 4個の View と 2個の ImageView を配置しアウトレットを作成 ImageView は User Interaction Enabled を ON にすることCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 9 9
  • 10. ジェスチャー検知用のViewを配置② ViewController.xib を編集する。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 10 10
  • 11. GestureRecognizerをViewに設定 ViewController.xib を編集する。 6種類の GestureRecognizer を View にドラッグ&ドロップCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 11 11
  • 12. GestureRecognizerのアクションを作成 ViewController.xib を編集する。 今回は処理を実装しませんが各 delegate に File’s Owner をセットCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 12 12
  • 13. GestureRecognizerのアクションを実装① ViewController.m - (IBAction)tap:(id)sender { // 【追加】タップ検知処理 UITapGestureRecognizer *recognizer = (UITapGestureRecognizer*) sender; NSLog(@"detected UITapGestureRecognizer taps:%d", [recognizer numberOfTapsRequired]); } - (IBAction)pinch:(id)sender { // 【追加】ピンチ検知処理 UIPinchGestureRecognizer *recognizer = (UIPinchGestureRecognizer*) sender; NSLog(@"detected UIPinchGestureRecognizer scale:%f", [recognizer scale]); // 画像の拡大縮小処理 CGAffineTransform trans = CGAffineTransformMakeScale(recognizer.scale, recognizer.scale); [_view2 setTransform:trans]; } - (IBAction)rotation:(id)sender { // 【追加】回転検知処理 UIRotationGestureRecognizer *recognizer = (UIRotationGestureRecognizer*) sender; NSLog(@"detected UIRotationGestureRecognizer rotation:%f", [recognizer rotation]); // 画像の回転処理 CGAffineTransform trans = CGAffineTransformMakeRotation(recognizer.rotation); [_view3 setTransform:trans]; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 13 13
  • 14. GestureRecognizerのアクションを実装② ViewController.m - (IBAction)swipe:(id)sender { // 【追加】スワイプ検知処理 UISwipeGestureRecognizer *recognizer = (UISwipeGestureRecognizer*) sender; NSLog(@"detected UISwipeGestureRecognizer direction:%d", [recognizer direction]); } - (IBAction)pan:(id)sender { // 【追加】パン検知処理 UIPanGestureRecognizer *recognizer = (UIPanGestureRecognizer*) sender; CGPoint p = [recognizer translationInView:recognizer.view]; NSLog(@"detected UIPanGestureRecognizer x:%f y:%f", p.x, p.y); } - (IBAction)longPress:(id)sender { // 【追加】長押し検知処理 UILongPressGestureRecognizer *recognizer = (UILongPressGestureRecognizer*) sender; if (recognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"detected UILongPressGestureRecognizer touches:%d", [recognizer numberOfTouchesRequired]); } }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 14 14
  • 15. 2.ナビゲーションコントローラCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 15 15
  • 16. ナビゲーションコントローラとは • Navigation Barは、ユーザがデータ階層をたどることができるようにするた めのユーザインターフェイスの仕組みです。最上位レベルの項目からスタ ートして、下位層の項目 へドリルダウンします。 • UINavigationController はNavigation Barを管理するための、 UIViewController クラスのサブクラスです。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 16 16
  • 17. ナビゲーションコントローラの構造 • ナビゲーションコントローラの構造は次のとおりです。 戻る UINavigationBar pop pop push push ViewController UINavigationControllerCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 17 17
  • 18. 画面を追加する① ViewController2.xib / h / m を作成する。 ViewController2.xib を編集する。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 18 18
  • 19. 画面を追加する② ViewController2.h @property (strong, nonatomic) NSString *text; @end ViewController2.m - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { self.title = @"二つ目の画面"; ・・・ - (void)viewDidLoad { [super viewDidLoad]; // 【追加】ラベル表示 _label.text = _text; ・・・ - (IBAction)pressedNext:(id)sender { // 【追加】画面遷移処理 ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; viewController.text = _text; [self.navigationController pushViewController:viewController animated:YES];Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 19 19
  • 20. ナビゲーションコントローラを表示する AppDelegate.h @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UIViewController *viewController; @end AppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. // 【修正】最初に表示するViewControllerとNavigationControllerを作成する UIViewController *root = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; root.title = @"一つ目の画面"; self.viewController = [[UINavigationController alloc] initWithRootViewController:root]; self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; ここで渡すViewControllerが } 画面に表示されるのです。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 20 20
  • 21. 画面を遷移する ViewController.m #import "ViewController2.h" - (IBAction)tap:(id)sender { UITapGestureRecognizer *recognizer = (UITapGestureRecognizer*) sender; NSLog(@"detected UITapGestureRecognizer taps:%d", [recognizer numberOfTapsRequired]); // 【追加】画面遷移処理 ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; viewController.text = @"タップしたよ!"; [self.navigationController pushViewController:viewController animated:YES]; } - (IBAction)longPress:(id)sender { UILongPressGestureRecognizer *recognizer = (UILongPressGestureRecognizer*) sender; if (recognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"detected UILongPressGestureRecognizer touches:%d", [recognizer numberOfTouchesRequired]); // 【追加】画面遷移処理 ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; viewController.text = @"長押ししたよ!"; [self.navigationController pushViewController:viewController animated:YES]; } }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 21 21
  • 22. ★やってはいけないこと★ ViewController.m <例1> - (IBAction)tap:(id)sender { UITapGestureRecognizer *recognizer = (UITapGestureRecognizer*) sender; NSLog(@"detected UITapGestureRecognizer taps:%d", [recognizer numberOfTapsRequired]); // 【追加】画面遷移処理 ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; viewController.label.text = @"タップしたよ!"; [self.navigationController pushViewController:viewController animated:YES]; } <例2> - (IBAction)tap:(id)sender { UITapGestureRecognizer *recognizer = (UITapGestureRecognizer*) sender; NSLog(@"detected UITapGestureRecognizer taps:%d", [recognizer numberOfTapsRequired]); // 【追加】画面遷移処理 ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; [self.navigationController pushViewController:viewController animated:YES]; viewController.label.text = @"タップしたよ!"; } iOS6以降ならOKかな∼ 次の画面へのパラメータは、イニシャライザの引数か、 プロパティを追加して渡しましょう。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 22 22
  • 23. 3.タブメニュー(タブバー)Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 23 23
  • 24. タブバー概要 • Xcodeでプロジェクトを作成する際に、Tabbed Application テンプレートを選 択すれば、簡単にタブバーを持ったアプリケーションが作成できます。 • 現在のプロジェクトにタブバーを追加し、各タブメニュー内にこれまで作 成したNavigationContollerを表示するように修正していきましょう。 UINavigationBar ViewController UINavigationController UITabBarControllerCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 24 24
  • 25. タブバー実装 AppDelegate.m 【AppDelegate.m】 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. // 【修正】最初に表示するViewControllerとNavigationControllerとTabBarを作成する UIViewController *root1= [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; UIViewController *root2= [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; UIViewController *root3= [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; root1.title = @"一つ目の画面(1)"; root2.title = @"一つ目の画面(2)"; root3.title = @"一つ目の画面(3)"; // NavigationController作成 UINavigationController *navi1 = [[UINavigationController alloc] initWithRootViewController:root1]; // TabBar作成 UITabBarController *tabBar = [[UITabBarController alloc] init]; tabBar.viewControllers = @[navi1, root2, root3]; self.viewController = tabBar;Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 25 25
  • 26. 4.モーダルビューCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 26 26
  • 27. モーダルビュー概要 • UIViewController で作成した画面を、モーダル形式で表示することがで きます。 • モーダル形式の場合、画面全体に表示することができるため、出来るだけ 画面を広く使いたい場合に利用されます。 • また、ユーザーに『これまでの操作とは異なる内容の操作になる』と認識 させたい場合にも利用します。 • モーダル表示する UIViewController には、閉じるための手段を用意する 必要があります。 • Androidでの startActivityForResult / onActivityResult のように、画 面の戻り(値)に関する明確なメカニズムは無く、デリゲートにより呼び出 し元画面へ処理を渡すことで対応します。デリゲートでは @protocol(Java でのinterface)を利用します。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 27 27
  • 28. モーダルビュー実装① ViewController2.h // 【追加】デリゲートプロトコル @protocol ModalViewControllerDelegate <NSObject> @required - (void) close:(UIViewController*) sender result:(int) result; @end @interface ViewController2 : UIViewController @property (weak, nonatomic) IBOutlet UILabel *label @property (strong, nonatomic) NSString *text; @property (weak, nonatomic) id<ModalViewControllerDelegate> delegate; - (IBAction)pressedNext:(id)sender; // 【追加】「閉じる」ボタンを追加してください - (IBAction)pressedClose:(id)sender; @endCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 28 28
  • 29. モーダルビュー実装② ViewController2.m - (IBAction)pressedClose:(id)sender { // 【追加】画面終了処理 if (self.delegate) { [self.delegate close:self result:666]; } else { // ★iOS6より前まではこの書き方でOK // [sender dismissModalViewControllerAnimated:YES]; // ★iOS6以降では dismissModalViewControllerAnimated は非推奨 [sender dismissViewControllerAnimated:YES completion:^(void) { NSLog(@"completed dismissViewControllerAnimated"); }]; } } iOS4以降で導入されたブロック構文(=クロージャ、無名関数)ですね。 ViewController.h #import "ViewController2.h" @interface ViewController : UIViewController <UIGestureRecognizerDelegate, ModalViewControllerDelegate>Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 29 29
  • 30. モーダルビュー実装③ ViewController.m - (IBAction)swipe:(id)sender { ・・・ ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"ViewController2" bundle:nil]; viewController.text = @"スワイプしたよ!"; viewController.delegate = self; // ★iOS6より前まではこの書き方でOK // [self presentModalViewController:viewController animated:YES]; // ★iOS6以降では presentModalViewController は非推奨 [self presentViewController:viewController animated:YES completion:^(void) { NSLog(@"completed presentViewController"); }]; } // 【追加】 - (void) close:(UIViewController*) sender result:(int) result { NSLog(@"ModalViewController Result!! : %d", result); // モーダル表示している画面なので閉じる(↑この判定は暫定的なものです) // ★iOS6より前まではこの書き方でOK // [sender dismissModalViewControllerAnimated:YES]; // ★iOS6以降では dismissModalViewControllerAnimated は非推奨 [sender dismissViewControllerAnimated:YES completion:^(void) { NSLog(@"completed dismissViewControllerAnimated"); }]; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 30 30
  • 31. 5.リストCopyright (C) 2012 Groove Systems Inc. All Rights Reserved. 31 31
  • 32. リスト概要 • Androidのリストと書き方は大きく異なりますが、基本的な考え方は大きく 変わりません。セルViewの再利用の仕組みも同様にあります。 • ListView → UITableView • Adapter → UITableView のデータソース • ListActivity → UITableViewController • データ(行)を複数のセクションに分けて表示することも可能で、セクシ ョン毎にヘッダ/フッダを表示できます。 • 行を指定する際は、NSIndexPath クラスを使用します。NSIndexPath クラスは section と row の二つの値を持ち、section はセクションの番号 (0∼)、row はセクション内での行番号(0∼)を表します。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 32 32
  • 33. リスト実装① ViewController3.h / m を作成する。 ViewController3.h @interface ViewController3 : UITableViewController @property (strong, nonatomic) NSArray *pref; @property (strong, nonatomic) NSArray *city; @end AppDelegate.m #import "ViewController3.h" ・・・ UIViewController *list= [[ViewController3 alloc] initWithStyle:UITableViewStylePlain]; list.title = @"リスト"; tabBar.viewControllers = @[navi1, root2, root3, list];Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 33 33
  • 34. リスト実装② ViewController3.m - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // 【追加】リストのデータ(Xcode4.4未満では [NSArray arrayWithObjects:... を使用) self.pref = @[@"岐阜県", @"愛知県", @"三重県"]; self.city = @[@[@"岐阜市", @"大垣市", @"高山市"], @[@"名古屋市", @"一宮市", @"稲沢市"], @[@"津市", @"四日市市", @"桑名市"]]; ・・・ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // 【修正】セクションの数を返す(デフォルトは1) return [_pref count]; } // 【追加】セクションヘッダのタイトルを返す - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [_pref objectAtIndex:section]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // 【修正】セクション毎の行数を返す NSArray *arr = [_city objectAtIndex:section]; return [arr count]; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 34 34
  • 35. リスト実装③ ViewController3.m - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; // キューからViewを取得する UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { // キューから取得出来なかった場合は新たにViewを作成する cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // 行に表示する値をセットする NSArray *arr = [_city objectAtIndex:indexPath.section]; cell.textLabel.text = [arr objectAtIndex:indexPath.row]; // 行のViewを返す AdapterのgetView()に相当 return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // 【追加】選択時処理 NSArray *arr = [_city objectAtIndex:indexPath.section]; NSLog(@"selected row pref:%@ city:%@", [_pref objectAtIndex:indexPath.section], [arr objectAtIndex:indexPath.row]); // 選択を解除する [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES]; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 35 35
  • 36. 6.グリッド(UICollectionView)Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 36 36
  • 37. UICollectionView概要 • UICollectionView はiOS6から追加されたViewです。これまでグリッド状 のUIは自力で実装する必要が有りましたが、これからは UICollectionView があるので楽チンになります!!(※iOS6以降のみで 利用可能です) • GridView → UICollectionView • Adapter → UICollectionView のデータソース • ????? → UICollectionViewController • UITableView と概ね同じような使い方ができるっぽいのですが... • すいません、準備不足でxibを用いたカスタムセルが上手く実装出来ません でした。カスタムセルなサンプルコードは StoryBorads なので、 ちょっと違 うんですよね。Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 37 37
  • 38. UICollectionView実装① ViewController4.h / m を作成する。 AppDelegate.m // グリッド UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; layout.itemSize = CGSizeMake(60, 60); // セクションとアイテムの間隔 layout.minimumLineSpacing = 2.0; // アイテム同士の間隔 layout.minimumInteritemSpacing = 2.0; layout.sectionInset = UIEdgeInsetsMake(12, 12, 12, 12); UIViewController *coll= [[ViewController4 alloc] initWithCollectionViewLayout:layout]; coll.title = @"グリッド"; tabBar.viewControllers = @[navi1, root2, root3, list, coll];Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 38 38
  • 39. UICollectionView実装② ViewController4.m - (void)viewDidLoad { [super viewDidLoad]; // 【追加】セルの登録 [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"]; } // 【追加】セクションの数を返す - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 2; } // 【追加】セルの数を返す - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section { if (section == 0) return 30; else return 18; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 39 39
  • 40. UICollectionView実装③ ViewController4.m // 【追加】セルを返す - (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath]; CGRect rect = CGRectMake(0.0, 0.0, 60.0, 20.0); UILabel *label = [[UILabel alloc] initWithFrame:rect]; [label setTextColor:[UIColor darkGrayColor]]; label.text = [NSString stringWithFormat:@"{%d,%d}", indexPath.section, indexPath.row]; [cell addSubview:label]; [cell setBackgroundColor:[UIColor whiteColor]]; return cell; }Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 40 40
  • 41. おわり おつかれさまでした!!Copyright (C) 2012 Groove Systems Inc. All Rights Reserved. 41 41