web-dev-qa-db-fra.com

UIButton ne respecte pas Aspect Fill contentMode après le redimensionnement de l'animation

Je suis utiliser la mise en page automatique. Voici l'état initial de la vue. 

Au centre se trouve un bouton contenu dans une vue. Le bouton contient contentMode Aspect Fill et l'image est définie comme image d'arrière-plan du bouton.

enter image description here

Ensuite, j'utilise le code suivant pour transformer la vue, ce qui permettra d'agrandir la carte centrale pour remplir l'écran et de déplacer l'image vers le haut de la vue:

cardTrailingSpaceConstraint.constant = 0
cardLeadingSpaceConstraint.constant = 0
cardView.removeConstraint(cardAspectRatioConstraint)
let cardHeightConstraint = NSLayoutConstraint(item: cardView, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 1.0, constant: 0)
view.addConstraint(cardHeightConstraint)

dishImageButton.removeConstraint(dishButtonBottomSpaceConstraint)
let dishButtonHeightConstraint = NSLayoutConstraint(item: dishImageButton, attribute: .Height, relatedBy: .Equal, toItem: cardView, attribute: .Height, multiplier: 0.2, constant: 0)
cardView.addConstraint(dishButtonHeightConstraint)

cardView.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: nil, animations: { [unowned self] () -> Void in
    self.cardHeader.alpha = 0
    self.cardView.layer.cornerRadius = 0
    self.cardView.layoutIfNeeded()

    }) { [unowned self] (finished) -> Void in

        }

Le résultat est:

enter image description here

Cependant, ce n'est pas ce que je veux. Le bouton ne respecte pas le contentMode et l'image est alors étirée.

Quelqu'un peut-il me dire comment gérer le mode de remplissage Aspect du bouton? 

15
HanXu
  1. Définissez le type de bouton sur UIButtonTypeCustom («Personnalisé» dans un storyboard ou xib).
  2. Définissez l'image du bouton, pas son image d'arrière-plan.
  3. Dans viewDidLoad, définissez button.imageView.contentMode sur UIViewContentMode.ScaleAspectFill.
39
rob mayoff

Swift 3


Sortir de la réponse de Rob:

    let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 80, height: 30))
    btn.setImage(UIImage(named: "albumsBtn"), for: UIControlState.normal)
    btn.imageView?.contentMode = UIViewContentMode.scaleAspectFit
    btn.addTarget(self.navigationController, action: #selector(CustomGalleryViewController.showAlbums(_:)), for:  UIControlEvents.touchUpInside)
    let item = UIBarButtonItem(customView: btn)
    self.navigationItem.leftBarButtonItem = item
12
Jessie

Swift 2

button.imageView?.contentMode = UIViewContentMode.ScaleAspectFit

tout contentMode:

  .ScaleToFill
   .ScaleAspectFit
   .ScaleAspectFill
   .Redraw 
   .Center 
   .Top
   .Bottom
   .Left
   .Right
   .TopLeft
   .TopRight
   .BottomLeft
   .BottomRight
6
CrazyVK

Version Swift 2.x:

let myButton = UIButton(type: .Custom)
myButton.frame = CGRectMake(0, 0, 200, 20)
myButton.backgroundColor = UIColor.blackColor()
myButton.imageView.contentMode = .ScaleAspectFill // ALTERNATIVE:  .ScaleAspectFit
myButton.setImage(UIImage(named: "myImageName"), forState: .Normal)
myButton.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
view.addSubview(myButton)
5
xscoder

Swift 4.2

Extension

 

// Inspectable image content mode
extension UIButton {
    /// 0 => .ScaleToFill
    /// 1 => .ScaleAspectFit
    /// 2 => .ScaleAspectFill
    @IBInspectable
    var imageContentMode: Int {
        get {
            return self.imageView?.contentMode.rawValue ?? 0
        }
        set {
            if let mode = UIViewContentMode(rawValue: newValue),
                self.imageView != nil {
                self.imageView?.contentMode = mode
            }
        }
    }
}

UPDATE: Ceci et d'autres réponses ne fonctionnent pas pour moi dans iOS 11. La réponse la plus proche est celle de @Jaro mais je pense qu'il est préférable de créer un UIImageView et d'ajouter un bouton ou de créer une classe de UIImageView qui aurait un identificateur de geste et une animation de clic.

4
Nik Kov

Essayez ceci avant [btn setImage: forState:] usage:

btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
btn.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
3
Jaro

La langue semble avoir eu une mise à jour.

J'ai dû creuser un peu plus pour obtenir la solution xscoder pour:

myButton.imageView.contentMode = .ScaleAspectFill 

la version mise à jour est la suivante:

myButton.imageView?.contentMode = UIView.ContentMode.scaleAspectFit

1
ivan ramirez

Vous pouvez sous-classer le bouton et ajouter les éléments suivants:

class FitButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)


    }

    override func layoutSubviews() {
        self.imageView?.contentMode = .scaleAspectFill
        self.contentHorizontalAlignment = .fill
        self.contentVerticalAlignment = .fill
        super.layoutSubviews()


    }

}
1
João Nunes

Dans Xcode 10.1, vous pouvez utiliser le générateur d'interface. Dans l'inspecteur d'attributs à droite, utilisez la section Contrôle comme suit:

 ios Swift xcode 10.1 uibutton scale to fill

1
bradkratky

pourrait aider quelqu'un

button.subviews.first?.contentMode = .scaleAspectFit
1
ARSHWIN DENUEV LAL