UIButton nie przejdzie do Aspect Fit na iPhonie

105

Mam kilka przycisków UIB, aw IB są ustawione na Aspect Fit, ale z jakiegoś powodu zawsze się rozciągają. Czy jest coś jeszcze, co musisz ustawić? Wypróbowałem wszystkie różne tryby widoku i żaden z nich nie działa, wszystkie są rozciągane.

marty
źródło
Odpowiedź @Werner Altesischer jest właściwa. Wprowadź odpowiednie zmiany.
Harshit Gupta
1
@marty Czy ustawiasz obraz tła czy obraz? obraz tła nie obsługuje tego, tylko obraz.
Juan Boero

Odpowiedzi:

45

Miałem ten problem wcześniej. Rozwiązałem to, umieszczając mój obraz w miejscu UIImageView, w którym contentModeustawienia faktycznie działają, i dodając do tego przezroczysty niestandardowy element UIButton.

EDYCJA: Ta odpowiedź jest przestarzała. Zobacz odpowiedź @Werner Altewischer, aby uzyskać poprawną odpowiedź w nowoczesnych wersjach iOS.

Dan Ray
źródło
Tak, próbowałem, ale teraz nie mogę dostać przycisku do ponownego dopasowania do obrazu
marty
Jak zarządzasz stanami przycisków za pomocą tej techniki? Wydaje się, że odpowiadanie na interakcje użytkownika, takie jak „wyróżnienie”, byłoby koszmarem.
SooDesuNe
3
To mógł być właściwy sposób, aby to zrobić 2,5 roku temu, kiedy udzielono odpowiedzi na to pytanie, ale teraz możesz edytować wewnętrzny ImageView UIButton i ustawić tam tryb zawartości. Zobacz odpowiedź @Werner Altewischer
Steve Haley,
233

Rozwiązaniem jest ustawienie contentModewe imageViewwłaściwości UIButton. Aby UIButtonto działało, należy utworzyć z typem niestandardowym (w przeciwnym razie niljest zwracany dla tej właściwości).

Werner Altewischer
źródło
67
To zadziałało dla mnie:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar
2
Działa to również w moim przypadku, ale jeśli ustawię adjustsImageWhenHighlighted = YES, obraz zostanie ponownie rozciągnięty po dotknięciu przycisku.
cduck
1
Rozciąganie w adjustsImage zostało wyeliminowane w iOS 6.
Ben Flynn,
3
W iOS 8 to właściwie nie działa dla mnie. Oryginalna odpowiedź (z umieszczeniem imageView za przezroczystym przyciskiem) działa najlepiej.
user1416564
3
w Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor
57

Ta metoda zadziałała dla mnie bardzo dobrze .:

W Xib wybierz przycisk i ustaw user defined runtime attributes:

  • Kluczowa ścieżka: self.imageView.contentMode
  • Rodzaj: Number
  • Wartość: 1

Kliknij tutaj, aby zobaczyć bardziej przejrzyste rozwiązanie

Używamy liczby, ponieważ nie możesz tam użyć enum. Ale UIViewContentModeScaleAspectFit jest równa 1.

István Stefánovics
źródło
2
To również zaktualizowało obraz w konstruktorze interfejsu w czasie projektowania. Świetne rozwiązanie.
George Filippakos
Świetne rozwiązanie, mało kodu i działa jak urok, wyliczenie jest oparte na elementach listy trybu zawartości.
Kross
Możesz także dodać rozszerzenie, aby było to nieco łatwiejsze: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat
Bez „siebie” imageView.contentModedziałało na mnie!
Jeevan,
22

Jeśli robisz to w Interface Builder, możesz użyć Inspektora atrybutów środowiska wykonawczego, aby ustawić to bezpośrednio, bez żadnego kodu.

Ustaw ścieżkę klucza na przycisku na „imageView.contentMode” z typem „Number” i wartością „1” (lub w innym trybie, który chcesz).

imageview.contentMode = 1

averydev
źródło
14

Użyj imageView przycisku dla contentMode. Nie bezpośrednio na samym przycisku.

homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];
Ahmed Elashker
źródło
6

Jeśli umieścisz obraz w miejscu UIImageViewza przyciskiem, stracisz wbudowaną funkcjonalność UIButtonklasy, taką jak adjustsImageWhenHighlightedi adjustsImageWhenDisabled, oraz oczywiście możliwość ustawiania różnych obrazów dla różnych stanów (bez mglistego robienia tego samodzielnie).

Jeśli chcemy, aby obraz był nierozciągnięty dla wszystkich stanów kontrolnych , jednym zatwierdzeniem jest pobranie obrazu za pomocą imageWithCGImage:scale:orientation, jak w poniższej metodzie:

- (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;
}

Aby to zrealizować, napisalibyśmy:

UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];

Powinno to zapobiec rozciągnięciu obrazu we wszystkich stanach kontrolnych. U mnie zadziałało, ale daj mi znać, jeśli nie!

UWAGA: tutaj zajmujemy się problemem związanym z UIButton, ale insideButton:równie dobrze może być insideView:lub cokolwiek chciałoby się dopasować do obrazu.

