가로 세로 맞춤으로 UIImageView 정렬
내 UIImageView의 경우 Aspect Fit (InterfaceBuilder) 수직 정렬을 어떻게 배열합니까?
[편집-이 코드는 2011 년부터 약간의 곰팡이가 났지만 모두 @ArtOfWarefare의 모드를 통합했습니다]
UIImageView를받을 수 없습니다. MyImageView
UIImageView를 포함 하는 간단한 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
)를 선택한 경우 추가 정렬 규칙을 수있는 옵션이 없기 때문에 까다 롭습니다 .
그러나 여기에 대한 해결 방법이 있습니다.
먼저 크기를 계산하여 소스 이미지의 크기를 명시 적으로 조정해야합니다 ( 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의 프레임을 전달하여 원본 이미지 에서이 함수를 호출하고 결과를 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를 사용했습니다.
나는 어떤 것과 같은 것과 같은 것이 있는지, 누군가가있는 것과 같은 것과 같은 문제가있는 경우 내가 상단에서 인터페이스 빌더에서 이미지를 공유 할 수 있도록 변경하기 위해 한 것과 같은 것을 공유 할 것입니다. 내 ViewController의 뷰를 채우는 UIImageView가있는 장치 화면의 크기에 관계없이 상단을 동일하게 유지했습니다.
Retina 4 폼 팩터를 적용했습니다 (Editor-> Retina 4 폼 팩터 적용).
높이와 너비를 고정했습니다.
이제 화면 크기가 변경 될 때 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];
도움이 되셨기를 바랍니다.
다음 해결책을 찾았습니다.
UIImageView
콘텐츠 모드를top
다음으로 설정 합니다 .imageView.contentMode = .top
- UIImageView 경계에 맞게 이미지 크기 조정
이미지를로드하고 크기를 조정하여 Kingfisher를 사용합니다 .
let size = imageView.bounds.size
let processor = ResizingImageProcessor(referenceSize: size, mode: .aspectFit)
imageView.kf.setImage(with: URL(string: imageUrl), options: [.processor(processor)])
UIImageView를 서브 클래하여 싱하고 setImage : 메서드를 재정의 한 문제를 해결했습니다. 원래 클래스는 먼저 원본 및 크기에 대한 하위 원본 값을 저장하여 원래 크기를 경계 상자로 사용할 수 있습니다.
콘텐츠 모드를 UIViewContentModeAspectFit로 설정했습니다. setImage 내부 : 이미지 너비와 높이 비율을 입찰 이미지와 동일한 비율에 맞게 이미지보기의 크기를 조정했습니다. 크기 조정 후 프레임 속성을 조정하여 이전과 동일한 지점에서 이미지보기를 설정 한 다음 super setImage :를 호출했습니다.
결과적으로 프레임이 이미지에 정확히 맞도록 프레임이 정렬 된 이미지 뷰가 생성 프레임에 맞는 기능이 작동하고 이미지 뷰를 배치하는 데 무거운 작업을 수행합니다.
내가 다루는 코드는 다음과 가변적입니다.
먼저, 일반적으로 일반적으로 유용합니다.
UIImageView + FrameAdditions
@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의 하위 클래스입니다. 아이디어를 전달해야합니다. 이 정렬을 확장 할 새로운 모드를 설정하기 위해 될 수 있습니다.
BottomCenteredImageView
@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
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에서 크기 조정 후 오른쪽 정렬 된 이미지의 예 :
- 이미지를 보유하는 UIImageView 생성
- 오른쪽, 아래쪽, 너비에 대한 제한 추가
- 이미지 설정 :
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
'ProgramingTip' 카테고리의 다른 글
ng2-ng-container와 ng-template 태그의 차이점 (0) | 2020.10.27 |
---|---|
StyleCop 규칙 위반 (0) | 2020.10.27 |
하드 코딩없이 Cake 패턴으로 의존성 공급을 어떻게합니까? (0) | 2020.10.27 |
어떤 소멸자가 실행되고 (0) | 2020.10.27 |
C ++에서 부호있는 정수 오버플로가 여전히 정의되지 않은 동작입니까? (0) | 2020.10.27 |