Каким образом размещать изображение с сохранением высоты и ширины?

swift

#1

Добрый день всем
Хотелось бы отображать изображения в tableView с сохранением пропорций высоты и ширины
Делаю все это так

cell.image_article.kf.setImage(with: url_article)
        let ratio = cell.image_article.contentClippingRect.width / cell.image_article.contentClippingRect.height
                    let newHeight = cell.image_article.frame.width / ratio
                    cell.image_height.constant = newHeight
                    UIView.setAnimationsEnabled(false)
                    self.tableview.beginUpdates()
                    self.tableview.endUpdates()

И extension

extension UIImageView {
    var contentClippingRect: CGRect {
        guard let image = image else { return bounds }
        guard contentMode == .scaleAspectFit else { return bounds }
        guard image.size.width > 0 && image.size.height > 0 else { return bounds }
        
        let scale: CGFloat
        if image.size.width > image.size.height {
            scale = bounds.width / image.size.width
        } else {
            scale = bounds.height / image.size.height
        }
        
        let size = CGSize(width: image.size.width * scale, height: image.size.height * scale)
        let x = (bounds.width - size.width) / 2.0
        let y = (bounds.height - size.height) / 2.0
        
        return CGRect(x: x, y: y, width: size.width, height: size.height)
    }
}  

Это все работает правильно, но я хотел бы чтобы высота высчитывалась до того как изображение вставиться в мой UIImage, а сейчас получается так что таблица загружается, высчитывается высота и потом ячейка обновляется. Как сделать так чтобы изображение принимало нужную высоту, и только потом таблица бы отображала ячейку?
Или можете привести примеры вашего кода, как вы решаете проблему изображений с сохранением пропорций в tableView?


#2

а зачем всё это, когда у image есть свойство content mode с параметром .scaleAspectFill


#3


Получается так же как я и хотел
Но остается пустое пространство, как его убрать?


#4

Aspect Fill как раз должен масштабировать картинку с сохранением пропорций, чтобы заполнить полностью вью. Проверьте картинку, возможно она у вас уже с белыми полями )))


#5

Нет
Такого быть не может
Это происходит не только с этой картинкой
Постмотрите, вот даже есть изображение с использованием разных content mode


#6

Ну вы сами ответили на свой вопрос: Aspect Fill растягивает картинку и обрезает, чтобы заполнить полностью вью, что вам и рекомендовали.
Возможно вы просто поставили Aspect Fit, вместо Aspect Fill


#7

Да
Но только мне нужно с сохранением пропорций картинки
aspectFill ведь обрезает часть картинки
Если изображение будет иметь большую высоту, то большая часть изображения будет где то за ImageView


#8

А мне как бы нужно чтобы был aspectFit, но только без пустого пространства


#9

Естественно, так другого не дано:

  1. вы делаете картинку в тех же пропорциях, что и вью, что бы всё влезло - ручками меняете разрешение картинки;
  2. меняете пропорции, чтобы картинка соответствовала пропорциям вью - sale to fit;
  3. растягиваете картинку по большей стороне, в соотвествии с больше стороной вью, чтобы вольностью влезла картинка с сохранением пропорций Aspect Fit;
  4. растягиваете картинку по меньшей стороне, чтобы картинка польностью заполнила вью, с обрезкой картинки - Aspect fill.

#10

тут только руками менять/создавать разрешение картинки, чтобы оно соответствовало соотношению вью, по-моему бесполезное занятие, тк видимо явно не вы рисовали картинку… ищите другую, или создайте свою.


#11

Ну вот мы и вернулись к началу обсуждения
Уже есть extension в котором я это все делаю
И он все делает отлично
Просто если взять допустим ленту в вк, там каждая ячейка в таблице возвращает свою высоту уже с учетом изображения, а не как я сейчас делаю(асинхронно обновляю ячейку, после того как узнал размер)


#12

так я про это и говорю, что то что вы делаете, уже есть под капотом, результат будет тот, что я описал выше.

Ну если хотите поиграться, то ваше расширение надо применять в переопредлённом методе viewDidLayoutSubviews - там вы получите актуальные размеры.

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

    }

#13

Если вам интересно, я решил проблему следующим способом
По апи решил возвращать высоту и ширину
Исходя из этого расчеты будут происходить до того как ячейка загрузит данные
Спасибо вам


#14

Примерно так нужно было?


#15

нет
Нужна была обычная лента новостей, как в инстаграм или вк


#16

Я про соотношение сторон изображения


#17

@ODiN не понял сути вопроса, а вот @Psilc как раз о том.
Автору нужно показывать всю картинку целиком, без обрезки, но и с сохранением пропорций, т.е. каждая ячейка поста будет разной высоты, зависит от размеров картинки.


#18

А, тогда да, вы правы


#19

Да как же вас поймёшь, когда толком задачу не говорят )))