2013-07-31 10 views
10

Mam UIView zawierający UIButton. UIButton ma 2 tytuły ustawione dla stanów UIControlStateNormal ("Follow") i UIControlStateSelected ("Follow"). Używam automatycznego układu na Uibuttonie i ma ograniczenie, aby być pewną odległością od górnej części podglądu, a inną, aby być pewną odległością od lewej strony superview. Użyłem też na nim "Rozmiar pasujących treści".Rozmiar wewnętrzny nie aktualizuje się po zmianie stanu UIButton

Po ustawieniu przycisku na wybrany stan z kodu, tytuł zmienia się poprawnie, ale wewnętrzna szerokość UIButtonu nie zmienia się, więc po zmianie z "Śledź" na "Po" tekst ulega elipsyzacji.

self.selected = self.following; 

enter image description hereenter image description here

Kiedy podejść do problemu inaczej i po prostu zmienić tekst UIControlStateNormal gdy ktoś kliknie przycisk, przycisk zmienia rozmiar poprawnie.

NSString *title = (self.following) ? @"Following" : @"Follow" 
[self setTitle:title forState:UIControlStateNormal]; 

enter image description hereenter image description here

Jest to błąd w UIKit? Spodziewam się, że przycisk zmieni swój wewnętrzny rozmiar, aby poprawnie odzwierciedlić nowy rozmiar tekstu, gdy jego stan się zmienia, szczególnie, że są inne rzeczy, które chciałbym zmienić oprócz samego tekstu dla stanów 2 przycisków.

Odpowiedz

21

jak David Caunt wskazano w komentarzu, nazywając invalidateIntrinsicContentSize spowoduje autolayout zmienić rozmiar przycisku, aby zmieścił się nowa treść .

self.selected = self.following; 
[self invalidateIntrinsicContentSize]; 

PS. David, jeśli chcesz zamieścić swojego komandora jako odpowiedź, usunę mój.

+1

Czy ktoś próbował tego już późno (iOS 8.2+)? Jedyne bezpośrednie rozwiązanie, które działa dla mnie to setTitle @ abdullaha: forState. Próbowałem również podążać za tą linią z layoutIfNeeded. –

+0

aby być kompletnym i kompatybilnym z każdym systemem układu, który musiałam wykonać, wywołując setNeedsLayout i wywołując go w każdym superizycie superwizji dopóki nie będzie więcej ... wydaje się być jedynym sposobem zmiany dotyczy wszystkich rozmiarów wpływ. (jeśli są w subviewsach itp.) – Ben

1

W swoim scenopisie wybierz swój UIButton i wybierz edytor -> rozmiar dopasowany do rozmiaru treści.

EDIT: Spróbuj tego:

[self.myButton setTitle:@"Following" forState:UIControlStateSelected]; 
[self.myButton sizeToFit]; 
+0

Próbowałem tego, jest wspomniany w pytaniu. – jvergeldedios

+0

@jvedi Upewnij się, że twój Uibutton jest włączony, gdy to zrobisz. –

+0

To było, wciąż bez zmian. – jvergeldedios

0

czy jest to błąd, czy po prostu tak jest, nie wiem, ale wygląda na to będziesz musiał obejść - - Nie sądzę, że robisz coś złego. Jeśli chcesz, aby przełączać pomiędzy wybrane i nie po każdym kontakcie, można zrobić coś takiego:

- (IBAction)buttonClick:(UIButton *)sender { 
    sender.selected = !sender.selected; 
    if (sender.selected) { 
     [self.button setTitle:@"Following" forState:UIControlStateNormal]; 
     //Do whatever else you want to do here for the selected state 
    }else{ 
     [self.button setTitle:@"Follow" forState:UIControlStateNormal]; 
    } 
} 
+0

Skończyłem z czymś takim, ale nadal wydaje mi się dziwne, że zmiana stanu nie działała tak po prostu. No cóż. – jvergeldedios

+0

@jvedi, zgadzam się. Wydaje się dziwne, że wewnętrzny rozmiar nie działa dla UIControlStateSelected. To brzmi jak coś, o czym Apple po prostu zapomniało wprowadzić. – rdelmar

+6

Musisz tylko wywołać "invalidateIntrinsicContentSize" i powinno działać. 'setTitle: forState' prawdopodobnie wywołuje tę metodę wewnętrznie. –

1

Dla mnie ustawienie contentEdgeInsets dał mi jedyne niezawodne rozwiązanie.

Używam przycisków niestandardowych z obrazami tła. Tak więc plasterki pojawiają się w obrazie. Okazuje się, że sposób w jaki plasterkuje się obrazy może również wpływać na rozmiar zawartości wewnętrznej! Sprawdź to! Musiałem więc upewnić się, że robię to w identyczny sposób między obrazami dla różnych stanów. Używam także przypisanych ciągów. Zamieszczone tutaj rozwiązania nie zadziałały w moim przypadku.

Po dniu (!) Eksperymentowania stwierdziłem, że wystarczające wartości contentEdgeInsets na przycisku powodują, że zachowuje się poprawnie, gdy tytuły są zmieniane za pomocą autolayout. Nie ma potrzeby, aby unieważniać wewnętrzny rozmiar treści lub wywoływać dowolny kod układu, jeśli to zrobisz.

Możesz ustawić contentEdgeInsets w kodzie lub IB.

self.button.contentEdgeInsets = UIEdgeInsetsMake(10.0, 16.0, 10.0, 16.0); 

Myślę, że kod Swift jest identyczny z wyjątkiem atrybutu var.

Apple mówi to w dokumentach: "Przycisk używa tej właściwości do określenia właściwości intrinsicContentSize i sizeThatFits :.".

enter image description here