Come usare UIScrollView nello Storyboard


125

Ho una vista di scorrimento con contenuto alto 1000 px e vorrei poterlo disporre per un facile design sullo storyboard.
So che può essere fatto programmaticamente, ma voglio davvero essere in grado di vederlo visivamente. Ogni volta che inserisco una vista di scorrimento su un controller di visualizzazione, questa non scorre. È possibile farlo funzionare come voglio o devo farlo nel codice?


1
Salve a tutti, per favore vedi i commenti qui sotto per nuovi modi per farlo. L'ho scritto 2 anni fa e xCode è cambiato molto. Ci sono altri modi per farlo ora, quindi fai attenzione. Soluzioni iOS 7 e iOS 8 suggerite nei commenti
Alex Reynolds,

Eccomi di nuovo 2 anni dopo ancora ricevendo commenti su come questo non funziona o il completamento automatico è meglio. La domanda originale era come farlo in iOS 5/6. In questi giorni uso solo il autolayout, quindi dovresti / puoi farlo anche tu. Consulta le risposte su autolayout per assistenza. Si prega di valutare le risposte di autolayout se sono utili. Grazie a tutti
Alex Reynolds,

Risposte:


149

Sto rispondendo alla mia domanda perché ho appena trascorso 2 ore per trovare la soluzione e StackOverflow consente questo stile di QA.

Inizia a finire qui è come farlo funzionare nello storyboard.

1: vai al tuo controller di visualizzazione e fai clic su Attribute Inspector.

2: cambia la dimensione in Freeforminvece di Inferred.

3: vai alla vista principale su quello storyboard, non alla vista di scorrimento ma piuttosto alla vista di livello superiore.

4: fare clic Size Inspectore impostare questa vista sulla dimensione desiderata. Ho cambiato la mia altezza a 1000.

Ora vedrai che lo storyboard ha la tua configurazione di visualizzazione in modo da poter vedere l'intera altezza del tuo scorrimento per un facile design.

5: rilascia una vista di scorrimento e allungala in modo da occupare l'intera vista. Ora dovresti avere una vista di scorrimento con dimensioni di 320.1000 seduti su una vista nel controller della vista.

Ora dobbiamo farlo scorrere e dobbiamo mostrare i contenuti correttamente.

6: fare clic sulla vista di scorrimento e fare clic su Identity Inspector.

7: Aggiungi a User Defined runtime attributecon KeyPath, contentSizequindi digita SIZE e inserisci le dimensioni del contenuto. Per me lo è (320, 1000).

Dal momento che vogliamo vedere tutta la nostra vista di scorrimento sullo storyboard, l'abbiamo allungata e ha un frame di 320.1000, ma affinché questo funzioni nella nostra app dobbiamo cambiare il frame fino a quello che sarà lo scrollview visibile.

8: aggiungere a runtime attributecon KeyPath framecon tipo RECT e 0,0.320.416.

Ora quando eseguiamo la nostra app avremo una scrollview visibile con un frame di 0,0.320, 416 e possiamo scorrere fino a 1000. Siamo in grado di impaginare le nostre subview e immagini e quant'altro nello Storyboard nel modo in cui vogliamo che appaiano. Quindi i nostri attributi di runtime assicurano di visualizzarlo correttamente. Tutto questo senza 1 riga di codice.


5
Se si utilizza correttamente la funzione di ridimensionamento automatico della vista di scorrimento, non è necessario definire l' frameattributo. In effetti, tutti i dispositivi non hanno le stesse dimensioni esatte (iPhone 5).
Tronix117,

Tronix117, come risolvi questo problema senza quell'attributo?
Andras Hatvani,

2
Se hai una soluzione per iOS 7 fammi sapere. Questa risposta è stata pubblicata più di un anno fa prima di iOS 7. Sono invasa oppure aggiornerei questo per iPhone5 e iOS7
Alex Reynolds,

2
NOTA: Soluzione per FOR iOS7 è giù di sotto stackoverflow.com/a/22489795/1553014
Raja Rao

