调整大小后使用自动布局以编程方式居中 UIImageVIew

Posted

技术标签:

【中文标题】调整大小后使用自动布局以编程方式居中 UIImageVIew【英文标题】:Programmatically Centre UIImageVIew Using Auto Layout After Resize 【发布时间】:2015-11-25 11:41:58 【问题描述】:

我只在 IB 中使用过自动布局,想知道如何在调整 UIImageView 大小后以编程方式将其设置为垂直和水平居中。

基本上 UIImageView 包含一张照片,然后 UIImageView 会调整大小以适合照片。在此过程之后,我想知道如何设置约束以正确定位图像。

下面的代码展示了加载图片和设置 UIImageView 的过程。目前定位是手动完成的,不使用 AutoLayout。

- (void)setupUI 

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

self.imageViewCanvas.translatesAutoresizingMaskIntoConstraints = YES;
[self.imageViewCanvas setFrame:CGRectMake(0, 0, screenWidth, screenHeight)];

self.btnTool.alpha = 0;



- (void)loadNewImageIntoCanvas 

[self.imageViewCanvas setImage:self.imageToEdit];

[self imageSizeAfterAspectFit:self.imageViewCanvas];

[UIImageView animateWithDuration:0.2 animations:^
    self.imageViewCanvas.alpha = 1;
 completion:^(BOOL finished) 

    [self showBTNTool];

];




- (void)resetCanvasSize 

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

[self.imageViewCanvas setFrame:CGRectMake(0, 0, screenWidth, screenHeight)];



-(CGSize)imageSizeAfterAspectFit:(UIImageView*)imgview

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

CGRect newSize = [self frameForImage:self.imageViewCanvas.image inImageViewAspectFit:self.imageViewCanvas];

float newwidth = newSize.size.width;
float newheight = newSize.size.height;

float new_x = (screenWidth / 2) - (newwidth / 2);
float new_y = (screenHeight / 2) - (newheight / 2);

[self.imageViewCanvas setFrame:CGRectMake(new_x, new_y, newwidth, newheight)];

return CGSizeMake(0, 0);



-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView 

float imageRatio = image.size.width / image.size.height;

float viewRatio = imageView.frame.size.width / imageView.frame.size.height;

if(imageRatio < viewRatio)

    float scale = imageView.frame.size.height / image.size.height;

    float width = scale * image.size.width;

    float topLeftX = (imageView.frame.size.width - width) * 0.5;

    return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);

else

    float scale = imageView.frame.size.width / image.size.width;

    float height = scale * image.size.height;

    float topLeftY = (imageView.frame.size.height - height) * 0.5;

    return CGRectMake(0, topLeftY, imageView.frame.size.width, height);


【问题讨论】:

你为什么不直接说 self.imageViewCanvas.translatesAutoresizingMaskIntoConstraints = YES;然后设置它的框架? 我现在正在这样做,但是当我运行应用程序时会收到警告消息。沿着“无法同时满足约束”的思路。更新了问题以显示我是如何做到这一点的。 结果是图片位置不对? 没有图像在正确的位置,我正在考虑切换它,以便在调整图像大小后让 AutoLayout 管理定位。 你有复杂的接口需要依赖定位吗?自动布局似乎对你正在做的事情来说太过分了。将 translatesAutoresizingMaskIntoConstraints 设置为 true 会导致自动布局引擎创建约束,有时会发生冲突,但它知道要打破哪些约束以将元素放置在适当的框架中。 【参考方案1】:

为了使用自动布局使图像视图居中,您还需要对宽度和高度进行约束。不仅是 centerXAnchor 和 centerYAnchor。 因为UIImageView 没有intrinsicContentSize。

(请注意,centerXAnchorcenterYAnchor 方法仅适用于 ios 9.0+)

self.imageView.translatesAutoresizingMaskIntoConstraints = NO;

[self.imageView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
[self.imageView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;

[self.imageView.widthAnchor constraintEqualToConstant:self.imageWidth].active = YES;
[self.imageView.heightAnchor constraintEqualToConstant:self.imageHeight].active = YES;

【讨论】:

【参考方案2】:

你可以这么说。

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.imageViewCanvas attribute: NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.imageViewCanvas attribute: NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];

但这还不足以满足所有必要的约束。 IMO,在 IB 中设置约束更容易,如果您需要动态更改约束,为它们创建一个 IBOutlet,并更改它们的常量属性。

例如,您可以为图像视图的高度约束创建一个 IBOutlet,称为 imageViewHeightConstraint,为您的图像视图的宽度约束创建另一个,称为 imageViewWidthConstraint,然后您可以说:

self.imageViewHeightConstraint.constant = 400;
self.imageViewWidthConstraint.constant = 400;

【讨论】:

常量属性是大小吗?因此,如果我将其更改为新的 UIImageView 可以说是 400 x 400,那么常量将是 400?

以上是关于调整大小后使用自动布局以编程方式居中 UIImageVIew的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式设置 UIView 的自动调整大小掩码?

以编程方式自动布局不垂直居中

UIView 使用约束自动布局居中和调整大小

剩余空间中的自动布局居中视图(以编程方式)

自动布局视图 xib - 没有可编辑的约束?我需要居中的元素

自动布局 - 以编程方式定义异常约束