Como usar o UIScrollView no Storyboard

125

Eu tenho uma exibição de rolagem com conteúdo de 1000 px de altura e gostaria de colocá-la para facilitar o design no storyboard.
Eu sei que isso pode ser feito programaticamente, mas eu realmente quero poder visualizá-lo visualmente. Toda vez que eu coloco uma exibição de rolagem em um controlador de exibição, ela não rola. É possível fazê-lo funcionar como eu quero ou tenho que fazê-lo no código?

Alex Reynolds
fonte
1
Oi pessoal, veja os comentários abaixo para novas maneiras de fazer isso. Eu escrevi isso há 2 anos e o xCode mudou muito. Existem outras maneiras de fazer isso agora, portanto, esteja ciente. Soluções para iOS 7 e iOS 8 sugeridas nos comentários
Alex Reynolds
Aqui estão mais uma vez, dois anos depois, ainda recebendo comentários sobre como isso não funciona ou se o autolayout é melhor. A questão original era como fazê-lo no ios 5/6. Hoje em dia, só uso o autolayout para que você deva / possa também. Veja as respostas no autolayout para obter ajuda. Voto positivo as respostas do pagamento automático, se forem úteis. Obrigado a todos #
Alex Reynolds

Respostas:

149

Estou respondendo minha própria pergunta, porque passei apenas duas horas para encontrar a solução e o StackOverflow permite esse estilo de controle de qualidade.

Do início ao fim, aqui está como fazê-lo funcionar no storyboard.

1: vá para você visualizar o controlador e clique em Attribute Inspector.

2: altere o tamanho para em Freeformvez de inferido.

3: Vá para a visualização principal desse storyboard, não a visualização de rolagem, mas a visualização de nível superior.

4: Clique Size Inspectore defina essa visualização para o tamanho desejado. Eu mudei minha altura para 1000.

Agora você verá que o storyboard tem sua visualização configurada para poder ver toda a altura do seu pergaminho para facilitar o design.

5: Coloque uma vista de rolagem e estique-a para que ocupe toda a vista. Agora você deve ter uma visualização de rolagem com tamanho de 320.1000 em uma visualização no seu controlador de visualização.

Agora precisamos fazer a rolagem e mostrar o conteúdo corretamente.

6: Clique no seu scrollview e clique em Identity Inspector.

7: Adicione um User Defined runtime attributecom KeyPath do contentSizetipo SIZE e insira o tamanho do seu conteúdo. Para mim é (320, 1000).

Como queremos ver toda a nossa exibição de rolagem no storyboard, a esticamos e ela possui um quadro de 320.1000, mas para que isso funcione em nosso aplicativo, precisamos alterar o quadro para o que será a visualização de rolagem visível.

8: adicione a runtime attributecom KeyPath framecom o tipo RECT e 0,0,320,416.

Agora, quando executamos nosso aplicativo, teremos uma exibição de rolagem visível com um quadro de 0,0.320, 416 e podemos rolar para 1000. Podemos organizar nossas sub-visualizações e imagens e outros enfeites no Storyboard da maneira que queremos que apareçam. Em seguida, nossos atributos de tempo de execução certifique-se de exibi-lo corretamente. Tudo isso sem 1 linha de código.

Alex Reynolds
fonte
5
Se você usar corretamente o recurso de dimensionamento automático do scrollview, não precisará definir o frameatributo. De fato, todos os dispositivos não têm exatamente o mesmo tamanho (iPhone 5).
precisa saber é o seguinte
Tronix117, então como você resolve esse problema sem esse atributo?
Andras Hatvani
2
Se você tiver uma solução para o iOS 7, entre em contato. Essa resposta foi postada mais de um ano atrás, antes iOS 7. Estou inundado ou então eu atualizar esta para iPhone5 e iOS7
Alex Reynolds
2
NOTA: A solução para iOS7 está abaixo stackoverflow.com/a/22489795/1553014
Raja Rao
1
Nota: Para o iOS 8.3 XCode 6.3, a resposta está aqui: stackoverflow.com/questions/26742230/…
T.Coutlakis
51

