默认情况下,aspect fit会将图像与帧的底部对齐。有没有一种方法可以在保持aspect fit完整的同时 * 覆盖 * 对齐?
aspect fit
编辑
6mw9ycah1#
简而言之,您不能使用UIImageView来实现这一点。一种解决方案是将包含UIImageView的UIView子类化,并根据图像大小更改其帧。例如,您可以找到一个版本here。
UIImageView
UIView
guicsvcw2#
将UIImageView的底部布局约束优先级设置为最低(即250.第250章他会帮你的
wgxvkvu93#
方法是修改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; }
字符串
///Works perfectly with AspectFill. Note there's no protection for obscure issues like (say) scaledImageWidth is zero. class AlignmentImageView: UIImageView { enum HorizontalAlignment { case left, center, right } enum VerticalAlignment { case top, center, bottom } var horizontalAlignment: HorizontalAlignment = .center { didSet { updateContentsRect() } } var verticalAlignment: VerticalAlignment = .center { didSet { updateContentsRect() } } override var image: UIImage? { didSet { updateContentsRect() } } override func layoutSubviews() { super.layoutSubviews() updateContentsRect() } 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 } }
型
5fjcxozz4#
这将使图像填充宽度并且只占用它需要适合图像的高度(从宽度上讲)swift 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
rekjcdws5#
我也有类似的问题。最简单的方法是创建自己的UIImageView子类。我为子类3添加了属性,所以现在它可以在不知道内部实现的情况下轻松使用:
@property (nonatomic) LDImageVerticalAlignment imageVerticalAlignment; @property (nonatomic) LDImageHorizontalAlignment imageHorizontalAlignment; @property (nonatomic) LDImageContentMode imageContentMode;
字符串您可以在这里查看:https://github.com/LucasssD/LDAlignmentImageView
8gsdolmq6#
1.将纵横比约束与图像比例一起添加。1.不要将UIImageView固定到底部。1.如果你想动态地改变UIImage,记得更新长宽比约束。
4smxwvx57#
我在Interface Builder中通过设置UIImageView高度的约束解决了这个问题,因为当图像大于屏幕尺寸时,图像总是会被“推”起来。更具体地说,我将UIImageView设置为与它所在的View相同的高度(通过高度约束),然后在IB中使用间距约束定位UIImageView。这导致UIImageView具有“方面拟合”,其仍然遵守我在IB中设置的顶部间距约束。
lkaoscv78#
如果您能够子类化UIImageView,那么您可以覆盖image var。
image
override var image: UIImage? { didSet { self.sizeToFit() } }
字符串在Objective-C中,你可以通过覆盖setter来做同样的事情。
8条答案
按热度按时间6mw9ycah1#
简而言之,您不能使用
UIImageView
来实现这一点。一种解决方案是将包含
UIImageView
的UIView
子类化,并根据图像大小更改其帧。例如,您可以找到一个版本here。guicsvcw2#
将
UIImageView
的底部布局约束优先级设置为最低(即250.第250章他会帮你的wgxvkvu93#
方法是修改UIImageView层的contentsRect。下面的代码来自我的项目(UIImageView的子类),它假设scaleToFill并偏移图像,使其顶部、底部、左侧或右侧对齐,而不是默认的中心对齐。对于aspectFit,这将是一个类似的解决方案。
字符串
Swift版本
型
5fjcxozz4#
这将使图像填充宽度并且只占用它需要适合图像的高度(从宽度上讲)
swift 4.2:
字符串
rekjcdws5#
我也有类似的问题。最简单的方法是创建自己的UIImageView子类。我为子类3添加了属性,所以现在它可以在不知道内部实现的情况下轻松使用:
字符串
您可以在这里查看:https://github.com/LucasssD/LDAlignmentImageView
8gsdolmq6#
1.将纵横比约束与图像比例一起添加。
1.不要将UIImageView固定到底部。
1.如果你想动态地改变UIImage,记得更新长宽比约束。
4smxwvx57#
我在Interface Builder中通过设置UIImageView高度的约束解决了这个问题,因为当图像大于屏幕尺寸时,图像总是会被“推”起来。
更具体地说,我将UIImageView设置为与它所在的View相同的高度(通过高度约束),然后在IB中使用间距约束定位UIImageView。这导致UIImageView具有“方面拟合”,其仍然遵守我在IB中设置的顶部间距约束。
lkaoscv78#
如果您能够子类化
UIImageView
,那么您可以覆盖image
var。字符串
在Objective-C中,你可以通过覆盖setter来做同样的事情。