在“界面”构建器和以编程方式创建UI元素之间是否存在差异

时间:2012-06-18 11:07:50

标签: iphone objective-c ios

当我在设备上测试我的应用程序时,我遇到了一个非常奇怪的问题。我有两个与导航控制器连接的视图。我的第一个观点很简单,有一个UIButton。单击此按钮时,切换到第二个视图。我的第二个视图具有以编程方式创建的UIButtons(> 20)。有一个问题,我的切换动画工作速度较慢(比它应该)和喷射。我尝试用很多UIButton创建相同的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];
}

1 个答案:

答案 0 :(得分: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;