Download presentation
Presentation is loading. Please wait.
Published byOscar Stevenson Modified over 9 years ago
1
2010/12/16 朱中華
2
這個程式會先在 iPhone 螢幕上顯示 This is the Front View 及箭頭, click 任何地方後, 畫面會翻轉 (transition) 至下個畫面 ---This is the Back View 及箭頭,每次 click ,交替出 現,見下圖。
3
新產生 FlipView class 的 touchesEnded : 產生 flip 效果的方式由 14 、 19 行達成, 14 行, [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:[self superview] cache:YES]; 15 行, [[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1 ];
4
#import // Note: although Apple promised UIViewAnimationTransitionCurlUp as a transition, it's not live yet @interface FlipView : UIImageView @end @implementation FlipView - (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { // Start Animation Block CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:[self superview] cache:YES]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:1.0]; // Animations [[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1]; // Commit Animation Block [UIView commitAnimations]; } @end
5
以下是 loadView 程式: 由 38~44 行先將 This is the Front View 、 This is the Back View load 進來。 47~54 行加上 "This is the Front View" ,是 以 label 方式。 其後是以 label 方式加上 "This is the Back View" 。 66~67 行先 addSubview:backView 再 addSubview:frantView ,後加的在上面, 因此 frontView 在 front 。
6
@interface HelloController : UIViewController @end @implementation HelloController - (void)loadView { // Create the main view UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; contentView.backgroundColor = [UIColor blackColor]; self.view = contentView; [contentView release]; FlipView *frontView = [[FlipView alloc] initWithFrame:self.view.bounds]; frontView.image = [UIImage imageNamed:@"frontside.png"]; frontView.userInteractionEnabled = YES; FlipView *backView = [[FlipView alloc] initWithFrame:self.view.bounds]; backView.image = [UIImage imageNamed:@"backside.png"]; backView.userInteractionEnabled = YES; // Add an identifying label for front CGRect labelFrame = CGRectMake(40.0f, 200.0f, 240.0f, 60.0f); UILabel *frontLabel = [[UILabel alloc] initWithFrame:labelFrame]; frontLabel.text = @"This is the Front View"; frontLabel.font = [UIFont fontWithName:@"Georgia" size:24.0f]; frontLabel.textColor = [UIColor colorWithRed:0.82f green:1.0f blue:0.286f alpha:1.0f]; frontLabel.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]; [frontView addSubview:frontLabel]; [frontLabel release]; // Add an identifying label for back UILabel *backLabel = [[UILabel alloc] initWithFrame:labelFrame]; backLabel.text = @"This is the Back View"; backLabel.font = [UIFont fontWithName:@"Georgia" size:24.0f]; backLabel.textColor = [UIColor colorWithRed:0.82f green:1.0f blue:0.286f alpha:1.0f]; backLabel.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]; [backView addSubview:backLabel]; [backLabel release]; // add the views [self.view addSubview:backView]; [self.view addSubview:frontView]; [backView release]; [frontView release]; } @end
7
@interface SampleAppDelegate : NSObject @end @implementation SampleAppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; HelloController *hello = [[HelloController alloc] init]; [window addSubview:hello.view]; [window makeKeyAndVisible]; } @end int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate"); [pool release]; return retVal; }
8
這個程式讓使用者 click 後往上下左右 swipe , 圖就會依方向更換。如下圖。往右或往上。
9
FlipView class 是主軸,其中 instance variable , startTouchPosition 及 dirString 表示 click 開始點及 swipe 方向。 init 會 setMultipleTouchEnabled 。 getAnimation: direction 會得到 animation 的方向。 注意:改一下 type ,會成為 flip #import #import #define kAnimationKey @"transitionViewAnimation" @interface FlipView : UIImageView { CGPoint startTouchPosition; NSString *dirString; } @end
10
@implementation FlipView - (FlipView *) init { self = [super init]; [self setMultipleTouchEnabled:YES]; return self; } - (CATransition *) getAnimation:(NSString *) direction { CATransition *animation = [CATransition animation]; [animation setDelegate:self]; // [animation setType:@"oglFlip"]; [animation setType:kCATransitionPush]; [animation setSubtype:direction]; [animation setDuration:1.0f]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; return animation; }
11
touchesBegan 時,將 startTouchPosition 記下。 touchesMoved 時,由 ( startTouchesPosition.x - currentTouchPosition.x ) 及 ( startTouchesPosition.y - currentTouchPosition.y ) 判斷是否橫向移動。由 ( startTouchesPosition.y - currentTouchPosition.y ) 及 ( startTouchesPosition.x - currentTouchPosition.x ) 判斷是否縱向移動。 touchesEnded 時,若有 dirString 時,作移動的 animation 動作。
12
#define HORIZ_SWIPE_DRAG_MIN 12 #define VERT_SWIPE_DRAG_MAX 4 // The following swipe code derives from Apple Sample Code - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; startTouchPosition = [touch locationInView:self]; dirString = NULL; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = touches.anyObject; CGPoint currentTouchPosition = [touch locationInView:self]; if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN && fabsf(startTouchPosition.y - currentTouchPosition.y) = HORIZ_SWIPE_DRAG_MIN && fabsf(startTouchPosition.x - currentTouchPosition.x) <= VERT_SWIPE_DRAG_MAX) { // Vertical Swipe if (startTouchPosition.y < currentTouchPosition.y) dirString = kCATransitionFromBottom; else dirString = kCATransitionFromTop; } else { // Process a non-swipe event. // dirString = NULL; } }
13
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (dirString) { CATransition *animation = [self getAnimation:dirString]; [[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1]; [[[self superview] layer] addAnimation:animation forKey:kAnimationKey]; } } @end
14
先用 loadView load 進兩張圖片:先 load backside.png ,再 load frontside.png @interface HelloController : UIViewController @end @implementation HelloController - (void)loadView { // Create the main view UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; contentView.backgroundColor = [UIColor blackColor]; self.view = contentView; [contentView release]; UIImageView *backView = [[FlipView alloc] initWithFrame:self.view.bounds]; [backView setImage:[UIImage imageNamed:@"backside.png"]]; [backView setUserInteractionEnabled:YES]; [self.view addSubview:backView]; [backView release]; UIImageView *frontView = [[FlipView alloc] initWithFrame:self.view.bounds]; [frontView setImage:[UIImage imageNamed:@"frontside.png"]]; [frontView setUserInteractionEnabled:YES]; [self.view addSubview:frontView]; [frontView release]; } @end
15
@interface SampleAppDelegate : NSObject @end @implementation SampleAppDelegate // On launch, create a basic window - (void)applicationDidFinishLaunching:(UIApplication *)application { UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; HelloController *hello = [[HelloController alloc] init]; [window addSubview:hello.view]; [window makeKeyAndVisible]; } @end
16
int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate"); [pool release]; return retVal; }
17
這個程式會先在 iPhone 螢幕上顯示數字 1 , click 後 1 會以動畫方式逐漸消失、 2 會以動 畫方式逐漸出現,每次 click ,交替出現 1 、 2 ,見下圖。
18
toggleView class 的 initWithFrame 。 先看 IMAGE_VIEW_1 及 IMAGEVIEW_2 兩個 constant ,若有多個 view ,替每個 view 編號十分重 要,如此即可叫出某特定 view 。 BIGRECT 及 SMALLRECT 定出 view 的 boundary 。 注意,由左上角算起, BIGRECT 由 (0,0) 展開 (320,435) 大的 rectangle , SMALLRECT 由 ( 130, 187 ) 展開 (60, 60) 大的 rectangle 。 isOne 表示 1 是 否在 2 之上, YES 表示 1 在 2 之上, NO 表示 1 在 2 之下。 將 one.jpg 及 two.jpg load 進 memory ,先 addSubview two.png 再 addSubview one.png 會讓 one.png 自動在上方。
19
#define IMAGE_VIEW_1100 #defineIMAGE_VIEW_2101 #define BIGRECT CGRectMake(0.0f, 0.0f, 320.0f, 435.0f) #define SMALLRECT CGRectMake(130.0f, 187.0f, 60.0f, 60.0f) @interface ToggleView: UIView { BOOL isOne; } @end @implementation ToggleView - (id) initWithFrame: (CGRect) aFrame; { self = [super initWithFrame:aFrame]; // Load both views, make them non-interactive UIImageView *imgView1 = [[UIImageView alloc] initWithFrame:BIGRECT]; imgView1.image = [UIImage imageNamed:@"one.png"]; imgView1.userInteractionEnabled = NO; imgView1.tag = IMAGE_VIEW_1; UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:SMALLRECT]; imgView2.image = [UIImage imageNamed:@"two.png"]; imgView2.userInteractionEnabled = NO; imgView2.tag = IMAGE_VIEW_2; // image 1 is in front of image 2 to begin [self addSubview:imgView2]; [self addSubview:imgView1]; isOne = YES; [imgView1 release]; [imgView2 release]; return self; }
20
程式中 ToggleView class 為核心,若將其中 的 touchesBegan 程式稍加修改,由 0.5 改為 0.7 ,可將隱藏在下的數字 "1" 顯現出來。這 正是 " 數字 2" 在上方 (frontView) , " 數字 1" 在 下方的明確表現。
21
toggleView class 的 touchesBegan : 先把在上面的 image 放在 big ,下面的放在 small 。 動畫參數設好。注意 48 行 setAnimationDuration 後的數字改成 8.0(8 秒 ) ,這是讓過程緩慢呈現,以便 copy screen 方便。 原來是 1.0 。 swap 上、下圖的 boundary 。注意, 51 行的 setAlpha 為 0.5 ,因 big 要 到下面去了。 執行動畫。 將 big 的動畫隱藏起來。 將 big 放到 frontView 。這一行耐人尋味,明明 big 就已經在 frontView( 尤其是第一個畫面, imgView1 在 front) 了,為何還要再放 front 一次?原因十分簡單,現在的 big ,馬上要成為 little 了,如果不 放在 front ,若想看就看不見。試著 comment 掉 58 行,這時 1 、 2 都會 出現,這就是 59 行的作用。再試著 comment 掉 58 、 59 行,這時 1 是 big 時,看不見 2 ,因為 28~29 行, imgView1 永遠在 front ,小 boundary 的 2 就被蓋住了。 2 是 big 時,看得見 1 ,因為 28~29 行, imgView1 永遠在 front 。由此可知, bringSubviewFront 很好用,一 大 frame 一小 frame 時,只要將小 frame bringSubviewFront ,再加上 setAlpha:0.5( 或小於 1) ,就會出現重疊效果。
22
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { // Determine which view occupies which role UIImageView *big = (UIImageView *)[self viewWithTag: (isOne ? IMAGE_VIEW_1 : IMAGE_VIEW_2)]; UIImageView *little = (UIImageView *)[self viewWithTag: (isOne ? IMAGE_VIEW_2 : IMAGE_VIEW_1)]; isOne = !isOne; // Pack all the changes into the animation block CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:1.0]; [big setFrame:SMALLRECT]; [big setAlpha:0.5]; [little setFrame:BIGRECT]; [little setAlpha:1.0]; [UIView commitAnimations]; // Hide the shrunken "big" image. [big setAlpha:0.0f]; [[big superview] bringSubviewToFront:big]; } @end
23
@interface HelloController : UIViewController @end @implementation HelloController - (void)loadView { ToggleView *contentView = [[ToggleView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; contentView.backgroundColor = [UIColor whiteColor]; self.view = contentView; [contentView release]; } @end
24
@interface SampleAppDelegate : NSObject @end @implementation SampleAppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; HelloController *hello = [[HelloController alloc] init]; [window addSubview:hello.view]; [window makeKeyAndVisible]; } @end int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate"); [pool release]; return retVal; }
25
這程式主要是分別顯示 Lime 、 Orange 、 Pink 三種顏色在螢幕上,每 種同顏色畫面有不同的 Navigation Bar 。 Lime 畫面中間 title 是 Lime 、右有一個 Orange Button ,按下 Orange Button 則出現 Orange 畫面。 Orange 畫面中間 title 是 Orange ,左有 Lime Button ,按下 Lime Button 則回到 Lime 畫面,右有一個 Pink Button ,按下 Pink Button 則出現 Pink 畫面。 Pink 畫面中間 title 是 Pink ,左有一個 Orange Button ,按 下 Orange Button 則回到 Orange 畫面。如下圖。
26
如下各個圖所示,程式包含三個 UIViewController , LimeController(7 行 ) 、 PinkController(10 行 ) 、 OrangeController(13 行 ) 。重點是 PinkController(10 行 ) 、 OrangeController(13 行 ) 均 inherit 自 LimeController ,因而: 三者有各自的 init 、 loadView 、 loadButton 、 switch ,但是只有 LimeController 有完整的 loadView(32~41 行 ) ,及其他的 Task ,例如: shouldAutorotateToInterfaceOrientation 。看一下 LimeController 完整的 loadView(32~41 行 ) :
27
34 行: alloc 一個 UIView 。 35 行:設定顏色 Lime 。 36 、 37 行:設定 autoresize 特性。 38 行:指定這個 UIView 為 LimeController 的 view 。 39 行: release memory 。 40 行:呼叫 loadButton(40 行 ) ,將 Orange Button 放進 Navigation Bar(25 行 ) ,也將 action 定為 switch(29 行 ) 。 switch(43 行 ) 則會 pushViewController -- OrangeController(45 行 ) ,造成畫面轉換至 Orange 。
28
在 OrangeController 中, loadView 內 call [super loadView](72 行 ) , 就會跳至 32 行去執行 LimeController 內的 loadView ,但是卻不是完全 照 LimeController 內 callLimeController 的 loadButton 、 switch ,而且 call OrangeController 自己的 loadButton 及 switch ,進入 LimeController 的 loadView(32 行 ) 後詳如下: 34 行: alloc 一個 UIView 。 35 行:設定顏色 Lime 。 ( 未來 73 行再重設為 ORANGE) 36 、 37 行:設定 autoresize 特性。 38 行:指定這個 UIView 為 OrangeController 的 view 。 ( 此時 self 是 OrangeController) 39 行: release memory 。 40 行:呼叫 loadButton(61 行、這是 OrangeController 的 loadButton) ,將 Pink Button 放進 Navigation Bar(64 行 ) ,也將 action 定為 switch(67 行 ) ,但是這個 switch 是 OrangeController 的 switch ,在 76 行。 switch(76 行 ) 則會 pushViewController -- PinkController(78 行 ) , 造成畫面轉換至 Pink 。 執行完 [super loadView] , 73 行的 self.view.backgroundColor = ORAGNE ;將畫面換成 oragne
29
在 PinkController 中, loadView 內 call [super loadView](96 行 ) ,就 會跳至 32 行去執行 LimeController 內的 loadView ,但是卻不是完全照 LimeController 內 callLimeController 的 loadButton 、 switch ,而且 call PinkController 自己的 loadButton 及 switch ,進入 LimeController 的 loadView(32 行 ) 後詳如下: 34 行: alloc 一個 UIView 。 35 行:設定顏色 Lime 。 ( 未來 97 行再重設為 PINK) 36 、 37 行:設定 autoresize 特性。 38 行:指定這個 UIView 為 PinkController 的 view 。 ( 此時 self 是 PinkController) 39 行: release memory 。 40 行:呼叫 loadButton(89 行、這是 PinkController 的 loadButton) , loadButton 不做任何事,因為不需再放一個 button ,但是 PinkController 必需有自己的 loadButton ,否則會 call 到 LimeController 的 loadButton 。 執行完 [super loadView] , 97 行的 self.view.backgroundColor = PINK ;將畫面換成 pink 。
30
#define PINK [UIColor colorWithRed:0.925f green:0.0f blue:0.549f alpha:1.0f] #define LIME [UIColor colorWithRed:0.82f green:1.0f blue:0.286f alpha:1.0f] #define ORANGE [UIColor colorWithRed:1.0f green:0.522f blue:0.03f alpha:1.0f] @interface LimeController: UIViewController @end @interface PinkController: LimeController @end @interface OrangeController: LimeController @end
31
@implementation LimeController - (id) init { if (self = [super init]) self.title = @"Lime"; return self; } - (void) loadButton { self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Orange" style:UIBarButtonItemStylePlain target:self action:@selector(switch:)]; } - (void)loadView { UIView *contentView = [[UIView alloc] init]; contentView.backgroundColor = LIME; contentView.autoresizesSubviews = YES; contentView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); self.view = contentView; [contentView release]; [self loadButton]; }
32
- (void) switch: (id) sender { [[self navigationController] pushViewController:[[OrangeController alloc] init] animated:YES]; } -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } @end @implementation OrangeController - (id) init { if (self = [super init]) self.title = @"Orange"; return self; } - (void) loadButton { self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Pink" style:UIBarButtonItemStylePlain target:self action:@selector(switch:)]; }
33
- (void) loadView { [super loadView]; self.view.backgroundColor = ORANGE; } - (void) switch: (id) sender { [[self navigationController] pushViewController:[[PinkController alloc] init] animated:YES]; } @end @implementation PinkController - (id) init { if (self = [super init]) self.title = @"Pink"; return self; } - (void) loadButton { return; }
34
- (void) loadView { [super loadView]; self.view.backgroundColor = PINK; } @end @interface SampleAppDelegate : NSObject @end @implementation SampleAppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[LimeController alloc] init]]; [window addSubview:nav.view]; [window makeKeyAndVisible]; } @end int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate"); [pool release]; return retVal; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.