Aqui estão as etapas Auto Layoutque funcionaram para mim no XCode 8.2.1.

  1. Selecione Size Inspectorde View Controllere mude Simulated Sizepara Freeformcom altura 1000 em vez de Fixed.
  2. Renomeie a exibição View Controllercomo RootView .
  3. Arraste um Scroll Viewcomo subview do RootView e renomeie-o como ScrollView .
  4. Adicione restrições ao ScrollView :
    • ScrollView [Superior, Inferior, À esquerda , À direita] = RootView [Superior, Inferior, À esquerda , À direita]
  5. Arraste um Vertical Stack Viewcomo subview do ScrollView e renomeie-o como ContentView .
  6. Adicione restrições ao ContentView :
    • ContentView .height = 1000
    • ContentView [Superior, Inferior, À esquerda, À direita, Largura] = ScrollView [Superior, Inferior, À esquerda, À direita, Largura]
  7. Escolha Attributes Inspectorde ContentView e alterar Distributiona Fill Equallyvez de Fill.
  8. Arraste um Viewcomo subview do ContentView e renomeie-o como RedView .
  9. Defina Redcomo plano de fundo do RedView .
  10. Arraste um Viewcomo subview do ContentView e renomeie-o como BlueView .
  11. Defina Bluecomo plano de fundo do BlueView .
  12. Selecione RootView e clique no Update Framesbotão.
    • Update Framesé um novo botão no Xcode8, em vez do Resolve Auto Layout Issuesbotão. Parece um botão de atualização, localizado na barra de controle abaixo do Storyboard: Botão Atualizar quadros

Ver hierarquia:

  • RootView
    • ScrollView
      • ContentView
        • RedView
        • BlueView

Visualizar cena do controlador (altura: 1000):

cena

Execute no iPhone7 (Altura: 1334/2):

demonstração

jqgsninimo
fonte
Estou tendo o mesmo problema e gostaria de saber se isso funcionaria quando meu scrollview não é o tamanho do rootview?
GalaxyVintage
Mas a coisa é que ele wil têm um espaço em branco na parte inferior para ipad
G.Abhisek
Uma observação para definir BlueViewa parte superior RedViewda base para iniciantes como eu (Xcode 8.2): 1) Arraste o botão BlueView abaixo RedView (ou seja, eles não devem se sobrepor ou a etapa 4) não funcionará). 2) Abra o menu de pinos na parte inferior. 3) Clique na seta pequena à direita da restrição de margem superior. 4) Selecione a RedViewpartir desse menu e defina o valor como 0. Isso é diferente das versões anteriores do Xcode, nas quais você pode fazer coisas como Editor-> Pin-> ...
Krøllebølle 5/17
só por curiosidade, por que você usa uma exibição de pilha vertical em vez de uma UIView regular?
Changerrs
@ Changerrs que uso UIStackViewpara evitar o problema de definir restrições.
Jqgsninimo 31/07/19
43

Aqui estão as etapas que funcionaram para mim no iOS 7 e no XCode 5.

  1. Arraste um ViewController (ele vem com o UIView "View").

    1.1 Selecione "Visualizar controlador", selecione "File Inspector" e desmarque "Layout automático".

  2. Arraste um ScrollView (como filho do UIView "View" do ViewController)
  3. Selecione ScrollView e abra "Identity Inspector".
  4. Digite "contentSize" para keyPath. Selecione "Tamanho" para Tipo. E digite {320, 1000} para obter o valor.

    Nota: A Etapa 4 está simplesmente dizendo que o scroller contém algum conteúdo cujo tamanho é 320x1000 unidades. Portanto, definir contentSize fará o scroller funcionar.

  5. Selecione View Controller, selecione "Attributes Inspector" e selecione Freeform em Size.

    Nota: a etapa 5 nos permitirá alterar o tamanho de "View" fornecido com o controlador de exibição.

  6. Selecione "Visualizar" e, em seguida, selecione "Inspetor de tamanho".

  7. Defina Largura como 320 e altura para 1000.

Nota: 5, 6 e 7 é puramente para nós vermos uma visão ampliada ou expandida no StoryBoard. Nota: Certifique-se de desmarcar "Layout automático" no View Controller.

Sua hierarquia de visualizações deve ter a seguinte aparência: hierarquia

Raja Rao
fonte
3
Essa técnica ainda funciona a partir do Xcode 6.1 e iOS 8.1.
Chris Harris
1
Surpreendente. Obrigado por isso. Definitivamente funciona no Xcode 6.1 e iOS 8.1, como mencionado.
precisa
45
Ok ... então e se precisarmos de autolayout?
PostCodeism
1
Mutch melhor resposta .. Obrigado!
StefMa
1
Solução para iOS 8 Layout automático e classe de tamanho stackoverflow.com/questions/26742230/…
jithin
13

