2012-06-02 37 views
0

我想提出一個通用應用程序的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

回答

1

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另外,如果你可以友好並擺脫在你的答案中的代碼,這將是偉大的,因爲我寧願沒有代碼可見,因爲它最終會在我的應用程序! :) –