转改:UIPageControl

大家都见过iPhone上的那几个小点点了。那就是iPhone用来控制翻页的UIPageControl控件,但是许多人不会用UIPageControl,又不愿意去看Apple的文档和例子。所以首先我们来讲讲这个控件的使用。

1、新建项目UsingPageControl。删除MainWindow.xib文件。 在Resources组中添加几张图片,在这里我随便找了几张动物的图片,你也可以另外找几张。

2、编辑delegate类代码,#import "UsingPageControlViewController.h",在application:didFinishLaunchingWithOptions:方法中加入以下代码:

UIViewController *vc=[[UsingPageControlViewController alloc]init];

[window addSubview:vc.view];

3、加入框架QuartzCore.framework。然后新建类UsingPageControlViewController,继承UIViewController。在interface中声明必要变量:

#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>

#import <QuartzCore/QuartzCore.h>

 

 

@interfaceUsingPageControlViewController : UIViewController {

UIPageControl* pageCtr;

NSMutableArray* pages;

UIView *pageView;

int previousPage;

}

-(void)transitionPage:(int)from toPage:(int)to;

-(CATransition *) getAnimation:(NSString *) direction;

@end

 

4、在implementation中,编辑init方法,把我们要用到的3个图片文件名放入到pages数组:

-(id)init{

if (self = [super init]) {

pages=[[NSMutableArray alloc]initWithObjects:@"Dolphin.png",

   @"Butterfly.png",

   @"Hippopotamus.png",

   nil];

}

return self;

}

 

5、编辑loadView方法,在上方放入一个UIPageControl用于翻页,在下方放入一个UIView用于显示图片,注意上下分开,不要重叠,避免UIPageControl被遮挡住:

-(void)loadView{

[super loadView];

 

CGRect viewBounds = self.view.frame;

viewBounds.origin.y = 0.0;

viewBounds.size.height = 460.0;

//控件区域

pageCtr=[[UIPageControl alloc]initWithFrame:CGRectMake(viewBounds.origin.x,

   viewBounds.origin.y,

   viewBounds.size.width,

   60)];

pageCtr.backgroundColor=[UIColor blackColor];

pageCtr.numberOfPages = 3;

pageCtr.currentPage = 0;

// 设定翻页事件的处理方法

[pageCtr addTarget:self action:@selector(pageTurn:)

  forControlEvents:UIControlEventValueChanged];

[self.view addSubview:pageCtr];

// 页面区域

CGRect contentFrame=CGRectMake(viewBounds.origin.x,

 viewBounds.origin.y+60,

 viewBounds.size.width,

 viewBounds.size.height-60);

pageView=[[UIView alloc]initWithFrame:contentFrame];

[pageView setBackgroundColor:[UIColor brownColor]];

// 添加两个imageview,动画切换时用

for (int i=0; i<2; i++) {

[pageView addSubview:[[UIImageView alloc] initWithFrame:CGRectMake(0,

   0,

   contentFrame.size.width,

   contentFrame.size.height)]];

}

// 设置最上面的subview(显示的图片)

[[[pageView subviews] lastObject] setImage:[UIImage imageNamed:

[pages objectAtIndex:0]]];

[self.view addSubview:pageView];

 

}

6、翻页控件在感知到翻页动作时,会调用pageTurning方法:

-(void)pageTurn:(UIPageControl*)pageControl{

[self transitionPage:previousPage toPage:pageControl.currentPage];

previousPage=pageControl.currentPage;

}

 

7、transitionPage方法是这样定义的:

-(void)transitionPage:(int)from toPage:(int)to{

NSLog(@"previouspage:%d",from);

NSLog(@"currentpage:%d",to);

CATransition *transition;

if (from!=to) {

if(from<to){

transition=[self getAnimation:kCATransitionFromLeft];

}else{

transition=[self getAnimation:kCATransitionFromRight];

}

// 取出pageView的下面的图片作为准备显示的图片

UIImageView *newImage=(UIImageView *)[[pageView subviews] objectAtIndex:0];

// 将视图修改为要显示的图片

[newImagesetImage:[UIImage imageNamed:[pages objectAtIndex:to]]];

// 将pageView的上下图片交换

[pageView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];

// 显示上面的图片,隐藏下面的图片

[[pageView.subviews objectAtIndex:0] setHidden:YES];

[[pageView.subviews objectAtIndex:1] setHidden:NO];

// 设置转换动画

[[pageView layer] addAnimation:transition forKey:@"pageTurnAnimation"];

}

}

 

