2013年1月13日日曜日

Custome UITableViewCellの[self addSubview]と[self.contentView addView]の違い

UITableViewCellを継承してカスタムセルを作成する場合に
self.contentViewに対してaddSubviewするのと
selfにaddSubviewするのとではぱっと見同じでどこが違うんだろうというところが気になったので調べてみた。

わかりやすく背景に色をつけてやってみた。
赤背景 : contentView
青背景 : subviewに追加するview

self版

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.comment = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 30)];
        [self.comment setBackgroundColor:[UIColor blueColor]];
        [self addSubview:self.comment];
        [self setBackgroundColor:[UIColor blueColor]];
        [self.contentView setBackgroundColor:[UIColor redColor]];
    }
    return self;
}

self.contentView版


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.comment = [[UILabel allocinitWithFrame:CGRectMake(101020030)];
        [self.comment setBackgroundColor:[UIColor blueColor]];
        [self.contentView addSubview:self.comment];
        [self setBackgroundColor:[UIColor blueColor]];
        [self.contentView setBackgroundColor:[UIColor redColor]];
    }
    return self;
}


普通にaddSubviewするだけだと同じ。

http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1

ドキュメント見るとcontentViewの領域は編集とかアクセサリーViewと被らないようにするためっぽい。

■アクセサリーViewを有効にしてみる


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self setAccessoryType:UITableViewCellAccessoryCheckmark];
        
        self.comment = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 30)];
        [self.comment setBackgroundColor:[UIColor blueColor]];
        [self addSubview:self.comment];
        [self setBackgroundColor:[UIColor blueColor]];
        [self.contentView setBackgroundColor:[UIColor redColor]];
    }
    return self;
}


contentViewの領域が変わった

■編集モードにしてみる( [tableview setEditing:YES] )

self版


self.contentView版


■TableViewのスタイルをグループにする( UITableViewStyleGrouped )

self版




self.contentView版


結論とするとTableViewのスタイルをグループにしたり、編集とかaccessoryViewを使う場合に綺麗に表示するにはcontentViewにaddSubviewしたほうがいいです。
というかドキュメント通りに基本contentViewにaddSubviewすべきです。

2012年11月29日木曜日

CakePHPで The requested address not found

CakePHPでいかのようなエラーが出た場合、

Error: The requested address ' ' was not found on this server.

core.phpの

Configure::write('debug', 0);

を0から1に変更したらなおった

root権限の付与

昔はこんなことしなくてよかったような気がするけど
毎回忘れるので

> su
> visudo

でviで設定ファイルが開かれ編集する。

root     ALL=(ALL)  ALL

のようにユーザーごとにsudoの権限を設定してやらないといけない

2012年10月29日月曜日

CoreDataのデータを全て削除


(BOOL)resetDatastore
{
    [[self managedObjectContext] lock];
    [[self managedObjectContext] reset];
    NSPersistentStore *store = [[[self persistentStoreCoordinator] persistentStores] lastObject]; 
    BOOL resetOk = NO;

    if (store)
    {
        NSURL *storeUrl = store.URL;
        NSError *error;

        if ([[self persistentStoreCoordinator] removePersistentStore:store error:&error])
        {
            [[self persistentStoreCoordinator] release];
            __persistentStoreCoordinator = nil;
            [[self managedObjectContext] release];
            __managedObjectContext = nil;

            if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error])
            {
                NSLog(@"\nresetDatastore. Error removing file of persistent store: %@",
                  [error localizedDescription]);
                resetOk = NO;
            }
            else
            {
                //now recreate persistent store
                [self persistentStoreCoordinator];
                [[self managedObjectContext] unlock];
                resetOk = YES;
            }
        }
        else
        {
            NSLog(@"\nresetDatastore. Error removing persistent store: %@",
              [error localizedDescription]);
            resetOk = NO;
        }
        return resetOk;
    }
    else
    {
        NSLog(@"\nresetDatastore. Could not find the persistent store");
        return resetOk;
    }
}

2012年10月28日日曜日

半透明のviewを重ねる

