2012-03-12 11 views
5

Używam nowego interfejsu API UIAppearance w systemie iOS 5 do stylu UISegmentedControl z niestandardową grafiką. Muszę być w stanie ustalić pewne segmenty mają być wyłączone czasami w trakcie realizacji, ale metody UIAppearance wydają się nie pozwoli mi ustawić obraz dzielnik dla państwa UIControlStateDisabled.UISegmentedControl nie respektuje obrazów rozdzielacza ustawionych dla UIControlStateDisabled

Dzwonię:

[[UISegmentedControl appearance] setDividerImage:disabledSelectedImage 
            forLeftSegmentState:UIControlStateDisabled 
            rightSegmentState:UIControlStateSelected 
            barMetrics:UIBarMetricsDefault]; 

gdzie disabledSelectedImage jest to zmienny rozmiar obrazu z tego zasobu:

disabled-selected-image

Jednak kiedy ustawić lewy segment jest wyłączony ([UISegmentedControl setEnabled:forSegmentAtIndex:]), to Wynik jest następujący:

UISegmentedControl UI glitch

Wyraźnie widać, że nie wywiązał UISegmentedControl używać UIControlStateNormal - UIControlStateNormal dzielnika obrazu.

Wydaje się doskonale szczęśliwy dla mnie, aby ustawić obraz tła przy użyciu UIControlStateDisabled

[[UISegmentedControl appearance] setBackgroundImage:disabledImage 
            forState:UIControlStateDisabled 
            barMetrics:UIBarMetricsDefault]; 

(i szanuje obraz ja dostawę natomiast w stanie wyłączonym), ale nie obraz dzielnik. Czy ktoś natknął się na to lub znalazł rozwiązanie?

+0

To wygląda jak błąd. Myślę, że powinieneś złożyć go na stronie bugreport.apple.com. – jfortmann

+0

@jfortmann Myślę, że masz rację, zmieniłem przepływ na teraz, aby usunąć segmenty zamiast ich wyłączania. Wydaje się, że istnieje sporo błędów w API 'UIAppearance' dla' UISegmentedControl' –

+0

Dziękujemy za zgłoszenie! – jfortmann

Odpowiedz

3

Zdecydowałam, że musi to być błąd iOS i złożyli radar z Apple. Moim rozwiązaniem na razie jest usunięcie segmentów, a nie ich wyłączenie.

+0

Zrobiłem [to samo] (http://openradar.appspot.com/10999544) wcześniej w tym tygodniu. Cieszę się, że nie jestem jedyny. –

+0

@CoryKilger Zauważyłem również twój raport podczas budowania tego segmentowanego kontrolnego, ale na szczęście nie wpłynęło to na mnie, ponieważ nie musiałem najpierw wybierać drugiego segmentu. Przekażę wasz przez radar, więc mam nadzieję, że otrzymamy więcej uwagi. –

0

Nie potrzebowałem jeszcze używać kontroli wyglądu systemu iOS 5, ale jeśli wszystko inne zawiedzie, można dodać zmienny rozmiar obrazu jako element potomny rozdzielonej kontroli, aby ukryć brzydotę. To hack, ale może zadziałać i będzie względnie do przodu - kompatybilny. Po prostu upewnij się, że odpowiednio ustawisz maski autosizing.

+0

Mam zamiar używać niestandardowych segmentowanych kontrolek w całej aplikacji, prawdopodobnie z różną liczbą segmentów/pozycji itp. Tak więc niestety nie sądzę, że będzie to działało dla mnie. –

+0

Po co tworzyć własną podklasę UISegmentedControl, która automatycznie dodaje zmienny rozmiar obrazu? – TigerCoding

1

Trochę brzydki obejście, ale udało mi się naprawić to, co następuje, aż jabłko przytwierdza to samo.

Najpierw trzeba podklasy UISegmentedControl i dodać następujące:

@implementation MJSegmentedControl 

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    NSInteger cachedIndex = self.selectedSegmentIndex; 
    self.selectedSegmentIndex = 0; 
    self.selectedSegmentIndex = cachedIndex; 
} 

@end 
0

miałem ten sam problem i to naprawdę wydaje się być błąd. Jednak znalazłem rozwiązanie (obejście).

