Guide al layout dell'area sicura nei file xib – iOS 10

Ho iniziato ad adattare la mia app per iPhone X e ho riscontrato un problema in Interface Builder. Le guide al layout dell'area di sicurezza dovrebbero essere retrocompatibili, secondo i video ufficiali di Apple. Ho scoperto che funziona bene nello storyboard.

Ma nei miei file XIB, le guide al layout dell'area di sicurezza non sono rispettate in iOS 10.

Funzionano bene per la nuova versione del sistema operativo, ma i dispositivi iOS 10 sembrano semplicemente ipotizzare che la distanza dell'area di sicurezza sia zero (ignorando la dimensione della barra di stato).

Mi manca qualsiasi configuration richiesta? Si tratta di un bug Xcode e, in caso affermativo, di soluzioni alternative note?

Ecco uno screenshot del problema in un progetto di test (sinistra iOS 10, destra iOS 11):

allineamento dell'area sicura sulla parte superiore dello schermo

Solutions Collecting From Web of "Guide al layout dell'area sicura nei file xib – iOS 10"

Ci sono alcuni problemi con il layout dell'area sicura e la retrocompatibilità. Vedi il mio commento qui .

Potresti essere in grado di aggirare i problemi con vincoli aggiuntivi come 1000 priorità> = 20.0 a superview.top e 750 priorità == safearea.top. Se mostri sempre una barra di stato, ciò dovrebbe risolvere le cose.

Un approccio migliore potrebbe essere quello di avere storyboard / xib separati per pre-iOS 11 e iOS-11 e versioni successive, specialmente se si verificano più problemi di questo. Il motivo per cui è preferibile è che, prima di iOS 11, dovresti rispettare i vincoli di layout per le guide di layout in alto / in basso, ma per iOS 11 devi posizionarli in aree sicure. Le guide al layout sono sparite. La disposizione delle guide di layout per il pre-iOS 11 è stilisticamente migliore della semplice compensazione di un minimo di 20 pixel, anche se i risultati saranno gli stessi di IFF e mostrerai sempre una barra di stato.

Se segui questo approccio, dovrai impostare ciascun file sulla destinazione di distribuzione corretta su cui verrà utilizzato (iOS 11 o qualcosa prima) in modo che Xcode non ti dia avvertenze e ti permetta di usare le guide di layout o aree sicure, a seconda Nel tuo codice, verifica la presenza di iOS 11 in fase di esecuzione, quindi carica lo storyboard / xib appropriato.

Lo svantaggio di questo approccio è la manutenzione, (avrai due serie di controller di visualizzazione per mantenere e mantenere la sincronizzazione), ma una volta che l'app support solo iOS 11+ o Apple risolve la generazione del vincolo di guida al layout di compatibilità con le versioni precedenti, puoi get liberarsi delle versioni pre-iOS 11.

A proposito, come stai visualizzando il controller con cui stai vedendo questo? È solo il controller di visualizzazione radice o l'hai presentato o …? Il problema che ho notato ha a che fare con la spinta dei controller di visualizzazione, quindi potresti avere un caso diverso.

Ho finito per eliminare il vincolo sull'area di sicurezza che avevo nel mio file xib. Invece ho fatto uno sbocco alla UIView in questione, e dal codice l'ho collegato in questo modo, in viewDidLayoutSubviews.

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

Questo allaccia un piccolo "avviso" alla parte superiore dello schermo, ma si assicura che la vista del contenuto nell'avviso sia sempre al di sotto dell'area sicura superiore (iOS11ish) / topLayoutGuide (iOS10ish)

Semplice e una soluzione unica. Se qualcosa si rompe, tornerò 🙄.

Attualmente, la compatibilità con le versioni precedenti non funziona bene.

La mia soluzione è di creare 2 vincoli nel generatore di interfacce e rimuoverne uno a seconda della versione di ios che si sta utilizzando:

  • per view.top == safe area.top 11: view.top == safe area.top
  • per le versioni precedenti: view.top == superview.top + 20

Aggiungili entrambi come myConstraint e myConstraintIOS10 rispettivamente. Poi:

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

Trovato la soluzione più semplice – basta disabilitare safe area e utilizzare topLayoutGuide e bottomLayoutGuide + aggiungere correzioni per iPhone X. Forse non è una soluzione bellissima ma richiede less sforzi possibili