8、其中getAnimation方法根据用户手指滑动的方向返回CATransition转换动画:

// 返回一个转换动画

-(CATransition *) getAnimation:(NSString *) direction

{

CATransition *animation = [CATransition animation];

[animation setDelegate:self];

[animation setType:kCATransitionPush];

[animation setSubtype:direction];

[animation setDuration:1.0f];

[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

return animation;

}

这是一个翻页动画,通过其subtype属性设定翻页从哪边开始:上、下、左、右4个方向。duration属性是动画转换的时间;timingFunction属性指定转换过程中要使用的特效,使用常量字符串指定5种不同的效果(但不知什么原因,在这里不管设成什么值,都只有一种效果:淡入淡出)。

程序最终效果如下:

http://img.ph.126.net/OOXkrJ0gGIDLFYbTK-216g==/1347139238554061973.png

使用UIPageControl的例子如前面所示。但光以控件形式使用 UIPageControl还是不好用,因为虽然用户能通过手指扫动UIPageControl控件进行翻页,但UIPageControl控件在屏幕上所占的区域还是太小了,如果用户在整个屏幕都能通过扫动来进行翻页就更好了,这无疑大大增强的用户的体验。

这需要我们增加一个UIView控件,让它占据屏幕的整个区域。让UIView能识别用户手指扫动的手势,即几个touchesXXX方法。这样用户在屏幕上滑动手指时,实际上会被UIView捕捉为扫动手势。

首先,我们来实现这个UIView。新建类 SwipeView。SwipeView借鉴了《iPhone开发秘籍》中 Henry Yu 的实现,甚至我们都不需要做多少改变。

#import <UIKit/UIKit.h>

#import <QuartzCore/QuartzCore.h>

 

@interface SwipeView : UIView {

CGPoint startTouchPosition;

NSString *direction;

UIViewController *host;

}

- (void) setHost: (UIViewController *) aHost;

@end

#import "SwipeView.h"

@implementation SwipeView

 

- (id)initWithFrame:(CGRect)frame {

    if ((self = [super initWithFrame:frame])) {

        // Initializationcode

    }

    return self;

}

- (void) setHost: (UIViewController *) aHost

{

host = aHost;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

startTouchPosition = [touch locationInView:self];

direction = NULL;

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch =touches.anyObject;

CGPoint currentTouchPosition =[touch locationInView:self];

#defineHORIZ_SWIPE_DRAG_MIN 12

#defineVERT_SWIPE_DRAG_MAX 4

if (fabsf(startTouchPosition.x -currentTouchPosition.x) >=

HORIZ_SWIPE_DRAG_MIN &&

fabsf(startTouchPosition.y - currentTouchPosition.y) <=

VERT_SWIPE_DRAG_MAX)

{

// Horizontal Swipe

if (startTouchPosition.x <currentTouchPosition.x) {

direction = kCATransitionFromLeft;

}

else

direction = kCATransitionFromRight;

}

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

if (host!=nil && direction) {

SEL sel=NSSelectorFromString(@"swipeTo:");

if([host respondsToSelector:sel]) {

[host performSelector:sel withObject:direction];

}

}

@end

 

首先,打开我们前面所做的工程UsingPageControl。

在UsingPageControlVeiwController中导入头文件SwipeView.h。将UsingPageControlViewController中的pageView修改为SwipeView类型。

同时在pageView的初始化时使用SwipeView的initWithFrame方法,并调用setHost:方法:

pageView=[[SwipeView alloc]initWithFrame:contentFrame];

[pageView setHost:self];

接下来,我们需要在SwipeView的Host类UsingPageControlVeiwController实现指定的swipeTo:方法:

// SwipeView 的协议(委托)方法

- (void) swipeTo: (NSString *) aDirection

{

NSLog(@"swipe to");

int to=previousPage;

if ([aDirection isEqualToString:kCATransitionFromRight])

{

to++;

}else {

to--;

}

if (to>=0 && to<=2) {

// pageCtrl的值改变并调用pageTuren方法

[self transitionPage:previousPage toPage:to];

previousPage=pageCtr.currentPage=to;

 

}

}

 

 

自定义UIPageControl(可改变点颜色)

1.继承自UIPageControl  ,2.并准备两张图片 一个用于高亮显示 一个用于普通显示

关键代码如下

- (void) setImagePageStateNormal:(UIImage *)image

{

[imagePageStateNormal release];

imagePageStateNormal = [image retain];

[self updateDots];

}

 

- (void) setImagePageStateHightlighted:(UIImage *)image

{

[imagePageStateHightlighted release];

imagePageStateHightlighted = [image retain];

[self updateDots];

}

 

- (void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

{

[super endTrackingWithTouch:touch withEvent:event];

[self updateDots];

}

 

- (void) updateDots

{

if (imagePageStateNormal || imagePageStateHightlighted) {

NSArray *subView = self.subviews;

 

for (int i = 0; i < [subView count]; i++) {

UIImageView *dot = [subView objectAtIndex:i];

dot.image = (self.currentPage == i ? imagePageStateHightlighted : imagePageStateNormal);

}

}

}

UI控件篇——UIPageControl及其自定义

 

      UIPageControl类提供一行点来指示当前显示的是多页面视图的哪一页。当然,由于UIPageControl类可视样式的点击不太好操作,所以最好是确保再添加了可选择的导航选项,以便让页面控件看起来更像一个指示器,而不是一个控件。当用户界面需要按页面进行显示时,使用UIPageControl控件将要显示的用户界面内容分页进行显示会使编程工作变得快捷。

      用户点击页面控件,会触发UIControlEventValueChanged事件,并启动设置为控件动作的任何方法。可以通过调用currentPage查询控件的新值,并通过调整numberOfPages属性设置可用的页面数。

// 初始化页面控件
pageControl.numberOfPages = 9;
pageControl.currentPage = 0;

[pageControl addTarget:self action:@selector(pageTurn) forControlEvents:UIControlEventValueChanged];
复制代码
- (void)pageTurn:(UIPageControl *)pageControl
{
CATransition *transition;
int secondPage = [pageControl currentPage];
if((secondPage - currentPage)>0)
transition = [self getAnimation:@"fromRight"];
else
transition = [self getAnimation:@"fromLeft"];

UIImageView *newView = (UIImageView *)[[contentView subviews] objectAtIndex:0];
[newView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"ipad_wallpaper%02d.jpg",secondPage+1]]];
[contentView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[[contentView layer] addAnimation:transition forKey:@"transitionView Animation"];

currentPage = [pageControl currentPage];
}
复制代码

结合ScrollView后关于UIPageControl的页面设置算法:

// 在ScrollView的委托方法中

int index = fabs(scrollView.contentOffset.x) / scrollView.frame.size.width;
pageControl.currentPage = index;

自定义之一:给UIPageControl控件添加背景

 1 int pagesCount =5;
2 UIPageControl *pageControl = [[UIPageControl alloc] init];
3 pageControl.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height-15); // 设置pageControl的位置
4 pageControl.numberOfPages = pagesCount;
5 pageControl.currentPage = 0;
6
7 [pageControl setBounds:CGRectMake(0,0,16*(pagesCount-1)+16,16)]; //页面控件上的圆点间距基本在16左右。
8 [pageControl.layer setCornerRadius:8]; // 圆角层
9 [pageControl.setBackgroundColor:[UIColor clorWithWhite:0.0 alpha:0.2]];
10 [self.view addSubview:pageControl];

复制代码
 1 int pagesCount =5;
2 UIPageControl *pageControl = [[UIPageControl alloc] init];
3 pageControl.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height-15); // 设置pageControl的位置
4 pageControl.numberOfPages = pagesCount;
5 pageControl.currentPage = 0;
6
7 [pageControl setBounds:CGRectMake(0,0,16*(pagesCount-1)+16,16)]; //页面控件上的圆点间距基本在16左右。
8 [pageControl.layer setCornerRadius:8]; // 圆角层
9 [pageControl.setBackgroundColor:[UIColor clorWithWhite:0.0 alpha:0.2]];
10 [self.view addSubview:pageControl];
复制代码



 

 

posted @ 2012-06-02 11:16  dh99ming  阅读(306)  评论(0编辑  收藏  举报