iPhone之手势切换图片
今天我们介绍一下iPhone手势切换图片,算是对之前的小小总结。程序功能和常用的图片浏览软件类似,手指向左划动就回卷到上一幅图片,向右划动就后卷到下一幅图片。别看功能简单,但真正实现起来还是挺麻烦的。下面开始吧:
1.
新建一个Window-based Application,名称为Switch:
2.
分别新建三个UIViewController:FirstViewController,SecondViewController 和 RootViewController,其中 FirstViewController,SecondViewController 需要勾选第三项“With XIB for user interface”,而 RootViewController 则不用勾选(这样做的原因是我想介绍一下手动创建一个XIB的过程)
3.
下面介绍一下手动创建 RootViewController.XIB 并与RootViewController 关联的过程:
新建一个 Empty XIB,名称是 RootViewController.XIB:
4.
打开 RootViewController.XIB,我们发现少了 View 一项:
从左侧的Library库 中拖一个 View 到其中:
选中 File's Owner,按 Command + 4 打开属性窗口,在 Class 一栏选择 RootViewController,这样新创建的 RootViewController.XIB 就和 RootViewController 联系起来了:
然后,选中 File's Owner,按 Ctrl 键,鼠标拖动到 View 中,在弹出的 Outlets 中选择 View,这样新创建的 View 就和 RootViewController 的 View 联系起来了:
5.
修改 SwitchAppDelegate.m 如下:
//
// SwitchAppDelegate.m
// Switch
//
// Created by HuTao on 8/18/12.
// Copyright __MyCompanyName__ 2012. All rights reserved.
//
#import "SwitchAppDelegate.h"
#import "RootViewController.h"
@implementation SwitchAppDelegate
@synthesize window;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
RootViewController * root = [[RootViewController alloc]init];
window.rootViewController = root;
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[window release];
[super dealloc];
}
@end
运行一下,发现已经成功了,可以在 RootViewController.XIB 放置些控件以示区别
6.
将要显示的图片加入工程中,并且在 FirstViewController.XIB 和 SecondViewController.XIB 中分别铺满 UIImageView 控件,如下图:
7.
修改 FirstViewController.h 如下:
//
// FirstViewController.h
// Switch
//
// Created by HuTao on 8/18/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FirstViewController : UIViewController
{
IBOutlet UIImageView * imageView;
}
@property (retain, nonatomic) UIImageView * imageView;
-(void)loadImage:(NSString *)imageName;
@end
loadImage是提供给外部调用的一个方法,传入要显示的文件名,就会在UIImageView中显示出来
并把 UIImageView 和对应的 IBOutlet 连接起来
然后修改 FirstViewController.m 如下:
//
// FirstViewController.m
// Switch
//
// Created by HuTao on 8/18/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import "FirstViewController.h"
@implementation FirstViewController
@synthesize imageView;
-(void)loadImage:(NSString *)imageName
{
[imageView setImage:[UIImage imageNamed:imageName]];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
imageView = nil;
}
- (void)dealloc
{
[super dealloc];
[imageView release];
}
@end
[UIImageView setImage:UIImage] 显示图像
[UIImage imageNamed:NSString *] 将文件名转换成 UIImage
8.
SecondViewController 完全参照 FirstViewController 的修改
9.
修改 RootViewController.h 如下:
//
// RootViewController.h
// Switch
//
// Created by HuTao on 8/18/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
@class FirstViewController;
@class SecondViewController;
@interface RootViewController : UIViewController
{
FirstViewController * firstViewController;
SecondViewController * secondViewController;
//图片名称列表
NSArray * imageNameList;
//当前图片编号
int imageIndex;
//当前显示的是否是FirstViewController
BOOL firstUpside;
}
@property (retain, nonatomic) FirstViewController * firstViewController;
@property (retain, nonatomic) SecondViewController * secondViewController;
@property (retain, nonatomic) NSArray * imageNameList;
-(void)handleSwipeGesture:(UIGestureRecognizer*)sender;
-(void)curlImage:(UISwipeGestureRecognizerDirection)direction;
@end
修改 RootViewController.m 如下:
//
// RootViewController.m
// Switch
//
// Created by HuTao on 8/18/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import "RootViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
@implementation RootViewController
@synthesize firstViewController;
@synthesize secondViewController;
@synthesize imageNameList;
//划动手势后调用的回调函数
-(void)handleSwipeGesture:(UIGestureRecognizer *)sender
{
//划动的方向
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *)sender direction];
//上卷或下卷图片
[self curlImage:direction];
}
-(void)curlImage:(UISwipeGestureRecognizerDirection)direction
{
UIViewAnimationTransition transition;
//判断是上下左右
switch (direction)
{
case UISwipeGestureRecognizerDirectionUp:
NSLog(@"up");
return;
case UISwipeGestureRecognizerDirectionDown:
NSLog(@"down");
return;
case UISwipeGestureRecognizerDirectionLeft:
//往左划动,表示向前翻页
NSLog(@"left");
imageIndex = ( ([imageNameList count] - 1 + imageIndex) % [imageNameList count]);
transition = UIViewAnimationTransitionCurlDown;
break;
case UISwipeGestureRecognizerDirectionRight:
//往右划动,表示向后翻页
NSLog(@"right");
imageIndex = ( (++imageIndex) % [imageNameList count] );
transition = UIViewAnimationTransitionCurlUp;
break;
default:
return;
}
//loadImage必须放在insertSubview之后,否则无效?为什么?
UIViewController * coming = nil;
UIViewController * going = nil;
if(firstUpside == YES)
{
//由 FirstViewController 切换到 SecondViewController
coming = secondViewController;
going = firstViewController;
}
else
{
//由 SecondViewController 切换到 FirstViewController
coming = firstViewController;
going = secondViewController;
}
[UIView beginAnimations:@"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.view cache:YES];
[coming viewWillAppear:YES];
[going viewWillDisappear:YES];
[going.view removeFromSuperview];
[self.view insertSubview:coming.view atIndex:0];
if(firstUpside == YES)
{
[secondViewController loadImage:[imageNameList objectAtIndex:imageIndex]];
firstUpside = NO;
}
else
{
[firstViewController loadImage:[imageNameList objectAtIndex:imageIndex]];
firstUpside = YES;
}
[coming viewDidAppear:YES];
[going viewDidDisappear:YES];
//提交Animation
[UIView commitAnimations];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
imageNameList = [[NSArray alloc] initWithObjects:
@"1.jpg", @"2.jpg", @"3.jpg", @"4.jpg",
@"5.jpg", @"6.jpg", @"7.jpg", @"8.jpg", nil];
imageIndex = 0;
firstUpside = YES;
FirstViewController * temp1 = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
self.firstViewController = temp1;
//首先显示 FirstViewController
[self.view insertSubview:temp1.view atIndex:0];
[temp1 release];
[firstViewController loadImage:[imageNameList objectAtIndex:imageIndex]];
SecondViewController * temp2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
self.secondViewController = temp2;
[temp2 release];
//划动手势
//上划
UISwipeGestureRecognizer * swipeGestureUp = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGestureUp.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:swipeGestureUp];
[swipeGestureUp release];
//下划
UISwipeGestureRecognizer * swipeGestureDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGestureDown.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipeGestureDown];
[swipeGestureDown release];
//左划
UISwipeGestureRecognizer * swipeGestureLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeGestureLeft];
[swipeGestureLeft release];
//右划
UISwipeGestureRecognizer * swipeGestureRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGestureRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeGestureRight];
[swipeGestureRight release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
firstViewController = nil;
secondViewController = nil;
}
- (void)dealloc {
[super dealloc];
[firstViewController release];
[secondViewController release];
}
@end
虽然代码较多,但很好理解。
首先初始化了 FirstViewController 和 SecondViewController,然后加入了GestureRecognizer,一旦识别到划动手势,则调用 handleSwipeGesture回调函数。
在 curlImage 中,我采用的切换图片的原理是:定义两个 UIViewController,交替显示,以此达到翻页切换图片的目的。当然,还需要考虑只有0或1张图的情况,不过,这里我省略了。
另外经过我的测试,发现 loadImage 必须放在 insertSubview 之后,否则无效?为什么?
运行结果如下:
原图:
手指向右划动,切换到下一幅图片:
下一幅图片:
最后我把完整代码也上传上来了:
http://download.csdn.net/detail/htttw/4510398
完成!