【问题标题】:UIView width & height not adjusting to constraintsUIView 宽度和高度不适应约束
【发布时间】:2015-03-18 14:55:11
【问题描述】:

这是一个关于 iOS、XCode、Auto Layout 和 Objective-C 的问题。我觉得它有一个简单的答案,但我在 SO 中搜索了高低并找不到解决方案。

我想在 Google 地图的中心放置一个小十字准线图像,这样当用户在地图上平移时,图像保持固定。为此,我只需将 UIImageView 作为子视图添加到 Google 地图视图,这是一个 GMSMapView,我已经制作了一个 IBOutlet,self.mapView。

我使用以下方法计算放置图像的位置:

crosshairs.center = CGPointMake(self.mapView.bounds.size.width / 2, self.mapView.bounds.size.height / 2);

同时,我在地图视图上设置了约束,使其前导和尾随空格与超级视图挂钩。这应该使它的宽度和高度流动——至少我是这么认为的。

事实上,当我在运行时 NSLog 地图视图的宽度和高度时,它们反映了 Xcode 中尺寸检查器中指定的宽度(600)和高度(384)——即使我没有固定宽度也没有限制的高度。

结果是图像不是以屏幕为中心,而是以地图视图的错误宽度和高度(延伸到屏幕外)为中心。

我知道我忽略了一些愚蠢的东西,或者我错过了自动布局的基本概念。无论哪种方式,我都将不胜感激。

会

【问题讨论】:

  • 为什么不让 UIImageView 与 MapView 处于同一级别?
  • 你在哪里添加十字准线?您应该像以前一样在didLayoutSubviews 中执行此操作,然后不会设置框架 - 正如您所发现的那样,但正如@hashier 所说,您可以简单地在 IB 中添加十字准线并将它们限制在那里

标签: ios objective-c xcode autolayout


【解决方案1】:

使用自动布局时重要的是,您不应再手动更改框架(在您的情况下使用 setCenter:)。您应该使用约束来布局所有内容。

您可以在 mapView 顶部的情节提要中添加 UIImage 并将其居中,使用约束。

如果这不可能,您也可以在代码中添加约束,使用如下代码:

[self.mapView addSubview:crosshairs];
[crosshairs setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.mapView addConstraints:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:crosshairs attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
[self.mapView addConstraints:[NSLayoutConstraint constraintWithItem:self.mapView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:crosshairs attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];

根据您添加这些约束的位置,您可能需要调用[self.mapView layoutIfNeeded];。

使用约束,图像应始终位于 mapView 顶部的中心。

关于 mapView 的错误帧,这取决于您记录它的位置。如果您的IBOutlet 在UIViewController 中,您应该在[super viewWillLayoutSubviews]; 调用之后在viewWillLayoutSubviews: 中执行此操作。

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    NSLog(@"Map View frame %@", NSStringFromCGRect(self.mapView.frame));
}

如果您在自定义 UIView 类中有它,您应该检查 layoutSubviews: 中的框架

- (void)layoutSubviews {
    [super layoutSubviews];
    NSLog(@"Map View frame %@", NSStringFromCGRect(self.mapView.frame));
}

希望这能解决您的问题。

【讨论】:

  • 谢谢@Catalina 和 Paulw11。从根本上说,我的问题是我正在检查 viewDidLoad 中的框架,我猜在自动布局之前已经根据屏幕的实际尺寸更改了框架。当我将 NSLog 移动到 viewWillLayoutSubviews 时,它是正确的。再次感谢。
  • 我的根本错误也是如此。直到 viewWillLayoutSubviews 或至少在那个时候才明显设置约束。我要去更详细地研究视图生命周期,因为这花了我几个小时才能弄清楚。
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 2021-02-21
  • 2012-05-22
  • 1970-01-01
  • 2020-08-14
相关资源
最近更新 更多