如何使用相对点以编程方式定位视图?

时间:2010-04-19 20:40:21

标签: iphone cocoa-touch

当超视图的边界尚未知晓时,相对于其超视图大小定位视图的最佳方法是什么?

如果可能的话,我试图避免使用硬编码坐标。也许这很愚蠢,如果是这样,这是一个完全可以接受的答案。

使用自定义UI时,我遇到过很多次。最近的一个例子是我试图用自定义视图替换UINavigationItem纯文本标题。我希望该视图填充超级视图,但此外,我想在右侧显示UIActivityIndicatorView,插入约2个像素并垂直居中。这是代码:

- (void) viewDidLoad
{
    [super viewDidLoad];

    customTitleView = [[UIView alloc] initWithFrame:CGRectZero];
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    titleLabel.lineBreakMode = UILineBreakModeWordWrap;
    titleLabel.numberOfLines = 2;
    titleLabel.minimumFontSize = 11.0;
    titleLabel.font = [UIFont systemFontOfSize:17.0];
    titleLabel.adjustsFontSizeToFitWidth = YES;
    [customTitleView addSubview:titleLabel];

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width / 2) - 2,
                                     customTitleView.bounds.size.height / 2);
    spinnerView.hidesWhenStopped = YES;
    [customTitleView addSubview:spinnerView];

    self.navigationItem.titleView = customTitleView;
    [customTitleView release];
}

这是我的问题:在此代码运行时,customTitleView.bounds仍为零。自动调整大小的掩码还没有机会做它的事情,但我非常想要这些值,以便我可以计算其他子视图的相对位置(这里是活动指示符)。

这可能不丑吗?

1 个答案:

答案 0 :(得分:4)

customTitleView.bounds的宽度和高度为零的唯一原因是因为您使用CGRectZero以这种方式初始化它。您可以使用任何非零大小初始化视图,然后根据该任意大小定义其子视图。只要您已正确定义子视图的自动调整行为,当超视图的帧在运行时更改时,它们的布局将适当调整。

例如:

- (void) viewDidLoad
{
    [super viewDidLoad];

    customTitleView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    titleLabel = [[UILabel alloc] initWithFrame:customTitleView.bounds];
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    titleLabel.lineBreakMode = UILineBreakModeWordWrap;
    titleLabel.numberOfLines = 2;
    titleLabel.minimumFontSize = 11.0;
    titleLabel.font = [UIFont systemFontOfSize:17.0];
    titleLabel.adjustsFontSizeToFitWidth = YES;
    [customTitleView addSubview:titleLabel];
    [titleLabel release];

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width / 2) - 2,
                                     customTitleView.bounds.size.height / 2);
    spinnerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
    spinnerView.hidesWhenStopped = YES;
    [customTitleView addSubview:spinnerView];
    [spinnerView release];

    self.navigationItem.titleView = customTitleView;
    [customTitleView release];
}