statusBar、navigationBar、tabBarの高さを取得

ステータスバーの高さ
float
statusbarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

ナビゲーションバーの高さ
float
navigationbarHeight = self.navigationController.navigationBar.frame.size.height;

タブバーの高さ
float tabbarHeight = tabBarController.tabBar.frame.size.height;

CloudKitのデータベースで接続中のユーザーアカウントで作ったレコードを取得する

全体の流れ
1.接続中のユーザーのRecordIDを取得する
2.そのRecordIDを使ってクエリーを書く
3.クエリーを実行する

このまま書くとRecordIDが取得できる前に2が実行されてしまう。
1の部分はアプリ起動時等に先にやっておくのが良いと思う。

//接続中のユーザーのRecordIDを取得する
CKContainer*container=[CKContainer defaultContainer];
[container fetchUserRecordIDWithCompletionHandler:^(CKRecordID * recordID, NSError * error) {
    if(error==nil){
    NSLog(@”user fetch done”);
    self.userID=recordID;
}];

//そのRecordIDを使ってクエリーを書く
NSPredicate*predicate=[NSPredicate predicateWithFormat:@”creatorUserRecordID = %@”,[[CKReference alloc] initWithRecordID:recordID action:CKReferenceActionNone]];
CKQuery*query=[[CKQuery alloc]initWithRecordType:@”TargetRecords” predicate:predicate];

//クエリーを実行する
CKDatabase*publicDB=[CKContainer defaultContainer]publicCloudDatabase];
[publicDB performQuery:query inZoneWithID:nil completionHandler:^(NSArray*results,NSError*error){
    if(results.count>0){
        NSLog(@”userRecord fetch %lu”,(unsigned long)results.count);
    };
}];

CloudKitのデータベースで 現在接続中のUsersレコードを取得する

全体の流れ
1.データベースをセット
1.UsersレコードにアクセスできるOperation取得
2.レコード読み込み時のブロックをセット
4.Operation実行

//データベースをセット
CKDatabase*publicDB=[[CKContainer defaultContainer] publicCloudDatabase];

//UsersレコードにアクセスできるOperation取得
CKFetchRecordsOperation*operation=[CKFetchRecordsOperation fetchCurrentUserRecordOperation];

//レコード読み込み時のブロックをセット    operation.perRecordCompletionBlock=^(CKRecord*record,CKRecordID*recordID,NSError*error){
    if(error==nil){
         NSLog(@”user fetch done”);
         self.userID=recordID;
         self.user=record;
    }
};

//Operation実行
[publicDB addOperation:operation];

 

CloudKitで親子のテーブルのひも付け

全体の流れ
1.親のレコードからCKReferenceを得る
2.子レコード作る
3.子レコードのReferenceに入れる
4.子レコードを保存

親レコード:parentRecord
子レコードのタイプ:RecordType
子レコードにはCKReference型の”ref”カラムがあるとする。

//親レコードからCKReferenceを取得
CKReference*parentRef=[[CKReference alloc]initWithRecord:parentRecord action:CKReferenceActionDeleteSelf];

//子レコードを作る
CKRecord*newRecord=[CKRecord alloc]initWithRecordType:@”RecordType”];

//子レコードにCKReferenceをセット
[newRecord setValue:parentRef forKey:@”ref”];
…ここでその他のデータもセット

//保存
[publicDB saveRecord:record completionHandler:^(CKRecord*savedRecord,NSError*error){
}];

CoreDataのクエリーの書き方(NSPredicate,NSSortDescriptor)の書き方

全体の流れ
1.エンティティをセット
2.検索条件をセット(NSPredicate)
3.並び順をセット(NSSortDescriptor)
4.クエリー実行
5.CoreDataのクエリーだけでなく、CloudKitからのクエリーやNSArrayからの検索にも使える
6.NSPredicateは単純な比較もかけるし、predicateWithBlockを使えばかなり複雑なことも書ける

NSEntityDescription*entity = [NSEntityDescription entityForName:@”Item” inManagedObjectContext:self.context];
NSFetchRequest*req = [[NSFetchRequest alloc]init];