1
Nota: Per iOS 8.3 XCode 6.3, la risposta è qui: stackoverflow.com/questions/26742230/...
T.Coutlakis

51

Ecco i passaggi Auto Layoutche hanno funzionato per me su XCode 8.2.1.

  1. Selezionare Size Inspectordi View Controllere cambiare Simulated Sizein Freeformcon altezza 1000 anziché Fixed.
  2. Rinomina la vista View Controllercome RootView .
  3. Trascina una Scroll Viewsottoview di RootView e rinominala come ScrollView .
  4. Aggiungi vincoli per ScrollView :
    • ScrollView [Top, Bottom, Leading, Trailing] = RootView [Top, Bottom, Leading, Trailing]
  5. Trascina una Vertical Stack Viewsottoview di ScrollView e rinominala come ContentView .
  6. Aggiungi vincoli per ContentView :
    • ContentView .height = 1000
    • ContentView [Superiore, Inferiore, Principale, Trailing, Larghezza] = ScrollView [Superiore, Inferiore, Principale, Trailing, Larghezza]
  7. Selezionare Attributes Inspectordi contentView , e cambiare Distributional Fill Equallyposto di Fill.
  8. Trascina una Viewsottoview di ContentView e rinominala come RedView .
  9. Imposta Redcome sfondo di RedView .
  10. Trascina una Viewsottoview di ContentView e rinominala come BlueView .
  11. Imposta Bluecome sfondo di BlueView .
  12. Seleziona RootView e fai clic sul Update Framespulsante.
    • Update Framesè un nuovo pulsante in Xcode8, invece del Resolve Auto Layout Issuespulsante. Sembra un pulsante di aggiornamento, situato nella barra di controllo sotto lo Storyboard: Pulsante Aggiorna cornici

Visualizza gerarchia:

  • RootView
    • ScrollView
      • contentView
        • Redview
        • BlueView

Visualizza scena controller (altezza: 1000):

scena

Esegui su iPhone7 (altezza: 1334/2):

dimostrazione


sto avendo lo stesso problema e mi chiedo se questo funzionerebbe quando la mia scrollview non ha le dimensioni di rootview?
GalaxyVintage

Ma il fatto è che avrà uno spazio vuoto in fondo per ipad
G.Abhisek,

Una nota per impostare BlueViewdall'alto verso RedViewil basso per i principianti come me (Xcode 8.2): 1) Trascinare la parte BlueView inferiore RedView (ovvero non devono sovrapporsi o il passaggio 4) non funzionerà). 2) Apri il menu dei pin in basso. 3) Fare clic sulla piccola freccia a destra del vincolo del margine superiore. 4) Seleziona RedViewda quel menu e imposta il valore su 0. Questo è diverso dalle precedenti versioni di Xcode in cui potresti fare cose come Editor-> Pin-> ...
Krøllebølle

solo curioso, perché usi una vista stack verticale invece di una normale UIView?
Changerrs,

@Changerrs che uso UIStackViewper evitare il problema di impostare i vincoli.
jqgsninimo

43