Używałem pliku XIB z kontrolerem. W pliku XIB została właśnie podzielona kontrola segmentów, a wszystkie dostosowania zostały wykonane w metodzie -viewDidLoad.

Potem stworzyliśmy UIView podklasy który reprezentowany cały widok w XIB. Umożliwiło przeniesienie całego kodu dostosowywania widoku do metody -awakeFromNib tej podklasy UIView. Po przeniesieniu tego kodu obraz dzielnika został poprawnie ustawiony.

0

Jak sugeruje Fernando w tym wątku: Customizing UISegmentedControl in iOS 5

Można spróbować wysyłką ustawienia UISegmentedControl na głównej kolejki poprzez:

dispatch_async(dispatch_get_main_queue(),^{ 
    // disable part of the segmented control 
    [self.eventScopeSegmentedControl setEnabled:NO forSegmentAtIndex:2]; 
}); 

Zrobiłem to w viewDidLoad i to działało w porządku na ale gdy moja aplikacja jest naprawdę zajęta przy starcie, nie zawsze działa. Zgaduję, że istnieje warunek wyścigu, który może nadal przywracać ustawienia wprowadzone podczas działania proxy występu.

Dodałem kolejny brzydki hack, aby wykonać to wywołanie w viewWillAppear (po wywołaniu super: viewWillAppear) z flagą (ustawioną na viewWillLoad), aby zapewnić, że ta operacja zostanie uruchomiona tylko raz.

0

Istnieje naprawdę prosty sposób na zrobienie tego. Obecne zachowanie jest oczywiście błędem, więc nie jest to idealne rozwiązanie, ale po prostu obejście, które działa pięknie. Mianowicie, użyj dodatkowego UIView jako "wyłączonej wizualnej wskazówki".

Ogólne kroki:

  1. Dodaj UIView jako rodzeństwo do UISegmentedControl. Upewnić się, że UIView jest z przodu UISegmentedControl
  2. Zastosuj żądany kolor i przejrzystość do UIView pasujące do Twojego app skórę
  3. Przesuń UIView być dokładnie na szczycie UISegmentedControl
  4. kształtować UIView zbadania przez dokładna wielkość góry UISegmentedControl
  5. Nałożyć zaokrąglony narożnik do UIView lustro dokładny kształt UISegmentedControl

Gdy UISegmentedControl ma być wyłączona, wystarczy pokazać UIView i wyłączyć interakcji użytkownika na UISegmentedC ontrol.

Gdy funkcja UISegmentedControl ma być włączona, po prostu ukryj UIView i włącz interakcję użytkownika z UISegmentedControl.

W obu przypadkach nie należy zmieniać właściwości UISegmentedControl.enabled.

Zauważ, że wygląda na to, że jest wiele kroków, ale wszystko to może być zakodowane, aby dodać obsługę wyłączania Twojego niestandardowego UISegmentedControl, a następnie dodać 1 linijkę po dodaniu tego do skonfigurowanej metody sterowania podzielonego na segmenty.

Oto jak mój zwyczaj segmentacji kontrola wygląda przy stosowaniu tego rozwiązania:

Włączone segmentowej Kontrola

enabled segmented control

"disabled" segmentowej kontrola

disabled segmented control

Oto niektóre fragmenty kodu zainteresowania:

kształtować UIView dopasować UISegementedControl (konfiguracja czas ładowania)

UISegmentedControl* segmentedControl = ... 
    //Segmented Control disabled visual cue view 
    UIView* view = ... 

    //Step #2  
    view.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6]; 

    //Step #3 and #4 
    view.frame = segmentedControl.frame; 

    //Step #5 
    view.layer.cornerRadius = 5 
    view.clipsToBounds = YES; 

    //Ensure this is disabled by default 
    view.userInteractionEnabled = NO; 

Włącz/"Wyłącz" UISegementedControl (zmiana stanu Runtime)

BOOL segmentedControlEnabled = ... 

if(segmentedControlEnabled) { 
    segmentedControl.userInteractionEnabled = YES; 
    view.hidden = YES;  
} else {  
    segmentedControl.userInteractionEnabled = NO; 
    view.hidden = NO; 
} 

To wszystko.

-

Powiązane problemy