2014-10-27 19 views
57

Abbiamo un numero di app iOS a cui contribuiscono diversi sviluppatori. Un problema che continuo a notare è che le visualizzazioni nei nostri storyboard si spostano dalla posizione in cui sono state inserite o ridimensionate in modo che siano più piccole, che su etichette che sono state ridimensionate per adattarsi al testo originariamente diventa dolorosamente evidente quando le etichette sono tutte improvvisamente stanno troncando il loro testo.Interface Builder degrada storyboard, ridimensiona e riposiziona le visualizzazioni in piccoli incrementi

Sto notando che queste degradazioni delle nostre visualizzazioni appaiono in commit al nostro repository Git quando lo sviluppatore non ha apportato direttamente alcuna modifica allo storyboard. Potrebbero aver visualizzato lo storyboard in Interface Builder, ma non hanno apportato modifiche reali allo storyboard. I cambiamenti sono stati tuttavia salvati e commessi insieme a ciò su cui stavano lavorando.

Quando faccio un testo confronto tra le file di storyboard, prima e dopo i commit responsabili vedo piccoli cambiamenti di visualizzare fotogrammi come ad esempio:

<rect key="frame" x="203" y="8" width="362" height="29"/> 
          | 
          V 
<rect key="frame" x="203" y="7.5" width="362" height="29"/> 

e

<rect key="frame" x="446.00000170260091" y="7" width="302" height="30"/> 
         | 
         V 
<rect key="frame" x="446" y="7" width="302" height="30"/> 

e

<rect key="frame" x="364" y="3" width="200" height="38"/> 
         | 
         V 
<rect key="frame" x="363" y="3" width="200" height="38"/> 

e

<rect key="frame" x="284" y="7" width="97" height="30"/> 
         |    | 
         V    V 
<rect key="frame" x="283" y="7" width="96" height="30"/> 

e

<rect key="frame" x="384.00001078580522" y="7" width="101" height="30"/> 
         |        | 
         V        V 
<rect key="frame" x="383.00000530853856" y="7" width="100" height="30"/> 

maggior parte del tempo i numeri per dimensioni del telaio cambiano da solo una piccola quantità, sia un valore intero cambia di uno o di un valore di virgola mobile è troncato o la parte decimale è cambiato di poco.

Altre volte, i valori cambiano da pochi punti anche se, come:

<rect key="frame" x="334" y="3" width="200" height="38"/> 
         | 
         V 
<rect key="frame" x="331" y="3" width="200" height="38"/> 

e

<rect key="frame" x="251" y="7" width="223" height="30"/> 
             | 
             V 
<rect key="frame" x="251" y="7" width="220" height="30"/> 

e

<rect key="frame" x="478" y="3" width="274" height="38"/> 
         |     | 
         V     V 
<rect key="frame" x="475" y="3" width="276" height="38"/> 

noti che tutti questi cambiamenti esempio telaio erano preso dallo stesso esempio di commit quando lo sviluppatore non intendeva apportare una sola modifica allo storyboard. C'erano 269 differenze nell'XML tra le due versioni del file, tutte queste piccole variazioni nelle dimensioni o nelle posizioni dei fotogrammi. Lo storyboard XML è di ~ 9000 righe.

Sembra che il problema potrebbe avere qualcosa a che fare con l'uso di IB di numeri in virgola mobile e errori di arrotondamento e le differenze che si annullano di pochi pixel potrebbero essere un'aggregazione di questi errori di arrotondamento in un periodo di diverse volte di apertura, analisi e ri-serializzare i dati.

Questa è solo una teoria, anche se non sono stato in grado di individuare la causa esatta delle modifiche indesiderate. Spesso i commit non apportano modifiche significative ai frame, solo modifiche a virgola mobile insignificanti come 446.00000055262581 -> 446.00000112002783. Ma quando si verificano i gravi cambiamenti, sembrano verificarsi in gran numero.

I commit tra i quali si verificano le modifiche vengono effettuati anche dallo stesso sviluppatore utilizzando la stessa versione di Xcode e Interface Builder.In questo esempio, commit in cui sono stati presi questi dati, il tag del documento è <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="JAD-vj-VfC"> in entrambe le versioni del file storyboard, ad esempio.

Oltre a controllare che non vengano apportate modifiche insignificanti o non intenzionali ai file dello storyboard, vorrei limitare ciò che causa queste modifiche indesiderate alle visualizzazioni dello storyboard. Se è qualcosa che possiamo evitare di fare è il problema, possiamo essere consapevoli della causa.

Aggiornamento: Come utilmente ha osservato Tim, questo problema sembra essere causato durante l'utilizzo di Interface Builder su un display retina. Tutti gli sviluppatori che hanno causato il problema hanno retina MacBook Pro. Quelli di noi senza display retina non hanno riscontrato il problema.

risposta

4

Questo sembra essere un bug relativo alla serializzazione di Builder di CGFloat. I valori di dimensione e posizione per i riquadri di visualizzazione sono punti mobili. Ma i loro valori sono sempre interi. La manipolazione grafica interna richiede che siano in virgola mobile perché la matematica della trasformazione funzioni, ma tutto è sempre espresso in termini di valori di punti interi arrotondati.

Quando questi valori in virgola mobile vengono serializzati nello XML storyboard, IB serializza spesso i valori come numeri interi, ma occasionalmente li serializza anche come numeri in virgola mobile. Non sono sicuro del motivo per cui prende la decisione di farlo in questo modo quando lo fa, ma è meno comune. Nei miei fotogrammi di esempio sopra, 3 dei valori hanno finito per essere in virgola mobile, mentre gli altri sono numeri interi.

Anche nei miei esempi, spesso la rappresentazione in virgola mobile viene modificata per essere serializzata come un numero intero. Questo è dove credo che il bug sia stato trovato.

