Jeśli mam UIButton ustawiony za pomocą autolayout, jego rozmiar ładnie dostosowuje się do zawartości.
Jeśli button.image
ustawię obraz jako , rozmiar instruktażowy ponownie wydaje się to uwzględniać.
Jeśli jednak poprawię titleEdgeInsets
przycisk, układ nie bierze tego pod uwagę i zamiast tego obcina tytuł przycisku.
Jak mogę się upewnić, że wewnętrzna szerokość przycisku odpowiada wstawce?
Edytować:
Używam następujących:
[self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
Celem jest dodanie pewnej separacji między obrazem a tekstem.
ios
cocoa-touch
uiview
uibutton
autolayout
Ben Packard
źródło
źródło
titleEdgeInset
dokumentacji:The insets you specify are applied to the title rectangle after that rectangle has been sized to fit the button’s text. Thus, positive inset values may actually clip the title text.
Dodając wstawkę, na pewnoOdpowiedzi:
Możesz rozwiązać ten problem bez konieczności zastępowania jakichkolwiek metod lub ustawiania dowolnego ograniczenia szerokości. Możesz to zrobić w Konstruktorze interfejsów w następujący sposób.
Wewnętrzna szerokość przycisku pochodzi od szerokości tytułu plus szerokość ikony oraz wstawki lewej i prawej krawędzi treści .
Jeśli przycisk zawiera zarówno obraz, jak i tekst, są one wyśrodkowane jako grupa, bez odstępów między nimi.
Jeśli dodasz lewą wstawkę treści, jest ona obliczana względem tekstu, a nie tekstu + ikony.
Po ustawieniu ujemnego wstawki lewego obrazu obraz zostanie wyciągnięty w lewo, ale ogólna szerokość przycisku nie ulegnie zmianie.
Jeśli ustawisz wstawkę ujemnego lewego obrazu, rzeczywisty układ wykorzystuje połowę tej wartości. Tak więc, aby uzyskać wstawkę o wartości -20 punktów w lewo, musisz użyć wartości wstawki o wartości -40 punktów w Konstruktorze interfejsu.
Zapewniasz więc wystarczająco dużą lewą wstawkę zawartości, aby stworzyć miejsce zarówno na pożądaną lewą wstawkę, jak 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 lewymi i prawymi wstawkami treści oraz parę tekstu i ikon, które są wyśrodkowane jako grupa, z określoną ilością dopełnienia między nimi.
Niektóre przykładowe wartości:
źródło
UIButton
.Możesz sprawić, by działało to w Konstruktorze interfejsów (bez pisania kodu), używając kombinacji ujemnych i dodatnich wstawek tytułu i zawartości.
Aktualizacja : Xcode 7 zawiera błąd, w którym nie można wprowadzić wartości ujemnych w polu
Right
Wypełnienie, ale można użyć kontrolki krokowej obok niego, aby zmniejszyć wartość. (Dzięki Stuart)Spowoduje to dodanie 8 punktów odstępu między obrazem a tytułem i zwiększy wewnętrzną szerokość przycisku o tę samą wartość. Lubię to:
źródło
Right
polu.Dlaczego nie zastąpić
intrinsicContentSize
metody w UIView? Na przykład:Powinno to powiedzieć systemowi autoukładu, że powinien zwiększyć rozmiar przycisku, aby umożliwić wstawki i wyświetlić pełny tekst. Nie mam własnego komputera, więc tego nie przetestowałem.
źródło
intrinsicContentSize
jest metodą na UIView, a nie UIButton, więc nie będziesz bałaganu w żadnej z metod UIButton. Apple nie uważa, że to problem: „Przesłonięcie tej metody pozwala niestandardowemu widokowi komunikować się z układem układu o tym, jaki rozmiar chciałby być oparty na jego zawartości”. I OP nie powiedział nic o różnych przyciskach, tylko o jednym.intrinsicContentSize
jest rzeczywiście metodą UIView, a UIButton jest podklasą UIView, więc oczywiście można zastąpić tę metodę; nic w dokumentach Apple'a nie mówi, że nie powinieneś. Po prostu stwórz podklasę UIButton przy użyciu przesłoniętej metody Maarten i zmień UIButton w Konstruktorze interfejsów, aby był typu Twoja UIButtonSubclass i będzie działał idealnie.intrinsicContentSize
że UIButton powinien dodać w titleEdgeInsets, zamierzam zgłosić błąd w Apple.Nie określiłeś, w jaki sposób ustawiasz wstawki, więc domyślam się, że używasz titleEdgeInsets, ponieważ widzę ten sam efekt, który otrzymujesz. Jeśli zamiast tego użyję contentEdgeInsets, działa to poprawnie.
źródło
I dla Swift działało to:
Love U Swift
źródło
Ten wątek jest trochę stary, ale sam na niego wpadłem i byłem w stanie go rozwiązać za pomocą ujemnej wstawki. Na przykład zastąp tutaj żądane wartości wypełnienia:
W połączeniu z odpowiednimi ograniczeniami autoukładu otrzymujesz przycisk zmiany rozmiaru, który zawiera obraz i tekst! Patrz poniżej z
desiredLeftPadding
ustawieniem na 10.Widać, że rzeczywista ramka przycisku nie obejmuje etykiety (ponieważ etykieta jest przesunięta o 10 punktów w prawo, poza granicami), ale osiągnęliśmy 10 punktów wypełnienia między tekstem a obrazem.
źródło
W przypadku Swift 3 opartego na odpowiedzi Pegpeg :
źródło
Wszystkie powyższe nie działały na iOS 9+ , co zrobiłem to:
Teraz, aby dodać ramkę wokół przycisku, po prostu użyj metody:
źródło
Chciałem dodać 5-punktową spację między ikoną UIButton a etykietą. Oto jak to osiągnąłem:
Sposób, w jaki contentEdgeInsets, titleEdgeInsets i imageEdgeInsets odnoszą się do siebie, wymaga trochę dawania i odbierania z każdej wstawki. Więc jeśli dodasz trochę wstawek po lewej stronie tytułu, musisz dodać ujemną wstawkę po prawej stronie i zapewnić trochę więcej miejsca (poprzez dodatnią wstawkę) po prawej stronie zawartości.
Dodając odpowiednią wstawkę treści, aby pasowała do przesunięcia wstawek tytułu, mój tekst nie wykracza poza granice przycisku.
źródło
Ta opcja jest również dostępna w narzędziu do tworzenia interfejsów. Zobacz wstawkę. Ustawiłem lewą i prawą na 3. Działa jak urok.
źródło
Rozwiązaniem, którego używam, jest dodanie ograniczenia szerokości przycisku. Następnie gdzieś podczas 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.
źródło
constant
ograniczenie do nowej wartości ... i wiedzieć, kiedy rozmiar zawartości zmiany przycisku jest trudny bez podklasowania przycisku.setNeedsUpdateConstraints
można wykonać „ręcznie” po zaktualizowaniu tytułu lub obrazu przycisku. Następnie możesz zastąpićupdateConstraints
i ponownie obliczyćbuttonWidthConstraint
stałą. To niekoniecznie najlepsze podejście, ale działa wystarczająco dobrze dla mnie. YMMV;)wywołanie sizeToFit () zapewnia, że contentEdgeInset zostanie zastosowany
źródło