2011年8月3日水曜日

ストリングからクラスとセレクター(メソッド)生成

クラスやメソッド(@selector())はNSArrayやNSDictionary格納できない。
でも、NSStringからセレクターとクラスを生成できるからそれ格納しておけばおっけーですね!

Aclassname = @"TestView";
Bselectorname = @"TestMethod";

Class Aclass = NSClassFromString(Aclassname);
SEL Bselector = NSSelectorFromString(Bselectorname);

2011年6月20日月曜日

#defineの改行

#defineが長くて一行で収まらん!って時は改行できます

#define TES(__OBJ1,__OBJ2) {\
 if(__OBJ1!= __OBJ2){\
[__OBJ1 release];\
__OBJ1 =[__OBJ2 retain];} }

\のあとは何も入力せずに次の行にいくこと。スペースも駄目。
ちなみに"\"の入力はmacの場合「alt+¥」です。

2011年6月16日木曜日

UITabBarControllerのselectedIndex

UITabBarControllerのプロパティ、selectedIndexは
選択中のタブ番号(左から0~)返してくれるやつなんですが、
タブ切り替えでこのselectedIndexが変わるタイミングが若干ずれることに気づいた。

タブ0→タブ1に切り替えた際のタブ1の
ビューコントローラーで走るビューサイクルの例です。
※自分が乗ってるタブバーのインスタンス(tabBar)はどうにかして取得すること前提

-(void)viewWillAppear:(BOOL)animated{
     [super viewWillAppear:animated];
     NSLog(@"nowTabIndex:%d",tabBar.selectedIndex);//この時点ではtab0
}

-(void)viewDidAppear:(BOOL)animated{
     [super viewDidAppear:animated];
     NSLog(@"nowTabIndex:%d",tabBar.selectedIndex);//この時点ではtab1
}

…タブ切り替わった瞬間にindex変わろうよ!!

ところでタブバーに乗ってるビューコンからタブバーのインスタンスって
どうやって取得するんだ…?ナビコンみたいにセルフに問い合わせればたどり着けるの?
ぬーんタブバーあまり扱わないから未知数です…。

デフォルトフォント

意外に知ってると便利なのでデフォルトシリーズは
ここに書き出していく予定。
ログ出したらこうなった。

UIButtonのデフォルトフォント(xcode上で作成の場合)
 font-family: "Helvetica"; font-weight: normal; font-style: normal; font-size: 18px
 ※xibから作ったUIButtonのデフォルトフォント違うかもしれん

2011年6月1日水曜日

NSDictionaryの高速列挙

allValuesをつけると直接オブジェクトを取り出せるので覚えておくと便利かも。
そのかわりキーわからんけども。

-(void)firstEnum:(NSDictionary *)dict{
     for(NSString * keyname in dict){
            NSLog(@"キーは%@",keyname);
     }

     for(id obj in [dict allValues]){
            NSLog(@"オブジェクトは%@",obj);
     }
}

2011年5月28日土曜日

例外処理とAutoreleasePool

例外処理内で作ったAutoreleasePoolは@fainallyで解放しなくていいらしい

-(NSMutableArray *)testes{
 NSMutableArray * returnArr = [NSMutableArray array];
     @try{
       for(int Cnt= 0;Cnt<100;Cnt++){
           NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
       //[returnArr addObject:@"なにか"];  
            NSLog(@"%d番目は%@",Cnt,[returnArr objectAtindex:Cnt]);//←例外発生
            [pool release];//ここにはこない
       }
     }@catch (NSException * e) {
           NSLog(@"%@",e);
     }@finally {
     //pool解放なし
     }
     return returnArr;
}
…逆に今までfinallyに書いてたからクラッシュしてたのかしらー。

参考 NSAutoreleasePool祭り

2011年4月27日水曜日

キー値監視について

監視元1に対して監視先オブジェクトを複数作れる通知方法。
キーに関連づける値は一個じゃなくてもいいので依存度があまり高くない。
呼び出しメソッドの第2引数には監視先オブジェクトが入る。
第3、4は…よくわかってないです。
登録の解除は忘れずに。

/*---------監視するクラス---------*/

//ViewControllerの場合はwillAppearその他はinitでキー監視の宣言
-(void)viewWillAppear:(BOOL)animated{
      KansiClass * kansi = [[KansiClass alloc] init];
    //キー値監視登録
     [kansi addObserver:self forKeyPath:@"keyPath"
                            options:0 context:NULL];
}