Una cosa che ho notato con il modo in cui i fotogrammi di visualizzazione stavano cambiando, tendevano a spostarsi a sinistra oa ridursi di dimensioni. Quindi i valori stanno diventando sempre più piccoli. Puoi vedere negli esempi che ho fornito, questo è sempre il caso.

I punti mobili non hanno la precisione per esprimere esattamente i valori interi, ma sono precisi con diverse posizioni decimali. Quindi, mentre a volte gli interi sono espressi come quelli nei miei esempi come leggermente superiori al valore intero (vale a dire 384.00001078580522), altri sono espressi come leggermente inferiori al valore intero. Ecco un esempio di un cambiamento cornice che IB fatto:

<rect key="frame" x="457" y="7" width="291" height="30"/> 
         | 
         V 
<rect key="frame" x="456.99999985252464" y="7" width="291" height="30"/> 

Mentre questo cambiamento particolare non sembra modificare direttamente il valore del telaio. Entrambi i numeri sono essenzialmente uguali a 457. Ciò che penso si verifichi è quando questo XML viene nuovamente analizzato quando lo storyboard viene riaperto, potrebbe troncare il valore 456.99999985252464 e leggerlo come 456. Ciò causerà quindi il progressivo aumento dei valori più piccolo, restringendo le dimensioni o spostando la posizione dei frame a sinistra o in alto.

Ovviamente questa è solo una teoria e non fornisce un motivo per cui Interface Builder lo sta facendo. Sembra che sia iniziato dalla recente versione di Xcode 6. Inoltre, non spiega come sia andato da 8 a 7.5 su un esempio o anche l'unica volta che è passato da 274 a 276 nel mio ultimo esempio. Ma per la maggior parte, la maggior parte dei cambiamenti tende ad essere verso il basso.

Sto archiviando un bug con Apple per farlo esaminare.

+0

Grazie per la lunga spiegazione Jeff, questo capita anche a noi. Hai trovato un modo per evitarlo? – celiker

+1

@celiker Come Tim ha notato utile, questo sembra essere collegato all'uso di Interface Builder sui display retina. Tutti gli sviluppatori che abbiamo avuto causa il problema hanno display retina, mentre quelli di noi senza display retina non hanno avuto il problema. L'implementazione interna, l'analisi e la riscrittura di XML, non sembrano gestire correttamente la precisione dei pixel. Quindi evitare di usare IB su un display retina è l'unica soluzione a questo punto fino a quando Apple risolverà questo bug. –

+0

Questo mi sta facendo impazzire, con Xcode 9.1 ... Hai inserito un bug? –

17

L'indizio più interessante di questo mistero è che sembra particolarmente brutto quando si apre lo stesso storyboard su un display Retina anziché su un display senza retina.

All'inizio andavo avanti e indietro tra un iMac 4k e un Macbook Pro pre-retina e ricevevo un grande volume di modifiche (circa 300 righe alterate ogni volta).

Quindi ho semplicemente trascinato la finestra xcode dal mio monitor principale (4k/retina) al mio secondo monitor (2560x1440, non retina) - e mentre la finestra aveva le stesse dimensioni, xcode ha ridimensionato tutti gli elementi e si è lamentato ~ 50 visualizzazioni fuori posto. L'ho spostato sul display retina e circa la metà degli errori "fuori luogo" è andato via, ma la metà è rimasta. Il ridimensionamento, come suggerito, degrada i dati sottostanti.

Se più sviluppatori lavorano sullo stesso file, ciò si verifica spesso.

La soluzione? Probabilmente tutto questo su Apple per correggere - Non ho eseguito alcuna impostazione che potrebbe attenuarlo diversamente.

+0

Pradeep K ha trovato l'impostazione per consentire a Xcode di ignorare la modalità di visualizzazione Retina http://stackoverflow.com/a/36124980/2064473 sebbene questo, come ha sottolineato, sconfiggesse il punto di utilizzo di un display Retina. Ho disabilitato l'impostazione perché, in ogni caso, principalmente sviluppo su un display esterno. – Cyrus

3

Potrei avere una risposta a questo problema. È una caratteristica meno conosciuta dell'apertura delle app in modalità a bassa risoluzione. Recentemente abbiamo avuto un problema simile in cui la vista del contenuto delle celle di visualizzazione tabella aveva un extra di 0,5 per l'altezza quando la linea di separazione è impostata su predefinita o singola. Quando è impostato su Nessuno, questo problema non era presente. Passaggi 1. Trascinare un TVC predefinito nello storyboard. Controllare l'altezza della vista del contenuto della cella di visualizzazione tabella. Sarà 43.5. 2. Impostare la linea di separazione per la vista tabella su Nessuno. La vista del contenuto della cella diventa 44.

Ora uscire da Xcode e impostare la modalità Apri in bassa risoluzione nella finestra Trova informazioni del Finder per l'app Xcode. Ora se segui la stessa procedura sopra riportata mostrerà l'altezza della visualizzazione del contenuto per la cella di visualizzazione tabella come 43.

Quando ci sono diversi membri del team che lavorano su display retina e non-retina si otterrebbero semplicemente i file dello storyboard come modificato solo perché hai aperto lo storyboard nel display retina. Un modo per ovviare a questo è trasformare la modalità Apri in bassa risoluzione e lavorare. Ma poi sconfigge lo scopo di avere uno schermo retina, ma è meglio che avere gli storyboard contrassegnati come modificati anche se non hai cambiato nulla.

+0

Sto ancora vedendo l'incremento di 0,5 quando apri Xcode 8.2.1 in modalità bassa risoluzione e poi apro il mio file storyboard. – sethfri

+0

Xcode 7.2.1. Non ha funzionato anche per me. – TalL