您可能会使用UIControl 并知道它是UIView 的子类。因此,您可以在 UIControl 中实现一个布尔属性,该属性存储是否可以使用 Metal,并为其他技术提供后备以在金属不可用的情况下呈现内容。
您需要考虑当您分配多个自定义 UIControls 时,Metal/GPU 将一个一个地渲染它们而不是并行渲染它们,除非您定义一个全局渲染器,该渲染器可以一次渲染所有控件图形,并将其放置为 '基本 UIView 的几乎最前面的层。您将希望通过
来使用透明度
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0,0,0,0);
并且还要考虑触摸/事件处理可能会被这样的层干扰。这一切都可以很好地处理。或者你可以在你的基础视图中实现它,然后使用 UIControls 在提到的全局渲染器中设置即 Uniforms
作为起点,您将使用类似的东西
@interface yourUIControl {
MTKView * mtkview;
YourMetalRenderer * _yourRenderer;
BOOL _isMetalDriven;
}
@end
@implementation yourUIControl
-(BOOL)isMetalPerforming:(CGRect)frame {
mtkview = [[MTKView alloc] init];
[MTKView setAnimationsEnabled:NO];
mtkview.preferredFramesPerSecond = 24;
mtkview.presentsWithTransaction = NO;
mtkview.contentMode = UIViewContentModeScaleAspectFill;
mtkview.frame = frame;
mtkview.device = MTLCreateSystemDefaultDevice();
if(!mtkview.device) {
NSLog(@"Metal is not supported on this device");
return NO;
} else {
_yourRenderer = [[YourMetalRenderer alloc] initWithMetalKitView:mtkview];
if (!_yourRenderer) {
NSLog(@"Renderer failed initialization");
return NO;
} else {
[_yourRenderer mtkView:mtkview drawableSizeWillChange:mtkview.drawableSize];
mtkview.delegate = _yourRenderer;
[self addSubview:mtkview];
return YES;
}
}
}
然后在初始化您的自定义 UIControl 时像这样设置您的 BOOL 属性
-(instancetype)initWithFrame:(CGRect)frame {
if ( !(self = [super initWithFrame:frame]) ) return nil;
// ask for the renderer and set BOOL property
_isMetalDriven = [self isMetalPerforming:frame];
// handling fallback if i.e. metal is not performing
if (!_isMetalDriven) {
// your classic layer technique to create UIControls content here.
// dont forget when the control is changed in some way, you will forward
// changes to _yourRenderer (i.e. Uniform properties) OR to classic handling
}
//your other UIControl code
return self;
}
-(void)layoutSubviews {
if (!_isMetalDriven) {
//classic control layout here..
} else {
//metal backed layout here..
mtkview.frame = self.frame; //i.e.
}
}
@end
如果需要,您可以将 pause 渲染器设置为“是”和“否”,甚至可以根据 DisplayLink 或 setNeedsDisplay 使用 mtkView 中的适当属性进行渲染过程
您的CAMetalLayer 将存在于mtkview.layer 中