更改 UIImageView 大小以匹配图像与 AutoLayout

Posted

技术标签:

【中文标题】更改 UIImageView 大小以匹配图像与 AutoLayout【英文标题】:Change UIImageView size to match image with AutoLayout 【发布时间】:2013-06-02 00:25:30 【问题描述】:

我想更改我的 UIImageView 高度/宽度以匹配我从相册中选择的图像,我在这里找到了一个可以做到这一点的 sn-p。

-(CGRect)frameForImage:(UIImage *)imgs inImageViewAspectFit:(UIImageView *)imagev

  float imageRatio = imgs.size.width / imgs.size.height;
  float viewRatio = imagev.frame.size.width / imagev.frame.size.height;
  if(imageRatio < viewRatio)
  
    float scale = imagev.frame.size.height / imgs.size.height;
    float width = scale * imgs.size.width;
    float topLeftX = (imagev.frame.size.width - width) * 0.5;
    NSLog(@"image after aspect fit: width=%f",width);
    imagev.frame = CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
    return CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
  
  else
  
    float scale = imagev.frame.size.width / imgs.size.width;
    float height = scale * imgs.size.height;
    float topLeftY = (imagev.frame.size.height - height) * 0.5;
    NSLog(@"image after aspect fit: height=%f", height);
    imagev.frame = CGRectMake(0, topLeftY, imagev.frame.size.width, height);
    return CGRectMake(0, topLeftY, imagev.frame.size.width, height);
  

问题是当我从按钮调用它时它会改变 UIImageView 的高度/宽度

- (IBAction)changeSize:(id)sender

  [self frameForImage:image inImageViewAspectFit:self.imageView];    

但我希望它在我从相册中选择图像后立即执行此操作,这就是我设置它的方式。

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  [self frameForImage:image inImageViewAspectFit:self.imageView];
  [self dismissViewControllerAnimated:YES completion:NULL];

【问题讨论】:

仅使用xcode 标签来回答有关 IDE 本身的问题。谢谢! 只需为 UIImageView(在 Inspector 中)选择 ASPECT FIT - 就完成了。这里的所有都是它的。它是完全自动的。 【参考方案1】:

自动布局解决方案

自从确定您在项目中使用自动布局后,我制作了一个演示应用程序来向您展示如何更改图像视图的图像并调整高度。自动布局会自动为您执行此操作,但要注意的是您将使用的照片来自用户图库,因此它们可能非常大而且这个。

请查看应用程序:https://bitbucket.org/danielphillips/auto-layout-imageview

诀窍是创建图像视图高度的NSLayoutConstraint 的引用。当您更改图像时,您需要在给定宽度的情况下将其常量调整为正确的高度。

您的其他解决方案可能是在您的图像视图上设置contentMode,通过使用UIViewContentModeScaleAspectFit,您的图像将始终完整显示,但将锁定到图像视图的边界,这可以根据自动更改你有布局约束。

初步回复

看起来你真的把这件事弄得太复杂了,除非我错过了什么。

当您从图像选择器中获取新图像时,您需要做的就是根据UIImage 大小更改图像视图的框架。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  self.imageView.frame = CGRectMake(self.imageView.frame.origin.x
                                    self.imageView.frame.origin.y
                                    image.size.width
                                    image.size.height);
  [self dismissViewControllerAnimated:YES completion:NULL];

当然,这可能会非常大(它使用的原始图像可能非常大)。

所以让我们将宽度锁定为 280 点...这样我们就可以在纵向模式下始终在屏幕上显示完整的图像。

所以假设您的图像尺寸是 1000x800,而我们的图像视图可能是 280x100。我们可以像这样计算保留图像视图宽度的图像视图的正确高度:

CGSize imageSize        = CGSizeMake(1000.0, 800.0);
CGSize imageViewSize    = CGSizeMake(280.0, 100.0);

CGFloat correctImageViewHeight = (imageViewSize.width / imageSize.width) * imageSize.height;

self.imageView.frame = CGRectMake(  self.imageView.frame.origin.x,
                                    self.imageView.frame.origin.x,
                                    CGRectGetWidth(self.imageView.bounds),
                                    correctImageViewHeight);

【讨论】:

我尝试了你的第一个 sn-p,它不会改变宽度/高度,除非我添加 `[self.imageView setTranslatesAutoresizingMaskIntoConstraints:YES]; 控制台输出显示Will attempt to recover by breaking constraint &lt;NSLayoutConstraint:0x71ad740 UIImageView:0x71ac340.trailing == UIView:0x71ac5f0.trailing&gt; Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in &lt;UIKit/UIView.h&gt; may also be helpful.,但它仍然有效 正确,您正在使用 AutoLayout。这是一个非常重要的细节。【参考方案2】:

这是一个 Swift 类,它可以根据您选择的宽度或高度限制帮助返回正确的图像尺寸:

class func returnImageSizeForHeightLimit(heightLimit:CGFloat?, orWidthLimit widthLimit:CGFloat?, forImage theImage:UIImage)->CGSize?

    if let myHeightLimit = heightLimit 

        let theWidth = (myHeightLimit/theImage.size.height) * theImage.size.width

        return CGSizeMake(theWidth, myHeightLimit)
    

    if let myWidthLimit = widthLimit 

        let theHeight = (myWidthLimit/theImage.size.width) * theImage.size.height

        return CGSizeMake(myWidthLimit, theHeight)
    

    return nil

【讨论】:

重写为 UIImage 扩展可能会更好;)

以上是关于更改 UIImageView 大小以匹配图像与 AutoLayout的主要内容,如果未能解决你的问题,请参考以下文章

自动调整 UIImageView 的大小以适合底层图像

UIImageView:将大小更改为图像大小?

设置 UIImageView 以显示图像的中间部分

调整UIImageView的大小以包装“适合方面”的图像

以编程方式更改 UIImageView 帧大小

如何调整 uiimageview 的大小以仅适合 aspectfill 中的图像?