//監視キーに変更があった場合に呼び出される
-(void)observeValueForKeyPath:(NSString*)keyPath
                                             ofObject:(id)object
                                                change:(NSDictionary*)change
                                                context:(void*)context{
       if([keyPath isEqualToString:@"keyPath"]){
               //値変更したらこのクラスでやりたいことを記述
        }
}

-(void)dealloc{
//登録の解除
      [kansi removeObserver:self forKeyPath:@"keyPath"];
   [kansi release];
      [super dealloc];
}
/*---------監視されるクラス内---------*/

-(void)changeKansi{
      [self willChangeValueForKey:@"keyPath"];
      //監視値の変更
      kansiValue = FALSE;
     [self didChangeValueForKey:@"keyPath"];
}

2011年3月3日木曜日

iPad2のミラーリング機能

iPad2が正式に発表されましたね。
なんとミラーリング機能が追加されたとか。…やっとか;
Apple Digital AVアダプタが必要らしいです。

↓詳しくはこちら↓
あなたの画面を共有しよう!Apple Digital AVアダプタ。

Apple Digital AVアダプタがあっても
iPad2以外はミラーリングできないとか。へえ。

2011年3月1日火曜日

ホームボタン押下でアプリを起動時の状態にリセットする※iOS4.0以降

iOS4.0以降はマルチタスクなのでホームボタン押下では
アプリは一時停止するだけです。次立ち上げた時は前回状態に復帰します。
これをFast App Switchingというらしい。

でもホームボタンを押したら4.0以前のように
アプリを完全終了させたいケースもある訳です。
ログイン系とかテストとかメモリとかメモリとかメモリとか。
それを可能にするのがApplication does not run in backgroundの設定です。

設定方法はプロジェクト名.plistで
Application does not run in backgroundの項目を追加し、
チェックをつけるだけ。

通常は4.0以降の実機やシュミレータにてビルドして実行した際ホームボタン押下で
プロジェクト起動しっぱなしですが、チェックを入れた際にホームボタン押下で
デバッグが終了しましたと、xcode上のステータスに表示されます。
覚えておくと便利かも。

※起動時には戻るとはいえ、アプリ自体はサスペンドにはいます。
 サスペンドから復帰させた時に起動画面に戻るだけです。
 完全終了でサスペンドからも消す方法はないんじゃないかと。

