UIImage方面适合并对齐顶部

时间:2012-06-14 19:22:30

标签: ios cocoa uiimageview aspect-fit

默认情况下,aspect fit看起来像是将图像对齐到帧的底部。有没有办法在保持aspect fit完整的情况下覆盖对齐?

**编辑**

此问题早于自动布局。实际上,在WWDC 2012中显示了自动布局,同一周问了这个问题

8 个答案:

答案 0 :(得分:22)

简而言之,您无法使用UIImageView执行此操作。

一种解决方案是对包含UIView的{​​{1}}进行子类化,并根据图像大小更改其帧。例如,您可以找到一个版本here

答案 1 :(得分:5)

执行此操作的方法是修改UIImageView图层的contentsRect。我的项目(UIImageView的子类)中的以下代码假定scaleToFill并偏移图像,使其对齐顶部,底部,左侧或右侧而不是默认的中心对齐。对于aspectFit,将是一个类似的解决方案。

IONIC 2

Swift版本

typedef NS_OPTIONS(NSUInteger, AHTImageAlignmentMode) {
    AHTImageAlignmentModeCenter = 0,
    AHTImageAlignmentModeLeft = 1 << 0,
    AHTImageAlignmentModeRight = 1 << 1,
    AHTImageAlignmentModeTop = 1 << 2,
    AHTImageAlignmentModeBottom = 1 << 3,
    AHTImageAlignmentModeDefault = AHTImageAlignmentModeCenter,
};

- (void)updateImageViewContentsRect {
    CGRect imageViewContentsRect = CGRectMake(0, 0, 1, 1);

    if (self.image.size.height > 0 && self.bounds.size.height > 0) {

        CGRect imageViewBounds = self.bounds;
        CGSize imageSize = self.image.size;

        CGFloat imageViewFactor = imageViewBounds.size.width / imageViewBounds.size.height;
        CGFloat imageFactor = imageSize.width / imageSize.height;

        if (imageFactor > imageViewFactor) {
            //Image is wider than the view, so height will match
            CGFloat scaledImageWidth = imageViewBounds.size.height * imageFactor;
            CGFloat xOffset = 0.0;
            if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeLeft)) {
                xOffset = -(scaledImageWidth - imageViewBounds.size.width) / 2;
            } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeRight)) {
                xOffset = (scaledImageWidth - imageViewBounds.size.width) / 2;
            }
            imageViewContentsRect.origin.x = (xOffset / scaledImageWidth);
        } else if (imageFactor < imageViewFactor) {
            CGFloat scaledImageHeight = imageViewBounds.size.width / imageFactor;

            CGFloat yOffset = 0.0;
            if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeTop)) {
                yOffset = -(scaledImageHeight - imageViewBounds.size.height) / 2;
            } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeBottom)) {
                yOffset = (scaledImageHeight - imageViewBounds.size.height) / 2;
            }
            imageViewContentsRect.origin.y = (yOffset / scaledImageHeight);
        }
    }
    self.layer.contentsRect = imageViewContentsRect;
}

答案 2 :(得分:4)

只需将imageView的底部布局约束优先级设置为最低(即250),它就可以完成工作

答案 3 :(得分:1)

我有类似的问题。 最简单的方法是创建自己的UIImageView子类。我添加了子类3属性,所以现在可以在不知道内部实现的情况下轻松使用:

@property (nonatomic) LDImageVerticalAlignment imageVerticalAlignment;
@property (nonatomic) LDImageHorizontalAlignment imageHorizontalAlignment;
@property (nonatomic) LDImageContentMode imageContentMode;

你可以在这里查看: https://github.com/LucasssD/LDAlignmentImageView

答案 4 :(得分:1)

  1. 在图像比例中添加“长宽比”约束。
  2. 请勿将UIImageView固定在底部。
  3. 如果要动态更改UIImage,请记住要更新宽高比约束。

答案 5 :(得分:0)

我通过在UIImageView的高度上设置一个约束来在Interface Builder中本地解决这个问题,因为图像总是会被推送到&#39;当图像大于屏幕尺寸时。

更具体地说,我将UIImageView设置为与它所处的View相同的高度(通过高度约束),然后在IB中定位具有间距约束的UIImageView。这导致UIImageView具有“适应性”和“适应性”。它仍然尊重我在IB中设置的顶部间距约束。

答案 6 :(得分:0)

这将使图像填充宽度并仅占据其适合图像所需的高度(正在谈论宽度)

迅捷4.2:

let image = UIImage(named: "my_image")!
let ratio = image.size.width / image.size.height
cardImageView.widthAnchor
  .constraint(equalTo: cardImageView.heightAnchor, multiplier: ratio).isActive = true

答案 7 :(得分:-2)

如果您能够继承UIImageView,那么您可以覆盖image var。

override var image: UIImage? {
    didSet {
        self.sizeToFit()
    }
}

在Objective-C中,你可以通过覆盖setter来做同样的事情。