для своего UIImageView я выбираю Aspect Fit (InterfaceBuilder), но как я могу изменить вертикальное выравнивание?
iphone
cocoa-touch
interface-builder
Raegtime
источник
источник
Ответы:
[РЕДАКТИРОВАТЬ - этот код немного заплесневел, взятый из 2011 года, и все, кроме я включил моды @ ArtOfWarefare]
Вы не можете сделать это с UIImageView. Я создал простой подкласс UIView,
MyImageView
который содержит UIImageView. Код ниже.// 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
источник
initWithCoder
(я в основном скопировали ,initWithFrame
но заменил[super initWithFrame:]
с[super initWithCoder:]
) и 2 - я добавил в линию ,if (!self.image) return;
чтобыlayoutSubviews
таким образом , чтобы он не врезаться с недопустимой геометрией , если изображение ISN» t назначается при вызове. С этими двумя небольшими изменениями он работает потрясающе.dealloc
метод должен быть удален.При использовании раскадровки это может быть достигнуто с ограничениями ...
Во-первых, UIView с желаемым окончательным кадром / ограничениями. Добавьте UIImageView в UIView. Установите для 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
здесь желаемое изображение ( или даже в Интерфейсном Разработчике )!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, на случай, если у кого-то возникнет такая же проблема, как и у меня. У меня был UIImageView, который заполнял View моего ViewController, и я пытался сделать верхнюю часть такой же, независимо от размера экрана устройства.
Я применил форм-фактор Retina 4 (Редактор-> Применить форм-фактор Retina 4).
Прикрепил высоту и ширину.
Теперь, когда экран меняет размер, UIImageView фактически имеет тот же размер, а контроллер представления просто отсекает то, что находится за пределами экрана. Исходная точка кадра остается на 0,0, поэтому нижняя и правая часть изображения обрезаются, а не верхняя.
Надеюсь это поможет.
источник
Вы можете сделать это, сначала изменив масштаб, а затем изменив размер. Здесь следует упомянуть, что я был обусловлен ростом. Я имею в виду, что у меня должно было быть изображение высотой 34 пикселя независимо от ширины.
Итак, получите соотношение между фактической высотой содержимого и высотой представления (34 пикселя), а затем также масштабируйте ширину.
Вот как я это сделал:
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
Для загрузки и изменения размера изображения я использую 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)])
источник
Я решил эту проблему, создав подкласс UIImageView и переопределив метод setImage :. Подкласс сначала сохранит свои исходные значения для источника и размера, чтобы он мог использовать исходный установленный размер в качестве ограничивающей рамки.
Я установил режим содержимого на UIViewContentModeAspectFit. Внутри setImage: я взял отношение ширины изображения к высоте, а затем изменил размер изображения, чтобы он соответствовал тому же соотношению, что и изображение. После изменения размера я скорректировал свойства кадра, чтобы установить вид изображения на том же месте, что и раньше, а затем вызвал super setImage :.
Это приводит к тому, что рама изображения настраивается так, чтобы она точно соответствовала изображению, поэтому соотношение сторон работает, а свойства рамки просмотра изображения делают тяжелую работу по размещению вида изображения там, где оно должно быть, чтобы получить тот же эффект.
Вот код, который я использовал:
Во-первых, и я считаю, что это довольно полезно в целом, это категория в UIView, которая упрощает установку свойств фрейма в представлении с помощью таких свойств, как left, right, top, bottom, width, height и т. Д.
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
источник
Если вам нужно достичь аспектаFit и избавиться от пустых пространств
Не забудьте удалить ограничение ширины вашего изображения из раскадровки и наслаждайтесь
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.
+----------------------------------+ | [IMAGE]| +----------------------------------+
Измените ограничения, чтобы по-разному выровнять изображение.
источник