//リクエストにエンティティをセット
[req setEntity:entity];

//検索条件をセット
NSPredicate*predicate=[NSPredicate predicateWithFormat:@”registDate = %@”,selectedDate];
[req setPredicate:predicate];

//ソートを書く
NSSortDescriptor*sort1=[[NSSortDescriptor alloc]initWithKey:@”name” ascending:YES];
NSSortDescriptor*sort2=[[NSSortDescriptor alloc]initWithKey:@”registDate” ascending:YES];
NSArray*sortArray=@[sort1,sort2];
[req setSortDescriptors:sortArray];

//実行
NSArray*result=[self.context executeFetchRequest:req error:&error];


 

//中の要素をみながら比較する場合。条件に一致する場合はYESを返す
NSPredicate*predicate=[NSPredicate predicateWithBlock:^BOOL(id  record, NSDictionary * bindings) {
    if([record valueForKey:@”registDate”] == selectedDate){
        return YES;
    }else{
        return NO;
    }
}];

 

AutoLayoutの制約をコードで書く

全体の流れ
1.子になるViewを作る
2.親のViewに追加する
3.制約を書く
4.制約を追加する

親のViewにUIImageViewを追加してみる

UIImageView*imageView=[[UIImageView alloc]init];
imageView.translatesAutoresizingMaskIntoConstraints=NO;
[self.view addSubView:imageView];

NSMutableArray*array=[[NSMutableArray alloc]initWithCapacity:0];

//高さが300
[array addObject:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:300.0]];

//左は16開ける
[array addObject:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:16.0]];

//右も16開ける
[array addObject:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-16.0]];

//上は100開ける
[array addObject:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:100.0]];

[self.view addConstraints:array];
[self.view layoutIfNeeded];

iOS8からは制約の追加は
[NSLayoutConstraint activateConstraints:array]
って書くらしい。
制約の追加先を考えなくてもいいのは楽かも。


センターを揃える時
[array addObject:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:100.0]];

アスペクト比を決める場合(この例は横が縦の半分)
[array addObject:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:imageView attribute:NSLayoutAttributeHeight multiplier:1.0/2.0 constant:0.0]];

CloudKitで複数のアプリからデータベースを共有する

全体の流れ
1.App1とApp2からデータを共有するプラン
2.App1からは普通に接続
3.App2からはidを指定して接続

App1側
CKContainer*container=[CKContainer defaultContainer];

App2側
//App1のiCloudのidを指定する
CKContainer*container=[CKContainer containerWithIdentifier:@”xxx.iCloud.App1″];

 

UIImageViewでアニメーション(画像を入れ替える)

全体の流れ
1.NSArrayにいくつかの画像をセット
2.UIImageViewにそのArrayをセット
3.各種設定(タイミングとか)をセット
4.アニメーションスタート

UIImage *image1 = [UIImage imageNamed:@”hoge1.png”];
UIImage *image2 = [UIImage imageNamed:@”hoge2.png”];

UIImage *image3 = [UIImage imageNamed:@”hoge3.png”];

NSArray *images = [NSArray arrayWithObjects:image1, image2, image3, image4, nil];

self.imageView.animationImages = images;
// 3秒ごとに画像を変える
self.imageView.animationDuration = 3.0f;
// 3回繰り返し。0で無限
self.imageView.animationRepeatCount = 3;
 // アニメーションを開始

[self.imageView startAnimating];

// アニメーションを終了
// [self.imageView stopAnimating];

残念ながら画像が切り替わる時のエフェクトはつけられない。パッ、パッて変わる。

UITableViewで最下行以降は線を出さない

全体の流れ
1.UITableViewのフッターを設定するとそれ以降の行は表示されない。

【フッターに文字列を入れる場合】
-(NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
return @”これがフッターに出ます”;
}

【フッターの背景色を変える場合】
-(void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section{
[view setTintColor:[UIColor colorWithRed:1.f green:0.611f blue:0.905f alpha:1]];
}