半透明のviewの上にviewを以下のように重ねると
子のviewのalphaも親のalphaに引きづられてしまい、子のviewのalphaを1.0に設定してもどちらも半透明になってしまう。


    UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
    view.alpha = 0.5;
    [self.navigationController.view addSubview:view];
    
    UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(25, 25, 50,50)];
    childView.backgroundColor = [UIColor whiteColor];
    childView.alpha = 1.0;

これを解決するにはviewではなく、background colorのUIColorのalphaを変える必要がある。

    UIView* view = [[UIView allocinitWithFrame:CGRectMake(00, 100,100)];
    view.backgroundColor = [[UIColor blackColorcolorWithAlphaComponent:0.5];
    [self.navigationController.view addSubview:view];
    
    UIView* childView = [[UIView allocinitWithFrame:CGRectMake(252550,50)];
    childView.backgroundColor = [UIColor whiteColor];





2012年10月14日日曜日

iOS6変わったとこなど

相当すぎてますが、NDAも解禁ということで、、

UIViewControllerでメソッドがDeprecateされた

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html

modalView系が他のメソッドに完全に置き換わったのと、回転系のメソッドが変わったのと、unload系が呼ばれなくなってます。

Deprecateされたメソッドとその対策

廃止:modalViewController
代替手段:presentedViewController

廃止:automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
代替手段:shouldAutomaticallyForwardRotationMethods とshouldAutomaticallyForwardAppearanceMethods

廃止:dismissModalViewControllerAnimated:
代替手段:dismissViewControllerAnimated:completion:

廃止:presentModalViewController:animate
代替手段:presentViewController:animated:completion:

廃止:shouldAutorotateToInterfaceOrientation:
代替手段:supportedInterfaceOrientations と preferredInterfaceOrientationForPresentation をオーバーライド
廃止:viewDidUnload

廃止:viewWillUnload

viewUnload系はメモリが少なくなった場合でも呼ばれなくなった。

view**Unloadについてはこちらによく書かれています。
メモリワーニング対応としてはdidReceiveMemoryWarningでどうにかするしかないですね
http://www.zero4racer.com/blog/929
回転についてはこちらなど

縦長対応

iPhone5が 640 * 1136 になったのでそれに対応せねばならない。

スプラッシュ画像の対応
以下の名前のファイルを追加すればいい

Default-568h@2x.png

storyboardの変更
storyboardの画面右下の画面の ○ボタンを押せば画面が縦長になる


armv7sの追加

3rdParty性のライブラリを使ってたりしない限りはあまり関係ないですが、使っている場合はそのライブラリがarmv7s用のバイナリを含んでいない場合は、ビルドするときにarmv7sを消さないとだめです。

UICollectionViewが追加
データの一覧表示するのにこれまではTableViewしかなかったのが、UICollectionViewという別の表現手段が用意されました。使い方はパッと見UITableViewとかなり酷似しているのでそれほど難しくはなさそう。


UIRefreshControlが追加

引っ張って更新するのがフレームワークに導入された

これまではEGOTableViewPullRefreshさんにお世話になってましたが、iOS6からはオワコンになります。
UIRefreshControlはもちろんiOS6でしか動かないので、しばらくはまだオープンソースのほうが使われるでしょう。

NSHashTable, NSMapTable, NSPointerArray, NSPointerFunctions,とか増えた

この理解であっているかはちと怪しいが

NSHashTableはNSSetのweak reference版
NSMapTableはNSDictionaryのweak reference版
NSPointerArrayはNSArrayのweak reference版(ただしARC環境ではサポートしないと書いてある)

2012年9月18日火曜日

Objective-Cのクラスメソッドの差し替え

テストのときにUIAlertViewの表示を消してくれるライブラリで
どうやってUIAlertViewのメソッドをフックしてるのかと調べてみたところ
method_exchangeImplementations()を使って実装されてた。


+ (void)swapInstanceMethodsForClass: (Class) cls selector: (SEL)sel1 andSelector: (SEL)sel2 {
    Method method1 = class_getInstanceMethod(cls, sel1);
    Method method2 = class_getInstanceMethod(cls, sel2);
    method_exchangeImplementations(method1, method2);
}
method_exchangeImplementations()を使えばこのようにクラスメソッドを差し替えられるのでテストでは便利。