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

У меня есть вид изображения, который ограничен таким образом, что его левый, правый и верхний края прикреплены к его суперпредставлению, а его нижний край имеет фиксированный интервал к метке ниже. Он не имеет никаких ограничений по ширине или высоте, поэтому он должен получить свою высоту из собственного размера изображения. Режим контента установлен на Aspect Fit,

Это прекрасно работает, если изображение имеет меньшую или равную ширину с видом изображения (варианты 1 и 2, см. Изображения ниже). Однако, если изображение имеет ширину, которая превышает ширину содержащего его изображения, я столкнусь с проблемой (случай 3):

Изображение уменьшено, как ожидается, так, чтобы его ширина соответствовала ширине представления изображения. Но представление изображения не обновляет свою высоту соответственно, оставляя пробелы выше и ниже. Я понимаю, что представление изображения все еще получает свою высоту от исходной высоты изображения. Но из-за режима содержимого высота изображения теперь намного меньше, и я хочу, чтобы представление изображения регулировало его высоту в соответствии с фактической высотой изображения.

Я ищу аккуратное решение, которое работает для каждого из трех случаев, предпочтительно тот, который работает с IB_DESIGNABLE просмотров также. Есть идеи?

Случай 1

внутренняя ширина <ширина кадра

внутренняя ширина <ширина кадра

Дело 2

внутренняя ширина = ширина кадра

внутренняя ширина = ширина кадра

Дело 3

внутренняя ширина> ширина кадра

внутренняя ширина> ширина кадра ширина кадра">

1 ответ

Вы можете создать расширение на UIImageView следующим образом:

extension UIImageView {
    @IBInspectable var shouldAdjustHeight: Bool {
        get {
            return self.frame.size.height == self.adjustedHeight;
        }
        set {
            if newValue {
                if !shouldAdjustHeight {
                    let newHeight = self.adjustedHeight

                    // add constraint to adjust height
                    self.addConstraint(NSLayoutConstraint(
                        item:self, attribute:NSLayoutAttribute.Height,
                    relatedBy:NSLayoutRelation.Equal,
                    toItem:nil, attribute:NSLayoutAttribute.NotAnAttribute,
                    multiplier:0, constant:newHeight))
            }
        }
        else {
            let newHeight = self.adjustedHeight
            // create predicate to find the height constraint that we added
            let predicate = NSPredicate(format: "%K == %d && %K == %f", "firstAttribute", NSLayoutAttribute.Height.rawValue, "constant", newHeight)
            // remove constraint
            self.removeConstraints(self.constraints.filter{ predicate.evaluateWithObject($0) })
        }
    }
}

var adjustedHeight: CGFloat {
    let screenWidth = UIScreen.mainScreen().bounds.width
    let deviceScaleFactor = screenWidth/self.bounds.size.width
    return CGFloat(ceilf(Float(deviceScaleFactor * AVMakeRectWithAspectRatioInsideRect((self.image?.size)!, self.bounds).size.height))) // deviceScaleFactor multiplied with the image size for the frame
    // I am using size class in my XIB with value as (Any,Any) and I was not getting correct frame values for a particular device so I have used deviceScaleFactor.
    // You can modify above code to calculate newHeight as per your requirement
}
}

После добавления вышеуказанного расширения вы можете установить свойство в Interface-builder, как показано ниже.

При установке этого свойства, ограничение высоты будет добавлено к вашему imageView, Расчет adjustedHeight может быть не очень аккуратным в моем решении, так что вы можете посмотреть на это дальше.

Другие вопросы по тегам