Após horas de tentativa e erro, encontrei uma maneira muito fácil de colocar o conteúdo em visualizações de rolagem que estão fora da tela. Testado com o XCode 5 e iOS 7. Você pode fazer isso quase inteiramente no Storyboard, usando 2 pequenos truques / soluções alternativas:

  1. Arraste um controlador de exibição para o storyboard.
  2. Arraste um scrollView neste viewController, para a demonstração, você pode deixar o tamanho padrão, cobrindo a tela inteira.
  3. Agora vem o truque 1 : antes de adicionar qualquer elemento ao scrollView, arraste em uma 'visualização' regular (essa visualização será maior que a tela e conterá todos os subelementos, como botões, rótulos, ... vamos chamá-lo de ' vista anexa ').
  4. Deixe o tamanho Y da vista em anexo no inspetor de tamanho, por exemplo, 800.
  5. Coloque um rótulo na vista anexa, em algum lugar na posição Y 200, nomeie-o como 'rótulo 1'.
  6. Truque 2 : verifique se a vista anexa está selecionada ( não o scrollView! ) E defina sua posição Y como, por exemplo, -250, para que você possa adicionar um item que esteja 'fora' da tela
  7. Coloque um rótulo em algum lugar na parte inferior da tela e nomeie-o como 'rótulo 2'. Este rótulo é realmente 'fora da tela'.
  8. Redefina a posição Y da vista anexa para 0, você não verá mais o rótulo 2, pois foi posicionado fora da tela.

Até agora, para o trabalho de storyboard, agora você precisa adicionar uma única linha de código ao método 'viewDidLoad' do viewController para definir o conteúdo de scrollViews para que ele contenha toda a 'exibição anexa'. Não encontrei uma maneira de fazer isso no Storyboard:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

Você pode tentar fazer isso adicionando um contentSizekeyPath como sizea ao scrollView no Identity Inspector e configurando-o para (320, 1000).

Eu acho que a Apple deve facilitar isso no storyboard, em um TableViewController você pode simplesmente rolar para fora da tela no Storyboard (basta adicionar 20 células e verá que pode rolar), isso também deve ser possível com um ScrollViewController.

Ronny Webers
fonte
1
isso é jaxvy correto, quando recentemente relatei meu aplicativo para oferecer suporte ao layout automático, substitui a visualização por rolagem por uma visualização estática da tabela. Faz o mesmo trabalho e tem algumas vantagens extras também.
precisa
Que tal mudar contentSize dinamicamente porque todos os iPhones vem com tamanhos diferentes
Veeresh Kumbar
8

Como a rolagem funcionar no iOS7 e o layout automático no iOS 7 e no XCode 5.

Além disso: https://stackoverflow.com/a/22489795/1553014

Aparentemente, tudo o que precisamos fazer é:

  1. Defina todas as restrições como Visualização de rolagem (ou seja, corrija a visualização de rolagem primeiro)

  2. Em seguida, defina a restrição distance-from-scrollView no item mais abaixo para rolar a visualização (que é a super visualização).

Nota: A Etapa 2 informará o storyboard onde está o último conteúdo na exibição de rolagem.

Raja Rao
fonte
7

Neste exemplo, desmarquei o recurso Autolayout do construtor Interface. E ainda estou usando (sem nenhuma razão) a versão 4.6.1 relativamente antiga do Xcode.

Comece com um controlador de exibição que tenha uma exibição de rolagem sobre ele (a exibição principal).

1: Adicione uma exibição de contêiner, da Biblioteca de objetos, à exibição de rolagem. Observe que um novo controlador de exibição é adicionado ao storyboard e está vinculado ao controlador de exibição com a exibição de rolagem.

2: Selecione a visualização do contêiner e, no Inspetor de tamanhos, ancore-o na parte superior e esquerda sem redimensionar automaticamente.

insira a descrição da imagem aqui

3: Altere sua altura para 1000. (1000 é usado neste exemplo. Você deve aplicar o valor necessário.)

4: Selecione o novo controlador de exibição e, no Inspetor de atributos, altere Tamanho para Forma livre.

insira a descrição da imagem aqui

5: Selecione a vista do novo controlador de vista e, no tamanho Inspetor, altere a altura para 1000 (que é igual à altura da vista do contêiner).

6: Para seu teste posteriormente, enquanto ainda estiver na visualização do novo controlador de visualização, adicione uma etiqueta na parte superior e na parte inferior da visualização.

7: Selecione a vista de rolagem no controlador de vista original. No Inspetor de identidade, adicione um atributo com o keyPath definido como contentSize, digite definido como Tamanho e o valor definido como {320, 1000} (ou o tamanho da visualização do contêiner).

insira a descrição da imagem aqui

8: Execute no iPhone Simulator de 4 polegadas. Você poderá rolar do rótulo superior até o rótulo inferior.

