スライドショーのフルスクリーン化(2)

2010. 06. 17
イベント処理の実装は、新たに作ったUITouchableImageView.mと既存のSlide.mで実装しています。

UITouchableImageView.mにはビューで受け取るイベントの処理として、タップ回数の判別と、タップ回数別に呼び出すメソッドを2種実装し、Slide.mにはシングルタップした場合のフルスクリーン処理のメソッドを実装します。


●UITouchableImageView.mソースファイルの編集

UITouchableImageViewのソースファイルを編集します。
(太字が追加した部分)

#import "UITouchableImageView.h"

@implementation UITouchableImageView

- (id)initWithFrame:(CGRect)frame {

    tapCount = 0;

    if ((self = [super initWithFrame:frame])) {
        // Initialization code
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (void)dealloc {
    [super dealloc];
}

- (void)singleTap {
    if (tapCount == 1) {    // シングルタップの確認
        // フルスクリーンの開始と解除
        [slide enterOrExitFullScreen];
    }
}

- (void)doubleTap {
    if (tapCount == 2) {    // ダブルタップの確認
        // スライドショーの開始と停止
        [slide startStop:nil];
    }
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // タッチ情報の集合から1つを取り出す
    UITouch *touch = [touches anyObject];

    // タップカウントを取得
    tapCount = touch.tapCount;

    switch (tapCount) {
        case 1:    // シングルタップの処理
            [self performSelector:@selector(singleTap) withObject:nil afterDelay:0.4f];
            break;
        case 2:    // ダブルタップの処理
            [self performSelector:@selector(doubleTap) withObject:nil afterDelay:0.4f];
            break;
    }
}

@end

436

クラスの追加時に『Subclass of』で『UIView』を選択すると、initWithFrame:からdeallocまでが自動で挿入されます。

この自動挿入部に関しては本書で触れられていないのですが、サンプルコードを見ると、initWithFrame:でtapCount(タップ回数)の初期化を追加しているのと、drawRect:が有効になっています(コードの追加は無し)。

initWithFrame:はビューの初期化を行うメソッドですが、ここではtapCountの初期化を行っているだけです。

drawRect:は画像を描画するためのものですが、コメント欄に

『カスタム描画を行う場合だけ、drawRect:をオーバーライドしてください。
空の実装を行うと、アニメーションの実行中に不具合が出ます。』

とあるので、空実装はせずにコメントアウトしておくのが正しいと思われます。

deallocは特に変更することはないので、そのままにしておきます。

singleTapはシングルタップ時にSlide.mに実装するフルスクリーン切り替えメソッド(enterOrExitFullScreen)を呼び出します。

doubleTapはダブルタップ時にStart/Stop切り替えボタンのメソッド(startStop)を呼び出します。

touchesEnded:withEvent:は、タップした指を離した際に呼ばれるUIResponderのメソッドをオーバーライドして使用しています。

タッチ操作をセット(NSSet)として受け取った後に、tapCountプロパティでタップ回数を抽出し、判定に使用します。

switch文での分岐は、イベントを処理する際の遅延(ディレイ)を設定(0.4秒)するもので、0.4秒間のタップ回数が1回ならシングルタップ、2回ならダブルタップと判別しています。

touchesEnded:withEvent:はタップ毎に呼ばれるので、この処理を設けないとタップを1回した時点でsingleTapが呼び出されてしまい、ダブルタップが認識されないためです。


・initWithFrame:
(UIViewクラス)

- (id)initWithFrame:(CGRect)aRect

指定したフレーム矩形のビューオブジェクトを新規に割り当て、初期化して返します。

戻り値は初期化したビューオブジェクト、オブジェクトが生成できなかった場合はnilを返します。

新しいビューオブジェクトは、使用する前にウィンドウのビュー階層に入っている必要があります。

プログラムでビューオブジェクトを生成した場合、このメソッドはUIViewクラスのイニシャライザを指定します。

インターフェイスの設計にIntereface Builderを使う場合は、nibファイルからビューオブジェクトを読み込んだ後で、このメソッドを呼び出さないでください。

nibファイル内のオブジェクトを復元し初期化するにはinitWithCoder:メソッドを使用し、nibファイル内の属性とビューの属性が一致するように修正してください。

nibファイルからのビューの読み込みに関する詳細情報は、Resources Programming Guideを参照してください。

aRect:フレーム矩形のビューオブジェクトを生成します。
フレームの原点はスーパービューの座標になります。
このプロパティの設定は、centerとboundsプロパティの値によって変わります。


・drawRect:
(UIViewクラス)

- (void)drawRect:(CGRect)rect

渡された矩形の中に、レシーバの画像を描画します。

サブクラスでこのメソッドをオーバーライドする際は、実際にビューを描画します。

サブクラスが他のビューのコンテナの場合、このメソッドでサブクラスをオーバーライドする必要はありません。

デフォルトでは何も実装しません。

UIViewサブクラスを直接カスタムビューにする場合は、superの実装を呼び出す必要はありません。

スーパークラスの実装で実際に描画し、opaqueがYESの場合は、各サブクラスがrectをすべて満たす責任があります。

このメソッドを呼び出すと、レシーバはフレームと境界矩形の座標変換を引き受けて適用することができます。
(描画するクライアントの関数をすべて呼び出す必要があります)

現在描画する画像の内容を取得するUIGraphicsGetCurrentContext関数を使う場合は、同様に左上角が座標の原点になります。

drawRect:メソッドを呼び出している間は画像の内容が変更可能なので、保持しないでください。

rect:描画する限定範囲の矩形を定義します


・touchesEnded:withEvent:
(UIResponderクラス)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

ビューまたはウィンドウから、指を一本以上離した時にレシーバに伝えます。

このメソッドはデフォルトでは何も実装しません。

オブジェクトがtouchesEnded:withEvent:メッセージを受け取る際には、touchesBegan:withEvent:の実装で確立された状態情報をクリアする必要があります。

マルチタッチはデフォルトでは無効です。

マルチタッチイベントを受け取れるようにするには、一致するビューインスタンスのmultipleTouchEnabledプロパティをYESに設定する必要があります。


・anyObject
(NSSetクラス)

- (id)anyObject

レシーバの中のオブジェクトを一つ、またレシーバにオブジェクトが含まれていない場合はnilを返します。

返されるオブジェクトは、レシーバの都合の良いものが選ばれます。
(この選抜はランダムであることが保証されていません)


・tapCount
(UITouchクラス)

@property(nonatomic, readonly) NSUInteger tapCount

指でタップした回数を返します。(読み取り専用)

このプロパティの値は整数で示され、予め定義した期間に一定の位置を、ユーザが指でタップした回数を表します。

特定のビューまたはウィンドウで、ユーザのシングルタップ、ダブルタップ、またはトリプルタップを決定するには、このメソッドで返される値で評価してください。


・performSelector:withObject:afterDelay:
(NSObjectクラス)

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

デフォルトモードで使われているレシーバの現在のスレッドの遅延後、メソッドを呼び出します。

このメソッドは、実行ループの現在のスレッドでタイマーを設定し、aSelectorメッセージを実行します。

タイマーはデフォルトモード(NSDefaultRunLoopMode)で実行されるように構成されています。

タイマーが発火すると、スレッドは実行ループの待ち行列(キュー)のメッセージを取り出し、セレクタの実行を試みます。

デフォルトモードでの実行ループの実行ができれば成功で、そうでなければ実行ループがデフォルトモードになるまでタイマーは待機します。

デフォルトモード以外の実行ループのモードでメッセージを受け取りたい場合は、代わりにperformSelector:withObject:afterDelay:inModes:を使用してください。

メインスレッドでのセレクタの実行を確実に行いたい場合は、代わりにperformSelectorOnMainThread:withObject:waitUntilDone:またはperformSelectorOnMainThread:withObject:waitUntilDone:modes:メソッドを使用してください。

待ち行列のメッセージを取り消す場合は、cancelPreviousPerformRequestsWithTarget:またはcancelPreviousPerformRequestsWithTarget:selector:object:メソッドを使用してください。

このメソッドはセレクタの実行が終わるまで、レシーバとanArgumentパラメータを保持します。

aSelector:呼び出すメソッドを識別するセレクタです。
このメソッドは重要な戻り値を必要とせず、タイプIDの単一引数を必要とするか、または引数がありません。
SEL型の詳細は『Selectors』を参照してください。

anArgument:メソッドを呼び出す際に渡す引数を指定します。
引数を取らない場合はnilを渡します。

delay:メッセージを送る前の最小時間を指定します。
やむを得ずセレクタの直後に実行したい場合、遅延を0に指定してください。
スレッドの実行ループでセレクタが待ち行列に入るまでに、できるだけ早く実行してください。


●Slide.hヘッダファイルの編集

本書では触れられていませんが、Slide.hヘッダファイルにenterOrExitFullScreenの宣言するのを忘れないでください。
(太字が追加した部分)

#import <Foundation/Foundation.h>

@interface Slide : NSObject {

    // アウトレット
    IBOutlet UIImageView *imageSlide;    // 画像表示
    IBOutlet UIToolbar *toolbar;    // ツールバー
    IBOutlet UISlider *sliderDuration;    // 長さ変更
    IBOutlet UISegmentedControl *segShuffle;    //シャッフル
    IBOutlet UIButton *btnStartStop;    // 開始ボタン

}

// アクション
- (IBAction)startStop:(id)sender;    // スライドショーの開始停止
- (IBAction)changeOrder:(id)sender;    // スライドショーのシャッフル
- (IBAction)changeDuration:(id)sender;    // スライドショーの長さの変更

- (void)enterOrExitFullScreen;

@end

437


●Slide.mソースファイルの編集

最期にSlide.mにフルスクリーンの切り替えメソッドenterOrExitFullScreenを追加します。

- (void)enterOrExitFullScreen {
    // ツールバーの可視状態を変更
    toolbar.hidden =! toolbar.hidden;

    // アプリケーションのインスタンスを取得
    UIApplication *app = [UIApplication sharedApplication];

    // ステータスバーの可視状態を変更
    app.statusBarHidden =! app.statusBarHidden;
}

438


フルスクリーンにするということは、すなわちツールバーとステータスバーを非表示にすることになります。

ツールバーの非表示にはUIToolbarのスーパークラスであるUIViewのhiddenプロパティを使用します。

ステータスバーの非表示には、UIApplicationのstatusBarHiddenプロパティを使用するため、その前にアプリケーションのインスタンスを取得しています。

どちらのプロパティもブール値ですので、『!』で反転させて『=』で代入して切り替えています。
(比較演算子で非等価を表す『!=』ではありません)


・hidden
(UIViewクラス)

@property(nonatomic, getter=isHidden) BOOL hidden

レシーバを非表示にするブール値を決定します。

レシーバを非表示にする場合はYES、そうでない場合はNOになります。

デフォルトの値はNOです。

非表示はウィンドウからビューが見えなくなるだけでなく、入力イベントも受け付けません。

しかしスーパービューのサブビューリストには残っており、通常通り自動リサイズはされます。

サブビューのビューを隠すとサブビューを隠す効果は子孫のビューにも反映される場合があります。

この効果は暗黙的なもので、レシーバの子孫の非表示状態は変更しません。

ウィンドウの現在のファーストレスポンダーのビューを隠すと、次に有効なキービューが新たなファーストレスポンダーになります。

このプロパティの値はレシーバの状態のみに反映し、ビュー階層の先祖のレシーバの状態には影響しません。

したがって、先祖が非表示なためにレシーバが非表示になっている場合は、このプロパティをNOにすることができます。


・sharedApplication
(UIApplicationクラス)

+ (UIApplication *)sharedApplication

シングルトンのアプリケーションインスタンスを返します。

アプリケーションインスタンスはUIApplicationMain関数で生成されます。


・statusBarHidden
(UIApplicationクラス)

@property(nonatomic, getter=isStatusBarHidden) BOOL statusBarHidden

ステータスバーを非表示にするブール値を決定します。

ステータスバーを非表示にする場合はYES、そうでない場合はNOになります。



参考文献

UIView Class Reference

UIResponder Class Reference

NSSet Class Reference

UITouch Class Reference

NSObject Class Reference

UIApplication Class Reference

iOSアプリケーションプログラミングガイド

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る






Bose Solo 5 TV sound system
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
07 | 2017/08 | 09
Sun Mon Tue Wed Thu Fri Sat
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

ボーズ・オンラインストア
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR