トランジションアニメーション(2)

2010. 07. 03
前回の『トランジションアニメーション(1)』は『基礎からのiPhone SDK 改訂版』本書内で解説されている分なのですが、二つほど問題があります。

一つは再生モードを変更するchangeOrder:メソッドを修正していないのでモード変更が効かないこと。
(これは本書内で説明もなく、サンプルコードでも対処していません)

もう一つはトランジションアニメーションを行うnextSlide:メソッドで使用している二つのメソッド、setAnimationDuration:とsetAnimationTransition:forView:cache:がiPhone OS 4.0(iOS 4)以降は非推奨となっている点です。

折角なので両点の対策をしたいと思います。


●再生モード変更のタイマー化

タイマーを一旦停止・無効化した後でタイマーを再生成するところは、速度切り替えバーのchangeDuration:メソッドと全く同じです。

その間に通常またはシャッフルかのモードを検出して画像配列を組み替えるだけです。

これは初期化するメソッドawakeFromNibで呼び出している配列生成メソッドanimationImagesに、再生モードの検出とそれに応じた配列生成が組み込まれているので、そのまま呼び出せばいいことになります。
(太字が追加・修正した部分)

- (IBAction)changeOrder:(id)sender {

    // タイマーを止める
    [timerSlide invalidate];

    [images release];
    images = [[self animationImages] retain];

    // タイマーを生成
    timerSlide = [NSTimer scheduledTimerWithTimeInterval:sliderDuration.value / [images count] target:self selector:@selector(nextSlide:) userInfo:nil repeats:YES];
}

458

ここで注意しなければならないのが、画像配列imagesをretainしている点です。

retainしなければchangeOrder:メソッドから抜けた時点で参照できなくなりますし、最初にawakeFromNibで作った配列をreleaseせずにretainをすると、呼び出される度にインスタンスが増えて行く所謂メモリリークの状態になります。

試しに [images release]; をコメントアウトし、Xcodeの『実行』メニューの『パフォーマンスツールを使って実行』で『Leaks』を選択して、(未だに使い方がよく分からない)Instrumentsでメモリリークを確認してみます。

459

細かいことはよく分からないのでさておくとしまして、上部ペインのLeaksの項目に注目します。

今回の場合、通常からシャッフルに切り替えると『# Leaks Discovered(リーク発見)』に赤いバーが現れ、何度かモードを切り替えるとその度に『Total Leaked Bytes(合計リークバイト)』の青いバーが伸びていくことが分かります。

コメントアウトを元に戻してreleaseを有効にし、一旦『ビルドと実行』をかけ(そうしないとiPhone Simulatorのアプリケーションが更新されない)、同手順でInstrumentsでモニタしてみるとリークが出ないはずです。

また、このタイマー化により以前とアプリケーションの挙動が変わっています。

タイマー化以前はアニメーション停止状態でモードを変更しても停止したままでしたが、このやり方ですとアニメーション停止状態でモードを変更のボタンを押すとアニメーションが始まってしまいます。

加えてstartStop:メソッドを介していないためボタンの文字列が変更されずに、アニメーションされてもボタンが『Stop』のままとなる不具合があります。


●UIViewクラスのiOS 4非推奨メソッド

UIViewクラスで、iPhone OS 4.0(iOS 4)以降は非推奨となっているメソッドは、『Animating View』と分類されているメソッドでareAnimationsEnabledを除く14個になります。

beginAnimations:context:
commitAnimations
setAnimationBeginsFromCurrentState:
setAnimationCurve:
setAnimationDelay:
setAnimationDelegate:
setAnimationDidStopSelector:
setAnimationDuration:
setAnimationRepeatAutoreverses:
setAnimationRepeatCount:
setAnimationsEnabled:
setAnimationStartDate:
setAnimationTransition:forView:cache:
setAnimationWillStartSelector:

このスライドショーアプリケーションの改造途中だったので見落としていましたが、setAnimationDuration:とsetAnimationTransition:forView:cache:だけでなく、太字で示したbeginAnimations:context:、commitAnimations、setAnimationsEnabled:も非推奨となっています。

