首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用图层和中央调度渲染UIButtons的最快方法?

使用图层和中央调度渲染UIButtons的最快方法?
EN

Stack Overflow用户
提问于 2011-09-28 07:20:56
回答 3查看 1.1K关注 0票数 4

我有一个30 UIButtons的网格,可能还有更多的子类要使用层来呈现:一个基本CALayer、一个CAShapeLayer、一个CAGradientLayer和一个CATextLayer。我试图在加载相应的xib文件时尽量减少呈现/显示按钮所需的全部时间。如果我只是在viewDidLoad中依次设置每个按钮,则视图出现所需的时间大约是5-6秒,这显然是太多了。

为了加快按钮的设置速度,我使用的是大中央调度,如下所示。在viewDidLoad中,我在全局队列上使用dispatch_async设置每个按钮层(将形状和渐变层添加到基本层),这样按钮就可以在不同的线程中呈现。A块的末端,CATextLayer被添加到梯度层。

代码语言:javascript
复制
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    CGRect base_bounds = CGRectMake(0, 0, self.layer.bounds.size.width, self.layer.bounds.size.height - self.layer.bounds.size.height * 0.10f);
    CGPoint move_point = CGPointMake(0.0f, base_bounds.size.height * 0.10f);
    self.layer.masksToBounds = NO;
    baseLayer = [CALayer layer];

    baseLayer.cornerRadius = 10.0;
    baseLayer.shadowOffset = CGSizeMake(0.0f, 2.0f);
    baseLayer.shadowOpacity = 1.5f;
    baseLayer.shadowColor = [UIColor blackColor].CGColor;
    baseLayer.shadowRadius = 2.5f;
    baseLayer.anchorPoint = CGPointMake(0.5f, 0.5f);
    baseLayer.position    = move_point;

    CAShapeLayer *shape = [CALayer layer];
    shape.bounds = base_bounds;
    shape.cornerRadius = 10.0;
    shape.anchorPoint      = CGPointMake(0.0f, 0.0f);
    shape.position         = move_point;
    shape.backgroundColor = [UIColor darkGrayColor].CGColor;

    gradient = [CAGradientLayer layer];
    gradient.anchorPoint      = CGPointMake(0.0f, 0.0f);
    gradient.position         = CGPointMake(0.0f, 0.0f);
    gradient.bounds           = base_bounds;
    gradient.cornerRadius     = 10.0;
    gradient.borderColor      = [UIColor colorWithRed:0.72f
                                                green:0.72f
                                                 blue:0.72f
                                                alpha:1.0].CGColor;
    gradient.borderWidth      = 0.73;
    gradient.colors = [NSArray arrayWithObjects:
                       (id)[UIColor whiteColor].CGColor,
                       (id)[UIColor whiteColor].CGColor,
                       nil];


    [baseLayer addSublayer:shape];
    [baseLayer addSublayer:gradient];
    [self.layer addSublayer:baseLayer];

    [textLayer setBounds:gradient.bounds];
           [textLayer setPosition:CGPointMake(CGRectGetMidX(textLayer.bounds), CGRectGetMaxY(textLayer.bounds) - 6)];
           [textLayer setString:self.titleLabel.text]; 
           [textLayer setForegroundColor:[UIColor blackColor].CGColor];
           [gradient addSublayer:textLayer];

});

这种方法将整个时间缩短到大约2-3秒.我想知道是否有人能提出一个更快的方法来渲染按钮。请注意,我对任何放弃使用图层的解决方案都不感兴趣。

提前谢谢你。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-03 15:19:23

也许我忽略了这一点,但您是否可以更好地重写UIButton drawRect:方法和使用CoreGraphics ( CG )进行绘图将比秒快得多,您可以轻松地使用CG API进行渐变、文本和图像绘制。如果我正确理解,每个按钮有4层,30+按钮在同一个视图中(120+层)?如果是这样的话,我不认为您应该绘制这么多层(单独呈现/混合所有这些层将解释巨大的呈现时间)。另一种可能是有4个大的层,所有的按钮。

票数 3
EN

Stack Overflow用户

发布于 2011-09-30 20:09:36

这是我的主意

将您的CALayers与UIButton分开-- UIKit不允许任何背景线程上的任何内容。

当在按钮网格之前的屏幕上有机会时,请使用buttonGridViewController performSelectorInBackground:renderCALayers在后台呈现您的CALayers。

当您在viewDidLoad中加载按钮网格时,使用UIButtonTypeCustom类型覆盖UIButtons,并在“按钮”CALayers顶部添加backgroundColor = UIColor clearColor (确保在UIButtons上调用bringSubviewToFront,以便他们获得触摸事件)。

如果您不知道要呈现多少个按钮,则可能需要预渲染可能显示的最大数目。

如果您有任何问题,请评论。

编辑:

一些相关的东西,

What to replace a UIButton to improve frame rate?

UI design - Best way to deal with many UIButtons

How to get touch event on a CALayer?

我相信,从这一点开始,获得更快加载的唯一方法是替换或删除UIButtons,并使用另一种方法拦截触摸事件。这样,在视图出现之前,所有呈现都可以在后台线程中完成。

票数 1
EN

Stack Overflow用户

发布于 2011-10-03 22:01:14

您考虑过使用NSOperation生成按钮的层吗?在代码中,您将实例化一个操作队列,然后遍历每个按钮,在每个按钮启动时触发一个操作(传递生成该按钮层所需的相应参数)。

在您的NSOperation中,使用CoreGraphics生成您的层,然后通过您的完成处理程序(确保在主线程上调用它)将该层传回启动操作的按钮(在本例中是目标按钮)。这将为您提供相当好的性能,因为您的按钮层的按钮层将使用CoreGraphics从主线程上呈现,然后只有在该层被呈现后才会传递回UIKit以供表示。

NSOperation位于GCD之上,具有少量的开销,但在您的情况下提供了一些好处,例如设置依赖的先决条件和优先级的能力。

而且,我很确定您不应该在您共享的GCD块中调用UIColor。

希望这能帮上忙!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7579630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档