9: Execute no iPhone Simulator de 3,5 polegadas. Você poderá rolar do rótulo superior até o rótulo inferior.

Lembre-se de que o Xcode 4.6.1 pode ser construído apenas para iOS6 e versões inferiores. Usando essa abordagem e criação para iOS6, ainda consigo obter os mesmos resultados quando o aplicativo é executado no iOS7.

yoninja
fonte
5

Observe que, em a UITableView, é possível rolar a visualização da tabela selecionando uma célula ou um elemento nela e rolando para cima ou para baixo com o trackpad.

Por exemplo UIScrollView, gosto da sugestão de Alex, mas recomendo alterar temporariamente o controlador de exibição para forma livre, aumentar a altura da visualização raiz, criar sua interface do usuário (etapas 1 a 5) e depois alterá-la novamente para o tamanho padrão inferido quando terminar para que você não precise codificar os tamanhos do conteúdo como atributos de tempo de execução. Se você fizer isso, estará se abrindo para muitos problemas de manutenção tentando suportar dispositivos de 3,5 "e 4", bem como a possibilidade de aumentar as resoluções de tela no futuro.

Kyle Clegg
fonte
4

Você só deve definir a propriedade contentSize no viewDidAppear, como esta amostra:

- (void)viewDidAppear:(BOOL)animated{

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

}

Ele resolve os problemas de execução automática e funciona bem no iOS7.

Lucio Fonseca
fonte
NOTA: Alex Zavatone oferece uma maneira alternativa de definir contentSize, sem escrever código.
Home
4

Isenção de responsabilidade: - Apenas para os ios 9 e acima (exibição em pilha).

Se você estiver implantando seu aplicativo em dispositivos iOS 9, use uma exibição de pilha . Aqui estão os passos: -

  1. Adicione uma visualização de rolagem com restrições - fixe à esquerda, direita, inferior, superior (sem margens) à superview (visualização)
  2. Adicione uma exibição de pilha com as mesmas restrições para rolar a exibição.
  3. Outras restrições de exibição de pilha: - stackView.bottom = view.bottom e stackView.width = scrollView.width
  4. Comece a adicionar suas visualizações. A exibição de rolagem decidirá rolar com base no tamanho da exibição de pilha (que é essencialmente sua exibição de conteúdo)
DharinS
fonte
1
Essa é uma técnica útil, que minimiza o número de restrições que você precisa adicionar manualmente. Em geral, a maneira de obter a rolagem é garantir que haja restrições suficientes para o layout automático para calcular o tamanho do conteúdo. A exibição de pilha faz muito disso para você. Defina as pilhas spacingpara colocar algum espaço entre subvisões (filhos). Se precisar de mais espaço entre apenas duas subvisões, adicione um filho "espaçador": um UIView transparente com tamanho fixo.
Home
4

No iOS7, descobri que, se eu tivesse um View dentro de um UIScrollView em um ViewController do tamanho de FreeForm, ele não rolaria no aplicativo, independentemente do que eu fiz. Eu brinquei e descobri que o seguinte parecia funcionar, que não usa FreeForms:

  1. Inserir um UIScrollView dentro da View principal de um ViewController

  2. Defina as restrições de Autolayout no ScrollView, conforme apropriado. Para mim, usei o guia de layout de 0 à parte superior e o guia de layout de 0 à parte inferior

  3. Dentro do ScrollView, coloque uma exibição de contêiner. Defina sua altura para o que quiser (por exemplo, 1000)

  4. Adicione uma restrição de altura (1000) ao contêiner para que não seja redimensionado. A parte inferior estará no final do formulário.

  5. Adicione a linha [self.scrollView setContentSize: CGSizeMake (320, 1000)]; ao ViewController que contém o scrollView (que você conectou como um IBOutlet)

O ViewController (adicionado automaticamente) associado ao Container terá a altura desejada (1000) no Interface Builder e também rolará corretamente no controlador de exibição original. Agora você pode usar o ViewController do contêiner para organizar seus controles.

nh32rg
fonte
Votou esta resposta porque gosto da técnica; no entanto, acredito que você esteja errado sobre o FreeForm VC interferir na rolagem, independentemente da versão do iOS. Começando com iOS 6 (que acrescentou Auto Layout), um conjunto completo de restrições, como documentado em outras respostas, vai rolar. Eu não acho que o FreeForm interfira nisso (embora eu não tenha tentado). Talvez você estivesse perdendo alguma restrição não óbvia; O ScrollView + AutoLayout é um pouco complicado.
Home
3

eu quero colocar meus 5 centavos na resposta aceita: estou pesquisando o tópico há 2 dias e finalmente encontrei uma solução que sempre usarei sempre daqui para frente