iPhone OS 4.0以降で使えるようになったのは、contentScaleFactorプロパティと、『Animating Views with Blocks』と分類されている5つのメソッドとそのオプションです。

animateWithDuration:animations:
animateWithDuration:animations:completion:
animateWithDuration:delay:options:animations:completion:
transitionFromView:toView:duration:options:completion:
transitionWithView:duration:options:animations:completion:

UIViewAnimationOptions


・animateWithDuration:animations:
(UIViewクラス)

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations

指定した期間で、一つまたは複数のビューで使用されるアニメーションを変更します。

このメソッドは、デフォルトのアニメーションオプションを使用して、すぐに指定したアニメーションを実行します。

デフォルトのオプションは、UIViewAnimationOptionCurveEaseInOutとUIViewAnimationOptionTransitionNoneです。

duration:アニメーションの合計時間を秒単位で指定します。
負の値または0を指定した場合は、アニメーションをしないものになります。

animations:変更するブロックオブジェクトを含むビューを指定します。
これはビュー階層内にある、ビューの全てのアニメーションプロパティをプログラムに基づいて変更します。
このブロックはパラメータと戻り値を取りません。
このパラメータはNULL以外である必要があります。


・animateWithDuration:animations:completion:
(UIViewクラス)

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

指定した期間と完了ハンドラで一つまたは複数のビューで使用されるアニメーションを変更します。

このメソッドは、デフォルトのアニメーションオプションを使用して、すぐに指定したアニメーションを実行します。

デフォルトのオプションは、UIViewAnimationOptionCurveEaseInOutとUIViewAnimationOptionTransitionNoneです。

例えば、ビューが完全な透明になるまでフェードして、その後ビュー階層から取り除く場合は以下のようになります。

[UIView animateWithDuration:0.2
        animations:^{ view.alpha = 0.0; }
        completion:^(BOOL finished){ [view removeFromSuperview]; }]

duration:アニメーションの合計時間を秒単位で指定します。
負の値または0を指定した場合は、アニメーションをしないものになります。

animations:変更するブロックオブジェクトを含むビューを指定します。
これはビュー階層内にある、ビューの全てのアニメーションプロパティをプログラムに基づいて変更します。
このブロックはパラメータと戻り値を取りません。
このパラメータはNULL以外である必要があります。

completion:アニメーションシーケンスが終了した際に実行するブロックオブジェクトを指定します。
このブロックは戻り値を持たず、実際にアニメーションが終了する前に完了ハンドラが呼び出されたかを示すブール型引数を取ります。
アニメーションの期間が0の場合このブロックは次の実行ループサイクルの開始時に実行されます。
このパラメータはNULLにすることができます。


・animateWithDuration:delay:options:animations:completion:
(UIViewクラス)

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

指定した期間と遅延、オプション、完了ハンドラで、一つまたは複数のビューで使用されるアニメーションを変更します。

このメソッドはビューで実行するアニメーションの初期設定をします。

アニメーションパラメータのブロックオブジェクトには、一つまたは複数のビューのアニメーションのプロパティのコードを含まれています。

duration:アニメーションの合計時間を秒単位で指定します。
負の値または0を指定した場合は、アニメーションをしないものになります。

delay:アニメーションを開始する前に待機する時間を秒単位で指定します。
0を指定した場合は即時アニメーションを開始します。

options:アニメーションをどのように実行するかを示す、オプションのマスクを示します。
有効な定数のリストはUIViewAnimationOptionsを参照してください。

animations:変更するブロックオブジェクトを含むビューを指定します。
これはビュー階層内にある、ビューの全てのアニメーションプロパティをプログラムに基づいて変更します。
このブロックはパラメータと戻り値を取りません。
このパラメータはNULL以外である必要があります。

completion:アニメーションシーケンスが終了した際に実行するブロックオブジェクトを指定します。
このブロックは戻り値を持たず、実際にアニメーションが終了する前に完了ハンドラが呼び出されたかを示すブール型引数を取ります。
アニメーションの期間が0の場合このブロックは次の実行ループサイクルの開始時に実行されます。
このパラメータはNULLにすることができます。

※2010.7.6追記:delayの説明が抜けていたので、修正しました。


・transitionFromView:toView:duration:options:completion:
(UIViewクラス)

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion

