1

当我在设备上测试我的应用程序时,我遇到了一个非常奇怪的问题。我有 2 个与导航控制器连接的视图。我的第一个视图非常简单,只有一个 UIButton。单击此按钮时会切换到第二个视图。我的第二个视图具有以编程方式创建的 UIButtons (>20)。有一个问题,我的切换动画工作得更慢(比它应该的)而且有冲刺。我尝试使用很多 UIButtons 创建相同的 viewController,但使用 Interface Builder 并且我的动画工作正常!这个问题只有在我在真实设备上测试应用程序时才会遇到,在模拟器中所有这些变体都可以正常工作。这两种创建 UI 元素的变体有什么不同吗?以及如何通过编程方式创建包含许多 UI 元素的视图来解决这个问题(我更喜欢这种方式)。

Edit1 我有一个超类是 UIButton 的类。这是实现:

#import <QuartzCore/QuartzCore.h>
#import "UIHouseButtons.h"

@implementation UIHouseButtons 

- (id)initWithFrame:(CGRect)frame
{  
self = [super initWithFrame:frame];
if (self) {
    self = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    UIImage *buttonImageNormal = [UIImage imageNamed:@"stateNormal.png"];
    UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [self setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
    UIImage *buttonImagePressed = [UIImage imageNamed:@"stateNormal.png"];
    UIImage *strechableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [self setBackgroundImage:strechableButtonImagePressed forState:UIControlStateHighlighted];
    [[self layer] setCornerRadius:4.0f];
    [[self layer] setMasksToBounds:YES];
    [self.titleLabel setFont:[UIFont fontWithName:@"Times New Roman" size:15.0f]];
    self.frame = frame;
}
return self;
}

在我的第二个视图控制器中的-loadView方法之后:

UIHouseButtons *homeButton = [[UIHouseButtons alloc] initWithFrame:CGRectMake(435.0f, 5.0f, 40.0f, 25.0f)];
[homeButton setTitle:@"H" forState:UIControlStateNormal];
[self.view addSubview:homeButton];

同样的20次。

编辑 2编辑了我的 UIButtons 类:

- (id)init
{
self = [super init];
if (self) {
    self = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    //self.backgroundColor = [UIColor clearColor];
    UIImage *buttonImageNormal = [UIImage imageNamed:@"stateNormal.png"];
    UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [self setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
    UIImage *buttonImagePressed = [UIImage imageNamed:@"stateNormal.png"];
    UIImage *strechableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [self setBackgroundImage:strechableButtonImagePressed forState:UIControlStateHighlighted];
    [[self layer] setCornerRadius:4.0f];
    [[self layer] setMasksToBounds:YES];
    [self.titleLabel setFont:[UIFont fontWithName:@"Times New Roman" size:15.0f]];
    self.layer.shouldRasterize = YES;
    self.layer.rasterizationScale = [[UIScreen mainScreen] scale];
}
return self;
}

我的-viewDidLoad

- (void)viewDidLoad
{
[super viewDidLoad];
self.button1 = [[UIHouseButtons alloc] init];
self.button2 = [[UIHouseButtons alloc] init];
self.button3 = [[UIHouseButtons alloc] init];
self.button4 = [[UIHouseButtons alloc] init];
//and more 20 times

[self.view addSubview:self.button1];
[self.view addSubview:self.button2];
[self.view addSubview:self.button3];
[self.view addSubview:self.button4];
//and more 20 times
}

我的viewWillAppear

-(void)viewWillAppear:(BOOL)animated {
[self.button1 setFrame:CGRectMake(13.0f, 5.0f, 30.0f, 30.0f)];
[self.button2 setFrame:CGRectMake(57.0f, 5.0f, 30.0f, 30.0f)];
[self.button3 setFrame:CGRectMake(99.0f, 5.0f, 30.0f, 30.0f)];
[self.button4 setFrame:CGRectMake(141.0f, 5.0f, 30.0f, 30.0f)];
//and more 20 times
[super viewWillAppear:animated];
}
4

1 回答 1

3

您在模拟器中的速度没有问题,因为模拟器是 iPhone/iPad 的模拟器,而不是 iPhone/iPad 硬件的模拟器,它使用您计算机的 CPU 和 RAM。
只要您在以编程方式进行操作时遵守一些规则,创建控件的性能应该没有任何差异,这些规则是:
如果您不使用 nib 文件,请覆盖该方法-loadView并在其中仅创建一个UIView并设置它到self.view.
然后在-viewDidLoad方法中初始化您的视图层次结构-您的子视图self.view,它们的子视图(按钮/标签/等..)。如果你有硬编码的帧值,你可以在这里设置它们,但不要指望这个,因为在这种方法中,视图层次结构还没有正确设置。然后在-viewWillAppear:animated方法调整所有几何图形并仅执行轻量级操作,因为此方法应尽可能快地返回(否则您在呈现时可能会遇到故障)..
更新:
从您的代码片段更新中,我可以看到您的按钮层有圆角。这可能会成为性能问题,尤其是当按钮位于 UIScrollView 中时。UIHouseButtons.m将所有按钮的图层设置为在文件中栅格化

self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; //Add this if using images to adjust the proper rasterization scale for them.
self.layer.shouldRasterize = YES;
于 2012-06-18T11:19:26.540 回答