Konstruktor interfejsu: Do czego służy układ UIView w systemie iOS 6/7 Deltas?

111

Właśnie zauważyłem właściwość Delta iOS 6/7 znalezioną pod układem struktur UIView.

Do czego to służy i dlaczego tego brakuje w AutoLayout?

wprowadź opis obrazu tutaj

Frederick C. Lee
źródło

Odpowiedzi:

83

W rzeczywistości odnosi się to do różnicy między pozycjami układu od iOS6 do iOS7.

W systemie iOS7 w niektórych widokach pasek stanu może być ukryty lub przezroczysty iw efekcie nakładany na widok. Więc jeśli ustawisz element interfejsu użytkownika na (0,0, 0,0) w iOS6, pojawi się on poniżej paska stanu, ale w iOS7 będzie częściowo zakryty pod paskiem stanu. W takim przypadku chciałbyś mieć deltę, która pasuje do wysokości paska stanu (20,0 punktów), aby układ wyglądał tak samo w iOS6 i iOS7.

Uważam, że nie jest to potrzebne, jeśli używasz autoukładu, ale oczywiście tracisz obsługę iPada1, czego wielu z nas nie chce w tym momencie przyznać.

digarok
źródło
27
U mnie znalazłem, że to delta z iOS 7 na iOS 6.
Obniżyłem
jest to szczególnie przydatne w przypadku UIProgressView, który jest znacznie cieńszy w iOS 7
Lee Probert
108

Uwaga: zauważyłem to pytanie jakiś czas temu, ale teraz zamieszczam odpowiedź, ponieważ umowa NDA została zniesiona

Dlaczego nie pojawia się w przypadku Autoukładu?

Jak być może zauważyłeś, iOS 7 zapewnia zupełnie nowy wygląd. Wygląd elementów interfejsu użytkownika zmienił się, ale zmieniły się też niektóre ich rozmiary (lub ogólnie dane). Może to sprawić, że projekt interfejsu dostosowany zarówno do systemu iOS 7, jak i jego poprzedników, będzie trochę uciążliwy.

Oficjalną linią Apple jest użycie AutoLayout do rozwiązania tego problemu; powinno to zająć dużo kłopotów z układaniem elementów interfejsu użytkownika. Czasami włączenie tego nie jest łatwe, zwłaszcza jeśli nadal musisz obsługiwać iOS 5 z powodów biznesowych lub twoje interfejsy są zarządzane w sposób, który utrudnia implementację Autoukładu. W związku z tym wydaje się, że Apple zapewnił sposób, aby Twoja praca była nieco łatwiejsza, jeśli należysz do tej niszowej kategorii i nazwali to iOS 6/7 Deltas.

Ok, więc co to robi?

Chociaż etykieta w Interface Builder jest nieco niejasna, co oznacza „Delta” w tym kontekście, kod zawarty w pliku .xib, który odpowiada tej funkcji, jest nieco bardziej przejrzysty:

<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>

Nazwa klucza insetFor6xAndEarlierwyraźnie określa, co to robi; możesz zapewnić alternatywne wstawki dla elementów interfejsu użytkownika, gdy są uruchamiane na poprzednikach iOS 7. Na przykład powyższe definiuje następującą zmianę delta:

x: 50
y: 100
width: -100
height: 200

Chociaż wartości zapisane w .xib nie odpowiadają bezpośrednio cytowanym wartościom, istnieje między nimi korelacja.

x: -minX
y: -minY
width: minX + maxX
height: minY + maxY

Poniższe obrazy pokazują tę zmianę wizualnie. To dość ekstremalny przykład, ale ma zademonstrować jego umiejętności. W praktyce spodziewałbym się, że zmiany delta będą wynosić tylko kilka pikseli.

Widok iOS7

Widok iOS6

Możesz zauważyć, że wartości są odwrotne dla widoku iOS 6; Dzieje się tak, ponieważ delty zależą od typu widoku, z którym pracujesz. Jeśli edytujesz dla iOS 6, istnieją różnice, aby poprawnie przekształcić element dla iOS 7 (odwrotność powyższego przykładu).

Aby wyświetlić różne style, możesz zmienić sposób, w jaki Interface Builder przedstawia go w oparciu o system operacyjny, na którym będzie działać. Jest to zawarte w dokumencie File Inspector-> Interface Builder (pierwsza zakładka na prawym pasku), tak jak:

Przełącznik stylu interfejsu

Czy to istnieje, jeśli chcę ręcznie zakodować mój interfejs?

Nie bezpośrednio, ale możesz łatwo osiągnąć ten sam efekt, przeprowadzając warunkowe sprawdzanie wersji systemu operacyjnego w swoim kodzie i odpowiednio ustawiając odpowiednią pozycję / rozmiar. Możliwość delta istnieje w Interface Builder, ponieważ nie byłoby prostego sposobu na warunkowe pozycjonowanie bez posiadania odpowiedniego kodu, a celem Interface Builder jest usunięcie jak największej ilości kodu z drogi dla interfejsu użytkownika.

