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.
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.
Odpowiedzi:
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.
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).
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Ta metoda zadziałała dla mnie bardzo dobrze .:
W Xib wybierz przycisk i ustaw user defined runtime attributes:
self.imageView.contentModeNumber1
Używamy liczby, ponieważ nie możesz tam użyć enum. Ale UIViewContentModeScaleAspectFit jest równa 1.
extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
imageView.contentModedziałało na mnie!
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];
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.
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];
To zadziałało dla mnie
[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
Dziękuję @ayreguitar za komentarz
Oto szybka alternatywna odpowiedź:
myButton.imageView?.contentMode = .ScaleAspectFit
Łą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)
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
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):

Następnie ustaw jego klasę:

Jesteś skończony!
Zamiast tego

, dopasowanie obrazu przycisku jest teraz zgodne z oczekiwaniami:

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()
}
}
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.
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
To pokrywa się z wieloma innymi odpowiedziami, ale rozwiązaniem dla mnie było
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;Podobnie jak @Guillaume, utworzyłem podklasę UIButton jako plik Swift. Następnie ustaw moją klasę niestandardową w Interface Builder:
A tutaj plik Swift:
import UIKit
class TRAspectButton : UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.imageView?.contentMode = .ScaleAspectFit
}
}
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.