webentwicklung-frage-antwort-db.com.de

UIButton respektiert nicht den Aspektfüllmodus, nachdem die Animation geändert wurde

Ich benutze das automatische Layout. Es folgt der Anfangszustand der Ansicht. 

In der Mitte befindet sich eine Schaltfläche, die in einer Ansicht enthalten ist. Die Schaltfläche verfügt über contentMode Aspect Fill und das Bild wird als Hintergrundbild der Schaltfläche festgelegt.

enter image description here

Dann verwende ich den folgenden Code, um die Ansicht zu transformieren, wodurch die mittlere Karte vergrößert wird, um den Bildschirm auszufüllen, und das Bild an den Anfang der Ansicht verschoben wird:

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

        }

Das Ergebnis ist:

enter image description here

Es ist jedoch nicht das, was ich will. Die Schaltfläche respektiert den contentMode nicht und das Bild wird dann gestreckt.

Kann mir jemand sagen, wie man den Aspect Fill contentMode der Schaltfläche verwaltet? 

15
HanXu
  1. Setzen Sie den Schaltflächentyp auf UIButtonTypeCustom ("Benutzerdefiniert" in einem Storyboard oder Xib).
  2. Legen Sie das Bild der Schaltfläche fest, nicht das Hintergrundbild der Schaltfläche.
  3. In viewDidLoad setzen Sie button.imageView.contentMode auf UIViewContentMode.ScaleAspectFill.
39
rob mayoff

Swift 3


Gehen von Robs Antwort:

    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

Schnell 2

button.imageView?.contentMode = UIViewContentMode.ScaleAspectFit

all contentMode:

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

Swift 2.x Version:

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

Schnell 4.2

Erweiterung

 

// 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: Diese und andere Antworten funktionieren in ios 11 für mich nicht. Die beste Antwort ist von @Jaro, aber ich denke, es ist besser, eine UIImageView zu erstellen und darüber eine Schaltfläche hinzuzufügen oder eine benutzerdefinierte zu erstellen Klasse von UIImageView, die über eine Gestenerkennung und Klickanimation verfügt.

4
Nik Kov

Versuchen Sie dies vor [btn setImage: forState:] usage:

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

Die Sprache scheint ein Update zu haben.

Ich musste ein wenig tiefer graben, um die xscoder-Lösung zu erhalten:

myButton.imageView.contentMode = .ScaleAspectFill 

die aktualisierte Version sieht wie folgt aus:

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

1
ivan ramirez

Sie können die Schaltfläche subclassieren und diese hinzufügen:

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

In Xcode 10.1 können Sie den Interface Builder verwenden. Verwenden Sie im Attribute-Inspector auf der rechten Seite den Abschnitt "Control" wie folgt:

 ios Swift xcode 10.1 uibutton scale to fill

1
bradkratky

könnte jemandem helfen

button.subviews.first?.contentMode = .scaleAspectFit
1

Swift

für die Schaltfläche hat contentMode Aspekt Füllen:

btn.contentHorizontalAlignment = .fill
btn.contentVerticalAlignment = .fill
btn.imageView?.contentMode = .scaleAspectFill
0
Ramazan Karami

Diese Lösung hat bei mir funktioniert, als ich die benutzerdefinierte Schaltfläche für das BarButtonItem verwendet habe

1. Bild vom Server laden
2. Bild zuschneiden
3. Stellen Sie das Bild für die Schaltfläche ein

Hier ist die Funktion zum Zuschneiden von Bildern:

extension UIImage {
  func crop(to:CGSize) -> UIImage {
    guard let cgimage = self.cgImage else { return self }

    let contextImage: UIImage = UIImage(cgImage: cgimage)

    let contextSize: CGSize = contextImage.size

    //Set to square
    var posX: CGFloat = 0.0
    var posY: CGFloat = 0.0
    let cropAspect: CGFloat = to.width / to.height

    var cropWidth: CGFloat = to.width
    var cropHeight: CGFloat = to.height

    if to.width > to.height { //Landscape
        cropWidth = contextSize.width
        cropHeight = contextSize.width / cropAspect
        posY = (contextSize.height - cropHeight) / 2
    } else if to.width < to.height { //Portrait
        cropHeight = contextSize.height
        cropWidth = contextSize.height * cropAspect
        posX = (contextSize.width - cropWidth) / 2
    } else { //Square
        if contextSize.width >= contextSize.height { //Square on landscape (or square)
            cropHeight = contextSize.height
            cropWidth = contextSize.height * cropAspect
            posX = (contextSize.width - cropWidth) / 2
        }else{ //Square on portrait
            cropWidth = contextSize.width
            cropHeight = contextSize.width / cropAspect
            posY = (contextSize.height - cropHeight) / 2
        }
    }

    let rect: CGRect = CGRect(x : posX, y : posY, width : cropWidth, height : cropHeight)

    // Create bitmap image from context using the rect
    let imageRef: CGImage = contextImage.cgImage!.cropping(to: rect)!

    // Create a new image based on the imageRef and rotate back to the original orientation
    let cropped: UIImage = UIImage(cgImage: imageRef, scale: self.scale, orientation: self.imageOrientation)

    cropped.draw(in: CGRect(x : 0, y : 0, width : to.width, height : to.height))

    return cropped
  }
}
0
Neo Nguyen