UIButton non ascolta l'impostazione della modalità contenuto?


91

firstButton è un UIButton di tipo Custom. Sto inserendo programmaticamente tre di loro in ogni cella di una tabella, quindi:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

Altrove, gli sto dicendo di clipToBounds. Quello che ottengo è un ritaglio del quadrato centrale dell'immagine, piuttosto che un rendering in scala proporzionale di esso. Ho provato in molti modi, inclusa l'impostazione della proprietà mode su firstButton.imageView, che inoltre non sembra funzionare.


1
Vedere la soluzione di Chris Nolet di seguito: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

Vedi stackoverflow.com/a/28205566/481207 che mostra che l'impostazione sia di contentVerticalAlignment che di contentHorizontalAlignment è richiesta per UIViewContentModeScaleAspectFit.
Matt

Risposte:


186

Ho avuto lo stesso problema. Vedo che questa domanda è un po 'vecchia, ma voglio fornire una risposta chiara e corretta per salvare altre persone (come me) un po' di tempo quando compare nei loro risultati di ricerca.

Mi ci è voluto un po 'di ricerca e sperimentazione, ma ho trovato la soluzione. È sufficiente impostare il ContentMode dell'ImageView "nascosto" che si trova all'interno del pulsante UIB.

[[firstButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[firstButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

Forse è a questo che alludeva Dan Ray nella sua risposta accettata, ma sospetto di no.


1
No, non lo era. La soluzione su cui ho deciso è stata utilizzare un UIImageView per contenere l'immagine, quindi un pulsante UIB chiaro e trasparente di tipo "personalizzato" sopra di essa.
Dan Ray

Dave, almeno su iOS 3.2, la tua soluzione non sembra funzionare per me. Peccato, perché speravo di ottenere l'evidenziazione dell'immagine su click "gratuitamente". Mi sono anche assicurato che button.imageView non fosse nullo dove stavo impostando contentMode e ho impostato l'immagine dopo aver impostato contentMode, proprio come stai facendo.
Jacques

2
Giusto per chiarire, "non funziona" significa "l'immagine è mostrata alla sua piena risoluzione, non ridimensionata come speravo".
Jacques

Jacques, quanto sopra funziona per me in iOS 4.x. Sfortunatamente, posso riprodurre il problema "non ridimensionare" quando creo con un target v3.2. Ho provato a cambiare la dimensione del frame della vista UIButton, ma neanche questo sembrava aiutare. ugh.
Dave

4
Vedere la soluzione di Chris Nolet di seguito: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

74

Se hai a che fare con l'immagine di UIButton (al contrario della sua backgroundImage), l'impostazione di contentMode sull'UIButton stesso o sulla sua imageView non ha alcun effetto (nonostante ciò che dicono le altre risposte).

In alternativa, fai questo invece:

self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
self.button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

Oppure ridimensiona l'immagine di conseguenza.

OPPURE usa semplicemente un UIImageView (che rispetta adeguatamente contentMode) con un UITapGestureRecognizer allegato o un UIButton trasparente sopra di esso.


4
Questo funziona per il mio caso in iOS 7 mentre tutti gli altri qui no.
Byte

5
L'impostazione di contentHorizontalAlignment e contentVerticalAlignment è la soluzione corretta. Vedi stackoverflow.com/a/28205566/481207 per una spiegazione.
Matt

1
Questa è la risposta che stavo cercando.
Ninjaneer

4
Questa risposta non è corretta. È Non è necessario impostare contentModesul imageViewse si vuole fare qualsiasi tipo di riempimento aspetto o forma, come altre risposte hanno chiarito. Fare riferimento a: stackoverflow.com/a/7944316/746890 .
Chris Nolet

50

Invece di impostare il contentModesul pulsante stesso, ti consigliamo di serie contentHorizontalAlignmente contentVerticalAlignmentle proprietà e (cruciale) il contentModeper il pulsante di imageViewper qualsiasi tipo di riempimento aspetto o forma. Ecco un esempio:

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Naturalmente, puoi anche fare altre cose come allineare l'immagine del pulsante alla parte superiore del pulsante. Se non hai bisogno di un riempimento o adattamento dell'aspetto, puoi semplicemente impostare l'allineamento da solo:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

In Swift, ti consigliamo di utilizzare:

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

Funziona con tutte le versioni di iOS, comprese le ultime versioni con layout automatico (ad es. Da iOS 4 a iOS 11+).


2
Grazie Chris - questo ha risolto il mio problema, o meglio, lo ha fatto in combinazione con contentEdgeInsets, al fine di sostenere leggermente la mia immagine dal bordo superiore.
Rob Reuss

7

Dopo un paio d'ore di confusione, ecco come l'ho fatto funzionare con iOS 3.2. Come ha detto Dusker, l'uso di setBackgroundImage invece di setImage ha fatto il lavoro per me.

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];

6

La risposta è usare un UIImageView con tutte le deliziose impostazioni della modalità contenuto che desideri, quindi sovrapporre un pulsante personalizzato sopra di esso. Stupido che non puoi fare tutto in un colpo, ma sembra che non puoi.


4

Ho trovato una soluzione per questo. Imposta la adjustsImageWhenHighlightedproprietà di UIButtona NO.

  UIButton *b = [[UIButton alloc] initWithFrame:rect];
        [b setImage:image forState:UIControlStateNormal];
        [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
        [b setAdjustsImageWhenHighlighted:NO];

Spero che questo ti aiuti. Sentiti libero di commentare qui sotto, seguirò tutte le tue domande.


Questa è la soluzione perfetta.
Gaurav

Non funziona Ciò impedisce semplicemente che il pulsante venga evidenziato.
Matt

4

La mia risposta è simile a quella di Kuba. Avevo bisogno che la mia immagine venisse impostata programmaticamente.

UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
for(UIView *view in button.subviews) {
    view.contentMode = UIViewContentModeScaleAspectFill;
}

3

L'unica soluzione che ha funzionato per me:

[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;


1

Invece di setImage prova setBackgroundImage


3
Hmp. A, è stupido, dovrebbe rispettare l'impostazione della MODALITÀ CONTENUTO per il suo CONTENUTO, giusto? E B, ANCORA non sembra rispettare l'impostazione della modalità: ora è bloccato su "stretch" (che è, in questo caso, più simile a "squeeze") e non sta ridimensionando il contenuto rispetto al suo aspetto rapporto.
Dan Ray

1

Credo che qui abbiamo un semplice problema di creazione dell'interfaccia: a quanto pare l'IB ignora qualsiasi modifica alla modalità di contenuto DOPO aver impostato la proprietà dell'immagine.

la soluzione è semplice: imposta la modalità contenuto, rimuovi i nomi delle immagini precedentemente impostati (assicurati di rimuoverli in tutti gli stati, predefinito, evidenziato ecc.), quindi reinserisci i nomi delle immagini desiderati in tutti gli stati desiderati - et voilà .


1
lo stesso vale per impostare la modalità contenuto a livello di programmazione - non impostare l'immagine PRIMA di impostare la modalità contenuto
JohnPayne

0

Consiglio anche di dare un'occhiata alla adjustsImageWhenHighlighted UIButtonproprietà per evitare strane deformazioni dell'immagine, quando si preme il pulsante.


0

Nel tentativo di capirlo, il mio metodo è diventato un po 'più hacker col passare del tempo, e ho finito per sottoclassare UIButton e sovrascrivere setHighlighted:

Per me funziona semplicemente abbattere l'immagine alfa a 0,5, perché sono su uno sfondo nero.

Tuttavia, funziona solo se commento [super setHighlighted:] (dove sembra che il codice elastico per l'immagine sia attivo), il che non sembra proprio il modo giusto per risolverlo ... tutto sembra essere funziona bene, però. Vedremo come regge mentre continuo a lavorarci.

- (void)setHighlighted:(BOOL)highlight {
    if (highlight) {
        [self.imageView setAlpha:.5];
    }  else {
        [self.imageView setAlpha:1];        
    }

//    [super setHighlighted:highlight];
}

1
Nella remota possibilità che qualcuno lo trovasse pertinente, il mio metodo sopra sembrava funzionare bene fino a quando non ho inserito i pulsanti su un UIScrollView, dove a volte l'evidenziazione del pulsante si è "bloccata", che è quello che sospettavo potesse accadere alla fine.
jankins

0

Se qualcuno cerca una risposta che funziona su iOS 6 e iOS 7 e storyboard:

Puoi impostare l'immagine nel tuo storyboard:

inserisci qui la descrizione dell'immagine

E poi:

for(UIView* testId in self.subviews) {
    if([testId isKindOfClass:[UIImageView class]])
        [testId setContentMode:UIViewContentModeScaleAspectFill];
}

0

Se il pulsante UIB non sembra ascoltare le impostazioni dei vincoli di layout, controllare se le immagini sono più grandi della dimensione del pulsante. Usa sempre le immagini @ 2x e @ 3x per le risoluzioni della retina.


0

Queste due cose (che inizialmente sono piuttosto difficili da trovare) allungheranno l'immagine del tuo UIButton per adattarla alle dimensioni del pulsante:

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

si dovrebbe sempre provare a impostarlo nello Storyboard piuttosto che nel codice.

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.