transformの合成、アニメーション基本(ちょっと修正

だいたいこんな感じ。Viewのtransformは常に上書きされる。
90度回転をtransformに設定した後、拡大を設定すると
90度回転はなかったことになってるので注意。
回転した状態で拡大する場合はCGAffineTransformConcatで
transformを合成して設定する必要がある。
ちなみに
animeView.transform = CGAffineTransformIdentity;
で初期状態にもどる

*3/1修正 回転も拡大縮小も中心起点だった;
      アフィン変換いまいちわかってないなー。
-(void)startAnime:(UIView*)animeView{
 //開始前に縮小しておく
 animeView.transform = CGAffineTransformMakeScale(0.1, 0.1);
 //アニメーション設定開始
 [UIView beginAnimations:nil context:NULL];
 //アニメーションの秒数
 [UIView setAnimationDuration:0.3];
 //動きの設定
 [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
 //delegate設定(endAnimeがいらないならnilでOK)
 [UIView setAnimationDelegate:self];
 //アニメーション終了後にやりたい処理
 [UIView setAnimationDidStopSelector:@selector(endAnime)];

 //90度回転しながら元の大きさに拡大
 CGAffineTransform transform1,transform2;
 transform1 = CGAffineTransformMakeRotation(M_PI * 90 / 180.0f);
 /*
 //ちなみに移動はこれ 
 transform1 = CGAffineTransformTranslate(transform1, 128, 128);
 */
 //拡大
 transform2=CGAffineTransformMakeScale(1.0, 1.0);
 //transformの合成
 CGAffineTransform concat = 
  CGAffineTransformConcat(transform1, transform2);
 //transformの適用
 [animeView setTransform:concat];
 //アニメーション設定終了
 [UIView commitAnimations];
}

-(void)endAnime{
 //アニメーション終了後にやりたい処理を書く
}

2011年2月28日月曜日

debugビルド以外NSLogを出さない

プロジェクトのOther Sourcesフォルダ内のアプリ名_Prefix.pchに以下を追加。
これを使うにはプリプロセッサにDEBUGを追加する必要あり詳しくはこっち
// Debbugログ出力切り替え
#ifdef DEBUG
# define NSLog(...) NSLog(__VA_ARGS__)
#else
# define NSLog(...) {}
#endif

NSNotificationの登録

//登録(didloadなどで)
[[NSNotificationCenter defaultCenter] addObserver:class 
selector:@selector(yobimethod:) name:@"notificationName" object:nil];

/*class内*/

-(void)yobu{//呼び出し※引数はなくてもOK 
   NSDictionary *userInfo = 
   [NSDictionary dictionaryWithObject:obj forKey:@"objkey"];
   
   [[NSNotificationCenter defaultCenter] postNotificationName:
        @"notificationName" object:nil userInfo:userInfo];
}


//呼び出されるメソッド
-(void)yobimethod:(NSNotification *)notification{
  NSString*key = [[notification userInfo] objectForKey:@"objkey"];
}

2011年2月24日木曜日

角丸UIView

#import <QuartzCore/QuartzCore.h>//使用クラスにインポートの必要あり

-(void)createKadomaru{
 UIView * maru = [[[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)] autorelease];
 maru.center = self.view.center;
 maru.backgroundColor = [UIColor whiteColor];
 maru.layer.cornerRadius = 4.0;//角の丸み 値が大きいほど丸い
 maru.clipsToBounds = YES;
 [self.view addSubview:maru];
}

←完成はこんな感じ。
今まで角丸部分は画像を用意してたのに…
これは便利。QuartzCoreのインポートを忘れないこと。
clipsToBoundsはUIViewのプロパティでYESならサブビューを
メインビューの内側に描画。(デフォルトはNO)

2011年2月22日火曜日

releaseとdebugで処理を変える

*前準備
Xcode上の左グループとファイル内の最上位にあるプロジェクト名のファイルをクリック
→情報→ビルドタブ→GCC 4.2 - プリプロセス項目内のプリプロセッサマクロに
DEBUGと追加

クラス(どれでもいい)に下記を書くことで処理を分けられる
#ifdef DEBUG
NSLog(@"debugはこっちを通る");
#else
NSLog(@"release,distributionはこっちを通る");
#endif

2011年1月19日水曜日

NSArray 逆順に高速列挙

NSArray * array=[NSArray arrayWithObjects:
          @"a",@"b",@"c",@"d",@"e",nil];
for(NSString*obj in [array reverseObjectEnumerator]){
  NSLog(@"word=%@",obj); 
}
eから順にaまで出力されます。よしよし。

ちなみに、高速列挙中に列挙しているarrayの要素を
足したり消したりしたらエラーになる。

クラス比較

配列に入っているオブジェクトが何のクラスかで処理を変える時等に使えます。
比較クラスを継承したサブクラスの場合も結果はTRUEになるので注意。

BOOL stringflg = [obj isKindOfClass:[NSString class]];

2011年1月13日木曜日

drawRect 再描画の注意点

UIViewなどにdrawRectで描画した線や図形を消去、再描画するには
//全再描画
[drawView setNeedsDisplay];
//一部再描画なら
[drawView setNeedsDisplayInRect:CGRectmake(0,0,100,100)];
をする。注意したいのはdrawViewが元々透明でなければ
前回分の描画が残ってしまうということ。

drawViewのinitWithFrameメソッド内にでも透明プロパティを設定すること!
※初期値は不透明の設定
drawView.opaque=YES
drawRectで描いたものはUIViewの背景色みたいな扱いだから
違う位置に再描画しても前回分が残ってしまうのかなーとか思うことに。
ちなみに前回分を消去して画面をクリアにしたい場合は、View自体になんか
フラグでも持たせてdrawRect内の描画部分をフラグによって素通りするように
すればいいと思います。

?:(クエスチョン、コロン)の3項演算

たまに見かけるこれ、

 式1?式2:式3

3項演算というらしい。
式1の結果がTRUEなら式2実行、式3無視。
式1の結果がFALSEなら式3実行、式2無視という動き。
式1の結果は必ずBoolean型でないと駄目。

int c = ( a>b ? a+b : a-b);
NSLog(@"c=%d",c);

a=3,b=2の時、cは5
a=2,b=3の時、cは-1
となる。 

2011年1月6日木曜日

NSNotificationの解除

NSNotificationを登録したらdeallocで以下を入れておく。
登録したNotificationを全て削除できる。便利。
[[NSNotificationCenter defaultCenter] removeObserver: self];

notification名を指定して削除もできる。
一つだけ削除するとか何か意味があるんだろうか…?
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationname" object:nil];