2012年1月29日 星期日

Filter4Cam 學習之 ViewTransitions

since: 2012/01/29
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 的 storyboardARC
         來建立整個專案.

----------------------------------------------------------------------------------------------

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.

   2. 將 View Controller 的 Action: nextTransition: 連結到 UI 上的 Bar Button Item.

----------------------------------------------------------------------------------------------

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:

    切換 view 中:

    第二個 view:

© 2010 Apple Inc. All Rights Reserved. (Last updated: 2010-06-28)

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。