web-dev-qa-db-fra.com

Comment redimensionner UIImageView en fonction de la taille et du rapport de UIImage dans Swift 3?

S'il vous plaît ne marque pas comme un doublon, je n'ai pas trouvé de solution compte tenu des threads disponibles.

J'ai un UIImageView et l'utilisateur peut télécharger UIImages dans différents formats. Le problème est que j'ai besoin de UIImageView pour redimensionner en fonction du ratio de l'image donnée.

J'utilise actuellement Aspect fit, mais le UIImageView reste vide sur de grandes parties de lui-même. J'aimerais que le UIImageView se redimensionne en fonction de son contenu. Par exemple, si la photo est 1: 1, 4: 3, 6: 2, 16: 9 ...

enter image description here

L'aide est très appréciée.

Comme demandé, c'est ce que je veux:

enter image description here

J'ai eu un UIImageView qui était carré, chargé avec une image dans 16: 7 ou autre chose et le UIImageView redimensionné pour s'adapter à la taille de l'image ...

38
David Seek

Il semblerait que vous souhaitiez redimensionner un ImageView en fonction du rapport d'image et de la taille de la vue du conteneur. Voici l'exemple de Swift (Désolé, l'ancienne réponse avec un bogue, je l'ai corrigée)):

   let containerView = UIView(frame: CGRect(x:0,y:0,width:320,height:500))
   let imageView = UIImageView()

    if let image = UIImage(named: "a_image") {
        let ratio = image.size.width / image.size.height
        if containerView.frame.width > containerView.frame.height {
            let newHeight = containerView.frame.width / ratio
            imageView.frame.size = CGSize(width: containerView.frame.width, height: newHeight)
        }
        else{
            let newWidth = containerView.frame.height * ratio
            imageView.frame.size = CGSize(width: newWidth, height: containerView.frame.height)
        }
    }
28
Yun CHEN

J'ai passé de nombreuses heures à essayer de trouver une solution au même problème que vous rencontrez et c'est la seule solution qui a fonctionné pour moi (Swift 4, xCode 9.2):

class ScaledHeightImageView: UIImageView {

    override var intrinsicContentSize: CGSize {

        if let myImage = self.image {
            let myImageWidth = myImage.size.width
            let myImageHeight = myImage.size.height
            let myViewWidth = self.frame.size.width

            let ratio = myViewWidth/myImageWidth
            let scaledHeight = myImageHeight * ratio

            return CGSize(width: myViewWidth, height: scaledHeight)
        }

        return CGSize(width: -1.0, height: -1.0)
    }

}

Ajoutez la classe au projet et définissez UIImageView sur la classe personnalisée ScaledHeightImageView. Le mode de contenu de la vue d'image est Aspect Fit.

Mon problème est le même que celui indiqué dans ce post. À l'intérieur de mon prototype ContentView de TableViewCell, j'ai un StackView vertical contraint à chaque bord. À l’intérieur de StackView, il y avait une étiquette, ImageView et une autre étiquette. Avoir ImageView réglé sur AspectFit n'était pas suffisant. L'image aurait la taille et les proportions appropriées, mais ImageView n'enveloppait pas l'image réelle, ce qui laissait un espace supplémentaire entre l'image et l'étiquette (comme dans l'image ci-dessus). La hauteur de ImageView semblait correspondre à la hauteur de l'image d'origine plutôt qu'à la hauteur de l'image redimensionnée (après que aspectFit ait fait son travail). D'autres solutions que j'ai trouvées ne résolvent pas complètement le problème pour diverses raisons. J'espère que ça aidera quelqu'un.

40
olearyj234

J'ai passé de nombreuses heures sur ce sujet et j'ai finalement obtenu une solution qui fonctionnait pour moi (Swift):

  • dans IB, je règle le 'Mode de contenu' de UIImageView sur 'Aspect Fit'
  • dans IB, je règle UIImageView contrainte de largeur égal à ce que vous voulez (dans mon cas, la largeur de la vue)
  • dans IB, je mets la valeur contrainte de hauteur de UIImageView == égale à 0 et crée un sortie référençant pour elle (par exemple, constraintHeight)

Ensuite, lorsque j'ai besoin d'afficher l'image, j'écris simplement ce qui suit (échantillonné à partir des réponses ci-dessus):

let ratio = image.size.width / image.size.height
let newHeight = myImageView.frame.width / ratio
constraintHeight.constant = newHeight
view.layoutIfNeeded()

En gros, cela garantit que l'image remplit la largeur de UIImageView et force la hauteur de celle-ci à être égale à la hauteur de l'image après sa mise à l'échelle

22
Raimondo Previdi

La solution que j'ai utilisée est basée sur solution de olearyj234 , mais fait en sorte qu'aucune image ne prenne pratiquement pas de place (ou plus précisément, le minimum requis par iOS sera accepté). Il utilise également ceil pour éviter les problèmes pouvant survenir avec des valeurs non entières lorsque UIImageView est incorporé dans des éléments tels que le défilement de cellules.

class FixedWidthAspectFitImageView: UIImageView
{

    override var intrinsicContentSize: CGSize
    {
        // VALIDATE ELSE RETURN
        // frameSizeWidth
        let frameSizeWidth = self.frame.size.width

        // image
        // ⓘ In testing on iOS 12.1.4 heights of 1.0 and 0.5 were respected, but 0.1 and 0.0 led intrinsicContentSize to be ignored.
        guard let image = self.image else
        {
            return CGSize(width: frameSizeWidth, height: 1.0)
        }

        // MAIN
        let returnHeight = ceil(image.size.height * (frameSizeWidth / image.size.width))
        return CGSize(width: frameSizeWidth, height: returnHeight)
    }

}
1
John Bushnell

Définissez votre imageView sur aspectFit, ce qui redimensionnera l’image pour ne pas dépasser le cadre de votre imageView.

Vous pouvez obtenir la taille de votre UIImage de votre imageView avec la logique de cette question - en gros, obtenez simplement la hauteur et la largeur de UIImage.

Calculez le rapport et définissez la largeur/hauteur de l'imageView pour qu'elle s'adapte à votre écran.

Il existe également une question similaire à laquelle vous pouvez obtenir une réponse.

0
Ben Ong