TapTaps(1)~イベント処理メソッド(1)

2012. 03. 03
TapTapsはシングルタップ、ダブルタップ、トリプルタップ、クァドラプルタップを検出してラベルに表示します。

7845

各タップを検出した時点でラベルに表示するので、そのタップ回数以下のラベルが全て表示されることになります。


●プロジェクトの作成

View-based Applicationテンプレートで、プロジェクト名を『TapTaps』とします。

7815

7846


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

シングルタップ、ダブルタップ、トリプルタップ、クァドラプルタップそれぞれのタップを表示するラベルのアウトレットと、検出時の動作を記述するインスタンスメソッド、そしてラベルを表示してから一定時間後にラベルを消去するメソッドの宣言を行います。
(太字が追加した部分)

#import <UIKit/UIKit.h>

@interface TapTapsViewController : UIViewController {
    UILabel *singleLabel;
    UILabel *doubleLabel;
    UILabel *tripleLabel;
    UILabel *quadrupleLabel;

}

@property (nonatomic, retain) IBOutlet UILabel *singleLabel;
@property (nonatomic, retain) IBOutlet UILabel *doubleLabel;
@property (nonatomic, retain) IBOutlet UILabel *tripleLabel;
@property (nonatomic, retain) IBOutlet UILabel *quadrupleLabel;

- (void)singleTap;
- (void)doubleTap;
- (void)tripleTap;
- (void)quadrupleTap;
- (void)eraseMe:(UILabel *)label;


@end

7847


1)アウトレット


シングルタップ、ダブルタップ、トリプルタップ、クァドラプルタップそれぞれのタップを検出した際に表示する、4つのラベルのインスタンス変数(singleLabel、doubleLabel、tripleLabel、quadrupleLabel)とプロパティをアウトレットとして宣言します。


2)タップメソッド

シングルタップ、ダブルタップ、トリプルタップ、クァドラプルタップそれぞれのタップを検出した際の動作を記述する、4つのインスタンスメソッド(singleTap、doubleTap、tripleTap、quadrupleTap)を宣言します。


3)消去メソッド

各ラベルを表示から一定時間後に消去するメソッドeraseMe:を宣言します。

本書や原著であるApress社のiOS 3.x版のサンプルコードの『13 TapTaps』では、何故か引数がUITextFieldクラスになっています。
(後述するiOS 4.x版のサンプルコードでも同様)

元のメソッドではUILabelクラスのオブジェクトを(キャストせずにそのまま)引数として受け取り、UITextFieldクラスのオブジェクトとしてtextプロパティで文字列の消去を行っています。

ちなみにUITextFieldクラスはUILabelクラスのスーパークラスというわけではありません。
(『UIKit Framework Reference Figure I-1 UIKit class hierarchy』参照)

NSObject
        ∟UIResponder
                    ∟UIView
                            ∟UILabel
                            ∟UIControl
                                    ∟UITextField

実際には何も問題無く意図した通りに動くのですが、UITextFieldクラスにする理由も明示されていないので、ここでは引数をUILabelクラスに変更しています。


●TapTapsViewController.xibの編集

TapTapsViewController.hヘッダファイルの変更が終わったら保存し、ビューコントローラのnibファイルTapTapsViewController.xibを開いてラベルの追加を行います。


1)ラベルの追加

LibraryウィンドウのLabelを選択し、Viewウィンドウの上方にラベルを4つ設置します。

7848


2)ラベルへのアウトレットの接続

DocumentウィンドウでFile's Ownerを選択し、InspectorウィンドウでConnectionsタブを開き、Outletsの4つのラベル(singleLabel、doubleLabel、tripleLabel、quadrupleLabel)をViewウィンドウのラベルに上から順に接続します。

7849


3)ラベルのサイズ変更

Documentウィンドウで各ラベルを選択し、InspectorウィンドウでSizeタブを開き、下表のようにサイズを変更します。

LabelXYWH
singleLabel202028021
doubleLabel204928021
tripleLabel207828021
quadrupleLabel2010728021


4)ラベルの属性変更

InspectorウィンドウのAttributesタブを開き、属性の変更を行います。

Label)

・Text
予め入っている文字列『Label』を削除します。
これにより初期状態では何も表示されないことになります。

・Layout:Alignment
文字列のレイアウトを左寄せから中央揃えに変更します。

・Font
フォントを『Helvetica, 17.0』から『HelVetica Bold, 17.0』に変更します。

・Text
文字色をDefaultから変更します。

プルダウンメニューから『Other...』を選択してColorsウィンドウを開き、『Crayons』アイコンを選択します。

7850

singleLabelはMaraschino、doubleLabelはClover、tripleLabelはMidnight、quadrupleLabelはMochaに変更します。

・Highlighted
サンプルコードではWhite ColorではなくDefaultになっていますが、今回は関係無いのでそのままにしています。

View)

・Mode
サンプルコードではLeftではなくScale To Fillになっていますが、今回は関係無いのでそのままにしています。

7851


5)ビューの属性変更

DocumentウィンドウでViewを選択し、InspectorウィンドウでAttributesタブを開き、ViewのInteractionの『Multiple Touch』にチェックを入れます。

本書ではチェックを入れるようにと指示されていますが、タップ回数に応じたメソッドの呼び出しが目的であり、マルチタッチかどうかは特に関係がなく、実際原著であるApress社のiOS 3.x版のサンプルコードではチェックが入れられていません。(iOS 4.x版のサンプルコードも同様)

7852

全ての変更が済んだらnibファイルを保存します。


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

