programing

Aspect Fit(측면 맞춤

batch 2023. 8. 4. 22:47
반응형

Aspect Fit(측면 맞춤

나로서는UIImageView는 나는선을 선택합니다.Aspect Fit(Interface Builder) 그런데 수직 정렬을 변경하려면 어떻게 해야 합니까?

[편집 - 이 코드는 2011년의 약간 곰팡이가 핀 코드이며 @ArtOfWare의 모드를 통합했습니다.]

UIImageView에서는 이 작업을 수행할 수 없습니다..MyImageViewUIImageView가 포함되어 있습니다.아래 코드.

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

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

첫째, 원하는 최종 프레임/제약 조건을 포함한 UIV 뷰입니다.UIImageView를 UIIview에 추가합니다.내용 모드를 가로 세로 채우기로 설정합니다.UIImageView 프레임을 이미지와 동일한 비율로 만듭니다. 이렇게 하면 나중에 Storyboard 경고가 발생하지 않습니다.표준 구속조건을 사용하여 측면을 UI뷰에 고정합니다.표준 제약 조건을 사용하여 상단 OR 하단을(정렬할 위치에 따라) UIView에 고정합니다.마지막으로 가로 세로 비율 제약 조건을 UI 이미지 보기에 추가합니다(비율을 이미지로 확인).

모드를 할 수 ..scaleAspectFit).

그러나 이에 대한 해결 방법은 다음과 같습니다.

으로 조정해야 먼저치계소이크스의합미지명다조니기정야해로시으를적수를산여하▁it▁a▁first▁in▁explicit합▁beif다▁image▁your니ensions▁('▁need▁resize먼▁to조▁calcul▁sourced크저야정ly).UIImageView와 함께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의 imageView에 할당하면 됩니다.UIImageView.image 원하는 imageView로 설정해야 합니다.contentMode여기(또는 인터페이스 빌더에서도)!

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

설정 시도:

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

이것은 저에게 효과가 있었습니다.

UIImageView를 사용했습니다.현상액 덕분에 이미지의 정렬을 변경할 수 있도록 정렬됨

UI 이미지 보기정렬됨

이것이 오래된 스레드라는 것은 알지만, 인터페이스 빌더에서 이미지 보기의 위쪽에서 아래쪽으로 잘라낸 영역을 쉽게 변경하기 위해 수행한 작업을 공유해야 한다고 생각했습니다. 저와 같은 문제가 있는 사람이 있을 경우를 대비해서요.View Controller의 View를 채우는 UIImageView를 가지고 있었고, 장치 화면 크기에 관계없이 상단을 동일하게 유지하려고 했습니다.

  1. Retina 4 Form Factor (Editor->Apply Retina 4 Form Factor) 를 적용하였습니다.

  2. 저는 높이와 너비를 핀으로 고정했습니다.

화면 크기가 변경되면 UIImageView는 실제로 동일한 크기가 되고 보기 컨트롤러는 화면 밖에 있는 것을 클리핑합니다.프레임 원점은 0.0으로 유지되므로 이미지의 위쪽이 아닌 아래쪽과 오른쪽이 잘립니다.

이게 도움이 되길 바랍니다.

먼저 크기를 조정한 후 크기를 조정하여 이 작업을 수행할 수 있습니다.여기서 언급할 것은 제가 키에 따라 조절되었다는 것입니다.제 말은, 저는 너비에 상관없이 34px 높이의 이미지를 가져야만 했습니다.

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

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

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

이게 도움이 되길 바랍니다.

저는 다음과 같은 해결책을 생각해냈습니다.

  1. UIImageView에서 " " "로 설정합니다.top:imageView.contentMode = .top
  2. UIImageView 경계에 맞게 이미지 크기 조정

이미지를 로드하고 크기를 조정하려면 Kingfisher를 사용합니다.

let size = imageView.bounds.size
let processor = ResizingImageProcessor(referenceSize: size, mode: .aspectFit)
imageView.kf.setImage(with: URL(string: imageUrl), options: [.processor(processor), .scaleFactor(UIScreen.main.scale)])

aspectFit을 달성하고 빈 공간을 제거해야 하는 경우

스토리보드에서 이미지 보기의 너비 제약을 제거하고 즐기는 것을 잊지 마십시오.

class SelfSizedImageView :UIImageView {
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        guard let imageSize = image?.size else {
            return
        }
        
        let viewBounds = bounds
        let imageFactor = imageSize.width / imageSize.height
        let newWidth = viewBounds.height * imageFactor
        
        let myWidthConstraint = self.constraints.first(where: { $0.firstAttribute == .width })
        myWidthConstraint?.constant = min(newWidth, UIScreen.main.bounds.width / 3)
        
        layoutIfNeeded()
    }}

UIImageView를 하위 분류하고 setImage: 메서드를 재정의하여 이 문제를 해결했습니다.하위 클래스는 먼저 원래 집합 크기를 경계 상자로 사용할 수 있도록 오리진 및 크기에 대한 원래 값을 저장합니다.

컨텐츠 모드를 UIViewContentModeAspectFit로 설정했습니다.세트 이미지 내부: 이미지 너비 대 높이 비율을 잡은 다음 이미지와 동일한 비율에 맞게 이미지 보기의 크기를 조정했습니다.크기를 조정한 후 프레임 속성을 조정하여 이전과 동일한 위치에 이미지 보기를 설정한 다음 슈퍼셋을 이미지:라고 불렀습니다.

이렇게 하면 이미지 보기의 프레임이 이미지에 정확히 맞도록 조정되므로, 가로 맞춤 기능과 이미지 보기 프레임 속성이 이미지 보기를 동일한 효과를 얻기 위해 필요한 위치에 배치하는 데 큰 부담을 줍니다.

제가 사용한 코드는 다음과 같습니다.

먼저, 일반적으로 꽤 유용하다고 생각합니다. UIView의 범주는 왼쪽, 오른쪽, 위쪽, 아래쪽, 너비, 높이 등의 속성을 통해 보기에 프레임 속성을 쉽게 설정할 수 있도록 합니다.

UI 이미지 보기+프레임 추가

@interface UIView (FrameAdditions)

@property CGFloat left, right, top, bottom, width, height;
@property CGPoint origin;

@end

@implementation UIView (FrameAdditions)

- (CGFloat)left {
    return self.frame.origin.x;
}

- (void)setLeft:(CGFloat)left {
    self.frame = CGRectMake(left, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
}

- (CGFloat)right {
    return self.frame.origin.x + self.frame.size.width;
}

- (void)setRight:(CGFloat)right {
    self.frame = CGRectMake(right - self.frame.size.width, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
}

- (CGFloat)top {
    return self.frame.origin.y;
}

- (void)setTop:(CGFloat)top {
    self.frame = CGRectMake(self.frame.origin.x, top, self.frame.size.width, self.frame.size.height);
}

- (CGFloat)bottom {
    return self.frame.origin.y + self.frame.size.height;
}

- (void)setBottom:(CGFloat)bottom {
    self.frame = CGRectMake(self.frame.origin.x, bottom - self.frame.size.height, self.frame.size.width, self.frame.size.height);
}

- (CGFloat)width {
    return self.frame.size.width;
}

- (void)setWidth:(CGFloat)width {
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, width, self.frame.size.height);
}

- (CGFloat)height {
    return self.frame.size.height;
}

- (void)setHeight:(CGFloat)height {
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, height);
}

- (CGPoint)origin {
    return self.frame.origin;
}

- (void)setOrigin:(CGPoint)origin {
    self.frame = CGRectMake(origin.x, origin.y, self.frame.size.width, self.frame.size.height);
}

@end

UIImageView의 하위 클래스입니다.완전히 테스트된 것은 아니지만, 아이디어를 전달해야 합니다.이 옵션을 확장하여 맞춤에 대한 새 모드를 설정할 수 있습니다.

하단 중심 이미지 보기

@interface BottomCenteredImageView : UIImageView

@end


@interface BottomCenteredImageView() {
    CGFloat originalLeft;
    CGFloat originalBottom;
    CGFloat originalHeight;
    CGFloat originalWidth;
}

@end

@implementation BottomCenteredImageView

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [self initialize];
    }
    return self;
}