Ecco i passaggi che hanno funzionato per me su iOS 7 e XCode 5.

  1. Trascina un ViewController (viene fornito con UIView "Visualizza").

    1.1 Selezionare "Visualizza controller" e selezionare "File Inspector" e deselezionare "Layout automatico".

  2. Trascina un ScrollView (come figlio dell'UIView "View" di ViewController)
  3. Seleziona ScrollView e apri "Identity Inspector".
  4. Immettere "contentSize" per keyPath. Seleziona "Dimensione" per Tipo. Immettere {320, 1000} per valore.

    Nota: il passaggio 4 sta semplicemente dicendo che lo scroller contiene alcuni contenuti le cui dimensioni sono 320x1000 unità. Quindi l'impostazione contentSize farà funzionare lo scroller.

  5. Seleziona Visualizza controller, seleziona "Impostazioni attributi" quindi seleziona Forma libera da Dimensione.

    Nota: il passaggio 5 ci consentirà di modificare le dimensioni di "Visualizza" fornito con il controller di visualizzazione.

  6. Seleziona "Visualizza", quindi seleziona "Impostazioni dimensioni".

  7. Impostare Larghezza su 320 e altezza su 1000.

Nota: 5, 6 e 7 è puramente per noi vedere la vista estesa o estesa all'interno di StoryBoard. Nota: assicurarsi di deselezionare "Layout automatico" su Visualizza controller.

La gerarchia della vista dovrebbe essere simile a: gerarchia


3
Questa tecnica funziona ancora a partire da Xcode 6.1 e iOS 8.1.
Chris Harris,

1
Sorprendente. Grazie per questo. Funziona sicuramente su Xcode 6.1 e iOS 8.1 come menzionato.
Shanker Kaura,

45
Ok ... quindi se avessimo BISOGNO di autolayout?
PostCodeism,

1
Mutch meglio rispondere .. Grazie!
StefMa,

1
Soluzione per iOS 8 Auto layout e la classe dimensionale stackoverflow.com/questions/26742230/...
Jithin

13

Dopo ore di tentativi ed errori, ho trovato un modo molto semplice per mettere i contenuti in scrollview che sono "offscreen". Testato con XCode 5 e iOS 7. Puoi farlo quasi interamente in Storyboard, usando 2 piccoli trucchi / soluzioni:

  1. Trascina un controller di visualizzazione sullo storyboard.
  2. Trascina uno scrollView su questo viewController, per la demo puoi lasciare le sue dimensioni predefinite, coprendo l'intero schermo.
  3. Ora arriva il trucco 1 : prima di aggiungere qualsiasi elemento a scrollView, trascina in una 'vista' normale (questa vista sarà ingrandita rispetto allo schermo e conterrà tutti gli elementi secondari come pulsanti, etichette, ... chiamiamolo il ' vista chiusa ').
  4. Lascia che la dimensione Y di questa vista inclusa nella finestra di ispezione dimensioni sia ad esempio 800.
  5. Inserisci un'etichetta sulla vista chiusa, da qualche parte nella posizione Y 200, chiamala "etichetta 1".
  6. Trucco 2 : assicurati che la vista racchiusa sia selezionata ( non scrollView! ) E imposta la sua posizione Y ad esempio -250, in modo da poter aggiungere un elemento che è 'fuori' dallo schermo
  7. Inserisci un'etichetta, da qualche parte nella parte inferiore dello schermo, chiamala "etichetta 2". Questa etichetta è in realtà "fuori schermo".
  8. Ripristina la posizione Y della vista chiusa su 0, non vedrai più l'etichetta 2, poiché era posizionata fuori dallo schermo.

Finora per il lavoro dello storyboard, ora è necessario aggiungere una singola riga di codice al metodo 'viewDidLoad' di viewController per impostare i contenuti scrollViews in modo che contenga l'intera 'vista chiusa'. Non ho trovato un modo per farlo in Storyboard:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scrollView.contentSize = CGSizeMake(320, 800);
}

Puoi provare a farlo aggiungendo un contentSizekeyPath sizea scrollView in Identity Inspector e impostandolo su (320, 1000).

Penso che Apple dovrebbe rendere tutto più semplice nello storyboard, in un TableViewController puoi semplicemente scorrere fuori dallo schermo in Storyboard (aggiungi solo 20 celle e vedrai che puoi semplicemente scorrere), questo dovrebbe essere possibile anche con un ScrollViewController.


1
questo è jaxvy corretto, quando recentemente ho importato la mia app per supportare il layout automatico, ho sostituito la vista di scorrimento con una vista di tabella statica. Fa lo stesso lavoro e ha anche alcuni vantaggi extra.
Ronny Webers,

Che ne dici di cambiare contenuto Dimensiona in modo dinamico perché tutti gli iPhone hanno dimensioni diverse
veeresh kumbar

8

