89 votes

Comment redimensionner UIImageView en fonction de la taille / du rapport d'UIImage dans Swift 3?

S'il vous plaît ne pas marquer les doublons, je n'ai pas trouvé de solution compte tenu de threads disponibles.

J'ai un UIImageView et que l'utilisateur est en mesure de télécharger UIImages dans divers formats. Le problème est que j'ai besoin de l' UIImageView pour redimensionner basé sur l'Image donnée du rapport.

Actuellement, je suis en utilisant Aspect fit, mais l' UIImageView reste vide sur de grandes parties de lui-même. Je voudrais avoir l' UIImageView redimensionne en fonction de son contenu. E. g si le pic est 1:1, 4:3, 6:2, 16:9...

enter image description here

De l'aide est très apprécié.

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

enter image description here

J'ai eu un UIImageView qui était carré, chargé avec une Image en 16:7 ou quoi que ce soit et l' UIImageView redimensionné pour s'adapter à la taille de l'Image...

90voto

olearyj234 Points 491

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 pour le projet et de définir les UIImageView à la classe personnalisée ScaledHeightImageView. L'affichage de l'image du mode de contenu est l'Aspect Ajustement.

Mon problème est le même que celui indiqué dans ce post. À l'intérieur de mon prototype TableViewCell de ContentView, j'ai une verticale Empilervoir contraint de chaque bord. À l'intérieur de la Empilervoir il y avait une Étiquette, ImageView et un autre Label. Avoir l'ImageView ensemble de AspectFit n'était pas assez. L'image est à la bonne taille et les proportions, mais l'ImageView ne pas envelopper l'image réelle en laissant une bande d'espace supplémentaire entre l'image et de l'étiquette (comme dans l'image ci-dessus). L'ImageView hauteur semblait correspondre à la hauteur de l'image d'origine plutôt que de la hauteur de l'image (après aspectFit fait c'est du boulot). Les autres solutions que j'ai trouvé n'a pas de résoudre complètement le problème, pour diverses raisons. J'espère que cela aide quelqu'un.

70voto

Raimondo Previdi Points 193

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

  • dans IB, j'ai mis UIImageView du Contenu en Mode' à 'Aspect Ajustement"
  • dans IB, j'ai mis UIImageView de la largeur de la contrainte à être égal à tout ce que vous voulez (dans mon cas, le point de vue de la largeur)
  • dans IB, j'ai mis UIImageView la hauteur de la contrainte à être égal à 0, et de créer une prise de référencement pour elle (par exemple, constraintHeight)

Puis, quand j'ai besoin d'afficher l'image, j'ai simplement écrit ce qui suit (échantillonnés à 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()

Fondamentalement, ce qui assure que l'image remplisse l'UIImageView de la largeur et les forces de l'UIImageView de hauteur égale à la hauteur de l'image après avoir mis à l'échelle

46voto

Yun CHEN Points 3978

Il semble que vous souhaitiez redimensionner une ImageView en fonction du rapport d'image et de la taille de la vue du conteneur, voici l'exemple dans Swift (Désolé, l'ancienne réponse avec un bug, je l'ai corrigé):

    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)
        }
    }
 

3voto

John Points 73

La solution que j'ai utilisée est basée sur la solution de olearyj234 , mais fait qu'aucune image ne prend essentiellement aucun espace (ou plus précisément le minimum iOS acceptera). Il utilise également ceil pour éviter les problèmes qui peuvent survenir avec des valeurs non entières lorsque UIImageView sont intégrés dans des éléments tels que les cellules de défilement.

 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)
    }

}
 

0voto

Ben Ong Points 635

Définissez votre imageView à aspectFit, qui va redimensionner l'image pour ne pas dépasser votre imageView cadre.

Vous pouvez obtenir la taille de votre UIImage de votre imageView avec la logique de cette question - fondamentalement, il suffit d'obtenir la hauteur et la largeur de la UIImage.

Le calcul du ratio, et de définir la largeur/hauteur de l'imageView pour s'adapter à votre écran.

Il y a aussi une question similaire à la votre que vous pourriez vous obtenez la réponse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X