- (void)awakeFromNib {
    [self initialize];
}

- (void)initialize {
    originalLeft = self.frame.origin.x;
    originalHeight = CGRectGetHeight(self.frame);
    originalWidth = CGRectGetWidth(self.frame);
    originalBottom = self.frame.origin.y + originalHeight;
}

- (void)setImage:(UIImage *)image {
    if(image) {
        self.width = originalWidth;
        self.height = originalHeight;
        self.left = originalLeft;
        self.bottom = originalBottom;

        float myWidthToHeightRatio = originalWidth/originalHeight;
        float imageWidthToHeightRatio = image.size.width/image.size.height;
        if(myWidthToHeightRatio >= imageWidthToHeightRatio) {
            // Calculate my new width
            CGFloat newWidth = self.height * imageWidthToHeightRatio;
            self.width = newWidth;
            self.left = originalLeft + (originalWidth - self.width)/2;
            self.bottom = originalBottom;
        } else {
            // Calculate my new height
            CGFloat newHeight = self.width / imageWidthToHeightRatio;
            self.height = newHeight;
            self.bottom = originalBottom;
        }
        self.contentMode = UIViewContentModeScaleAspectFit;
        [super setImage:image];
    } else {
        [super setImage:image];
    }
}

@end

@michael-plat에 대한 크레딧

주요 사항

  • imageView.contentMode = .scaleAspectFit
  • let width = Layout.height * image.size.width / image.size.height
  • imageView.widthAnchor.constraint(equalToConstant: width).isActive = true

코드:

func setupImageView(for image: UIImage) {
    let imageView = UIImageView()
    imageView.backgroundColor = .orange

    //Content mode
    imageView.contentMode = .scaleAspectFill
    
    view.addSubview(imageView)

    //Constraints
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    imageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true

    //Feel free to set the height to any value
    imageView.heightAnchor.constraint(equalToConstant: 150).isActive = true

    //ImageView width calculation
    let width = Layout.height * image.size.width / image.size.height
    imageView.widthAnchor.constraint(equalToConstant: width).isActive = true
}

크기에 맞게 이미지를 정렬하려면 자동 레이아웃을 사용합니다.UIImageView에서 맞춤 스케일 후 오른쪽 정렬된 이미지 예:

  1. 이미지를 보유한 UIImageView 생성
  2. 오른쪽, 위쪽, 아래쪽, 너비에 자동 구속조건 추가
  3. 이미지 설정:
myUIImageView.contentMode = .ScaleAspectFit
myUIImageView.translatesAutoresizingMaskIntoConstraints = false
myUIImageView.image = UIImage(named:"pizza.png")

가로 세로 맞춤 조정된 이미지가 UIImageView에서 오른쪽 정렬됩니다.

+----------------------------------+
|                           [IMAGE]|
+----------------------------------+

제약 조건을 변경하여 이미지 보기 내에서 다르게 정렬합니다.

언급URL : https://stackoverflow.com/questions/3272335/alignment-uiimageview-with-aspect-fit

반응형