come si usa UIScrollView in Interface Builder?


95

Anche se UIScrollViewin passato l' ho usato con successo manipolandolo a livello di programmazione, ho problemi a farlo funzionare configurandolo esclusivamente in Interface Builder.

Ho una semplice pagina "about" nella mia app per iPhone. Ha UITextViewalcune icone e collegamenti alle mie altre app. Ho aggiunto tutte queste visualizzazioni al mio UIScrollView, disponendole in modo che la loro dimensione totale sia> 480. Quando avvio la mia app, lo scrollview mostra solo i contenuti che si adattano allo schermo e nulla scorre.

È possibile farlo interamente tramite IB o devo manipolare contentSize tramite codice?

Risposte:


130

Hai dimenticato di impostare la proprietà contentSize di UIScrollView. Stranamente non puoi farlo da Interface Builder. Dovrai farlo dal controller di visualizzazione che gestisce questa visualizzazione a scorrimento.


42
Wow, rende IB piuttosto inutile ... Questo ha funzionato, grazie.
George Armhold,

20
È possibile creare una sottoclasse di UIScrollvView che controlla se c'è solo una sottoview in (0,0) e quindi imposta automaticamente contentSize in base a quella sottoview.
Stefan Arentz

1
Questo è il miglior consiglio che ho ricevuto da un po 'di tempo. Non sono riuscito a capire perché la mia visualizzazione a scorrimento non funzionasse e non ho trovato quelle informazioni su contentSize da nessun'altra parte. Grazie.
Drew C

46
Stavo cercando di capire come impostare contentSize in Interface Builder e ho trovato questa discussione. Almeno per me, in Xcode 4.5, posso impostarlo utilizzando "Attributi di runtime definiti dall'utente", aggiungendo una voce denominata contentSizedi tipo Sizee impostando il valore desiderato.
nlogax

5
Sono ancora sconcertato dal motivo per cui iOS non si limita a impostare automaticamente la contentSizevisualizzazione a scorrimento in base alle dimensioni delle sue visualizzazioni secondarie , almeno come comportamento predefinito.
aroth

113

La risposta di Boby_Wan mi ha fatto riflettere e ho trovato la seguente soluzione per configurare il contentSize di UIScrollView da Interface Builder:

  1. Seleziona UIScrollViewnella scena Storyboard
  2. Vai all'Identity inspector , crea un nuovo attributo di runtime definito dall'utente (fai clic sul pulsante +)
  3. Modificare l'attributo Percorso chiave incontentSize
  4. Modificare il tipo di attributo inSize
  5. Ora impostare il valore a { width contenuto desiderato , desiderato altezza contenuti }

ad esempio, impostando il valore su {320, 920} l'utente farà scorrere verso il basso un'intera schermata aggiuntiva sull'iPhone.

(Sto usando xcode 4.3.3, l' obiettivo di distribuzione iOS del progetto è 5.1)

Quando l'ho fatto per la prima volta ho ricevuto il seguente errore:

Configurazione illegale:
     attributi di runtime definiti dall'utente del tipo di dimensione con versioni di Xcode precedenti alla 4.3
     MainStoryboard.storyboard

Se anche tu ricevi questo errore è semplice da correggere: seleziona lo Storyboard nel Navigatore progetto e apri l' ispettore File . Trova / espandi la sezione Documento di Interface Builder e c'è un menu a discesa per Sviluppo . Assicurati che sia impostato suXcode 4.3


7
Fantastica scoperta! PS: sono sbalordito che questo sia il meglio che Apple possa fare. Immagino che questo dimostri che anche il personale Apple non usa mai il proprio strumento (costruttore di interfacce) :).
Adam

Fantastico, questo ha appena funzionato per me in Xcode 4.4. Ma ora come metto i pulsanti sulla parte della visualizzazione a scorrimento che non posso "vedere" in IB?
Robert Atkins

1
L'ho appena risolto - devi rilasciare il trascinamento quando il puntatore è ancora all'interno dello "schermo", altrimenti tornerà a quando sei partito. Che dolore.
Robert Atkins

Ho provato in questo modo, ma ricevo un errore "this class is not key value coding-compliant for the key keyPath", potete aiutarmi per favore cosa sto facendo di sbagliato? tieni presente che uso xamarin-ios-c #
SoftSan

25

Con il layout automatico (iOS6 +), puoi evitare l'impostazione contentSize. Imposta invece i seguenti vincoli:

  1. Fissa la parte superiore della visualizzazione a scorrimento alla parte superiore del suo figlio più in alto.
  2. E appuntare la parte inferiore alla parte inferiore del suo bambino più in basso.

