update: 2012/01/29
reference: iOS Developer Library - ViewTransitions
sample code: ViewTransitions.zip
A. 有關 ViewTransitions
1. 這個 ViewTransitions 範例應用程式, 展示如何在二個 view 之間使用內建的
Core Animation transitions(轉變) 來執行切換特效. 藉著觀看這些程式碼,
你將會瞭解如何使用 CATransition 物件去設定並控制 transitions.
2. 這篇文章, 參考 apple 的文件, 並且調整成採用 iOS5 的 storyboard 與 ARC
來建立整個專案.
----------------------------------------------------------------------------------------------
B. 說明
1. 要試驗這個範例, 用 Xcode 編譯並在模擬器或實機上執行. 按下 "Transition"
按鈕來從一張圖片執行切換特效到另一張圖片. 這個應用程式採用隨機的方式
來選擇轉換的效果.
2. 套件清單:
a. AppDelegate.h / .m
隸屬 UIApplication delegate 類別, 為應用程式主要的 controller.
b. main.m
ViewTransitions 應用程式的主要進入點.
----------------------------------------------------------------------------------------------
C. 新增專案
1. Xcode > File > New > New Project...
iOS > Application > Single View Application > Next
Product Name: ViewTransitions
Device Family: iPhone
Use Storyboard: checked
Use Automatic Reference Couting: checked
> Next > Create
2. 將 QuartzCore.framework 加入到專案裡:
D. 基本 UI 配置
點選 MainStoryboard.storyboard 檔案.
1. 拖拉一個 Toolbar 到 UI 的最下方, 它會自動夾帶一個 Bar Button Item.
2. 在 UI 上點二下 Bar Button Item 將其顯示名稱改成: Transition.
3. 拖拉二個 Flexible Space Bar Button Item 分別到 Bar Button Item 的左右方.
----------------------------------------------------------------------------------------------
E. 開啓 ViewController.h 檔案, 調整如下:
#import <UIKit/UIKit.h>
//@add
#import <QuartzCore/QuartzCore.h>
@interface ViewController : UIViewController
{
//@add
UIView *containerView;
UIImageView *view1;
UIImageView *view2;
BOOL transitioning;
}
//@add
@property (nonatomic, strong) IBOutlet UIView *containerView;
//@add
-(IBAction)nextTransition:(id)sender;
-(void)performTransition;
@end
----------------------------------------------------------------------------------------------
F. 調整 UI 連結設定
點選 MainStoryboard.storyboard 檔案.
1. 將 View Controller 的 Outlet: containerView 連結到 UI 上的 view.
G. 開啓 ViewController.m 檔案, 調整如下:
#import "ViewController.h"
@implementation ViewController
//@add
@synthesize containerView = _containerView;
....
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//@add: Create the two views to transition between, and add them to our
// containerView. We'll hide the second one until we are ready to
// transition to it.
UIImage *image1 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image1.jpg" ofType:nil]];
view1 = [[UIImageView alloc] initWithImage:image1];
UIImage *image2 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image2.jpg" ofType:nil]];
view2 = [[UIImageView alloc] initWithImage:image2];
view2.hidden = YES;
[self.containerView addSubview:view1];
[self.containerView addSubview:view2];
transitioning = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
//@add
self.containerView = nil;
}
//@add
-(void)performTransition
{
// First create a CATransition object to describe the transition
CATransition *transition = [CATransition animation];
// Animate over 3/4 of a second
transition.duration = 0.75;
// using the ease in/out timing function
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// Now to set the type of transition. Since we need to choose at random,
// we'll setup a couple of arrays to help us.
NSString *types[4] = {kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, kCATransitionFade};
NSString *subtypes[4] = {kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom};
int rnd = random() % 4;
transition.type = types[rnd];
if(rnd < 3) // if we didn't pick the fade transition, then we need to set a subtype too
{
transition.subtype = subtypes[random() % 4];
}
// Finally, to avoid overlapping transitions we assign ourselves as the delegate
// for the animation and wait for the -animationDidStop:finished: message.
// When it comes in, we will flag that we are no longer transitioning.
transitioning = YES;
transition.delegate = self;
// Next add it to the containerView's layer. This will perform the transition
// based on how we change its contents.
[self.containerView.layer addAnimation:transition forKey:nil];
// Here we hide view1, and show view2, which will cause Core Animation
// to animate view1 away and view2 in.
view1.hidden = YES;
view2.hidden = NO;
// And so that we will continue to swap between our two images,
// we swap the instance variables referencing them.
UIImageView *tmp = view2;
view2 = view1;
view1 = tmp;
}
//@add: Called when the animation completes its active duration or is removed
// from the object it is attached to.
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
transitioning = NO;
}
//@add
-(IBAction)nextTransition:(id)sender
{
if(!transitioning)
{
[self performTransition];
}
}
....
----------------------------------------------------------------------------------------------
H. 編譯並執行:
說明: 1. 將二個 UIImageView 加到入目前的 view 中, Apple 官方的作法
是在 AppDelegate.m 中處理(application:didFinishLaunchingWithOptions:)
, 而在這裡我是將它移到 ViewController.m 中處理(viewDidLoad), 因此
造成執行的結果中, UIImageView 會覆蓋到部分的 Toolbar.
2. 解決辦法, 可在 MainStoryboard.storyboard 檔案中, 新增二個 UIImageView
, 並與 ViewController 作 IBOutlet 的連結關係.
第一個 view:
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。