iOSアプリ開発のメモ置き場

ささたつがiOSアプリ開発で知ったObjective-Cのtipsなどを書いていく所存

UILongPressGestureRecognizer を使ってイベントを登録すると二重に呼ばれる!?

タイトルの通りですが、UILongPressGestureRecognizer を使ってイベントを登録するとなぜかイベントが二重に呼ばれてしまうので困っていました。

なんと、長押ししたタイミングで発火するものと、指を話したときに発火するものがあるみたいですね。なんやこの(謎)仕様はー!!

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{ 
    if (sender.state == UIGestureRecognizerStateEnded) {
        // 指を離したときに何か処理をしたければこちら
    } else if (sender.state == UIGestureRecognizerStateBegan){
        // 長押ししたタイミングで何か処理をしたければこちら
    }
}

tableViewCell に自作の xib ファイルを利用する方法

1) 適当な xib ファイル(今回は CustomCell.xib というのを作成した)を作成する。ここでデザインは行う。

2) CustomCell.xib の UILabel などをカスタマイズするために、UITableViewCell を継承したカスタムセルを作成する(今回は CustomTableViewCell というのを作成した)

3) CustomCell.xib のクラスとして CustomTableViewCell を指定する(そうしないと IBOutlet が紐付けられない)

f:id:sasata299:20140416105035p:plain

4) コントローラ側で xib ファイル名と適当な Identifier を指定して登録する

[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"MyCell"];

5) tableView の cell を返すときに、先ほど指定した Identifier を指定する

CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];


※ 2) と 3) は UILabel などを動的にカスタマイズしない場合には不要


参考:mixi-inc/iOSTraining - 4.3 セルのカスタマイズ

NSUserDefaults に自作クラスのオブジェクトを保存する

NSUserDefaults にデフォルトで保存できるのは NSString や NSDictionary など一部のもののみなので、自作クラスのオブジェクトを保存するためには NSData (バリナリ) にシリアライズしてあげる必要がある。


シリアライズして NSUserDefaults に保存する

// user は User クラスのオブジェクト
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:user] // このとき [user encodeWithCoder:] が呼ばれる
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"userData"];


NSUserDefaults から取り出して デシリアライズする

NSData *data = (NSData*)[[NSUserDefaults standardUserDefaults] objectForKey:@"userData"]
User *user = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // このとき [user initWithCoder:] が呼ばれる

下に引っ張って更新 (Pull to Refresh) する方法

UITableViewController の refreshControl っていうプロパティにセットするだけ!簡単すぎてビックリ!

以前は大変だったみたいだけど、iOS6 から簡単になったみたいですね〜

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.refreshControl = [[UIRefreshControl alloc] init];
    [self.refreshControl addTarget:self action:@selector(onRefresh:) forControlEvents:UIControlEventValueChanged];
}

- (void)onRefresh:(id)sender
{
    // 更新開始
    [self.refreshControl beginRefreshing];
    
    // 更新処理をここに記述
    
    // 更新終了
    [self.refreshControl endRefreshing];
}