vá para o item 4 na resposta aceita e esqueça de adicionar atributos de quadros e conteúdos e assim por diante

para tornar tudo automático, basta usar a solução deste link

tudo é claro, fácil, elegante e funciona como um encanto no ios 7. estou muito feliz com tudo isso lol

jungle_mole
fonte
link atualizado
ToolmakerSteve
sua solução (se você seguir o seu link até o fim) envolve a adição de uma linha de código, de modo que este não é particularmente em linha com a pergunta - usando apenas storyboard
Boris Gafurov
@BorisGafurov não é um pouco desatualizado com o ios7 de qualquer maneira. e mb não é em linha, mas eu tenho certeza que têm ajudado a par de ppls qualquer forma .. que assim seja
jungle_mole
3

Aqui está uma solução simples.

  1. Defina o atributo de tamanho do seu controlador de exibição no storyboard como "Forma livre" e defina o tamanho desejado. Verifique se é grande o suficiente para caber no conteúdo completo da sua exibição de rolagem.

  2. Adicione sua visualização de rolagem e defina as restrições como faria normalmente. ou seja, se você deseja que a visualização de rolagem seja do tamanho da sua visualização, anexe as margens superior, inferior, à esquerda e à direita à superview como faria normalmente.

  3. Agora, verifique se há restrições nas subvisões da visualização de rolagem que conectam a parte superior e inferior da visualização de rolagem. O mesmo para esquerda e direita se você tiver rolagem horizontal.

insira a descrição da imagem aqui

Hulk_SMASH
fonte
2

Aqui está uma resposta um pouco suja que leva à mesma solução para visualizações de rolagem vertical, mas (contra o ethos do stackoverflow) não responde à pergunta. Em vez de usar um scrollView, basta usar um UITableView, arrastar um UIView normal para o cabeçalho e torná-lo tão grande quanto você deseja, agora você pode rolar o conteúdo no storyboard.

TimWhiting
fonte
IMHO, é uma boa resposta, não contra o ethos do stackoverflow, para sugerir uma abordagem alternativa (a menos que o OP diga especificamente que eles precisam fazer do jeito que estão perguntando.) E o maior valor do stackoverflow está ajudando todas as outras pessoas que acompanham e leia as perguntas e respostas. :)
ToolmakerSteve
0

Aparentemente, você não precisa especificar a altura! O que é ótimo se ele mudar por algum motivo (você redimensiona componentes ou altera o tamanho da fonte).

Acabei de seguir este tutorial e tudo funcionou: http://natashatherobot.com/ios-autolayout-scrollview/

(Observação: não há necessidade de implementar viewDidLayoutSubviews, a menos que você queira centralizar a visualização, para que a lista de etapas seja ainda mais curta).

Espero que ajude!

Lukasz Czerwinski
fonte
0

A chave é o contentSize.

Isso geralmente está ausente e não é indicado ao adicionar um UIScrollView.

Selecione o UIScrollView e selecione o Identity Inspector.

Adicione um contentSizekeyPath como sizea ao scrollView no Identity Inspector e defina-o como (320, 1000).

Role para longe.

Alex Zavatone
fonte
Essa é uma abordagem e eu mesma a usei. No entanto, não considero a abordagem preferida. É "mais limpo / mais flexível" fornecer um conjunto completo de restrições, de forma que o layout automático possa calcular o tamanho do conteúdo. Três alternativas: restrições de cima para baixo , ou use a exibição de pilha ou restrinja a posição do item inferior .
Home
0

Se você estiver usando o layout automático, a melhor abordagem é usar UITableViewController com células estáticas no storyboard.

Uma vez, também enfrentei o problema com uma exibição que requer muito mais rolagem, portanto altere o UIScrollView com a técnica mencionada acima.

Usman Awan
fonte
0

Veja como configurar uma visualização de rolagem usando o Xcode 11

1 - Adicione a visualização de rolagem e defina as restrições superior, inferior, inicial e final

insira a descrição da imagem aqui

2 - Adicione uma Visualização de conteúdo à visualização de rolagem, arraste uma conexão ao Guia de layout de conteúdo e selecione Principal, Superior, Inferior e À direita. Certifique-se de definir seus valores como 0 ou as constantes que você deseja.

insira a descrição da imagem aqui

3 - Arraste da Visualização de conteúdo para o Guia de layout do quadro e selecione Larguras iguais

insira a descrição da imagem aqui

4 - Defina uma constante de restrição de altura como Visualização de conteúdo

JP Aquino
fonte