UIImage方面适合并对齐到顶部

2020/12/08 01:11 · ios ·  · 0评论

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

**编辑**

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

简而言之,您不能使用来执行此操作UIImageView

一种解决方案是将UIView包含的a子类化UIImageView并根据图像大小更改其帧。例如,您可以在此处找到一个版本

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

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;
}

迅捷版

class AlignmentImageView: UIImageView {

    enum HorizontalAlignment {
        case left, center, right
    }

    enum VerticalAlignment {
        case top, center, bottom
    }


    // MARK: Properties

    var horizontalAlignment: HorizontalAlignment = .center
    var verticalAlignment: VerticalAlignment = .center


    // MARK: Overrides

    override var image: UIImage? {
        didSet {
            updateContentsRect()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        updateContentsRect()
    }


    // MARK: Content layout

    private func updateContentsRect() {
        var contentsRect = CGRect(origin: .zero, size: CGSize(width: 1, height: 1))

        guard let imageSize = image?.size else {
            layer.contentsRect = contentsRect
            return
        }

        let viewBounds = bounds
        let imageViewFactor = viewBounds.size.width / viewBounds.size.height
        let imageFactor = imageSize.width / imageSize.height

        if imageFactor > imageViewFactor {
            // Image is wider than the view, so height will match
            let scaledImageWidth = viewBounds.size.height * imageFactor
            var xOffset: CGFloat = 0.0

            if case .left = horizontalAlignment {
                xOffset = -(scaledImageWidth - viewBounds.size.width) / 2
            }
            else if case .right = horizontalAlignment {
                xOffset = (scaledImageWidth - viewBounds.size.width) / 2
            }

            contentsRect.origin.x = xOffset / scaledImageWidth
        }
        else {
            let scaledImageHeight = viewBounds.size.width / imageFactor
            var yOffset: CGFloat = 0.0

            if case .top = verticalAlignment {
                yOffset = -(scaledImageHeight - viewBounds.size.height) / 2
            }
            else if case .bottom = verticalAlignment {
                yOffset = (scaledImageHeight - viewBounds.size.height) / 2
            }

            contentsRect.origin.y = yOffset / scaledImageHeight
        }

        layer.contentsRect = contentsRect
    }

}

UIImageView底部布局约束优先级设置为最低(即250),它将为您处理。

这将使图像填充宽度并仅占据其适合图像所需的高度(横向交谈)

迅捷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

我有类似的问题。最简单的方法是创建自己的UIImageView子类。我为子类3添加了属性,因此现在可以轻松使用它,而无需了解内部实现:

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

您可以在此处检查它:https :
//github.com/LucasssD/LDAlignmentImageView

  1. 将纵横比约束与您的图像比例一起添加。
  2. 不要将UIImageView固定在底部。
  3. 如果要动态更改UIImage,请记住要更新纵横比约束。

我通过在Interface Builder中设置UIImageView的高度限制来解决此问题,因为当图像大于屏幕尺寸时,图像将始终被“推入”。

更具体地说,我将UIImageView设置为其与View相同的高度(通过高度限制),然后将UIImageView放置在IB中并带有间距限制。这将导致UIImageView具有“外观适合度”,但仍遵守我在IB中设置的顶部间距约束。

如果您可以继承UIImageView,则可以覆盖imagevar。

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

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

本文地址:http://ios.askforanswer.com/uiimagefangmianshihebingduiqidaodingbu.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!