2017-09-19 42 views
38

Zacząłem dostosowywać moją aplikację na iPhone X i znalazłem problem w programie Interface Builder. Zgodnie z oficjalnymi filmami Apple, przewodniki dotyczące bezpiecznego obszaru są zgodne z poprzednimi wersjami. Odkryłem, że działa dobrze w scenorysach.Przewodniki układu bezpiecznego obszaru w plikach xib - iOS 10

Ale w moich plików XIB, prowadnice układu strefy bezpieczeństwa nie są przestrzegane w iOS 10.

one działać dobrze dla nowej wersji systemu operacyjnego, ale urządzenia iOS 10 wydaje się po prostu przyjąć bezpieczną odległość obszaru jako zera (ignorując rozmiar paska stanu).

Czy brakuje jakiejkolwiek wymaganej konfiguracji? Czy jest to błąd Xcode, a jeśli tak, wszelkie znane obejścia?

Oto zrzut ekranu z emisją w projekcie badawczym (lewy iOS 10, tuż iOS 11):

safe area alignment on top of the screen

Odpowiedz

41

Są pewne problemy z bezpiecznym układ terenu i wstecznej kompatybilności. Zobacz mój komentarz powyżej here.

Być może uda ci się obejść problemy z dodatkowymi ograniczeniami, takimi jak priorytet 1000> = 20.0 do superview.top i 750 priorytet == safearea.top. Jeśli zawsze wyświetlasz pasek stanu, to powinno to naprawić.

Lepszym rozwiązaniem może być posiadanie oddzielnych scenorysów/ksigów dla systemów pre-iOS 11 i iOS-11 i nowszych, zwłaszcza jeśli napotkasz więcej problemów. Powodem tego jest to, że pre-iOS 11 powinien zawierać ograniczenia układu do przewodników układu górnego/dolnego, ale w przypadku systemu iOS 11 należy rozmieścić je w bezpiecznych obszarach. Przewodniki układu zniknęły. Wyznaczanie przewodników układu dla pre-iOS 11 jest lepsza stylistycznie niż tylko kompensacja minimum 20 pikseli, nawet jeśli wyniki będą takie same IFF zawsze pokazuje pasek stanu.

Jeśli podejmiesz takie podejście, musisz ustawić każdy plik na właściwy cel wdrożenia, na którym będzie on używany (system iOS 11 lub coś wcześniejszego), aby Xcode nie wyświetlał ostrzeżeń i nie w zależności od prowadnic układu lub obszarów bezpiecznych. W swoim kodzie, sprawdź w systemie uruchomionym iOS 11, a następnie załaduj odpowiedni storyboard/xibs.

Wadą tego podejścia jest konserwacja (będziesz mieć dwa zestawy kontrolerów widoku do utrzymania i synchronizacji), ale gdy Twoja aplikacja obsługuje tylko iOS 11 lub nowszy lub Apple naprawi kreację ograniczenia zgodności , możesz pozbyć się wersji pre-iOS 11.

Nawiasem mówiąc, w jaki sposób wyświetlasz kontroler, z którym to widzisz? Czy jest to tylko kontroler widoku root lub czy go przedstawiłeś, czy ...? Problem, który zauważyłem, ma związek z popychaniem kontrolerów widoku, więc możesz trafić w inny przypadek.

+0

Mój specyficzny problem dotyczy tylko plików XIB i zdaje się mieć miejsce zarówno w przypadku kontrolerów wypychanych, jak i prezentowanych. Twoje obejście z wieloma ograniczeniami brzmi jak dobre rozwiązanie w większości sytuacji. Dzięki! Nadal mam nadzieję, że rozwiążą te problemy, zanim nadejdzie iPhoneX. –

+0

Bardzo dziękuję za sugestię priorytetową! Teraz działa jak urok na iOS 9 i iOS 11 na iPhone'ie X. –

+0

Czy mogę wypowiedzieć na ten temat: "Jeśli zawsze wyświetlasz pasek stanu, to powinno to naprawić". Nie widzę sposobu wyświetlania paska stanu na symulatorze iPhone X w orientacji poziomej. Następnie opisane obejście "1000 priority> = 20.0 do superview.top i 750 priorytet == safearea.top" miałoby lukę 20px na górze dla iPhone X w krajobrazie. Moim rozwiązaniem było usunięcie ograniczenia "1000 priority> = 20.0" w viewDidLoad, jeśli iOS <11. Czy brakuje mi sposobu na wymuszenie paska stanu w krajobrazie iPhone X? –

-3

Znaleziony Najprostszym rozwiązaniem - wystarczy wyłączyć safe area i używać topLayoutGuide i bottomLayoutGuide + dodaj poprawki dla iPhone X. Może to nie jest piękne rozwiązanie, ale wymaga mniej wysiłku w możliwie jak

0

skończyło się na usunięciu ograniczenia do bezpiecznej strefy które miałem w moim pliku xib. Zamiast tego zrobiłem ujście do UIView, o którym mowa, i od kodu tak go podpiąłem, w viewDidLayoutSubviews.

let constraint = alert.viewContents.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 0) 
constraint.priority = 998 
constraint.isActive = true 

To wiąże mały „wpis” na górze ekranu, ale zapewnia, że ​​zawartość zobaczyć wewnątrz alert jest zawsze poniżej bezpiecznej okolicy górnego (iOS11ish)/topLayoutGuide (iOS10ish)

Proste i jednorazowe rozwiązanie. Jeśli coś się zepsuje, wrócę.

1

Obecnie zgodność wsteczna nie działa dobrze.

Moje rozwiązanie jest stworzenie 2 ograniczeń w interfejsie konstruktora i usunąć jeden w zależności od wersji iOS używasz:

  • dla iOS 11: view.top == safe area.top
  • dla wcześniejszych wersji: view.top == superview.top + 20

Dodaj je jako punkty sprzedaży odpowiednio jako myConstraint i . Następnie:

override func viewDidLoad() { 
    if #available(iOS 11.0, *) { 
     view.removeConstraint(myConstraintIOS10) 
    } else { 
     view.removeConstraint(myConstraint) 
    } 
}