当前位置:编程学习 > wap >>

IOS设计模式之(适配器模式,观察者模式)

适配器(Adapter)模式
适配器可以让一些接口不兼容的类一起工作。它包装一个对象然后暴漏一个标准的交互接口。
如果你熟悉适配器设计模式,苹果通过一个稍微不同的方式来实现它-苹果使用了协议的方式来实现。你可能已经熟悉UITableViewDelegate, UIScrollViewDelegate, NSCoding 和 NSCopying协议。举个例子,使用NSCopying协议,任何类都可以提供一个标准的copy方法。
 
 如何使用适配器模式
 
前面提到的水平滚动视图如下图所示:
 
 
 
 
为了开始实现它,在工程导航视图中右键点击View组,选择New File...使用iOS\Cocoa Touch\Objective-C class 模板创建一个类。命名这个新类为HorizontalScroller,并且设置它是UIView的子类。
 
打开HorizontalScroller.h文件,在@end 行后面插入如下代码:
Objective-c代码  
@protocolHorizontalScrollerDelegate <NSObject>  
// methods declaration goes in here  
@end  
 
上面的代码定义了一个名为HorizontalScrollerDelegate的协议,它采用Objective-C 类继承父类的方式继承自NSObject协议。去遵循NSObject协议或者遵循一个本身实现了NSObject协议的类 是一条最佳实践,这使得你可以给HorizontalScroller的委托发送NSObject定义的消息。你不久会意识到为什么这样做是重要的。
在@protocol和@end之间,你定义了委托必须实现以及可选的方法。所以增加下面的方法:
 
Objective-c代码  
@required  
  
// ask the delegate how many views he wants to present inside the horizontal scroller  
  
- (NSInteger)numberOfViewsForHorizontalScroller:(HorizontalScroller*)scroller;  
  
   
  
// ask the delegate to return the view that should appear at <index>  
  
- (UIView*)horizontalScroller:(HorizontalScroller*)scroller viewAtIndex:(int)index;  
  
   
  
// inform the delegate what the view at <index> has been clicked  
  
- (void)horizontalScroller:(HorizontalScroller*)scroller clickedViewAtIndex:(int)index;  
  
   
  
@optional  
  
// ask the delegate for the index of the initial view to display. this method is optional  
  
// and defaults to 0 if it's not implemented by the delegate  
  
- (NSInteger)initialViewIndexForHorizontalScroller:(HorizontalScroller*)scroller;  
 
     这里你既有必需的方法也有可选方法。必需的方法要求委托必须实现它,因为它提供一些必需的数据。在这里,必需的是视图的数量,指定索引位置的视图,以及用户点击视图后的行为,可选的方法是初始化视图;如果它没有实现,那么HorizontalScroller将缺省用第一个索引的视图。
下一步,你需要在HorizontalScroller类中引用新建的委托。但是委托的定义是在类的定义之后的,所以在类中它是不可见的,怎么办呢?
解决方案就是前置声明委托协议以便编译器(和Xcode)知道协议的存在。如何做?你只需要在@interface行前面增加下面的代码即可:
 
@protocolHorizontalScrollerDelegate;
 
继续在HorizontalScroller.h文件中,在@interface 和@end之间增加如下的语句:
Objective-c代码  
@property (weak) id<HorizontalScrollerDelegate> delegate;  
- (void)reload;  
 
 
这里你声明属性为weak.这样做是为了防止循环引用。如果一个类强引用它的委托,它的委托也强引用那个类,那么你的app将会出现内存泄露,因为任何一个类都不能释放调分配给另一个类的内存。
id意味着delegate属性可以用任何遵从HorizontalScrollerDelegate的类赋值,这样可以保障一定的类型安全。
reload方法在UITableView的reloadData方法之后被调用,它重新加载所有的数据去构建水平滚动视图。
 
用如下的代码取代HorizontalScroller.m的内容:
 
Objective-c代码  
#import "HorizontalScroller.h"  
  
   
  
// 1  
  
#define VIEW_PADDING 10  
  
#define VIEW_DIMENSIONS 100  
  
#define VIEWS_OFFSET 100  
  
   
  
// 2  
  
@interfaceHorizontalScroller () <UIScrollViewDelegate>  
  
@end  
  
  
// 3  
  
@implementationHorizontalScroller  
  
{  
  
    UIScrollView *scroller;  
  
}  
  
   
  
@end  
 
 
 
让我们来对上面每个注释块的内容进行一一分析:
 
   1. 定义了一系列的常量以方便在设计的时候修改视图的布局。水平滚动视图中的每个子视图都将是100*100,10点的边框的矩形.
   2. HorizontalScroller遵循UIScrollViewDelegate协议。因为HorizontalScroller使用UIScrollerView去滚动专辑封面,所以它需要用户停止滚动类似的事件
   3.创建了UIScrollerView的实例。
 
下一步你需要实现初始化器。增加下面的代码:
 
Objective-c代码  
- (id)initWithFrame:(CGRect)frame  
  
{  
  
    self = [super initWithFrame:frame];  
  
    if (self)  
  
    {  
  
        scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];  
  
        scroller.delegate = self;  
  
        [self addSubview:scroller];  
  
        UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollerTapped:)];  
  
        [scroller addGestureRecognizer:tapRecognizer];  
  
    }  
  
    return self;  
  
}  
 
滚动视图完全充满了HorizontalScroller。UITapGestureRecognizer检测滚动视图的触摸事件,它将检测专辑封面是否被点击了。如果专辑封面被点击了,它会通知HorizontalScroller的委托。
现在,增加下面的代码:
 
Objective-c代码  
- (void)scrollerTapped:(UITapGestureRecognizer*)gesture  
  
{  
  
    CGPoint location = [gesture locationInView:gesture.view];  
  
    // we can't use an enumerator here, because we don't want to enumerate over ALL of the UIScrollView subviews.  
  
    // we want to enumerate only the subviews that we added  
  
    for (int index=0; index<[self.delegate numberOfViews
补充:移动开发 , IOS ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,