Far funzionare Scrolling in iOS7 e layout automatico in iOS 7 e XCode 5.

Inoltre: https://stackoverflow.com/a/22489795/1553014

Apparentemente, tutto ciò che dobbiamo fare è:

  1. Impostare tutti i vincoli su Vista scorrimento (ovvero correggere prima la vista di scorrimento)

  2. Quindi imposta il vincolo distance-from-scrollView sull'elemento più in basso per scorrere la vista (che è la super vista).

Nota: il passaggio 2 indicherà lo storyboard in cui si trova l'ultimo contenuto nella vista di scorrimento.


7

Per questo esempio, ho deselezionato la funzione Autolayout del builder Interface. E sto ancora usando (senza alcun motivo) la relativamente vecchia versione 4.6.1 di Xcode.

Inizia con un controller di visualizzazione che ha una vista di scorrimento (la vista principale).

1: Aggiungi una vista contenitore, dalla Libreria oggetti, alla vista di scorrimento. Si noti che un nuovo controller di visualizzazione viene aggiunto allo storyboard ed è collegato al controller di visualizzazione con la vista di scorrimento.

2: Seleziona la vista contenitore e, in Impostazioni dimensioni, rendila ancorata in alto e a sinistra senza ridimensionamento automatico.

inserisci qui la descrizione dell'immagine

3: modifica l'altezza su 1000. (1000 viene utilizzato per questo esempio. Dovresti applicare il valore richiesto).

4: Seleziona il nuovo controller di visualizzazione e, dalla finestra di ispezione Attributi, modifica Dimensione in Forma libera.

inserisci qui la descrizione dell'immagine

5: Seleziona la vista del nuovo controller di visualizzazione e, in Impostazioni dimensioni, modifica l'altezza su 1000 (che è uguale all'altezza della vista contenitore).

6: per il test in un secondo momento, mentre si è ancora nella vista del nuovo controller di visualizzazione, aggiungere un'etichetta nella parte superiore e nella parte inferiore della vista.

7: selezionare la vista di scorrimento dal controller della vista originale. Nella finestra di ispezione Identità, aggiungere un attributo con keyPath impostato su contentSize, digitare set su Size e il valore impostato su {320, 1000} (o la dimensione della vista del contenitore).

inserisci qui la descrizione dell'immagine

8: esegui il simulatore iPhone da 4 pollici. Dovresti essere in grado di scorrere dall'etichetta superiore fino all'etichetta inferiore.

9: esegui su iPhone Simulator da 3,5 pollici. Dovresti essere in grado di scorrere dall'etichetta superiore fino all'etichetta inferiore.

Ricorda che Xcode 4.6.1 può essere creato solo per iOS6 e versioni precedenti. Utilizzando questo approccio e la creazione per iOS6, sono ancora in grado di ottenere gli stessi risultati quando l'app viene eseguita su iOS7.


5

Nota che all'interno di a UITableView, puoi effettivamente scorrere la vista tabella selezionando una cella o un elemento in essa e scorrendo verso l'alto o verso il basso con il trackpad.

Per un motivo UIScrollView, mi piace il suggerimento di Alex, ma consiglierei di cambiare temporaneamente il controller di visualizzazione in forma libera, aumentare l'altezza della vista radice, costruire l'interfaccia utente (passaggi 1-5) e quindi riportarlo alla dimensione inferita standard quando hai finito in modo da non dover codificare le dimensioni del contenuto come attributi di runtime. Se lo fai, ti stai aprendo a molti problemi di manutenzione cercando di supportare sia i dispositivi da 3,5 "e 4", sia la possibilità di aumentare le risoluzioni dello schermo in futuro.


4

È necessario impostare solo la proprietà contentSize su viewDidAppear, come in questo esempio:

- (void)viewDidAppear:(BOOL)animated{

     [super viewDidAppear:animated];
     self.scrollView.contentSize=CGSizeMake(306,400.0);

}

Risolve i problemi di autolayout e funziona bene su iOS7.


