[iphone] 가로 세로 맞춤으로 UIImageView 정렬

내 UIImageView의 경우 Aspect Fit (InterfaceBuilder)을 선택했지만 수직 정렬을 어떻게 변경할 수 있습니까?



답변

[편집-이 코드는 2011 년부터 약간 곰팡이가 났지만 모두 @ArtOfWarefare의 모드를 통합했습니다]

UIImageView로 이것을 할 수 없습니다. MyImageViewUIImageView를 포함 하는 간단한 UIView 하위 클래스 를 만들었습니다 . 아래 코드.

// MyImageView.h
#import <UIKit/UIKit.h>

@interface MyImageView : UIView {
    UIImageView *_imageView;
}

@property (nonatomic, assign) UIImage *image;

@end

// 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


답변

스토리 보드를 사용하는 경우 제약 조건으로 달성 할 수 있습니다.

먼저 원하는 최종 프레임 / 제약 조건이있는 UIView입니다. UIView에 UIImageView를 추가하십시오. contentMode를 Aspect Fill로 설정합니다. UIImageView 프레임을 이미지와 동일한 비율로 만듭니다 (이렇게하면 나중에 스토리 보드 경고가 표시되지 않음). 표준 제약 조건을 사용하여 측면을 UIView에 고정합니다. 표준 제약 조건을 사용하여 상단 또는 하단 (정렬하려는 위치에 따라)을 UIView에 고정합니다. 마지막으로 가로 세로 비율 제한을 UIImageView에 추가합니다 (비율을 이미지로 확인).


답변

이미 콘텐츠 모드 ( .scaleAspectFit)를 선택한 경우 추가 정렬 규칙을 설정할 수있는 옵션이 없기 때문에 약간 까다 롭습니다 .

그러나 여기에 대한 해결 방법이 있습니다.

먼저 크기를 계산하여 소스 이미지의 크기를 명시 적으로 조정해야합니다 ( UIImageViewwith 인 경우 contentMode = .scaleAspectFit).

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속성에 할당하기 만하면 됩니다. 또한 contentMode여기 에서 원하는 imageView를 설정했는지 확인 하십시오 ( 또는 Interface Builder에서 )!

let image = UIImage(named: "MySourceImage")
imageView.image = image?.aspectFitImage(inRect: imageView.frame)
imageView.contentMode = .left


답변

설정 시도 :

imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.clipsToBounds = YES;

이것은 나를 위해 일했습니다.


답변

개발자 덕분에 이미지 정렬을 변경하기 위해 UIImageViewAligned를 사용했습니다.

UIImageViewAligned


답변

나는 이것이 오래된 스레드라는 것을 알고 있지만 누군가가 내가 한 동일한 문제가있는 경우를 대비하여 Interface Builder에서 이미지보기의 상단에서 하단으로 잘린 영역을 쉽게 변경하기 위해 내가 한 일을 공유 할 것이라고 생각했습니다. 내 ViewController의 뷰를 채우는 UIImageView가 있었고 장치 화면의 크기에 관계없이 상단을 동일하게 유지하려고했습니다.

  1. Retina 4 폼 팩터를 적용했습니다 (Editor-> Apply Retina 4 폼 팩터).

  2. 높이와 너비를 고정했습니다.

이제 화면 크기가 변경 될 때 UIImageView는 실제로 동일한 크기이며 뷰 컨트롤러는 화면에서 벗어난 부분을 잘라냅니다. 프레임 원점은 0,0에 유지되므로 이미지의 상단이 아닌 하단과 오른쪽이 잘립니다.

도움이 되었기를 바랍니다.


답변

먼저 크기를 조정 한 다음 크기를 조정하여 수행 할 수 있습니다. 여기서 언급 할 것은 제가 키에 의해 조절된다는 것입니다. 내 말은, 너비에 상관없이 높이 34px의 이미지를 가져야했습니다.

따라서 실제 콘텐츠 높이와 뷰 높이 (34 px) 사이의 비율을 구한 다음 너비도 조정합니다.

내가 한 방법은 다음과 같습니다.

CGSize size = [imageView sizeThatFits:imageView.frame.size];

CGSize actualSize;
actualSize.height = imageView.frame.size.height;
actualSize.width = size.width / (1.0 * (size.height / imageView.frame.size.height));

CGRect frame = imageView.frame;
frame.size = actualSize;
[imageView setFrame:frame];

도움이 되었기를 바랍니다.