首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Aspect Fit对齐UIImageView

使用Aspect Fit对齐UIImageView
EN

Stack Overflow用户
提问于 2010-07-18 00:35:42
回答 12查看 93.4K关注 0票数 84

对于我的UIImageView,我选择了Aspect Fit (InterfaceBuilder),但我如何更改垂直对齐方式?

EN

回答 12

Stack Overflow用户

发布于 2011-04-05 05:54:11

编辑-这段代码有点发霉,来自2011年,除了我合并了@ArtOfWarefare的mods

你不能用/ UIImageView来做这件事。我创建了一个包含UIImageView的简单UIView子类MyImageView。下面的代码。

代码语言:javascript
复制
// MyImageView.h
#import <UIKit/UIKit.h>

@interface MyImageView : UIView {
    UIImageView *_imageView;
}

@property (nonatomic, assign) UIImage *image;

@end

代码语言:javascript
复制
// MyImageView.m

#import "MyImageView.h"

@implementation MyImageView

@dynamic image;

- (id)initWithCoder:(NSCoder*)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.clipsToBounds = YES;
        _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _imageView.contentMode = UIViewContentModeScaleAspectFill;
        [self addSubview:_imageView];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.clipsToBounds = YES;
        _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _imageView.contentMode = UIViewContentModeScaleAspectFill;
        [self addSubview:_imageView];
    }
    return self;
}

- (id)initWithImage:(UIImage *)anImage
{
    self = [self initWithFrame:CGRectZero];
    if (self) {
        _imageView.image = anImage;
        [_imageView sizeToFit];

        // initialize frame to be same size as imageView
        self.frame = _imageView.bounds;        
    }
    return self;
}

// Delete this function if you're using ARC
- (void)dealloc
{
    [_imageView release];
    [super dealloc];
}

- (UIImage *)image
{
    return _imageView.image;
}

- (void)setImage:(UIImage *)anImage
{
    _imageView.image = anImage;
    [self setNeedsLayout];
}

- (void)layoutSubviews
{
    if (!self.image) return;

    // compute scale factor for imageView
    CGFloat widthScaleFactor = CGRectGetWidth(self.bounds) / self.image.size.width;
    CGFloat heightScaleFactor = CGRectGetHeight(self.bounds) / self.image.size.height;

    CGFloat imageViewXOrigin = 0;
    CGFloat imageViewYOrigin = 0;
    CGFloat imageViewWidth;
    CGFloat imageViewHeight;


    // if image is narrow and tall, scale to width and align vertically to the top
    if (widthScaleFactor > heightScaleFactor) {
        imageViewWidth = self.image.size.width * widthScaleFactor;
        imageViewHeight = self.image.size.height * widthScaleFactor;
    }

    // else if image is wide and short, scale to height and align horizontally centered
    else {
        imageViewWidth = self.image.size.width * heightScaleFactor;
        imageViewHeight = self.image.size.height * heightScaleFactor;
        imageViewXOrigin = - (imageViewWidth - CGRectGetWidth(self.bounds))/2;
    }

    _imageView.frame = CGRectMake(imageViewXOrigin,
                                  imageViewYOrigin,
                                  imageViewWidth,
                                  imageViewHeight);
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    [self setNeedsLayout];
}

@end
票数 41
EN

Stack Overflow用户

发布于 2014-12-19 23:38:14

如果使用故事板,这可以在有约束的情况下实现。

首先,具有所需的最终帧/约束的UIView。向UIView添加UIImageView。将contentMode设置为Aspect Fill。使UIImageView帧与图像的比例相同(这样可避免以后出现任何故事板警告)。使用标准约束将边固定到UIView。使用标准约束将顶部或底部(取决于您希望其对齐的位置)固定到UIView。最后,向UIImageView添加一个纵横比约束(确保ratio作为图像)。

票数 36
EN

Stack Overflow用户

发布于 2017-08-21 17:42:47

这有点棘手,因为如果您已经选择了一个内容模式(.scaleAspectFit),则没有选项来设置进一步的对齐规则。

但这里有一个解决方法:

首先需要通过计算尺寸来显式地调整源图像的大小(如果它在带有contentMode = .scaleAspectFitUIImageView中)。

代码语言:javascript
复制
extension UIImage {

    func aspectFitImage(inRect rect: CGRect) -> UIImage? {
        let width = self.size.width
        let height = self.size.height
        let aspectWidth = rect.width / width
        let aspectHeight = rect.height / height
        let scaleFactor = aspectWidth > aspectHeight ? rect.size.height / height : rect.size.width / width

        UIGraphicsBeginImageContextWithOptions(CGSize(width: width * scaleFactor, height: height * scaleFactor), false, 0.0)
        self.draw(in: CGRect(x: 0.0, y: 0.0, width: width * scaleFactor, height: height * scaleFactor))

        defer {
            UIGraphicsEndImageContext()
        }

        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

然后,您只需通过传递imageView的帧来对原始图像调用此函数,并将结果赋给UIImageView.image属性。此外,请确保在此处(甚至在界面生成器中)设置imageView所需的contentMode

代码语言:javascript
复制
let image = UIImage(named: "MySourceImage")
imageView.image = image?.aspectFitImage(inRect: imageView.frame)
imageView.contentMode = .left
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3272335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档