NOTA: Alex Zavatone offre un modo alternativo per impostare contentSize, senza scrivere codice.
ToolmakerSteve

4

Disclaimer: - Solo per iOS 9 e versioni successive (Stack View).

Se stai distribuendo la tua app su dispositivi iOS 9, usa una vista stack . Ecco i passaggi: -

  1. Aggiungi una vista di scorrimento con vincoli: pin a sinistra, a destra, in basso, in alto (senza margini) in superview (vista)
  2. Aggiungi una vista pila con gli stessi vincoli per scorrere la vista.
  3. Stack Visualizza altri vincoli: - stackView.bottom = view.bottom e stackView.width = scrollView.width
  4. Inizia ad aggiungere le tue opinioni. La vista di scorrimento deciderà di scorrere in base alla dimensione della vista pila (che è essenzialmente la vista contenuto)

1
Questa è una tecnica utile che minimizza il numero di vincoli che devi aggiungere manualmente. In generale, il modo per ottenere lo scorrimento consiste nell'assicurarsi che vi siano vincoli sufficienti per il completamento automatico per calcolare la dimensione del contenuto. Stack view fa molto di questo vincolo per te. Imposta lo stack spacingper mettere un po 'di spazio tra le sottoview (figli). Se hai bisogno di più spazio tra solo due visualizzazioni secondarie, aggiungi un figlio "spacer": una UIView trasparente con dimensioni fisse.
ToolmakerSteve

4

In iOS7 ho scoperto che se avessi una vista all'interno di un UIScrollView su un ViewController di dimensioni FreeForm, non sarebbe scorrere nell'app, indipendentemente da ciò che ho fatto. Ho giocato e ho scoperto che sembrava funzionare il seguente, che non usa FreeForms:

  1. Inserisci un UIScrollView nella vista principale di un ViewController

  2. Impostare i vincoli di Autolayout su ScrollView come appropriato. Per me ho usato 0 per la guida al layout superiore e 0 per la guida al layout inferiore

  3. All'interno di ScrollView, posizionare una vista contenitore. Imposta la sua altezza come preferisci (ad es. 1000)

  4. Aggiungi un vincolo Altezza (1000) al Contenitore in modo che non si ridimensioni. Il fondo sarà oltre la fine del modulo.

  5. Aggiungi la riga [self.scrollView setContentSize: CGSizeMake (320, 1000)]; al ViewController che contiene scrollView (che è stato collegato come IBOutlet)

Il ViewController (aggiunto automaticamente) associato al contenitore avrà l'altezza desiderata (1000) in Interface Builder e scorrerà anche correttamente nel controller di visualizzazione originale. Ora puoi utilizzare ViewController del contenitore per impaginare i tuoi controlli.


