Il pulsante UIB non andrà su Aspect Fit su iPhone


105

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.


La risposta di @Werner Altesischer è quella giusta. Apporta le modifiche appropriate.
Harshit Gupta

1
@marty Stai impostando un'immagine di sfondo o un'immagine? l'immagine di sfondo non lo supporta, solo l'immagine.
Juan Boero

Risposte:


45

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.


Sì, l'ho provato, ma ora non riesco a ottenere il pulsante per riattaccare l'immagine
martedì

Come gestisci gli stati dei pulsanti con questa tecnica? Sembra che rispondere all'interazione dell'utente come "evidenziato" sarebbe un incubo.
SooDesuNe

3
Questo potrebbe essere stato il modo giusto per farlo 2,5 anni fa, quando è stata data risposta a questa domanda, ma ora puoi modificare l'ImageView interna di UIButton e impostare la modalità del contenuto lì. Vedi la risposta di @Werner Altewischer
Steve Haley

233

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à).


67
Questo ha funzionato per me:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar

2
Questo funziona anche per me, ma se imposto AdjustsImageWhenHighlighted = YES, l'immagine viene allungata di nuovo quando tocco il pulsante.
cduck

1
L'allungamento in AdjustsImage è stato eliminato in iOS 6.
Ben Flynn

3
In iOS 8, questo in realtà non funziona per me. La risposta originale (posizionando un'immagine ImageView dietro un pulsante trasparente) funziona meglio.
user1416564

3
in Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor

57

Questo metodo ha funzionato molto bene per me .:

In Xib selezionare il pulsante e impostare user defined runtime attributes:

  • Percorso chiave: self.imageView.contentMode
  • Genere: Number
  • Valore: 1

Clicca qui per vedere più chiaramente la soluzione

Usiamo number perché non puoi usare enum lì. Ma UIViewContentModeScaleAspectFit è uguale a 1.


2
Questo ha anche aggiornato l'immagine nel generatore di interfacce durante la fase di progettazione. Ottima soluzione.
George Filippakos

Ottima soluzione, poco codice e funziona come un fascino, l'enumerazione si basa sugli elementi dell'elenco in modalità contenuto.
Kross

Puoi anche aggiungere un'estensione per renderlo un po 'più semplice: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat

Senza "sé" ha imageView.contentModefunzionato per me!
byJeevan

22

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

imageview.contentMode = 1


14

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];

6

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.


6

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];

4

Questo ha funzionato per me

[button.imageView setContentMode:UIViewContentModeScaleAspectFit];

Grazie a @ayreguitar per il suo commento


4

Ecco una risposta alternativa in rapida:

myButton.imageView?.contentMode = .ScaleAspectFit

4

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)

3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;

Sebbene questo snippet di codice possa risolvere la domanda, includere una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. - Dalla recensione
Ferrybig

2

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

UIButtonWithImageAspectFit: crea e imposta l'immagine


Quindi, imposta la sua classe:

UIButtonWithImageAspectFit: imposta la classe personalizzata

Hai finito!
Invece
Pulsante UIB senza adattamento aspetto immagine
dell'aspetto dell'immagine del tuo pulsante, ora l'adattamento è come previsto:
Pulsante UIB con adattamento aspetto immagine


2

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


    }

}

1

Ho avuto problemi con l'immagine che non si ridimensionava proporzionalmente, quindi il modo in cui l'ho risolta era usando gli inserti sui bordi.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

1

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.


1

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


1

Questo si sovrappone a molte delle altre risposte, ma la soluzione per me è stata quella

  • impostare il 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;
  • disabilitare "Autoresize Subviews";
  • imposta "Bordo" su "Immagine" e i valori "Alto" e "Basso" appropriati per "Inset" (che potrebbe essere necessario solo se tu, come me, hai utilizzato un PDF come immagine).

0

Puoi usare imageWithCGImage come mostrato sopra (ma senza le parentesi mancanti).

Inoltre ... milioni di telefoni non 4.0 non funzioneranno affatto con quel codice.


0

[button sizeToFit] ha funzionato per me.


0

Simile a @Guillaume, ho creato una sottoclasse di UIButton come Swift-File. Quindi imposta la mia classe personalizzata in Interface Builder:

costruttore di interfacce.

E qui il file Swift:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}

-1

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.


7
C'è un'eco qui? ;-)
Dan Ray
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.