Alexander Wallin
źródło
6

Miałem ten problem jakiś czas temu. Problem polegał na tym, że próbowałem zastosować ten efekt do przycisku UIButton w tle, który jest ograniczony i dlatego nie można go tak łatwo dostosować.

Sztuczka polega na tym, aby ustawić go jako zwykły obraz, a następnie zastosować technikę @ ayreguitar i to powinno to naprawić!

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];
Joe Barbour
źródło
4

To zadziałało dla mnie

[button.imageView setContentMode:UIViewContentModeScaleAspectFit];

Dziękuję @ayreguitar za komentarz

Karan Alangat
źródło
4

Oto szybka alternatywna odpowiedź:

myButton.imageView?.contentMode = .ScaleAspectFit
João Neves
źródło
4

Łącząc razem kilka różnych odpowiedzi w jedno rozwiązanie - utwórz przycisk o niestandardowym typie, ustaw właściwość imageView contentMode przycisku i ustaw obraz dla przycisku (nie obraz tła, który nadal będzie skalowany do wypełnienia).

//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)
Oszust
źródło
3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
selaband
źródło
Chociaż ten fragment kodu może rozwiązać problem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod. - Z recenzji
Ferrybig
2

Ta odpowiedź jest oparta na odpowiedzi @ WernerAltewischer .

Aby uniknąć podłączenia mojego przycisku do IBOutlet w celu wykonania na nim kodu, podklasowałem klasę UIButton:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

- (void) awakeFromNib {
    [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}

@end



Teraz utwórz niestandardowy przycisk w swoim xib i ustaw jego obraz (nie obraz tła):

UIButtonWithImageAspectFit: utwórz i ustaw obraz


Następnie ustaw jego klasę:

UIButtonWithImageAspectFit: ustaw niestandardową klasę

Jesteś skończony!
Zamiast tego
UI Przycisk bez dopasowania proporcji obrazu
, dopasowanie obrazu przycisku jest teraz zgodne z oczekiwaniami:
UIButton z dopasowaniem proporcji obrazu

Guillaume
źródło
2

ios 12. Musisz także dodać wyrównanie zawartości

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


    }

}
João Nunes
źródło
1

Miałem problemy z nieproporcjonalną zmianą rozmiaru obrazu, więc sposób, w jaki go naprawiłem, polegał na użyciu wstawek krawędziowych.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
ninjaneer
źródło
1

Tryby zawartości UIView mają zastosowanie do odpowiedniej „zawartości” CALayera. Działa to w przypadku UIImageViews, ponieważ ustawiają CALayertreść na odpowiednie CGImage.

drawRect: ostatecznie renderuje do zawartości warstwy.

Niestandardowy UIButton(o ile wiem) nie ma zawartości (przyciski w stylu zaokrąglonego prostokąta mogą być renderowane przy użyciu zawartości). Przycisk ma podglądy: tło UIImageView, obraz UIImageViewi tytuł UILabel. UstawianiecontentMode podrzędnego może zrobić, co chcesz, ale majstrowanie przy UIButtonhierarchii widoków jest trochę niemożliwe.

tc.
źródło
1

Zmiana UIButton.imageView.contentModenie działa na mnie.
Rozwiązałem problem, ustawiając obraz na właściwość „Tło”.
W razie potrzeby możesz dodać ograniczenie współczynnika

Soohwan Park
źródło
1

To pokrywa się z wieloma innymi odpowiedziami, ale rozwiązaniem dla mnie było

  • ustaw contentModez UIImageViewna przycisku do .ScaleAspectFit- który może być sporządzona w „Użytkownika Runtime Atrybuty” w konstruktorze Interface (tj. self.imageView.contentMode, liczba, 1) lub w UIButtonpodklasie;
  • wyłącz „Autoresize Subviews”;
  • ustaw „Krawędź” na „Obraz” i odpowiednie wartości „Góra” i „Dół” dla „Wstawki” (co może być potrzebne tylko wtedy, gdy tak jak ja użyłeś pliku PDF jako obrazu).
plindberg
źródło
0

Możesz użyć imageWithCGImage, jak pokazano powyżej (ale bez brakujących nawiasów).

Ponadto ... miliony telefonów innych niż 4.0 nie będą w ogóle działać z tym kodem.

Alice
źródło
0

[button sizeToFit] pracował dla mnie.

Hila
źródło
0

Podobnie jak @Guillaume, utworzyłem podklasę UIButton jako plik Swift. Następnie ustaw moją klasę niestandardową w Interface Builder:

konstruktor interfejsu.

A tutaj plik Swift:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}
Motine
źródło
-1

Miałem ten sam problem, ale nie mogłem go uruchomić (być może jest to błąd w SDK).

Ostatecznie, jako obejście, umieściłem UIImageViewza moim przyciskiem i ustawiłem opcje, które chciałem, a następnie po prostu umieściłem na nim puste UIButtonmiejsce.

Anshu Chimala
źródło
7
Czy jest tu echo? ;-)
Dan Ray