iOSアプリ開発の逆引き辞典

iPhone/iPadで使えるアプリ開発のTipsをまとめてみました

UIScreenクラスを使ってディスプレイの解像度(サイズ)を取得する

UIScreenクラスは、ディスプレイに関する情報を取得することができるクラスです。

ディスプレイサイズを取得する

ディスプレイサイズを取得するには、UIScreenクラスのscaleプロパティを使用します。

CGRect screenSize = [[UIScreen mainScreen] bounds];  

ディスプレイの密度を取得する

UIScreenクラスのscaleプロパティを取得することで、ディスプレイの密度を取得する事ができます。これによって実行デバイスがRetinaディスプレイを搭載しているかどうかを判定することができます。

CGFloat scale = [[UIScreen mainScreen] scale];

このscaleの値が、iPhone 3GSやiPad miniの標準解像度の場合は1.0、iPhone 4以降のRetinaディスプレイの場合2.0となります。

ステータスバーを含まない領域のサイズを取得する

ステータスバーを含まない領域のサイズを取得するには、UIScreenクラスのapplicationFrameプロパティを使用します。

CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];

UIImageオブジェクトからアルファ値(alpha channel)の配列を取得する

iOSではビットマップは32bitのRGBAで扱われます。

重なりあった複雑な描画やUIViewのヒットテストでhitTest:withEvent:メソッドの判定などでUIImageに設定されている画像のアルファ値(alpha channel)を使いたいシーンがあります。

本記事ではUIImageオブジェクトからアルファ値の配列を取得する方法をご紹介します。

- (NSData *)alphaDataWithImage:(UIImage *)image
{
    CGImageRef imageRef = image.CGImage;
    
    CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
    NSData *pixelData = (__bridge NSData*) dataRef;
    unsigned char *buffer = (unsigned char *)[pixelData bytes];
    
    size_t width = CGImageGetWidth(imageRef);
    size_t height = CGImageGetHeight(imageRef);
    size_t pixelSize = CGImageGetBitsPerPixel(imageRef) / 8;
    
    // Get alpha data.
    size_t size = width * height;
    unsigned char array[size];
    for (int i = 0; i < size; i++) {
        unsigned char alpha = * (buffer + (i * pixelSize + 3));
        array[i] = alpha;
    }
    
    NSData* data = [NSData dataWithBytes:(const void *)array
                                  length:sizeof(unsigned char) * size];
    
    CFRelease(dataRef);
    return data;
}

上記のalphaDataWithImage:メソッドを以下のように使用してアルファ値を取得します。

UIImage *image = [UIImage imageNamed:@"test_image"];
NSData *alphaData = [self alphaDataWithImage:image];

デバイスの向きを定義するUIDeviceOrientation列挙型

デバイスの向きを定義するUIDeviceOrientation列挙型には下記のような定義が存在しています。

説明
UIDeviceOrientationPortrait iPhoneを縦にして、ホームボタンが下にある状態
UIDeviceOrientationPortraitUpsideDown iPhoneを縦にして、ホームボタンが上にある状態
UIDeviceOrientationLandscapeLeft iPhoneを横にして、ホームボタンが左にある状態
UIDeviceOrientationLandscapeRight iPhoneを横にして、ホームボタンが右にある状態
UIDeviceOrientationFaceUp iPhoneの液晶面を天に向けた状態
UIDeviceOrientationFaceDown iPhoneの液晶面を地に向けた状態
UIDeviceOrientationUnknown 向きが分からない状態

それぞれがどのような状態なのかをiPhoneシミュレータを使用して紹介します。

UIDeviceOrientationPortrait (縦向き)

f:id:ch3cooh393:20140301032402p:plain

UIDeviceOrientationPortraitUpsideDown (縦向き、逆さま)

f:id:ch3cooh393:20140301032403p:plain

UIDeviceOrientationLandscapeLeft (横向き、ホームボタンが左)

f:id:ch3cooh393:20140301032405p:plain

UIDeviceOrientationLandscapeRight (横向き、ホームボタンが左)

f:id:ch3cooh393:20140301032404p:plain

デバイスが回転されたことを検出する

iPhone/iPadアプリでデバイスを回転させて横向きにすると、より詳細にデータ表示したい時があります。デバイスを回転されたのとトリガーにして

デバイスが回転されたかの監視を開始する

UIDeviceクラスのインスタンスのbeginGeneratingDeviceOrientationNotificationsメソッドを実行することで、センサーデバイスの有効にして加速度の変化の配信を開始します。

アプリ側でデバイスの向きの変化を受信する為には、通知センターにUIDeviceOrientationDidChangeNotification通知が発生した時に通知してもらえるように登録します。

-(void)viewDidAppear:(BOOL)animated
{
    // 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    
    // 通知を解除する
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(didChangedOrientation:)
        name:UIDeviceOrientationDidChangeNotification object:nil];
}

デバイスが回転されたかの監視を終了する

通知を受け取るのを止める時には、通知センターから通知を受けるのを解除します。合わせてセンサーデバイスからの通知を止めてしまいましょう。

- (void)viewDidDisappear:(BOOL)animated
{
    // 通知を解除する
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc removeObserver:self
        name:UIDeviceOrientationDidChangeNotification object:nil];
    
    //
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}

デバイスが回転された通知を受け取る

前述のサンプルコードでは、デバイスの向きを変更するとdidChangedOrientation:メソッドに通知がくるように通知センターへ登録しました。

通知センターからはNSNotificationクラスで通知されてくるのでobjectプロパティ、さらにorientationプロパティを取得するとデバイスの向きを定義するUIDeviceOrientation列挙型の値を取得することができます。

- (void)didChangedOrientation:(NSNotification *)notification
{
    UIDeviceOrientation orientation = [[notification object] orientation];
    switch (orientation) {
            
        case UIDeviceOrientationPortrait:
            // iPhoneを縦にして、ホームボタンが下にある状態
            break;
            
        case UIDeviceOrientationPortraitUpsideDown:
            // iPhoneを縦にして、ホームボタンが上にある状態
            break;
            
        case UIDeviceOrientationLandscapeLeft:
            // iPhoneを横にして、ホームボタンが左にある状態
            break;
            
        case UIDeviceOrientationLandscapeRight:
            // iPhoneを横にして、ホームボタンが右にある状態
            break;
            
        case UIDeviceOrientationFaceUp:
            // iPhoneの液晶面を天に向けた状態
            break;
            
        case UIDeviceOrientationFaceDown:
            // iPhoneの液晶面を地に向けた状態
            break;
            
        case UIDeviceOrientationUnknown:
        default:
            // 向きが分からない状態
            break;
    }
}

UIDeviceOrientation列挙型には、下記のような定義が存在しています。UIDeviceOrientation列挙型については「デバイスの向きを定義するUIDeviceOrientation列挙型 - iOSアプリ開発の逆引き辞典」で詳細に紹介していますので合わせてお読みください。

説明
UIDeviceOrientationPortrait iPhoneを縦にして、ホームボタンが下にある状態
UIDeviceOrientationPortraitUpsideDown iPhoneを縦にして、ホームボタンが上にある状態
UIDeviceOrientationLandscapeLeft iPhoneを横にして、ホームボタンが左にある状態
UIDeviceOrientationLandscapeRight iPhoneを横にして、ホームボタンが右にある状態
UIDeviceOrientationFaceUp iPhoneの液晶面を天に向けた状態
UIDeviceOrientationFaceDown iPhoneの液晶面を地に向けた状態
UIDeviceOrientationUnknown 向きが分からない状態

参考