我有一个UIView,其图层将有子图层.我想为每个子图层分配代理,因此委托方法可以告诉图层要绘制什么.我的问题是:
作为CALayer的代表,我应该提供什么?文档说不要使用层所在的UIView,因为这是为视图的主CALayer保留的.但是,创建另一个类只是为了成为我创建的CALayers的代表,这就失去了不继承CALayer的目的.人们通常使用什么作为CALayer的代表?或者我应该只是亚类?
另外,为什么实现委托方法的类不必遵循某种CALayer协议?这是一个我不太了解的更广泛的首要问题.我认为所有需要实现委托方法的类都需要协议规范,以便实现者遵守.
Dav*_*Lee 30
我希望在我的UIView子类中保留层委托方法,我使用一个基本的重新委派委托类.此类可以在不进行自定义的情况下重复使用,从而无需为CALayer创建子类或仅为图层绘制创建单独的委托类.
@interface LayerDelegate : NSObject
- (id)initWithView:(UIView *)view;
@end
Run Code Online (Sandbox Code Playgroud)
有了这个实现:
@interface LayerDelegate ()
@property (nonatomic, weak) UIView *view;
@end
@implementation LayerDelegate
- (id)initWithView:(UIView *)view {
self = [super init];
if (self != nil) {
_view = view;
}
return self;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {
NSString *methodName = [NSString stringWithFormat:@"draw%@Layer:inContext:", layer.name];
SEL selector = NSSelectorFromString(methodName);
if ([self.view respondsToSelector:selector] == NO) {
selector = @selector(drawLayer:inContext:);
}
void (*drawLayer)(UIView *, SEL, CALayer *, CGContextRef) = (__typeof__(drawLayer))objc_msgSend;
drawLayer(self.view, selector, layer, context);
}
@end
Run Code Online (Sandbox Code Playgroud)
图层名称用于允许每层自定义绘制方法.例如,如果您已为图层指定了名称layer.name = @"Background";,那么您可以实现如下方法:
- (void)drawBackgroundLayer:(CALayer *)layer inContext:(CGContextRef)context;
Run Code Online (Sandbox Code Playgroud)
请注意,您的视图需要强大的引用此类的实例,并且它可以用作任意数量的层的委托.
layerDelegate = [[LayerDelegate alloc] initWithView:self];
layer1.delegate = layerDelegate;
layer2.delegate = layerDelegate;
Run Code Online (Sandbox Code Playgroud)
Fel*_*xyz 28
最轻微的解决方案是在文件中创建一个小助手类作为使用CALayer的UIView:
在MyView.h中
@interface MyLayerDelegate : NSObject
. . .
@end
Run Code Online (Sandbox Code Playgroud)
在MyView.m中
@implementation MyLayerDelegate
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
. . .
}
@end
Run Code Online (Sandbox Code Playgroud)
只需将它们放在文件的顶部,紧接在#import指令下面.这样,感觉更像是使用"私有类"来处理绘图(虽然它不是 - 委托类可以由导入标题的任何代码实例化).