Ho un paio di pulsanti UIB e in IB sono impostati su Aspect Fit, ma per qualche motivo si allungano sempre. C'è qualcos'altro che devi impostare? Ho provato tutte le diverse modalità di visualizzazione e nessuna di esse funziona, si allungano tutte.
Ho un paio di pulsanti UIB e in IB sono impostati su Aspect Fit, ma per qualche motivo si allungano sempre. C'è qualcos'altro che devi impostare? Ho provato tutte le diverse modalità di visualizzazione e nessuna di esse funziona, si allungano tutte.
Risposte:
Ho già avuto quel problema. L'ho risolto inserendo la mia immagine in una UIImageView, in cui le contentModeimpostazioni funzionano effettivamente, e aggiungendo una personalizzazione trasparente UIButtonsopra.
EDIT: questa risposta è obsoleta. Vedi la risposta di @Werner Altewischer per la risposta corretta nelle versioni moderne di iOS.
La soluzione è impostare il contentModesulla imageViewproprietà del UIButton. La UIButtondeve essere creato con il tipo personalizzato per far funzionare tutto questo credo (altrimenti nilviene restituito per questa proprietà).
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Questo metodo ha funzionato molto bene per me .:
In Xib selezionare il pulsante e impostare user defined runtime attributes:
self.imageView.contentModeNumber1
Usiamo number perché non puoi usare enum lì. Ma UIViewContentModeScaleAspectFit è uguale a 1.
extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
imageView.contentModefunzionato per me!
Se lo stai facendo in Interface Builder, puoi usare l'ispettore degli attributi di runtime per impostarlo direttamente senza alcun codice.
Imposta il tuo percorso chiave sul pulsante in modo che sia "imageView.contentMode" con un tipo di "Numero" e un valore di "1" (o la modalità che preferisci).
Usa imageView del pulsante per contentMode. Non direttamente sul pulsante stesso.
homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];
Se metti l'immagine UIImageViewdietro il pulsante, perderai la funzionalità incorporata della UIButtonclasse, come adjustsImageWhenHighlightede adjustsImageWhenDisabled, e ovviamente la possibilità di impostare immagini diverse per stati diversi (senza il timore di farlo tu stesso).
Se vogliamo avere un'immagine senza strech per tutti gli stati di controllo , un approccio è ottenere l'immagine usando imageWithCGImage:scale:orientation, come nel seguente metodo:
- (UIImage *) getScaledImage:(UIImage *)img insideButton:(UIButton *)btn {
// Check which dimension (width or height) to pay respect to and
// calculate the scale factor
CGFloat imgRatio = img.size.width / img.size.height,
btnRatio = btn.frame.size.width / btn.frame.size.height,
scaleFactor = (imgRatio > btnRatio
? img.size.width / btn.frame.size.width
: img.size.height / btn.frame.size.height;
// Create image using scale factor
UIImage *scaledImg = [UIImage imageWithCGImage:[img CGImage]
scale:scaleFactor
orientation:UIImageOrientationUp];
return scaledImg;
}
Per implementare ciò scriveremmo:
UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];
Ciò dovrebbe impedire che l'immagine si allunghi in tutti gli stati di controllo. Ha funzionato per me, ma fammi sapere se non funziona!
NOTA: qui stiamo affrontando un problema relativo a UIButton, ma insideButton:potrebbe anche essere insideView:, o qualunque cosa a cui si vorrebbe adattare l'immagine.
Ho avuto questo problema tempo fa. Il problema che ho avuto è stato che stavo cercando di applicare questo effetto al pulsante UIB in background che è limitato e quindi significa che non puoi regolarlo facilmente.
Il trucco è impostarlo come un'immagine, quindi applicare la tecnica di @ ayreguitar e questo dovrebbe risolverlo!
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];
Questo ha funzionato per me
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
Grazie a @ayreguitar per il suo commento
Ecco una risposta alternativa in rapida:
myButton.imageView?.contentMode = .ScaleAspectFit
Combinando insieme alcune risposte diverse in un'unica soluzione: creare un pulsante con un tipo personalizzato, impostare la proprietà imageView contentMode del pulsante e impostare l'immagine per il pulsante (non l'immagine di sfondo, che verrà comunque ridimensionata per riempirsi).
//Objective-C:
UIImage *image = [UIImage imageNamed:"myImageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
//Swift:
let image = UIImage(named: "myImageName.png")
let button = UIButton(type: .custom)
button.imageView?.contentMode = .scaleAspectFit
button.setImage(image, for: .normal)
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
Questa risposta è basata sulla risposta di @ WernerAltewischer .
Per evitare di connettere il mio pulsante a un IBOutlet per eseguire il codice su di esso, ho sottoclassato la classe di UIButton:
// .h
@interface UIButtonWithImageAspectFit : UIButton
@end
// .m
@implementation UIButtonWithImageAspectFit
- (void) awakeFromNib {
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}
@end
Ora crea un pulsante personalizzato nel tuo xib e imposta la sua immagine (non l'immagine di sfondo):

Quindi, imposta la sua classe:

Hai finito!
Invece

dell'aspetto dell'immagine del tuo pulsante, ora l'adattamento è come previsto:

ios 12. È necessario aggiungere anche il contenuto Allineamento
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()
}
}
Le modalità di contenuto UIView si applicano al "contenuto" di CALayer corrispondente. Questo funziona per UIImageViews perché impostano il CALayercontenuto sul corrispondente CGImage.
drawRect: alla fine esegue il rendering nel contenuto del livello.
Un custom UIButton(per quanto ne so) non ha contenuto (i pulsanti di stile arrotondati-rect potrebbero essere renderizzati usando il contenuto). Il pulsante ha viste secondarie: lo sfondo UIImageView, l'immagine UIImageViewe il titolo UILabel. L'impostazione delle visualizzazioni contentModesecondarie può fare quello che vuoi, ma scherzare con la UIButtongerarchia delle visualizzazioni è un po 'un no-no.
Il cambiamento UIButton.imageView.contentModenon ha funzionato per me.
Ho risolto il problema impostando l'immagine sulla proprietà "Sfondo".
Puoi aggiungere un vincolo di rapporto se necessario
Questo si sovrappone a molte delle altre risposte, ma la soluzione per me è stata quella
contentModedel UIImageViewper il pulsante per .ScaleAspectFit- che può essere fatto sia nella “User Defined Runtime attributi” in Interface Builder (es. self.imageView.contentMode, numero, 1) o in un UIButtonsottoclasse;Simile a @Guillaume, ho creato una sottoclasse di UIButton come Swift-File. Quindi imposta la mia classe personalizzata in Interface Builder:
E qui il file Swift:
import UIKit
class TRAspectButton : UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .ScaleAspectFit
}
}
Ho avuto lo stesso problema, ma non sono riuscito a farlo funzionare (forse è un bug con l'SDK).
Alla fine, come soluzione alternativa, ho posizionato un UIImageViewpulsante dietro il mio pulsante e ho impostato le opzioni che volevo su quello, quindi ho semplicemente inserito uno spazio vuoto UIButtonsopra di esso.