在 iOS 10 中,cornerRadius 导致加载时间过长

Posted

技术标签:

【中文标题】在 iOS 10 中,cornerRadius 导致加载时间过长【英文标题】:cornerRadius causes long load time in iOS 10 【发布时间】:2016-10-21 19:08:30 【问题描述】:

我的应用程序有问题。我有一个带有 25 个按钮的视图,改变了cornerRadius。从 ios 10 开始,加载此视图大约需要 5-6 秒。 以下是相关代码:

- (void)setupTiles 
 for (TileButton *btn in tiles_btn) 
  btn.alpha = 0.0;
  btn.layer.borderColor = [UIColor blackColor].CGColor;
  btn.layer.borderWidth = 1.0f;
  [btn layoutIfNeeded];
  bin.layer.cornerRadius = btn.frame.size.width*0.3;
 
 [self colorTilesWithArray:currentTileColors];

当我删除以下行时,会立即加载视图:

[btn layoutIfNeeded];
bin.layer.cornerRadius = btn.frame.size.width*0.3;

按钮被分组在一个插座集合中,以防有必要知道。

有人有解决办法吗? 提前致谢!

尼哥

Image 1: This takes about 5-6 seconds

Image 2: This is the View that will be loaded

TileButton.h-文件:

@interface TileButton : UIButton

@property (nonatomic) int colorMode;

+ (UIColor *)blue;
+ (UIColor *)red;
+ (UIColor *)green;
+ (UIColor *)yellow;
+(UIColor *)colorForColorCode:(int)colorCode;
-(int)colorMode;

@end

TileButton.m-文件:

@implementation TileButton
- (instancetype)init 
self = [super init];
if (self) 
    self.layer.cornerRadius = self.frame.size.width*0.3;

return self;


+(UIColor *)blue 
return [UIColor colorWithRed:41.0/255.0 green:161.0/255.0 blue:255.0/255.0 alpha:1];


+(UIColor *)red 
return [UIColor colorWithRed:255.0/255.0 green:71.0/255.0 blue:109.0/255.0 alpha:1];


+(UIColor *)green 
return [UIColor colorWithRed:0.0/255.0 green:185.0/255.0 blue:30.0/255.0 alpha:1];
 

+(UIColor *)yellow 
return [UIColor colorWithRed:255.0/255.0 green:198.0/255.0 blue:26.0/255.0 alpha:1];
 

+(UIColor *)colorForColorCode:(int)colorCode 
switch (colorCode) 
    case 1:
        return [TileButton blue];
        break;
    case 2:
        return [TileButton red];
        break;
    case 3:
        return [TileButton green];
        break;
    case 4:
        return [TileButton yellow];
        break;
    default:
        return [UIColor blackColor];
        break;



-(int)colorMode 
if (CGColorEqualToColor(self.backgroundColor.CGColor, [TileButton blue].CGColor))
    return 1;
else if (CGColorEqualToColor(self.backgroundColor.CGColor, [TileButton red].CGColor))
    return 2;
else if (CGColorEqualToColor(self.backgroundColor.CGColor, [TileButton green].CGColor))
    return 3;
else if (CGColorEqualToColor(self.backgroundColor.CGColor, [TileButton yellow].CGColor))
    return 4;
else
    return -1;


@end

【问题讨论】:

应该删除layoutIfNeeded。这么说是没用的,而且很糟糕。 除了删除对layoutIfNeeded 的调用外,for 循环中的所有内容都可能移至TileButton 构造函数。 您可以尝试使用图像背景而不是设置圆角半径吗? 我猜有某种循环调用 layoutIfNeeded 调用 layoutSubviews 然后调用 layoutIfNeeded。您可以通过在 layoutSubviews 中放置打印语句来确定是否确实如此。也尝试使用 setNeedsLayout 而不是 layoutIfNeeded。 layoutIfNeeded 告诉系统现在进行布局,而 setNeedsLayout 只是告诉系统标记视图以在下一次重绘之前的某个时间重新计算。您也可以尝试不在每个视图上调用 LayoutIfNeeded;在循环结束时在 superview 上调用它;它会级联到孩子们。 感谢您的快速回答。我使用了layoutIfNeeded,因为没有它,自 iOS 10 以来它不会显示任何按钮。但我会尝试setNeedsLayout。此外,我将尝试将其移至构造函数中。 @HMHero 我想尝试使这些按钮“独立于分辨率”,所以我不必为每个屏幕尺寸制作图像 【参考方案1】:

由于您是在 Interface Builder 中创建按钮,因此您需要在 awakeFromNib 方法中设置 cornerRadius。它应该看起来像这样:

@implementation TileButton
-(void) awakeFromNib 
     [super awakeFromNib];
     self.layer.cornerRadius = self.frame.size.width*0.3;

https://developer.apple.com/reference/objectivec/nsobject/1402907-awakefromnib

【讨论】:

【参考方案2】:

为什么不能在for循环外设置圆角半径?

UIButton *btn = [UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; // set your frame here
bin.layer.cornerRadius = btn.frame.size.width*0.3; // width stays the same, set it here
for (TileButton *btn in tiles_btn) 
    btn.alpha = 0.0;
    btn.layer.borderColor = [UIColor blackColor].CGColor;
    btn.layer.borderWidth = 1.0f;
    // you need to set the button frame here
    btn.frame = CGRectMake(0,0,0,0);
    [btn layoutIfNeeded];

[self colorTilesWithArray:currentTileColors];

【讨论】:

因为 Outlet Collection 中有 25 个按钮,并且仅在 for 循环中,我可以为每个按钮设置cornerRadius:/【参考方案3】:

假设 TileButton 是 UIButton 的子类,在初始化时,您可以将 TileButton 设置为自定义颜色、宽度和角半径。这样一来,您的所有按钮都已在按钮创建时进行了指定的自定义。

【讨论】:

以上是关于在 iOS 10 中,cornerRadius 导致加载时间过长的主要内容,如果未能解决你的问题,请参考以下文章

UIActionSheet 无法在 iOS9 中按预期显示

UIlabel layer.cornerRadius 在 iOS 7.1 中不起作用

使用cornerradius IOS使其圆形时发出相关的UIimageView

UIlabel layer.cornerRadius在iOS 7.1中不起作用

UIImageView.layer.cornerRadius 在不同像素密度上创建圆形图像的问题 ios

UITableViewcornerRadius 在 iOS 上存在边框性能问题