Autolayout - Wewnętrzny rozmiar UIButton nie zawiera wstawek tytułu
Jeśli mam UIButton ustawiony za pomocą autolayout, jego rozmiar ładnie dopasowuje się do jego zawartości.
Jeśli ustawię obraz jako button.image
, rozmiar instrinsic ponownie wydaje się to tłumaczyć.
Jeśli jednak poprawię titleEdgeInsets
przycisku, układ nie uwzględnia tego i zamiast tego obcina tytuł przycisku.
Jak mogę upewnić się, że wewnętrzna szerokość przycisku odpowiada wstawce?
Edit:
Używam "po": {]}
[self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
Celem jest dodanie pewnej separacji między obrazem a tekstem.
11 answers
Można rozwiązać ten problem bez konieczności nadpisywania metod lub ustawiania ograniczeń szerokości. Możesz to zrobić w interfejsie Builder w następujący sposób.
Wewnętrzna szerokość przycisku pochodzi od szerokości tytułu plus szerokości ikony oraz lewej i prawej zawartości wstawek krawędzi.
Jeśli przycisk ma zarówno obraz, jak i tekst, są one wyśrodkowane jako grupa, bez odstępów między nimi.
Jeśli dodasz lewą wstawkę zawartości, będzie ona obliczana względnie do tekstu, a nie do ikony tekst+.
Jeśli ustawisz ujemną lewą wstawkę obrazu, obraz zostanie wyciągnięty w lewo, ale nie ma to wpływu na ogólną szerokość przycisku.
Jeśli zostanie ustawiona ujemna lewa wstawka obrazu, rzeczywisty układ będzie używał połowy tej wartości. Aby uzyskać wstawkę -20 punktów w lewo, musisz użyć wartości wstawki -40 punktów w Builderze interfejsu.
Więc podajesz wystarczająco duży lewy wkład zawartości, aby utworzyć miejsce dla obu żądanych lewych wkładek i wewnętrzne wypełnienie między ikoną a tekstem, a następnie przesuń ikonę w lewo, podwajając żądaną ilość wypełnienia między ikoną a tekstem. Rezultatem jest przycisk z równymi wstawkami zawartości po lewej i prawej stronie oraz para tekstu i ikon, które są wyśrodkowane jako grupa, z określoną ilością wypełnień między nimi.
Niektóre przykładowe wartości:
// Produces a button with the layout:
// |-20-icon-10-text-20-|
// AutoLayout intrinsic width works as you'd desire.
button.contentEdgeInsets = UIEdgeInsetsMake(10, 30, 10, 20)
button.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 20:32:03
Możesz to uruchomić w Kreatorze interfejsów (bez pisania kodu), używając kombinacji negatywnego i pozytywnego tytułu oraz wstawek treści.
Aktualizacja: Xcode 7 ma błąd, w którym nie można wprowadzić wartości ujemnych w polu Wstaw Right
, ale można użyć kontrolki krokowej obok, aby zmniejszyć wartość. (Thanks Stuart)
Spowoduje to dodanie 8PT odstępu między obrazkiem a tytułem i zwiększy wewnętrzną szerokość przycisku o taką samą kwotę. Tak:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-22 10:01:51
Dlaczego nie przesłaniać metody intrinsicContentSize
w UIView? Na przykład:
- (CGSize) intrinsicContentSize
{
CGSize s = [super intrinsicContentSize];
return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right,
s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom);
}
To powinno powiedzieć systemowi autolayout, że powinien zwiększyć rozmiar przycisku, aby umożliwić wstawianie i pokazać pełny tekst. Nie mam własnego komputera, więc tego nie testowałem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 12:57:11
Nie sprecyzowałeś, jak ustawiasz wstawki, więc zgaduję, że używasz titleEdgeInsets, ponieważ widzę ten sam efekt, który otrzymujesz. Jeśli używam contentEdgeInsets zamiast tego działa poprawnie.
- (IBAction)ChangeTitle:(UIButton *)sender {
self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
[self.button setTitle:@"Long Long Title" forState:UIControlStateNormal];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-23 03:06:26
Ten wątek jest trochę stary, ale sam na to wpadłem i byłem w stanie rozwiązać go za pomocą negatywnego wstawki. Na przykład, zastąp żądane wartości wypełnienia tutaj:
UIButton* myButton = [[UIButton alloc] init];
// setup some autolayout constraints here
myButton.titleEdgeInsets = UIEdgeInsetsMake(-desiredBottomPadding,
-desiredRightPadding,
-desiredTopPadding,
-desiredLeftPadding);
W połączeniu z odpowiednimi ograniczeniami autolayout, kończysz z przyciskiem automatycznej zmiany rozmiaru, który zawiera obraz i tekst! Zobacz poniżej z desiredLeftPadding
ustawionym na 10.
Przycisk z obrazkiem i krótkim tekstem
Przycisk z obrazkiem i długim tekstem
Widać, że rzeczywisty ramka przycisku nie obejmuje etykiety (ponieważ etykieta jest przesunięta o 10 punktów w prawo, poza granice), ale osiągnęliśmy 10 punktów wypełnienia między tekstem a obrazem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-18 02:50:58
I dla Swift pracował to:
extension UIButton {
override open var intrinsicContentSize: CGSize {
let intrinsicContentSize = super.intrinsicContentSize
let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom
return CGSize(width: adjustedWidth, height: adjustedHeight)
}
}
Love U Swift
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-29 02:18:21
Wszystko powyżej nie działało dla iOS 9+, to co zrobiłem to:
- Dodaj ograniczenie szerokości (dla minimalnej szerokości, gdy przycisk nie ma żadnego tekstu. Przycisk będzie automatycznie skalowany, jeśli zostanie podany tekst)
- Ustaw relację na większą lub równą
Teraz, aby dodać obramowanie wokół przycisku, użyj metody:
button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-07 12:43:30
Dla Swift 3 na podstawie pegpeg ' s odpowiedź:
extension UIButton {
override open var intrinsicContentSize: CGSize {
let intrinsicContentSize = super.intrinsicContentSize
let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom
return CGSize(width: adjustedWidth, height: adjustedHeight)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 13:24:06
Opcja jest również dostępna w interface builder. Zobacz też Ustawiłem lewo i prawo na 3. Działa jak urok.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-03 14:26:02
Chciałem dodać odstęp 5pt pomiędzy ikoną UIButton a etykietą. Tak to osiągnąłem:
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
// more button config etc
infoButton.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 5);
infoButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5);
Sposób, w jaki contentEdgeInsets, titleEdgeInsets i imageEdgeInsets odnoszą się do siebie, wymaga trochę dawania i brania od każdego wstawki. Więc jeśli dodasz jakieś wstawki do tytułu po lewej stronie, musisz dodać wstawkę negatywną po prawej stronie i zapewnić trochę więcej miejsca (poprzez wstawkę pozytywną) NA treści po prawej stronie.
Poprzez dodanie odpowiedniego wstawki treści, aby dopasować przesunięcie tytułu Wstaw mój tekst nie wychodzi poza granice przycisku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-19 07:36:46
Rozwiązaniem, którego używam, jest dodanie ograniczenia szerokości na przycisku. Następnie gdzieś w inicjalizacji, po ustawieniu tekstu, zaktualizuj ograniczenie szerokości w następujący sposób:
self.buttonWidthConstraint.constant = self.shareButton.intrinsicContentSize.width + 8;
Gdzie 8 jest tym, czym jest twoja wstawka.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-29 06:00:23