CALayer setCornerRadius滞后于iPad中的UITableView?

问题描述:

我想提出一个通用应用程序的iPhone/iPad的,似乎有很多滞后的用下面的代码:CALayer setCornerRadius滞后于iPad中的UITableView?

CALayer *imageLayer = [cell.myImageView layer]; 
[imageLayer setMasksToBounds:YES]; 
[imageLayer setCornerRadius:6.0]; 

奇怪的是,iPhone的版本有没有滞后,而iPad版有一些滞后。我在两个设备之间的代码中没有区别,但是如果我注意到代码之上的一切似乎都在两个设备上都很好。不过,我仍然想在我的UIImageView“myImageView”上使用圆角。

我只在第一次单元初始化的时候在cellForRowAtIndexPath中执行那段代码,因为我所有的单元都是一样的。

有谁知道为什么会发生这种情况?

谢谢!

+0

我建议你向我们展示整个cellforrowatindexpath数据源方法源代码 – Lefteris

CALayer操作正在使用大量的CPU功耗进行绘制。

所以最好的解决方案是使用核心图形绘制图像。 洛伦Brichter是第一次向我们展示了如何:

这是他ABTableViewCell头(.h)文件

// Copyright (c) 2008 Loren Brichter 
// 
// Permission is hereby granted, free of charge, to any person 
// obtaining a copy of this software and associated documentation 
// files (the "Software"), to deal in the Software without 
// restriction, including without limitation the rights to use, 
// copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following 
// conditions: 
// 
// The above copyright notice and this permission notice shall be 
// included in all copies or substantial portions of the Software. 
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
// OTHER DEALINGS IN THE SOFTWARE. 
// 
// ABTableViewCell.h 
// 
// Created by Loren Brichter 
// Copyright 2008 Loren Brichter. All rights reserved. 
// 

#import <UIKit/UIKit.h> 

// to use: subclass ABTableViewCell and implement -drawContentView: 

@interface ABTableViewCell : UITableViewCell 
{ 
    UIView *contentView; 
} 

- (void)drawContentView:(CGRect)r; // subclasses should implement 

@end 

这里代码为impelementation(.M)文件中的代码:

// Copyright (c) 2008 Loren Brichter 
// 
// Permission is hereby granted, free of charge, to any person 
// obtaining a copy of this software and associated documentation 
// files (the "Software"), to deal in the Software without 
// restriction, including without limitation the rights to use, 
// copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following 
// conditions: 
// 
// The above copyright notice and this permission notice shall be 
// included in all copies or substantial portions of the Software. 
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
// OTHER DEALINGS IN THE SOFTWARE. 
// 
// ABTableViewCell.m 
// 
// Created by Loren Brichter 
// Copyright 2008 Loren Brichter. All rights reserved. 
// 

#import "ABTableViewCell.h" 

@interface ABTableViewCellView : UIView 
@end 

@implementation ABTableViewCellView 

- (void)drawRect:(CGRect)r 
{ 
    [(ABTableViewCell *)[self superview] drawContentView:r]; 
} 

@end 



@implementation ABTableViewCell 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { 
     contentView = [[ABTableViewCellView alloc]initWithFrame:CGRectZero]; 
     contentView.opaque = YES; 
     [self addSubview:contentView]; 
    } 
    return self; 
} 


- (void)setFrame:(CGRect)f 
{ 
    [super setFrame:f]; 
    CGRect b = [self bounds]; 
    b.size.height -= 1; // leave room for the seperator line 
    [contentView setFrame:b]; 
} 

- (void)setNeedsDisplay 
{ 
    [super setNeedsDisplay]; 
    [contentView setNeedsDisplay]; 
} 

- (void)drawContentView:(CGRect)r 
{ 
    // subclasses should implement this 
} 

@end 

现在您需要做的是使用Core Graphics在drawContentView方法中绘制单元格。

这是我在App我使用的代码的一部分正在工作:

CALayer *cellLayer = [[CALayer alloc] init]; 
    CGRect cellFrame = self.bounds; 
    CGRect layerFrame = CGRectInset(cellFrame, 3, 3); 

    cellLayer.frame = cellFrame; 
    cellLayer.contentsScale = [[UIScreen mainScreen] scale]; 

    //round corners in Core Graphics (much faster than using the CALayer cornerRadius) 
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [[UIScreen mainScreen] scale]); 

    CGContextRef imgContext = UIGraphicsGetCurrentContext(); 

    CGContextSaveGState(imgContext); 
    //create the rounded rectangle to draw the image in 
    CGPathRef clippingPath = [UIBezierPath bezierPathWithRoundedRect:layerFrame cornerRadius:6.0f].CGPath; 
    CGContextAddPath(imgContext, clippingPath); 
    CGContextClip(imgContext); 

CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)[NSData dataWithContentsOfFile:ImageName]); 
      CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); 
      CGDataProviderRelease(imgDataProvider); 
      CGContextDrawImage (imgContext, layerFrame, imageRef); 
      CGImageRelease(imageRef); 

CGContextRestoreGState(imgContext); 

     //draw white outline 
     CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(cellFrame, 3, 3) cornerRadius:6.0f].CGPath; 
     CGContextAddPath(imgContext, path); 
     CGContextSetLineWidth(imgContext, 2.0); 
     CGContextSetRGBStrokeColor(imgContext,1,1,1,1); 
     CGContextStrokePath(imgContext); 

     // Get the image from the context 
     UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 


     cellLayer.contents = (__bridge id)img.CGImage; 

要使用你需要这样初始化它在你的tableView的cellForRowAtIndexPath数据源方法的自定义单元格:

static NSString *CellIdentifier = @"TableCell"; 

    ABTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) {   
     cell = [[ABTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
} 

还记得,因为你正在做自定义绘制你需要时刻reresfh细胞视图,当你修改的东西你自己使用:

[cell setNeedsDisplay]; 
+0

嗯,没有那么没有帮助。还有很多滞后。即使当我在这个视图中呈现我的游戏中心模态视图时,呈现该成就视图的动画也会滞后。在我的应用程序中没有其他视图有这个问题,这真的很奇怪。还有什么我可以优化? –

+0

如果你没有设置细胞图像,你测量多少FPS?只是想看看问题出在哪里......我会删除整个个人资料图片部分并测量 – Lefteris

+0

再次看看我的整个问题和原始帖子,我改变了一切:P另外,如果你可以友好并摆脱在你的答案中的代码,这将是伟大的,因为我宁愿没有代码可见,因为它最终会在我的应用程序! :) –