Ogólny...

Firma Apple zdecydowanie zaleca korzystanie z Autoukładu, który w większości przypadków ułatwia życie. Jeśli nie możesz go użyć (z powodów wymienionych powyżej), delty zapewniają elastyczność odpowiedniego pozycjonowania elementów interfejsu użytkownika, w oparciu o metryki bieżącego systemu operacyjnego, bez konieczności ręcznej zmiany ich położenia w kodzie. Dobrym przykładem jest dostosowanie się do braku paska stanu, ale istnieje wiele innych przypadków użycia.

Oczywiście, jeśli tworzysz tylko na iOS7 i nowsze wersje, nie musisz znać tej funkcji / nie odkryjesz jej. Tylko jeśli potrzebujesz mieć urządzenia z systemem iOS6, na których działa Twoja aplikacja, gdy są one zbudowane za pomocą zestawu SDK systemu iOS7 bez automatycznego układu, potrzebujesz delt.

W chwili pisania tego tekstu (21 sierpnia) nie mogę znaleźć żadnej dokumentacji dotyczącej tej funkcji ani żadnych wzmianek w materiałach WWDC. Bawiłem się i po kilku badaniach odkryłem to.

WDUK
źródło
2
Dziękuję bardzo WDUK
Kamar Shad
Jak dotąd brak nieruchomości, to właśnie musiałem wiedzieć
Jasper,
30

Wiem, że już na to odpowiedziano, dodając tylko mały wariant, mając nadzieję, że może to również pomóc tym, którzy nie używają automatycznego układu i nadal chcą obsługiwać iOS 6.1 i wcześniejsze wersje.

Przeczytaj ten przewodnik Apple dotyczący przejścia - obsługa wcześniejszej wersji

Wybierz „Wyświetl jako” na „iOS 7.0 i później”

wprowadź opis obrazu tutaj

Podstawowy interfejs użytkownika dla iOS 7. Dla iOS 6 podaj odpowiednią wartość delta. Użyj podglądu, aby zobaczyć, jak to będzie renderowane na urządzeniu z systemem iOS 7 i iOS 6.

wprowadź opis obrazu tutaj

Szybkie kroki:

Wybierz osobno każde bezpośrednie dziecko widoku głównego i dodaj 20 pikseli do jego wartości „Y”.

wprowadź opis obrazu tutaj

Następnie wybierz zbiorczo wszystkie bezpośrednie dzieci i daj delta Y jako -20px. Możesz to również zrobić zbiorczo lub indywidualnie.

wprowadź opis obrazu tutaj

Saran
źródło
9

AutoLayout wymaga co najmniej iOS 6.0. Jeśli chcesz obsługiwać iOS 5.0, nie możesz użyć AutoLayout.

Te delty są używane, aby pomóc Ci dostosować pozycję widoku w różnych wersjach iOS (głównie iOS 7 i iOS niższych niż 7).

Używam tych wartości, aby polubić to zdjęcie. wprowadź opis obrazu tutaj

nieszczęśliwy
źródło
1
Kiedy to zmieniam, nic się w ogóle nie dzieje, czy jest potrzebny inny krok?
Recycled Steel
@RecycledSteel zobacz moją odpowiedź tutaj: link
Riskov
3

Aby zobaczyć iOS 6/7 Delta w akcji, przedstawię wersję demonstracyjną z SegmentedControl, która pojawia się poprawnie na urządzeniach z iOS 6 i iOS 7.

Najpierw wybierz .Xib lub ViewController w Storyboard. Usuń zaznaczenie opcji Użyj automatycznego układu i wybierz „ Wyświetl jako iOS 7 lub nowszy

wprowadź opis obrazu tutaj

W kanwie Interface Builder umieść SegmentedControl tak, aby jego origin.y był 20. W iOS 6/7 Delta wybierz -20 dla DeltaY

wprowadź opis obrazu tutaj

Spowoduje to, że Twoja SegmentedControl zostanie umieszczona pod paskiem stanu w urządzeniach z systemem iOS 6 i iOS 7

wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

Kolejne przydatne cytaty z Przewodnika dla programistów do paska stanu iOS 7

Delty można ustawić indywidualnie dla każdego widoku i działać zgodnie z oczekiwaniami. Jeśli scenorys lub końcówka są ustawione na wyświetlanie w systemie iOS 6, ustawienie delt spowoduje przesunięcie tego widoku i / lub zmianę jego rozmiaru o ustawioną wartość przyrostu po uruchomieniu w systemie iOS 7. Alternatywnie, jeśli scenorys lub końcówka są ustawione na wyświetlanie w systemie iOS 7 delty zostaną zastosowane w przypadku uruchomienia w systemie iOS 6

onmyway133
źródło
0

Jeśli używasz AutoLayout, różnica nie jest dostępna. Spróbuj tego (testowane na iPhonie 4s z systemem iOS6):

- (void) viewWillLayoutSubviews {

//iOS 6 workaround offset
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {

    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10);

    self.view.frame = screenFrame;
}
}
Marcelo dos Santos
źródło