与えたパラメータを使用して、指定したビュー間の遷移アニメーションを生成します。

このメソッドは、fromViewのビューからtoViewのビューへの遷移アニメーションを、単純な方法で提供します。

デフォルトでは、ビュー階層内でfromViewのビューはtoViewのビューに置換されます。

両方のビューが既にビュー階層の一部の場合は、オプションパラメータのUIViewAnimationOptionShowHideTransitionViewsオプションで表示または非表示にすることができます。

別のアニメーションが既に実行中でない限りビューの遷移はすぐに開始され、実行中だった場合は現在のアニメーションが終了次第すぐに開始されます。

fromView:遷移を開始するビューを指定します。
デフォルトでは、このビューは遷移の一環として親ビューから削除されます。

toView:遷移を終了するビューを指定します。
デフォルトでは、このビューは遷移の一環としてfromViewの親ビューに追加されます。

duration:遷移アニメーションの期間を秒単位で指定します。
負の値または0を指定した場合は、アニメーションをしないものになります。

options:アニメーションをどのように実行するかを示す、オプションのマスクを示します。
有効な定数のリストはUIViewAnimationOptionsを参照してください。

completion:アニメーションシーケンスが終了した際に実行するブロックオブジェクトを指定します。
このブロックは戻り値を持たず、実際にアニメーションが終了する前に完了ハンドラが呼び出されたかを示すブール型引数を取ります。
アニメーションの期間が0の場合このブロックは次の実行ループサイクルの開始時に実行されます。
このパラメータはNULLにすることができます。


・transitionWithView:duration:options:animations:completion:
(UIViewクラス)

+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

指定したコンテナビューの遷移アニメーションを生成します。

このメソッドを使って、独自のビュー遷移アニメーションを生成することができます。

ブロックは、animationsパラメータでビュー階層から関連するビューの追加または削除を指定することができます。
(ビューの追加と削除の必要が無い場合は代わりに単純に表示または非表示にすることができます)

カスタムブロックを指定する場合、遷移の一部としてビューの任意の数を追加または削除することができます。

もちろん、アニメーションブロックの全てのビューは、このメソッドに共有するアニメーションパラメータを渡します。

例えば、同じコンテナビューの二つのビューをフリップで遷移する場合、以下のようなコードになります。

[UIView transitionWithView:containerView
        duration:0.2
        options:UIViewAnimationOptionTransitionFlipFromLeft
        animations:^{ [fromView removeFromSuperview]; [containerView addSubview:toView]
}
        completion:NULL];

view:遷移に関わるビューを含むコンテナビューを指定します。

duration:遷移アニメーションの期間を秒単位で指定します。
負の値または0を指定した場合は、アニメーションをしないものになります。

options:アニメーションをどのように実行するかを示す、オプションのマスクを示します。
有効な定数のリストはUIViewAnimationOptionsを参照してください。

animations:遷移に関わるビューの追加または削除するブロックオブジェクトを指定します。
このブロックはパラメータと戻り値を取りません。
このパラメータはNULL以外である必要があります。

completion:アニメーションシーケンスが終了した際に実行するブロックオブジェクトを指定します。
このブロックは戻り値を持たず、実際にアニメーションが終了する前に完了ハンドラが呼び出されたかを示すブール型引数を取ります。
アニメーションの期間が0の場合このブロックは次の実行ループサイクルの開始時に実行されます。
このパラメータはNULLにすることができます。


・UIViewAnimationOptions
(UIViewクラス)