1
Grazie - l'impostazione contentSizenon funziona con Xcode 5 e iOS 7
colincameron

18

Puoi farlo utilizzando solo Interface Builder, vai a Identity Inspector (la terza scheda Inspector) e aggiungi un nuovo attributo Runtime definito dall'utente con

  • Percorso chiave: contentSize
  • Tipo: dimensione
  • Valore: {larghezza, altezza}

14

Ora c'è un modo per fare una UIScrollViewpergamena senza lasciare Storyboard :

  1. Seleziona UIScrollViewnello Storyboard, vai all'ispettore Dimensioni e modifica il valore Inferiore (o qualsiasi altro valore che devi modificare) nella sezione Riquadri contenuto all'altezza dell'area del contenuto.
  2. Ora vai all'Identity inspector e crea un nuovo attributo di runtime definito dall'utente (facendo clic sul pulsante +) e nominalo contentSize. Non importa quale tipo o valore inserisci (puoi persino lasciare il loro valore predefinito).

Questo farà UIScrollViewfunzionare correttamente, anche se non so perché sia ​​necessario il secondo passaggio (l'ho scoperto per caso). :(


Modificare il valore Inferiore in cosa?
zakdances

Modificalo all'altezza dell'area del contenuto. Sembra funzionare e sostituisce il valore fornito per l'attributo "contentSize" definito dall'utente.
Reid Ellis

Sì, Reid, hai ragione: dovresti cambiare il valore Inferiore all'altezza dell'area del contenuto. Ho modificato il mio post originale per riflettere questo. Grazie!
RoberRM

4

un approccio che ho usato in passato è stato quello di trascinare la visualizzazione a scorrimento fuori dalla sua vista contenente nel generatore di interfacce e impostare la sua dimensione effettiva su ciò che vuole che sia contentSize.

ciò che non è intrinsecamente ovvio nel generatore di interfacce è che puoi avere viste non associate che sono memorizzate nel pennino, ma non fanno parte della vista principale per cui il pennino è principalmente.

nella vista in cui si desidera che risieda la scrollview, posizionare una semplice UIView, che si utilizza come segnaposto. (Questo è semplicemente così puoi progettare visivamente la sua posizione. Se stai usando solo l'intera vista, puoi saltare questo passaggio e usare il secondo frammento di codice che fornisco alla fine di questa risposta).

puoi quindi popolare la scrollview con i controlli, disponendola visivamente come vuoi che sia. fornire sia il segnaposto che le proprietà scrollview all'interno del controller della vista in modo da accedervi in ​​fase di esecuzione.

in fase di esecuzione, in - (void) viewDidLoad

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

in alternativa (se non hai utilizzato un segnaposto):

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.origin.x = 0;
f.origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

infine, se "perdi" la visualizzazione a scorrimento in Interface Builder (è possibile chiuderla in modo che scompaia dalla griglia di progettazione), niente panico. basta fare clic su di esso nell'elenco degli oggetti a sinistra della griglia di progettazione.


1
Grazie - ha funzionato bene. È inoltre necessario dichiarare IBOutlet in YourViewController.h per il segnaposto e le visualizzazioni di scorrimento e collegarli in Interface Builder. Infine, dot.notation non è stato apprezzato da xCode per la terza riga, quindi ha utilizzato la normale sintassi di invio dei messaggi - quindi tutto ha funzionato alla grande!
jiy

nessun problema. c'è sempre il pericolo quando si pubblicano frammenti di codice che alcune persone non possano usarli per ottenere il concetto, piuttosto che aspettarsi che il codice "esatto" funzioni in ogni situazione.
non sincronizzato il

Questo è il metodo che utilizzo effettivamente. Non ho nemmeno bisogno di ridimensionare questo programma. Penso che sia il modo in cui dovrebbe essere fatto. È l'unica vera risposta.
user4951

Dopo averlo disegnato all'esterno, lo sposterò in super visualizzazione. Tada.
user4951

In realtà ho iniziato a progettare alcune viste al di fuori di una scena per gli appunti e questo rende la vita molto più semplice in alcune situazioni anche estranee a questa. Grazie per questa risposta.
Benjamin

4

In Xcode 4.5 utilizzando il layout automatico non ho una sezione Inserti di contenuto nel mio ispettore delle dimensioni. Quindi ho dovuto aggiungerlo in Attributi di runtime definiti dall'utente e poi ha funzionato bene.

Quello che aggiungi in "Attributi di runtime definiti dall'utente" è keyPath == contentInset che è di tipo "Rect" (UIEdgeInsets, che ha lo stesso input di Rect) ed è definito come {top, left}, {bottom, right}. ContentSize definisce solo la regione della finestra scrollview. contentInset definisce l'area scorrevole.

Spero che questo aiuti qualcuno nella stessa situazione.


Per UITextView usa "textContainerInset" keyPath
Dima Deplov

4

Molte delle risposte di cui sopra sono fuorvianti o obsolete. A partire dal 2017 (forse molto prima) costruttore di interfaccia fa scrollviews di supporto con i contenuti di dimensioni automaticamente. Il trucco è che XCode dà un significato speciale e non standard ai vincoli tra lo scrollview e il contenuto al suo interno. Questi vincoli "interni" non influenzeranno effettivamente la dimensione del contenuto come ci si potrebbe altrimenti aspettare.

Ciò significa che puoi ad esempio avere la tua scrollview bloccata in fondo alla vista principale con margine zero, e anche avere il contenuto della tua scrollview bloccata in fondo alla scrollview con zero margine, ma il contenuto non sarà effettivamente allungato da questo. Invece il contenuto avrà la sua dimensione auto-determinata (più sotto) e questa sarà anche la dimensione dell'area scorrevole all'interno della scrollview.

Pensala in questo modo: c'è un'asimmetria nei vincoli di associazione a una scrollview: i vincoli dalla scrollview al mondo "esterno" (genitore) determinano la dimensione e la posizione della scrollview come al solito. Ma i vincoli "all'interno" di scrollview sono in realtà l'impostazione della dimensione e della posizione dell'area scorrevole della scrollview, legandola al contenuto.

Questo non è del tutto ovvio perché quando si impostano i vincoli XCode suggerirà sempre la spaziatura corrente e potrebbe non venire mai in mente di modificare intenzionalmente i vincoli rivolti verso l'interno e verso l'esterno in un modo che sia in conflitto. Ma puoi farlo e hanno il significato sopra descritto: uno controlla il layout di visualizzazione a scorrimento e uno controlla la dimensione dell'area del contenuto scorrevole.

Mi sono imbattuto in questo per caso e poi vedere come sembrava funzionare mi ha portato a questo articolo che lo spiega completamente e cita la fonte dei documenti di Apple per questo:

https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

Un'ultima informazione critica, sulla dimensione auto-determinata del contenuto: potresti sentire di essere in un catch-22 qui perché normalmente ridimensioni il tuo contenuto ad es. La larghezza della vista genitore, ma in questo caso il genitore è la vista a scorrimento e come descritto sopra, il vincolo non influirà sulla dimensione del contenuto. La risposta quièdi ricordare che puoi limitare gli elementi agli elementi non direttamente vicini nella tua gerarchia di visualizzazione: ad es. Puoi impostare la larghezza della visualizzazione del contenuto alla larghezza della visualizzazione principale invece di provare invano a farla fare alla visualizzazione a scorrimento per te.


2

Se si fa clic sull'icona Proprietà di qualsiasi controller di visualizzazione in Interface Builder, è possibile impostarlo su una dimensione "Forma libera" in Metriche simulate e modificare la dimensione della vista principale in modo che corrisponda alla dimensione del contenuto desiderata.

In questo modo puoi creare il contenuto del tuo ScrollView come se fosse un'unica grande vista. Poiché è solo una metrica simulata, il controller della vista verrà ridimensionato ai limiti della finestra quando viene caricato.


2

La configurazione di un UIScrollView tramite Interface Builder non è intuitiva. Ecco la mia lista di controllo per configurarlo:

  1. Seleziona il file XIB di UIViewController. In "Identity Inspector" del generatore di interfacce, modificare l'UIView nel tipo di classe UIScrollView

  2. In "File Inspector", deseleziona il layout automatico

  3. In "Attributes Inspector", modifica le dimensioni in Freeform. È quindi possibile allungare manualmente la visualizzazione a scorrimento oppure specificare una larghezza e un'altezza personalizzate in "Impostazioni dimensioni".

  4. In "Identity Inspector", aggiungi un nuovo attributo di runtime definito dall'utente chiamato "contentSize" di tipo "Size" e modificalo in un valore come {320, 1000}. Non è più possibile impostarlo a livello di programmazione e quindi è necessario questo passaggio in modo che Scroll View sappia che il contenuto della Scroll View è più grande della finestra.


2

Basta rimuovere l'autoLayout sulla tua visualizzazione a scorrimento. quindi il codice è semplice come questo:

scrollviewName.contentSize = CGSizeMake(0, 650);

basta creare una proprietà iboulet sul file .h quindi sintetizzare su file .m. Assicurati che lo scorrimento sia abilitato.


1

Sì, st3fan ha ragione, la proprietà contentSize di UIScrollView deve essere impostata. Ma non dovresti disattivare il layout automatico per questo scopo. Puoi facilmente configurare contentSize di UIScrollView con il layout automatico solo in IB, senza alcun codice.

È importante comprendere che quando si utilizza il layout automatico contentSize di UIScrollView non è impostato direttamente, viene calcolato in base ai vincoli di tutte le sottoview di UIScrollView. E tutto ciò di cui hai bisogno è fornire i vincoli appropriati per le sottoview per entrambe le direzioni.

Ad esempio, se hai solo una sottoview puoi impostarne l'altezza e lo spazio dall'alto e dal basso su superview (cioè scrollView nel nostro caso) contentSize.height è calcolato come somma

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.width viene calcolato in modo simile dai vincoli orizzontali.

Se ci sono troppo pochi vincoli per calcolare il contenuto, viene mostrato un piccolo pulsante rosso vicino alla voce Visualizza scena controller per informare sull'ambiguità del layout.

Se ci sono molte visualizzazioni secondarie, potrebbe trattarsi di una "catena" di vincoli: dall'alto alla sottoview più alta, altezze e spazi tra le sottoview e la sottoview più bassa verso il basso come nella risposta di Danyal Aytekin .

Ma in pratica nella maggior parte dei casièpiù conveniente solo aggiungere una vista vuota con le dimensioni richieste e impostare gli spazi in alto, a sinistra, in basso, a destra di scrollView a 0. Puoi usare questa vista come "vista del contenuto" cioè mettere tutte le altre sottoviste su di essa o se hai già molte sottoview e non vuoi spostarle e impostare nuovamente il layout, puoi aggiungere questa vista ausiliaria alle sottoview esistenti e renderla nascosta.

Per rendere scrollView scorrevole il contenuto calcolato deve essere maggiore della dimensione scrollView.


1

Puoi avere UIScrollView in StoryBoard con Autolayouts. Fondamentalmente ciò di cui hai bisogno è:

  1. Aggiungi UIScrollView
  2. Aggiungi tutti i vincoli (come gli inserti dai bordi superiore, sinistro, destro e inferiore)
  3. Aggiungi un UIView "contenitore" a UIScrollView
  4. Se vuoi solo uno scorrimento unidirezionale (diciamo verticale): imposta l'altezza in modo esplicito (per l'istanza, 600) e collega la larghezza alla larghezza di UIScrollView.
  5. Se vuoi lo scorrimento bidirezionale, imposta sia la larghezza che l'altezza.

impostazione dello storyboard



0

Trovo un modo più conveniente.

1: ridimensiona le dimensioni della visualizzazione a scorrimento per contenere tutta l'interfaccia utente al suo interno.

2: Aggiungi un iboutlet della visualizzazione a scorrimento.

3: In viewDidLoad, salva il frame.size della visualizzazione a scorrimento.
(es. _scrollSize = _scrollView.frame.size;)

4: In viewWillAppear, imposta contentSize in base alla CGSize salvata in precedenza.
(ad es. _scrollView.contentSize = _scrollSize;)

5: Fatto ~


0
  1. Aggiungi UIViewController
  2. In UIViewController 'Attribute Inspector -> Simulated Metrics' set size Freeform
  3. In UIViewController 'Size Inspector -> View Controller' imposta l'altezza 800
  4. Aggiungi UIScrollView in UIViewController
  5. Aggiungi tutti i vincoli a UIScrollView (in alto, a sinistra, a destra, in basso) e aggiungi l'allineamento X = center
  6. Aggiungi UIView in UIScrollView
  7. Aggiungi tutti i vincoli a UIView (in alto, a sinistra, a destra, in basso) e aggiungi l'allineamento X = centro. Sì, come per UIScrollView in # 3, ma per UIView
  8. Aggiungi vincolo di altezza a UIView. Ad esempio 780
  9. Correre

Storyboard


0

Crea un nuovo progetto Xcode

Vai al file Main.storyboard

Seleziona ScrollView dalla libreria degli oggetti.

Imposta il frame per ScrollView.

Aggiungi un'altra visualizzazione per scorrere la visualizzazione e mantenere la cornice uguale a quella di ScrollView.

Ora per impostare la sua altezza e larghezza dinamicamente, puoi configurare A UIScrollView usando il layout automatico in XIB

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.