Ho votato questa risposta perché mi piace la tecnica; tuttavia credo che ti sbagli sul fatto che FreeForm VC interferisca con lo scorrimento, indipendentemente dalla versione di iOS. A partire da iOS 6 (che ha aggiunto Layout automatico), un set completo di vincoli, come documentato in altre risposte, sarà scorrere. Non credo che FreeForm interferisca con quello (anche se non l'ho provato). Forse ti mancava un vincolo non ovvio; ScrollView + AutoLayout è un po 'un trucco.
ToolmakerSteve

3

voglio mettere i miei 5 centesimi alla risposta accettata: ho cercato argomento per 2 giorni e finalmente ho trovato una soluzione che userò sempre da ora in poi

vai all'elemento 4 nella risposta accettata e dimentica di aggiungere attributi di frame, contenuti e così via

per rendere tutto automatico basta usare la soluzione da questo link

tutto è chiaro, facile, elegante e funziona come un fascino su iOS 7. Sono abbastanza contento di tutto ciò che lol



la tua soluzione (se segui il tuo link fino alla fine) prevede l'aggiunta di una riga di codice, quindi questo non è particolarmente in linea con la domanda - usando solo lo storyboard
Boris Gafurov

@BorisGafurov non è comunque un po 'datato con iOS7. e mb non è in linea, ma sono sicuro che abbia aiutato un paio di persone comunque .. quindi lascia che sia
jungle_mole

3

Ecco una soluzione semplice.

  1. Impostare l'attributo size del controller della vista nello storyboard su "Freeform" e impostare la dimensione desiderata. Assicurati che sia abbastanza grande da adattarsi al contenuto completo della vista di scorrimento.

  2. Aggiungi la vista di scorrimento e imposta i vincoli come faresti normalmente. ad esempio, se si desidera che la vista di scorrimento abbia le dimensioni della vista, quindi collegare i margini superiore, inferiore, iniziale e finale alla superview come si farebbe normalmente.

  3. Ora assicurati solo che ci siano vincoli nelle viste secondarie della vista di scorrimento che collegano la parte superiore e inferiore della vista di scorrimento. Lo stesso vale per sinistra e destra se si dispone di scorrimento orizzontale.

inserisci qui la descrizione dell'immagine


2

Ecco un po 'di una risposta sporca che arriva alla stessa soluzione per le viste di scorrimento verticali, ma (contro l'etica di stackoverflow) non risponde alla domanda. Invece di usare un scrollView, basta usare un UITableView, trascinare un normale UIView nell'intestazione e renderlo grande quanto vuoi, ora puoi scorrere il contenuto nello storyboard.


IMHO, è una buona risposta, non contro l'etica di StackOverflow, per suggerire un approccio alternativo (a meno che OP non dica specificamente che devono farlo nel modo in cui stanno chiedendo). E il valore più grande di StackOverflow è aiutare tutte le altre persone che arrivano e leggi le domande e risposte. :)
ToolmakerSteve

0

Apparentemente non è necessario specificare l'altezza affatto! Il che è fantastico se cambia per qualche motivo (ridimensionate i componenti o cambiate le dimensioni del carattere).

Ho appena seguito questo tutorial e tutto ha funzionato: http://natashatherobot.com/ios-autolayout-scrollview/

(Nota a margine: non è necessario implementare viewDidLayoutSubviews a meno che non si desideri centrare la vista, quindi l'elenco dei passaggi è ancora più breve).

Spero che aiuti!


0

La chiave è contentSize.

Questo spesso manca e non è indicato quando si aggiunge un UIScrollView.

Seleziona UIScrollView e seleziona Identity Inspector.

Aggiungi un contentSizekeyPath come sizea allo scrollView in Identity Inspector e impostandolo su (320, 1000).

Scorri via.


Questo è un approccio e l'ho usato da solo. Tuttavia, non lo considero l'approccio preferito. È "più pulito / più flessibile" fornire una serie completa di vincoli, in modo tale che l'autolayout possa calcolare la dimensione del contenuto stesso. Tre alternative: vincoli dall'alto verso il basso , oppure utilizzare la vista pila o vincolare alla posizione dell'elemento inferiore .
ToolmakerSteve

0

Se si utilizza il layout automatico, l'approccio migliore consiste nell'utilizzare UITableViewController con celle statiche nello storyboard.

Una volta ho anche affrontato il problema con una vista che richiede molto più scorrimento, quindi cambia UIScrollView con la tecnica sopra menzionata.


0

Ecco come impostare una vista di scorrimento usando Xcode 11

1 - Aggiungi scrollview e imposta i vincoli superiore, inferiore, iniziale e finale

inserisci qui la descrizione dell'immagine

2 - Aggiungi una vista del contenuto alla vista di scorrimento, trascina una connessione nella Guida al layout del contenuto e seleziona Leading, Top, Bottom e Trailing. Assicurati di impostare i suoi 'valori su 0 o sulle costanti che desideri.

inserisci qui la descrizione dell'immagine

3 - Trascina dalla vista contenuto alla guida layout cornice e seleziona Pari larghezze

inserisci qui la descrizione dell'immagine

4 - Impostare una costante del vincolo di altezza sulla vista contenuto

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.