Cover Flow编程1118
来源:互联网 发布:dll文件恢复软件 编辑:程序博客网 时间:2024/05/01 08:21
http://supershll.blog.163.com/blog/static/3707043620121269379367/
第十一章 Cover Flow编程
虽然Cover Flow并未正式包含在iPhone SDK中,但它仍然是iPhone体验中最优秀的特性之一。使用Cover Flow能为用户提供极为出色的视觉选择,这一点令标准的滚动列表望尘莫及。本章将介绍Cover Flow,并展示如何在应用程序中使用它。11.1 UICoverFlowLayer类
虽然正式的SDK中未包含UIConverFlowLayer,但它仍然是标准的UIKit。通过Steve Nygard的类转储(class-dump)(www.codethecode.com/projects/class-dump/),能从UIKit框架中提取UICoverFlowLayer头文件,如代码清单11-1所示。在Mach-O文件的Obj-C程序中生成类声明便可启动类转储。
代码清单11-1 UICoverFlowLayer.h类头文件
。。。(说明)
以上代码说明,UICoverFlowLayer类定义的是图层,而不是视图。图层是抽象呈现类,存在于每个UIView对象中,它还为这些视图提供内部画布。因此,如果你要使用此类,需要将它包含在可用的视图中。以下部分具体说明其实现方法。
11.2 构建Cover Flow视图
在开始处理Cover Flow之前,需要在UIView中插入UICoverFlowLayer实例。把图层放入视图就使Cover Flow技术成为了标准的UIKit术语,然后便可在本书中使用UIView类进行开发了。为此,你仅需创建视图和分配图层。然而,为了让视图正常地显示和工作,你还需要额外执行一些步骤。
这些步骤定制用户与Cover Flow交互的方式。用户在视图中触摸、拖动、双击时,Cover Flow视图需要对此做出正确的响应。为此,视图必须发送dragFlow:atPoint:消息,以处理与Cover Flow图层的触摸和拖动的交互过程。
双击处理提出了另一个难题。Cover Flow并未针对双击实现任何标准的响应,然而,你缺希望应用程序能识别此交互过程,并对此执行一些合理的响应。按照我设计的UIView类,你就可以设置遵守CoverFlowHost协议的主应用程序。当视图截取双击操作时,就调用主应用程序的doubleTapCallback方法。这样,用户在所选择的封面上执行双击操作时,包含Cover Flow视图的视图控制器就能对此做出响应。
封面翻转(cover flipping)是指Cover Flow图像翻开以显示第二个视图(flipSelectedCover)时而采取的一种交互方式。通常,你可以使用双击反馈,或者使用封面翻转。但是,请确定只选取一种方式,如果同时实现两种方式,就会引发两种交互方式的无谓竞争,同时,你也许无法控制调用哪种响应方式。实现方法如代码清单11-2所示。
说明:本书示例代码中有关本章的完整项目,请参考http://ericasadun.com
代码清单11-2 构建Cover Flow视图
#import <UIKit/UIKit.h>
#import "UICoverFlowLayer.h"
@protocol CoverFlowHost <NSObject>
- (void)doubleTapCallback;
@end
@interface CoverFlowView:UIView {
id <CoverFlowHost> host;
id info;
UICoverFlowLayer *cfLayer;
UILabel *label;
}
- (CoverFlowView *)initWithFrame:(CGRect)aFrame andCount:(int)aCount;
- (void)tick;
- (void)setHost:(id)anObject;
- (void)flipSelectedCover;
- (UILabel *)label;
- (UICoverFlowLayer *)cfLayer;
@end
@implementation CoverFlowView
- (CoverFlowView *)initWithFrame:(CGRect)aRect andCount:(int)count
{
self=[super initWithFrame:aRect];
cfLayer=[[UICoverFlowLayer alloc] initWithFrame:[[UIScreen mainScreen] bounds] numberOfCovers:count];
[[self layer] addSublayer:cfLayer];
//Add the placeholder (image stand-in) layer
CGRect phrect=CGRectMake(0.0f,0.0f,200.0f,200.0f);
UIImageView *phimg=[[UIImageView alloc] initWithFrame:phrect];
[cfLayer setPlaceholderImage:[phimg layer]];
//Add its info (label) layer
label=[[UILabel alloc] init];
[label setTextAlignment:UITextAlignmentCenter];
[label setFont:[UIFont boldSystemFontOfSize:20.0f]];
[label setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]];
[label setTextColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.75f]];
[label setNumberOfLines:2];
[label setLineBreakMode:UILineBreakModeWordWrap];
[cfLayer setInfoLayer:[label layer]];
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint pt=[touch locationInView:self];
[cfLayer dragFlow:0 atPoint:pt];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint pt=[touch locationInView:self];
[cfLayer dragFlow:1 atPoint:pt];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint pt=[touch locationInView:self];
if ([touch tapCount]==2)
{
if (host) [host doubleTapCallback];
return;
}
[cfLayer drawFlow:2 atPoint:pt];
}
- (void)flipSelectedCover
{
[cfLayer flipSelectedCover];
}
- (BOOL)ignoresMouseEvents {return NO;}
- (void)tick {[cfLayer displayTick];}
- (void)setHost:(id)anObject {host=anObject;}
- (UILabel *)label {return label;}
- (UICoverFlowLayer *)cfLayer {return cfLayer;}
@end
11.3 构建Cover Flow视图控制器
建立CoverFlowView类之后,你就可以向任何视图控制器中添加此视图。让一切正常运行的诀窍在于核对几个计划框。为了让Cover Flow呈现最佳的工作状态,你需要采取以下措施。
1)隐藏应用程序状态栏。Cover Flow应用程序应该全屏运行,而不应出现令人分心的状态栏。隐藏状态栏的方式是调用[[UIApplication sharedApplication] setStatusBarHidden:YES]。
2)分配和初始化视图。你必须提前知道将要使用的封面数。准备好封面和标题字符串,这些能为视图提供数据源。随后,封面数将被传给初始化程序。
3)等待。等待LoadView方法将Cover Flow设置为主视图,然后开始当前的运行循环(run loop)。
4)提供委托和数据源方法。确保视图控制器能处理一些必要的Cover Flow委托和数据源回调。以下部分将详细介绍这些必要的和可选的方法。
当你完成上述这些目标后,应该会很快出现并运行有效的Cover Flow演示界面。图11-1显示通过视图控制器在代码清单11-3中建立的Cover Flow界面。在该Cover Flow中,蜡笔的不同颜色以一连串圆形样板的形式展现给用户。轻击翻转样板,将显示代表该颜色的6个字符的十六进制代码。
11.3.1 Cover Flow数据源方法
对于标准的Cover Flow操作,视图控制器为coverFlow:requestImageAtIndex:quality方法提供了UIImage。利用所提供的索引确定要返回的图像。此方法对于数据源的正常工作是非常必要的。为了更快地载入图像,可以使用松散的图像生成方式,而不要使用以下代码清单中的数组方式来创建运行中需要的图像。你可以将这些图像存储到稀疏目录下,而只为那些将要使用的图像构建Cover Flow数据源方法。
翻转图层是可选的。用户轻击它们时,通过图层就能集中封面进行浏览。使用翻转图层时,向视图控制器中添加coverFlow:requestFlipLayerAtIndex:方法。此方法返回图像图层以显示翻转项目的后退路径。
11.3.2 Cover Flow委托方法
如代码清单11-3所示,用户选取新页面时,Cover Flow视图产生selectionDidChange:回调方法。使用此方法能更新显示的标签文本,并跟踪最近所选项目的路径。
另一种委托方法是coverFlowFlipDidEnd:,它能通知你翻转动画何时完成。调用这种方法能实现从前向后翻转或者从后向前翻转,因此跟踪了对应状态的路径。请注意翻转视图是显示的还是隐藏的。
代码清单11-3 在视图控制器中构建Cover Flow视图
#import <UIKit/UIKit.h>
#import "CoverFlowView.h"
@interface CoverViewController:UIViewController
{
CoverFlowView *cfView;
UICoverFlowLayer *cfLayer;
UILabel *label;
NSMutableArray *covers;
NSMutableArray *titles;
int whichItem;
id target;
SEL selector;
NSMutableDictionary *colorDict;
UILabel *flippedView;
BOOL flipOut;
}
@end
//Cover Flow View Controller
@implementation CoverViewController
- (CoverViewController *)init
{
if (!(self=[super init])) return self;
//Read in the crayons and set up the arrays and dictionaries
NSArray *crayons=[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"crayons" ofType:@"txt"]] componentsSeparatedByString:@"\n"];
covers=[[NSMutableArray alloc] init];
titles=[[NSMutableArray alloc] init];
colorDict=[[NSMutableDictionary alloc] init];
//Create the title and cover arrays
for (NSString *crayon in crayons)
{
NSArray *theCrayon=[crayon componentsSeparatedByString:@"#"];
if ([theCrayon count] !=2) continue;
[titles addObject:[theCrayon objectAtIndex:0]];
[covers addObject:createImage([theCrayon objectAtIndex:1])];
[colorDict setObject:[theCrayon objectAtIndex:1] forKey:[theCrayon objectAtIndex:0]];
}
//Create the flip object
CGRect fliprect=CGRectMake(0.0f,0.0f,480.0f,480.0f);
flippedView=[[FlipView alloc] initWithFrame:fliprect];
[flippedView setTransform:CGAffineTransformMakeRotation(3.141592f/2.0f)];
[flippedView setUserInteractionEnabled:YES];
//Initialize
cfView=[[CoverFlowView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] andCount:[titles count]];
[cfView setUserInteractionEnabled:YES];
[cfView setHost:self];
cfLayer=[cfView cfLayer];
label=[cfView label];
//Finish setting up the Cover Flow Layer
whichItem=[titles count]/2;
[cfLayer selectCoverAtIndex:whichItem];
[cfLayer setDelegate:self];
selector=NULL;
target=NULL;
return self;
}
//Cover Flow delegate methods
- (void)coverFlow:(id)coverFlow selectionDidChange:(int)index
{
whichItem=index;
[label setText:[titles objectAtIndex:index]];
}
//Detect the end of the flip - both on reveal and hide
- (void)coverFlowFlipDidEnd:(UICoverFlowLayer *)coverFlow
{
if(flipOut)
[[[UIApplication sharedApplication] keyWindow] addSubview:flippedView];
else
[flippedView removeFromSuperview];
}
//Cover Flow datasource methods
- (void)coverFlow:(id)coverFlow requestImageAtIndex:(int)index quality:(int)quality
{
UIImage *whichImg=[covers objectAtIndex:index];
[coverFlow setImage:[whichImg CGImage] atIndex:index type:quality];
}
//Return a flip layer,one that preferably integrates into the flip presentation
- (id)coverFlow:(UICoverFlowLayer *)coverFlow requestFlipLayerAtIndex:(int)index
{
if (flipOut) [flippedView removeFromSuperview];
flipOut=!flipOut;
//Prepare the flip text
[flippedView setText:[NSString stringWithFormat:@"%@\n%@",[titles objectAtIndex:index],[colorDict objectForKey:[titles objectAtIndex:index]]]];
//Flip with a simple blank square
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f,140.0f,140.0f)];
[view setBackgroundColor:[UIColor clearColor]];
return [view layer];
}
//Utility methods
- (CoverFlowView *)cfView {return cfView;}
- (UICoverFlowLayer *)cfLayer {return cfLayer;}
- (int)selectedItem { return whichItem;}
- (void)start
{
[cfView startHeartbeat:@selector(tick) inRunLoopMode:(id)kCFRunLoopDefaultMode];
[cfLayer transitionIn:1.0f];
}
- (void)stop
{
[cfView stopHeartbeat:@selector(tick)];
}
- (void)loadView
{
[super loadView];
self.view=cfView;
[self start];
}
//Callback method for double tap
- (void) doubleTapCallback
{
}
@end
11.4 小结
通过阅读本章可以看出,iPhone编程中一些非常精致的细节都包含在公共的iPhone框架中,而不在正式的SDK中。苹果公司这种非正式策略的意图很明显:你可以在程序中使用这些项目,但是这样做存在一定的风险。在每个固件版本中,你的代码都可能会中断。这就意味着你需要在风险和回报之间寻找最佳的平衡点。
0 0
- Cover Flow编程1118
- Cover Flow布局
- Cover Flow 期待已久!
- Android下Cover Flow(1)
- Android OpenGL Gallery Cover Flow
- Cover Flow特效实现(1)
- Cover Flow特效实现(2)
- iphone基础之前篇:Cover Flow
- Cover flow基本原理及Tapku实现方法
- Cover flow基本原理及Tapku实现方法
- Cover flow基本原理及Tapku实现方法
- Cover flow基本原理及Tapku实现方法
- 在iOS上实现Cover Flow (一)
- 在iOS上实现Cover Flow (二)
- 在iOS上实现Cover Flow (三)
- Cover flow基本原理及Tapku实现方法
- 在iOS上实现Cover Flow (四)
- 在iOS上实现Cover Flow (五)
- android 泛型 baseservice
- 链表判断环问题
- 从一家电子商务网站学到的经验教训
- 跨站请求伪造CSRF防护方法
- @Repository、@Service、@Controller 和 @Component
- Cover Flow编程1118
- Tsinghua MOOC 范围查询(Range)
- [MS SQL]外键约束
- StringBuffer(可变字符串)和StringBuilder
- C# Windows Schedule task之获取task下次运行时间
- PHP各个版本区别
- JAVA设计模式之 命令模式【Command Pattern】
- AD 用户属性userAccountControl的详细解释
- Linux操作系统文件系统基础知识详解