使 UIImageView 及其 UIImage 按比例缩放而无需额外的填充

Posted

技术标签:

【中文标题】使 UIImageView 及其 UIImage 按比例缩放而无需额外的填充【英文标题】:Make an UIImageView and its UIImage scale proportionally without extra padding 【发布时间】:2012-10-15 15:33:40 【问题描述】:

我有一个包含 UIImageView 的 UIView。 UIImageViews 的工作方式类似于应用程序的品牌标志。当我旋转设备时,包含的 UIView 会根据屏幕的横向或纵向比例调整自身大小。

我想要实现的是让 UIImageView 相应地缩放,同时在左边距上保持比例。

这是顶部白色“横幅”的实际代码:

UIView *topBanner = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, height_topBanner)];
[topBanner setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin)];
[topBanner setBackgroundColor:[UIColor whiteColor]];
topBanner.autoresizesSubviews = YES;

    // the logo
    UIImage *topBanner_logo = [UIImage imageNamed:@"logo.png"];
    float logoAspectRatio = topBanner_logo.size.width/topBanner_logo.size.height;
    topBanner_logoView = [[UIImageView alloc] initWithFrame:CGRectMake(topBanner.frame.size.width/100*3, topBanner.frame.size.height/100*7, (topBanner.frame.size.height/100*86)*logoAspectRatio, topBanner.frame.size.height/100*86)];
    [topBanner_logoView setImage:topBanner_logo];
    topBanner_logoView.backgroundColor = [UIColor blueColor];
    topBanner_logoView.contentMode = UIViewContentModeScaleAspectFit;
    [topBanner_logoView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleRightMargin)];
    [topBanner addSubview:topBanner_logoView];

[self.view addSubview:topBanner];

这是我的起点:启动时的 iPad 肖像:

当我横向旋转它时会发生这种情况:

如您所见,UIImage 的比例还可以,但我得到了额外的边框(我设置了 UIImageView 的背景颜色以突出显示它),因为 UIImageView 会随着其大小的变化而伸展自己容器,并将 UIImage 放入 UIImageView 并放在其中心。

当我直接以横向模式启动应用程序时,会发生相同的情况 - 反过来 - :

然后我旋转它:

...我得到了顶部和底部带有额外边框的徽标。

我确实看到我可以编写一个函数来重新计算每次旋转更改时的每个大小,但我问自己是否有办法设置 UIImageView 和 UIImage 以使其在不破坏自动旋转/调整大小的情况下工作ios的程序。听起来很简单!

【问题讨论】:

【参考方案1】:

您可以通过不使用UIViewContentModeScaleAspectFit 来解决此问题,而是计算图像的纵横比并使用它来明确地基于另一个(宽度或高度)的宽度或高度。

例如我旋转到横向,所以我希望高度是视图的 80%。

    CGFloat w = logo.image.size.width;
    CGFloat h = logo.image.size.height;
    CGFloat a = w / h;

    CGFloat h_use = self.view.height *0.8;
    CGFloat w_use = h_use*a;

此外,既然您已明确设置纵横比,请将内容模式设置为 UIViewContentModeScaleAspectFill

【讨论】:

【参考方案2】:

您已将自动调整大小的蒙版设置为灵活的高度和宽度:

[topBanner_logoView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleRightMargin)];

如果你不这样做,默认情况下视图不会改变大小,因此图像也不会。

【讨论】:

但我希望徽标按比例调整其大小,不希望出现的行为是 UIImageView 会自行拉伸,从而在侧面创建此“填充”。【参考方案3】:

我想是因为topBanner_logoView.contentMode = UIViewContentModeScaleAspectFit;

尝试topBanner_logoView.contentMode = UIViewContentModeCentertopBanner_logoView.contentMode = UIViewContentModeLeft 以防止 UIImageView 的图像调整大小(并获得填充)。

如果 UIImageView 正在调整大小,请移除自动调整大小掩码。

【讨论】:

如果我删除调整大小属性和遮罩,徽标将停止调整自身大小,但我的目标是让它根据容器的大小相应调整大小。问题是,例如,从纵向到横向会产生这种带状效果,导致徽标在 UIImageView 内保持居中,而我希望它保持在左侧对齐。 是的,不幸的是它做的恰恰相反:它将 UIImageView 调整为原始 UIImage 的大小。

以上是关于使 UIImageView 及其 UIImage 按比例缩放而无需额外的填充的主要内容,如果未能解决你的问题,请参考以下文章

UIImage 从 UIImageView 流出

如何使 CAShape 层适合 UIImage 视图?

如何使 UIImageView 成为按钮?

如何在 UIImage 中“切割”透明孔?

使 UIImageView 模糊

是否可以在不损失质量的情况下调整 UIImage 的大小?