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 contentMode
impostazioni funzionano effettivamente, e aggiungendo una personalizzazione trasparente UIButton
sopra.
EDIT: questa risposta è obsoleta. Vedi la risposta di @Werner Altewischer per la risposta corretta nelle versioni moderne di iOS.
La soluzione è impostare il contentMode
sulla imageView
proprietà del UIButton
. La UIButton
deve essere creato con il tipo personalizzato per far funzionare tutto questo credo (altrimenti nil
viene 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.contentMode
Number
1
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.contentMode
funzionato 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 UIImageView
dietro il pulsante, perderai la funzionalità incorporata della UIButton
classe, come adjustsImageWhenHighlighted
e 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 UIImageView
s perché impostano il CALayer
contenuto 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 UIImageView
e il titolo UILabel
. L'impostazione delle visualizzazioni contentMode
secondarie può fare quello che vuoi, ma scherzare con la UIButton
gerarchia delle visualizzazioni è un po 'un no-no.
Il cambiamento UIButton.imageView.contentMode
non 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
contentMode
del UIImageView
per 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 UIButton
sottoclasse;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 UIImageView
pulsante dietro il mio pulsante e ho impostato le opzioni che volevo su quello, quindi ho semplicemente inserito uno spazio vuoto UIButton
sopra di esso.