【问题标题】:How can I programmatically position a view using relative points?如何使用相对点以编程方式定位视图?
【发布时间】:2010-04-19 20:40:20
【问题描述】:

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

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

我在使用自定义 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 仍然为零。自动调整大小的蒙版还没有机会做它的事情,但我非常想要这些值,以便我可以计算其他子视图的相对位置(这里是活动指示器)。

这可能不丑吗?

【问题讨论】:

  • titleLabelspinnerView 都是泄露对象
  • +1 问题,因为我有完全相同的问题 - 期待阅读答案
  • titleLabelspinnerView 没有泄露。它们在其他地方发布。

标签: iphone cocoa-touch


【解决方案1】:

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];
}

【讨论】:

  • 谢谢。我错过了两个关键点。首先,包含视图需要一些大小,大概是为了让布局行为做出明智的选择。其次,微调器没有将其autoresizingMask 设置为使用边距(顶部、底部和左侧以使其粘在右侧)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多