ヘッダファイルで宣言した4つのラベルのプロパティと4つのタップ用メソッド、ラベルを消去するeraseMe:メソッドの実装と、タッチイベント処理メソッドのtouchesBegan:withEvent:メソッドを追加します。
(太字が追加した部分)

#import "TapTapsViewController.h"

@implementation TapTapsViewController

@synthesize singleLabel;
@synthesize doubleLabel;
@synthesize tripleLabel;
@synthesize quadrupleLabel;

- (void)singleTap {
    singleLabel.text = @"Single Tap Detected";
    [self performSelector:@selector(eraseMe:) withObject:singleLabel afterDelay:1.6f];
}

- (void)doubleTap {
    doubleLabel.text = @"Double Tap Detected";
    [self performSelector:@selector(eraseMe:) withObject:doubleLabel afterDelay:1.6f];
}

- (void)tripleTap {
    tripleLabel.text = @"Triple Tap Detected";
    [self performSelector:@selector(eraseMe:) withObject:tripleLabel afterDelay:1.6f];
}

- (void)quadrupleTap {
    quadrupleLabel.text = @"Quadruple Tap Detected";
    [self performSelector:@selector(eraseMe:) withObject:quadrupleLabel afterDelay:1.6f];
}

- (void)eraseMe:(UILabel *)label {
    label.text = @"";
}


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    self.singleLabel = nil;
    self.doubleLabel = nil;
    self.tripleLabel = nil;
    self.quadrupleLabel = nil;
    [super viewDidUnload];

}

- (void)dealloc {
    [singleLabel release];
    [doubleLabel release];
    [tripleLabel release];
    [quadrupleLabel release];

    [super dealloc];
}

#pragma mark -

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    NSUInteger tapCount = [touch tapCount];

    switch (tapCount) {
        case 1:
            [self singleTap];
            break;
        case 2:
            [self doubleTap];
            break;
        case 3:
            [self tripleTap];
            break;
        case 4:
            [self quadrupleTap];
            break;
        default:
            break;
    }
}


@end

7853


1)プロパティの実装

ヘッダファイルで宣言した4つのプロパティ(singleLabel、doubleLabel、tripleLabel、quadrupleLabel)を@synthesizeで実装します。


2)タップ用メソッドの実装

タップ用メソッド(singleTap、doubleTap、tripleTap、quadrupleTap)はタップが検出された際にタップ回数に応じて呼び出されるメソッドで、それぞれ対応するラベルにタップ回数の文字列を表示した後、テキスト消去メソッドeraseMe:を呼び出して一定時間後に文字列の消去を行います。

各ラベルの文字列はtextプロパティで設定します。

テキスト消去メソッドeraseMe:はperformSelector:withObject:afterDelay:メソッドのセレクタで、表示から1.6秒後に実行されます。

呼び出し時にはそれぞれのラベルオブジェクトが引数として渡され、個別に消去されます。


3)eraseMe:メソッド

eraseMe:メソッドはラベルのテキストを消去するメソッドで、タップ用メソッド(singleTap、doubleTap、tripleTap、quadrupleTap)からラベルオブジェクトを引数として呼び出されます。

本書やサンプルコードでは引数をUITextFieldクラスとして受け取っていますが、理由が不明瞭なのでここでは素直にUILabelクラスとして受け取っています。

テキストの消去はtextプロパティで文字列を空に設定しているだけです。


4)不要なメソッドの削除

テンプレートで自動生成されるメソッドの内、initWithNibName:bundle:loadViewviewDidLoadメソッドは今回使用しないので削除します。


5)shouldAutorotateToInterfaceOrientation:メソッド

shouldAutorotateToInterfaceOrientation:のコメントアウトを解除してデフォルトのまま実装しています。


6)viewDidUnloadメソッド

viewDidUnloadに4つのプロパティの所有権放棄を追加しています。


7)deallocメソッド

deallocに4つのプロパティの解放を追加しています。


8)touchesBegan:withEvent:メソッド

touchesBegan:withEvent:メソッドはビューに一本以上の指が触れた時に呼び出されるメソッドで、ここではタップ回数を取得し、それに応じてタップ用メソッドの呼び出しを行っています。

タッチオブジェクトのセットからanyObjectメソッドで適切なオブジェクトを選抜し、そのオブジェクトからtapCountプロパティでタップ回数を取得します。

取得したタップ回数を用い、switch文で対応するタップ用メソッド(singleTap、doubleTap、tripleTap、quadrupleTap)の呼び出しを行います。


●実行結果

タップ回数の検出は排他処理を行っておらず、タップされる毎にtouchesBegan:withEvent:メソッドが呼び出され、その都度評価されます。

したがって、シングルタップはそのまま評価されますが、

7854

ダブルタップの場合、

1回目のタップ → touchesBegan:withEvent: → singleTap
 → 2回目のタップ → touchesBegan:withEvent: →  doubleTap

と評価されるため、シングルタップとダブルタップの両方のラベルが(僅かな時間差で)表示されます。

7855

トリプルタップ、クァドラプルタップの場合も同様に、そのタップ回数以下のタップが検出されてラベルが順次表示されます。

7856

7845



参考文献

iOSイベント処理ガイド

はじめてのiPhone3プログラミングはじめてのiPhone3プログラミング
(2009/12/17)
Dave Mark、Jeff LaMarche 他

商品詳細を見る

Beginning Ios 6 Development: Exploring the Ios SdkBeginning Ios 6 Development: Exploring the Ios Sdk
(2012/12/26)
David Mark、Jack Nutting 他

商品詳細を見る






Wave SoundTouch music system IV
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
06 | 2017/07 | 08
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

Wave SoundTouch music system IV
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