【Android】ActionBarを使ってみる ① (メニューボタン)
Android 3.0 (API Level 11) から導入されたActionBarについて、
少しずつ勉強していきたいと思います。
ActionBarとは
Android 3.0以降で提供されているアクティビティ用のウィジェットです。 ActionBarは、4つの領域に分かれており各領域からアプリへの操作を制御することが可能です。
1.App icon
アプリのテーマアイコンを表示する領域です。 タップにより、画面ナビゲーション階層の制御を行います。
2.View control
ドロップダウンメニューやタブコントロールなどビュー切り替えの機能を提供しています。 検索バーを表示して検索機能を実装することも可能です。
3.Action buttons
アプリ操作のアクションボタンを配置する領域です。 ボタンを長押しすることで、アクションの名前を表示します。
4.Action overflow
3.Action buttons
では、入りきらないボタンや、使用頻度の低いボタンを配置する領域です。
※ 参考
android:targetSdkVersion
がAPIレベル11以上を指定している場合、
ActionBarはデフォルトで表示されるようになっています。
※ただし、android:minSdkVersion
が11以上でない場合は、
ActionBar
クラスへアクセスして、APIを実行することができません
ActionBarを非表示にするには
AndroidManifest
のActivityにて、
<android:theme="@android:style/Theme.Holo.NoActionBar">
を指定します。
または、
ソースコードからActionBarクラスインスタンスを呼び出し、hide()
を実行することでも、
非表示にすることが可能です。
ActionBar actionbar = getActionBar(); actionbar.hide();
ActionBarにメニューボタンを表示する
Action buttons
とAction overflow
にメニューボタンを配置してみます。
1.メニューリソースの定義
メニューボタンを定義するには、まずres/menu
ディレクトリにあるメニューリソースxmlを作成します。
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/item1" android:icon="@android:drawable/ic_menu_share" android:showAsAction="always" android:title="hogehoge"/> </menu>
属性 | 説明 |
---|---|
id | リソースID |
icon | アイコン画像 |
showAsAction | メニュー項目をどこへ表示するかを指定する |
title | メニュータイトル ※iconが指定されている場合は、長押しするとタイトルが表示される |
※詳しい属性の情報については、メニューリソースのドキュメントを参照してください。
showAsAction
は、各メニューボタンをアクションバーのどこへ配置するかの定義で、
下記5つのオプションを指定可能です。
never:
メニューボタンは、常にAction overflow
領域へ表示される。ifRoom:
表示領域があれば、Action buttons
領域へ表示される。
表示できない場合は、Action overflow
領域へ表示される。withText:
ボタンアイコンと一緒にテキストを表示するcollapseActionView:
action viewを関連付けるて折り畳めるメニューを表示する。
(action viewの指定がない場合は、標準動作となる)always:
常にAction buttons
領域へ表示される。
2.リソースの適用
作成したリソースxmlは、
ActivityクラスのonCreateOptionsMenu()
をオーバーライドして、
inflateすることで画面上に表示されます。
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.example_menu, menu); return true; }
3.ボタンイベントのハンドリング
各メニューボタンのイベントは、ActivityクラスのonOptionsItemSelected()
をオーバーライドして、
ハンドリングすることができます。
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item1: Log.d("", "menu1 tap."); return true; default: return super.onOptionsItemSelected(item); } }
参考サイト
http://www.techdoctranslator.com/android/guide/ui/actionbar http://sakplus.jp/2012/02/23/actionbar/
【Android】動画を再生する
Androidで動画を再生するためには、いくつか方法があるみたいですが、
基本的な方法であるMediaPlayer
とVideoView
を使った再生方法を試してみました。
MediaPlayerを使って再生する
MediaPlayer
で動画を再生する為には、SurfaceView
を使用します。
SurfaceView
は、グラフィックを描画する為のViewで
SurfaceHolder.Callback
というInterfaceを使用してViewの管理を行います。
リファレンス
http://developer.android.com/reference/android/media/MediaPlayer.html
レイアウトの準備
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/surfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
実装ソース
public class MainActivity extends Activity implements SurfaceHolder.Callback { SurfaceView mSurfaceView; SurfaceHolder mSurfaceHolder; MediaPlayer mMediaPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Windowを透明にする getWindow().setFormat(PixelFormat.TRANSPARENT); mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); // SurfaceHolderを取得する mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); } @Override protected void onDestroy() { // メディアプレーヤーを解放する if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } super.onDestroy(); }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { String path = Environment.getExternalStorageDirectory().toString() + "/video.mp4"; mMediaPlayer = new MediaPlayer(); try { mMediaPlayer.setDataSource(path); // 画面にSurfaceHolderを指定する mMediaPlayer.setDisplay(holder); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(new MediaPlayer. OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mMediaPlayer.start(); } }); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // メディアプレーヤーを解放する if(mMediaPlayer != null){ mMediaPlayer.release(); mMediaPlayer = null; } } }
VideoViewで再生する
VideoView
は、内部でMediaPlayer
を使用したウィジェットで
MediaPlayer
よりも簡易に動画の再生が可能です。
リファレンス
http://developer.android.com/reference/android/widget/VideoView.html
レイアウトの準備
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <VideoView android:id="@+id/videoView" android:layout_height="wrap_content" android:layout_width="wrap_content" /> </RelativeLayout>
ファイルPathから再生
VideoView view = (VideoView) findViewById(R.id.videoView); videoView.setVideoPath(Environment.getExternalStorageDirectory().toString() + "/video.mp4"); videoView.start();
URLから再生
VideoView view = (VideoView) findViewById(R.id.videoView); videoView.setVideoURI(Uri.parse("http://sample/sample.mp4")); videoView.start();
再生コントローラを使用する
OSが準備する再生コントローラを使用するには、MediaController
クラスを使用します。
videoView.setMediaController(new MediaController(this));
注意点
上記サンプルソースでは、setVideoPath()
または、setVideoURI()
直後にstart()を実行していますが、
setVideoXX
メソッドは、非同期であるため準備ができるまで再生を待つ必要があります。
そのため、リスナーを設定し、準備が完了してから再生を行うのが正しい実装です。
VideoView view = (VideoView) findViewById(R.id.videoView); videoView.setVideoPath(Environment.getExternalStorageDirectory().toString() + "/video.mp4"); videoView.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { videoView.start(); } });
再生フォーマット
VideoView
およびMediaPlayer
の再生フォーマットは下記を参照して下さい。
http://developer.android.com/guide/appendix/media-formats.html
【iOS】画面遷移にUIKit Dynamicsのアニメーションを使ってみる
iOS7から使えるようになったカスタムの画面遷移UIViewControllerTransitioningDelegate
と
同じくiOS7から使えるようになった物理エンジンのラッパーUIKit Dynamics
を
組み合わせて画面遷移アニメーションを作ってみたいと思います。
今回は、重力によって地面に落ちて画面遷移するアニメーションを作成します。
落ちるときは、画面下に衝突した時に跳ねるようにしています。
また、表示するときは、天井にぶつかって跳ねる用にしました。
UIKit Dynamicsの準備
まずViewControllerの画面遷移で使用するUIViewControllerAnimatedTransitioning
に準拠したクラスを作成します。
今回は、UIKit Dynamics
を使ってアニメーションを行いたいので、UIDynamicBehavior
クラスを継承して作成します。
■ DropTransition.h
@interface INNDropViewBehavior : UIDynamicBehavior <UIViewControllerAnimatedTransitioning> @end
■ DropTransition.m
// class extension @interface DropTransition () <UIViewControllerAnimatedTransitioning, UIDynamicAnimatorDelegate> @property (nonatomic, strong) UIDynamicAnimator *animator; @property (nonatomic, strong) id <UIViewControllerContextTransitioning> transitionContext; @end @implementation DropTransition #pragma mark UIViewControllerAnimatedTransitioning - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { self.transitionContext = transitionContext; UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView *containerView = [transitionContext containerView]; // アニメーション対象のView(=遷移先のView) UIView *frontView = nil; UIView *backView = nil; CGVector gravityDirection; if (self.isPresent) { // 表示 frontView = toVC.view; backView = fromVC.view; // 画面の表示と非表示で重力の方向を逆にする gravityDirection = CGVectorMake(0, -1.0); frontView.frame = CGRectOffset(frontView.frame, 0, frontView.bounds.size.height); } else { // 画面閉じる frontView = fromVC.view; backView = toVC.view; gravityDirection = CGVectorMake(0, 1.0); } /* Viewの準備 */ [containerView addSubview:backView]; // アニメーションを行うViewは、跳ね返りをするために縦方向に2倍の高さを取る CGRect frame = [transitionContext initialFrameForViewController:fromVC]; UIView *canvasView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height * 2)]; [canvasView addSubview:frontView]; [containerView addSubview:canvasView]; /* UIKitDynamicsの準備 */ self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:canvasView]; self.animator.delegate = self; // 重力 UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[frontView]]; [self addChildBehavior:gravityBehavior]; gravityBehavior.gravityDirection = gravityDirection; // 衝突 UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[frontView]]; collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; [self addChildBehavior:collisionBehavior]; // property UIDynamicItemBehavior *propertyBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[frontView]]; propertyBehavior.elasticity = 0.4; // 弾力 propertyBehavior.friction = 1.0; // 摩擦 [self addChildBehavior:propertyBehavior]; [self.animator addBehavior:self]; } // TODO: 物理計算のアニメーションなので、秒数が正確にとれない.. - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { return 0; } #pragma mark - UIViewControllerAnimatedTransitioning - (void)animationEnded:(BOOL)transitionCompleted { // contextの解放 [self.animator.referenceView removeFromSuperview]; self.animator = nil; self.transitionContext = nil; } #pragma mark - #pragma mark UIDynamicAnimatorDelegate - (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator { // アニメーションが終わった時点で通知する [self.transitionContext completeTransition:YES]; } @end
ViewControllerの準備
次に、画面遷移元となるViewControllerにUIViewControllerTransitioningDelegate
のデリゲートメソッドを準備します。
■ ViewController.m
// 遷移は、segueを使用 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"moveto"]) { // 遷移先のViewControllerのtransitionを独自で行うようにdelegateを指定する [segue.destinationViewController setTransitioningDelegate:self]; } } #pragma mark - UIViewControllerAnimatedTransitioning -(id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { DropTransition *transition = [[DropTransition alloc] init]; transition = NO; return behavior; } - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { DropTransition *behavior = [[DropTransition alloc] init]; behavior.isPresent = YES; return transition; }
これだけで、モーダルの遷移を独自に実装できます。
面白いアニメーションも簡単に実装できそうなので色々試してみたいです。
※
画面の用途によってアニメーションを切り分けたい場合は、UIViewControllerAnimatedTransitioning
は遷移先のViewControllerに設定するでもいいかもしれません。
【Android】Styleの使い方
スタイルとはなに?
レイアウト属性とその値のセットをいくつか組み合わせて, 1つのIDで使用できるように定義したもです。
何のために使用する?
複数のレイアウト属性を共通で使いまわすために使用します。
例えばテキストの”フォント”、”フォントサイズ”、”フォントカラー”などの スタイルのセットを共通で使いまわすことができます。
どうやって使う?
res/values/の配下にxmlファイルを配置します。
idをソース上で使用する場合は、(R.style.*)として参照します。
<?xml version="1.0" encoding="utf-8"?> <resources> <style name=“[id名]”> <item name="android:textStyle">italic</item> <item name="android:textColor">#ffffff</item> </style> <style name="[id名]" parent="@style/FontAttr"> <item name="android:textSize">16sp</item> </style> </resources>
layout.xml上で定義する場合は、
style
属性に@style/[id名]
で参照できます。
<TextView style="@style/[id名]” android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="style text" />
どんなもの(スタイル)が定義できる?
<item>
に定義できる属性は、classリファレンスにサポートしているXML属性が記載されています。
親のスタイルを継承した場合
定義したスタイルを継承して新たなスタイルを作成することが可能です。
その場合は、<style>
タグにparent
属性を定義します。
例:
<style name=“[id名]” parent="@style/[親のid]”> <item name="android:textSize">16sp</item> </style>
【Android】selecterを使ってみる
selecterとは
Androidのdrawable
リソースの一つで、
状態によって、画像や色を差し替えることができる仕組みです。
(StateListDrawable
に分類される)
どうやって定義する?
xmlで作成します。
ファイルの置き場所は、res/drawable
配下になります。
selecterで表現できるの主な状態には、下記5パターンが存在します。
1.フォーカス時
2.無効状態かつフォーカス時
3.押下状態
4.無効状態
5.通常状態
(ファイル例)
<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- フォーカス時 --> <item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/focused" /> <!-- 無効状態 かつ フォーカス時 --> <item android:state_focused="true" android:state_enabled="false" android:state_pressed="false" android:drawable="@drawable/disabled_and_focused" /> <!-- 押下状態 --> <item android:state_focused="true" android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/pressed" /> <!-- 無効状態 --> <item android:state_enabled="false" android:drawable="@drawable/disabled" /> <!-- 通常状態 --> <item android:drawable="@drawable/normal" /> </selector>
selecterのxmlで指定する<Item>
タグは、上から評価されるため。
上記すべての状態において別のdrawableを指定したい場合は、
順番どおり記述する必要があります。
どうやって使用する?
レイアウトxmlで指定します。
(ImageViewの画像を状態ごとに変更したいとき)
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/sample_selecter” />
(TextViewの文字色を選択状態ごとに変更したいとき)
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:textColor="@drawable/sample_selecter"/>
@drawable/[selecterのファイル名]
で指定することができます。
その他ハマりどころ
TextViewで背景色や、文字色を状態別で変更したい場合にもselecterを使用しますが、
指定する属性(用途)によって<item>
タグの指定方法が異なるようです。
(異なる方法で実装すると実行時エラーが発生する)
android:textColorに指定する場合
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:color="#ff3f94be" /> <item android:state_selected="false" android:color="#99000000" /> </selector>
属性値としてandroid:color
として定義する。
android:backgroundに指定する場合
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" > <color android:color="#66000000" /> </item> <item android:state_selected="false"> <color android:color="#33000000" /> </item> </selector>
<color>
タグとして定義する。
selecterは、drawableの一種なので、
レイアウトxml上でdrawable
要素に対して指定しますが、
selecterのxml上でも各状態ごとに表示ファイルを分けたい場合などに、
ビットマップのdrawableを指定することがあります。
drawable
の中で更にdrawable
を指定するという点が、
まだちょっと慣れないです。。
drawable
は、種別が多いため基本的な仕組みを理解していないと、
ソースを読むときに苦労しそうです。
参考
[ソフトウェア技術ドキュメントを勝手に翻訳 7.5.3 Drawable リソース] (http://www.techdoctranslator.com/android/guide/resources/available-resources/drawable-resource)
【Android】独自Viewを作成する
最近、Androidの勉強を始めました。
Androidは、様々な要素をxmlで定義できる点が優れていると思います。 ですが、各xmlの関連とそれらをJavaソースから参照する方法を覚えるまでは、 Javaソースを見ても???となることが多々あります。。
Androidで独自のViewを作成した場合のレイアウトファイルの定義方法や、 独自の属性の作成方法について、混乱しそうなのでメモしておきたいと思います。
独自クラスのjavaファイル定義
public class CustomView extends View { public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } }
Viewのコンストラクタは以下の3つが存在します。
1.public View(Context context)
2.public View(Context context, AttributeSet attrs)
3.public View(Context context, AttributeSet attrs, int defStyle)
レイアウトパラメータを指定した場合、
上記2のattrs
を持つコンストラクタが利用されます。
スタイルを指定した場合、
上記3のdefStyle
を持つコンストラクタが利用されます。
レイアウトxmlでクラスを使う
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <!-- [パッケージ名] + [クラス名]でタグを定義 --> <com.example.customviewsample.CustomView /> </RelativeLayout>
新しい属性の定義
標準のTextViewには、textColor
やtextSize
などの属性が予め用意されていますが、
独自Viewのなかで新たに属性を定義することができます。
どうやって(どこに)定義する?
属性は、res/values/attrs.xml
を作成し定義します。
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomView"> <attr name="custom_title_width" format="integer"/> </declare-styleable> </resources>
<declare-styleable>
name属性には、独自Viewのクラス名を定義する。
<attr>
name属性には、新たに定義する属性名を定義。
format属性には、属性のフォーマット名を定義する。
formatに指定できる値には下記があります。 ・integer ・float ・boolean ・string ・color ・dimension
定義した値は、どうやって使う?
独自Viewを定義したレイアウトファイルに以下のように記載します。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myApp="http://schemas.android.com/apk/res/com.example.customviewsample” android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <!-- [パッケージ名] + [クラス名]でタグを定義 --> <com.example.customviewsample.CustomView myApp:custom_title_width="123"/> </RelativeLayout>
1.名前空間を定義する
xmlns:[名前]=“http://schemas.android.com/apk/res/[パッケージ名]“
2.属性に値をセット
myApp:custom_title_width="123"
1で定義した名前からres/values/attrs.xml
で定義した属性を参照することができます。
Javaファイルから読み込み
public class CustomView extends View { public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomView); int size = array.getInt(R.styleable.CustomView_custom_title_width, 3); a.recycle(); } public CustomView(Context context) { super(context); } }
コンストラクタで渡されるAttributeSet
からレイアウトファイルで定義した属性値を取得することができます。
context.obtainStyledAttributes()
は、引数にAttributeSet
とint[]
をとり、int[]はarrtibuteのid配列を指しています。
これを指定する定数は、R.styleable.[※1独自クラス名]
で参照することができます。
TypedArray
クラスのgetInt(int index, int defValue)は、
第一引数にTypedeArrayのindexを渡しますが、ここには、取得したいarrtibuteの属性のindexを指定します。
指定する定数は、R.styleable.[※1独自クラス名]_[※2属性名]
で参照することが可能です。
※1 res/values/attrs.xml
の<declare-styleable>
タグのname属性
※2 res/values/attrs.xml
の<attr>
タグのname属性
UIViewControllerのカスタム画面遷移① (モーダル遷移)
iOS7から、UIViewControllerの画面遷移を自由にカスタムできるようになりました。 今回は、UIViewControllerモーダル遷移について記載します。
遷移元ViewControllerの実装
遷移元のViewControllerにて、 UIViewControllerTransitioningDelegateを継承します。
/* アニメーションコントローラを返すメソッド(モーダルビュー表示) */ - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { // UIViewControllerAnimatedTransitioningを継承したNSObjectを返す ※後述 return [[TransitionObject alloc] init]; } /* アニメーションコントローラを返すメソッド(モーダルビュー消去) */ - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { // UIViewControllerAnimatedTransitioningを継承したNSObjectを返す ※後述 return [[TransitionObject alloc] init]; }
Segueを使用した画面遷移
StroryBordのSegueを利用する場合は、アクション実装箇所で下記のようにSegueの遷移を呼び出します。
(StroryBord上は、Modal
StyleのID@“TransitionSegueId”
Segueとして定義しておきます)
- (IBAction)pushButton:(id)sender { [self performSegueWithIdentifier:@“TransitionSegueId” sender:nil]; }
prepareForSegue
では、上記で実装したtransitioningDelegate
にViewControllerを指定しておきます。
※ modalPresentationStyleは、UIModalPresentationFullScreen
またはUIModalPresentationCustom
の必要があるようです。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { ViewController *viewController = (INRegisterFeedViewController *)segue.destinationViewController; viewController.transitioningDelegate = self; viewController.modalPresentationStyle = UIModalPresentationFullScreen; }
UIViewControllerAnimatedTransitioningの実装
上記のanimationControllerForPresentedController
にて指定しているTransitionObject
オブジェクトには、下記2つのメソッドの実装が必要となります。
/** * アニメーションにかかる時間を指定 * */ - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { return 0.5; } /** * 画面遷移アニメーションを指定 * */ - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { // UIViewAnimationなどで任意のアニメーションを指定 }
これだけで簡単にオリジナルのアニメーションを実装できます。 アニメーションモデルを分離して書けるので、シンプルですね。
もっと高度なアニメーション制御もできるようなので、 色々と試してみたいと思います。