enum    
    UIViewAnimationOptionLayoutSubviews=1<<0,
    UIViewAnimationOptionAllowUserInteraction=1<<1,
    UIViewAnimationOptionBeginFromCurrentState=1<<2,
    UIViewAnimationOptionRepeat=1<<3,
    UIViewAnimationOptionAutoreverse=1<<4,
    UIViewAnimationOptionOverrideInheritedDuration=1<<5,
    UIViewAnimationOptionOverrideInheritedCurve=1<<6,
    UIViewAnimationOptionAllowAnimatedContent=1<<7,
    UIViewAnimationOptionShowHideTransitionViews=1<<8,
     
    UIViewAnimationOptionCurveEaseInOut=0<<16,
    UIViewAnimationOptionCurveEaseIn=1<<16,
    UIViewAnimationOptionCurveEaseOut=2<<16,
    UIViewAnimationOptionCurveLinear=3<<16,
     
    UIViewAnimationOptionTransitionNone=0<<20,
    UIViewAnimationOptionTransitionFlipFromLeft=1<<20,
    UIViewAnimationOptionTransitionFlipFromRight=2<<20,
    UIViewAnimationOptionTransitionCurlUp=3<<20,
    UIViewAnimationOptionTransitionCurlDown=4<<20,
};    
typedef NSUInteger UIViewAnimationOptions;    

ブロックでビューをアニメーションするために指定するオプションです。

・UIViewAnimationOptionLayoutSubviews
親ビューと一緒にアニメーションする場合のサブビューの配置を指定します。

・UIViewAnimationOptionAllowUserInteraction
アニメーション中のビューに対するユーザ操作を許可します。

・UIViewAnimationOptionBeginFromCurrentState
既に動作しているアニメーションに現在の設定されているアニメーションを結合させて開始します。
このキーが存在しない場合、新しいアニメーションが開始する前に動作中のアニメーションが終了することを許可します。
他のアニメーションが動作中でない場合、このキーは影響を与えません。

・UIViewAnimationOptionRepeat
アニメーションを無限に繰り返します。

・UIViewAnimationOptionAutoreverse
アニメーションを後方と前方に進めます。
UIViewAnimationOptionRepeatオプションと組み合わせて使用する必要があります。

・UIViewAnimationOptionOverrideInheritedDuration
提出されたアニメーションに、指定した独自の期間の値を適用します。
このキーが存在しない場合、アニメーションは動作中のアニメーションの残り期間を受け継ぎます。

・UIViewAnimationOptionOverrideInheritedCurve
提出されたアニメーションに、指定した独自のカーブの値を適用します。
このキーが存在しない場合、アニメーションは動作中のアニメーションのカーブを受け継ぎます。

・UIViewAnimationOptionAllowAnimatedContent
アニメーションを行うビューのプロパティ値を動的に変更し、ビューの再描画を行います。
このキーが存在しない場合、ビューはスナップショットの画像を使用して再描画します。

・UIViewAnimationOptionShowHideTransitionViews
このキーが存在する場合、ビューの遷移を行う際に(削除や追加の代わりに)ビューを非表示または表示にします。
このキーを使用する際、双方のビューは事前に親ビューの階層中に存在している必要があります。
このキーが存在しない場合、遷移へのビューの追加またはビューの削除は、親ビューのサブビューリストで行います。

・UIViewAnimationOptionCurveEaseInOut
ease-in ease-outカーブにより遅くアニメーションを開始し、期間の中間では加速し、完了前には再び遅くなります。

・UIViewAnimationOptionCurveEaseIn
ease-inカーブにより遅くアニメーションを開始し、進行と共に加速します。

・UIViewAnimationOptionCurveEaseOut
ease-outカーブにより速くアニメーションを開始し、進行と共に減速します。

・UIViewAnimationOptionCurveLinear
リニアアニメーションカーブにより、期間中等速度でアニメーションします。

・UIViewAnimationOptionTransitionNone
遷移の指定はありません。

・UIViewAnimationOptionTransitionFlipFromLeft
縦軸を中心に左から右にビューが回転する、フリップの遷移を行います。
ビューの左側が手前に、右側が奥に向かって動きます。

・UIViewAnimationOptionTransitionFlipFromRight
縦軸を中心に右から左にビューが回転する、フリップの遷移を行います。
ビューの右側が手前に、左側が奥に向かって動きます。

・UIViewAnimationOptionTransitionCurlUp
ビューの下部から上へ巻き上げる遷移を行います。

・UIViewAnimationOptionTransitionCurlDown
ビューの上部から下へ巻き下げる遷移を行います。



参考文献

UIView Class Reference

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

商品詳細を見る






Lifestyle 650 home entertainment system
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
10 | 2017/11 | 12
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 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

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

Wish List
WACOM


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

Lifestyle 650 home entertainment system
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