como faço para usar UIScrollView no Interface Builder?


95

Embora eu já tenha usado com UIScrollViewsucesso no passado manipulando-o programaticamente, estou tendo problemas para fazer funcionar configurando-o exclusivamente no Interface Builder.

Tenho uma página "sobre" simples no meu aplicativo para iPhone. Ele tem um UITextView, alguns ícones e links para meus outros aplicativos. Eu adicionei todas essas visualizações à minha UIScrollView, organizando-as de forma que seu tamanho total seja> 480. Quando eu inicio meu aplicativo, a visualização de rolagem exibe apenas o conteúdo que cabe na tela e nada rola.

É possível fazer isso inteiramente via IB ou devo manipular o contentSize via código?

Respostas:


130

Você se esqueceu de definir a propriedade contentSize do UIScrollView. Estranhamente, você não pode fazer isso no Interface Builder. Você terá que fazer isso a partir do controlador de visualização que gerencia esta visualização de rolagem.


42
Uau, meio que torna o IB bastante inútil ... Isso funcionou, obrigado.
— George Armhold

20
Você poderia criar uma subclasse de UIScrollvView que verifica se há apenas uma subvisualização em (0,0) e, a seguir, define automaticamente o contentSize com base nessa subvisualização.
— Stefan Arentz

1
Esse é o melhor conselho que recebo há algum tempo. Não consegui descobrir por que minha visualização de rolagem não funcionava e não encontrei essa informação sobre contentSize em nenhum outro lugar. Obrigado.
— Drew C

46
Eu estava tentando descobrir como definir contentSize no Interface Builder e encontrei esta discussão. Pelo menos para mim, no Xcode 4.5, posso configurá-lo usando “Atributos de tempo de execução definidos pelo usuário”, adicionando uma entrada chamada contentSizede tipo Sizee configurando o valor desejado.
— nlogax,

5
Ainda estou perplexo com relação ao motivo pelo qual o iOS não define automaticamente o contentSizede uma visualização de rolagem com base nas dimensões de suas subvisualizações , pelo menos como o comportamento padrão.
— aroth

113

A resposta de Boby_Wan me fez pensar e descobri a seguinte solução para configurar o contentSize do UIScrollView no Interface Builder:

  1. Selecione o UIScrollViewna cena do Storyboard
  2. Vá para o inspetor de identidade , crie um novo Atributo de tempo de execução definido pelo usuário (clique no botão +)
  3. Altere o atributo Key Path paracontentSize
  4. Altere o atributo Tipo paraSize
  5. Agora definir o valor para { width conteúdo desejado , a altura desejada conteúdo }

por exemplo, definir o valor para {320, 920} permitirá que o usuário role para baixo em uma tela extra inteira no iPhone.

(Estou usando o xcode 4.3.3, o iOS Deployment Target do projeto é 5.1)

Quando fiz isso pela primeira vez, recebi o seguinte erro:

Configuração ilegal:
     atributos de tempo de execução definidos pelo usuário de tipo de tamanho com versões do Xcode anteriores a 4.3
     MainStoryboard.storyboard

Se você também obtiver este erro, é simples de corrigir: selecione o Storyboard no Navegador do Projeto e abra o Inspetor de Arquivos . Encontre / expanda a seção Documento do Interface Builder e há um menu suspenso para Desenvolvimento . Certifique-se de que esteja definido comoXcode 4.3


7
Achado incrível! PS: Estou surpreso que isso seja o melhor que a Apple poderia fazer. Acho que isso mostra que mesmo os funcionários da Apple nunca usam sua própria ferramenta (construtor de interface) :).
— Adam

Brilhante, isso acabou de funcionar para mim no Xcode 4.4. Mas agora como coloco botões na parte da visualização de rolagem que não consigo "ver" no IB?
— Robert Atkins,

1
Acabei de resolver - você precisa soltar o arrasto quando o ponteiro ainda estiver dentro da "tela", caso contrário, ele voltará para quando você começou. Que dor.
— Robert Atkins,

Eu tentei dessa forma, mas estou recebendo um erro, "this class is not key value coding-compliant for the key keyPath"por favor, pode me ajudar o que estou fazendo de errado? observe que eu uso xamarin-ios-c #
— SoftSan

25

Com o Autolayout (iOS6 +), você pode evitar a configuração contentSize. Em vez disso, defina as seguintes restrições:

  1. Prenda o topo da scrollview no topo de seu filho mais alto.
  2. E prenda a parte inferior na parte inferior de seu filho mais inferior.

1
Obrigado - a configuração contentSizenão funciona com Xcode 5 e iOS 7
— colincameron

18

Você pode fazer isso usando apenas o Interface Builder, vá para o Inspetor de Identidade (a terceira guia do inspetor) e adicione um novo atributo de Tempo de Execução Definido pelo Usuário com

  • Caminho da chave: contentSize
  • Tipo: Tamanho
  • Valor: {largura, altura}

14

Agora existe uma maneira de fazer um UIScrollViewpergaminho sem sair do Storyboard :

  1. Selecione UIScrollViewno Storyboard, vá para o inspetor Size e altere o valor Bottom (ou qualquer outro valor que você precise alterar) na seção Content Insets para a altura da área de conteúdo.
  2. Agora vá para o inspetor de identidade e crie um novo Atributo de tempo de execução definido pelo usuário (clicando no botão +) e nomeie-o contentSize. Não importa o tipo ou valor que você preenche (você pode até deixar o valor padrão).

Isso fará com que UIScrollViewfuncione bem, embora eu não saiba por que a segunda etapa é necessária (descobri por acaso). :(


Alterar o valor Bottom para quê?
— zakdances

Altere-o para a altura da área de conteúdo. Parece funcionar e substitui o valor fornecido para o atributo "contentSize" definido pelo usuário.
— Reid Ellis,

Sim, Reid, você está certo: você deve alterar o valor Bottom para a altura da área de conteúdo. Eu editei minha postagem original para refletir isso. Obrigado!
— RoberRM

4

uma abordagem que usei no passado é arrastar a visualização de rolagem para fora de sua visualização no construtor de interface e definir seu tamanho real para o que deseja que o contentSize seja.

o que não é inerentemente óbvio sobre o construtor de interface é que você pode ter visualizações não associadas que são armazenadas na ponta, mas não fazem parte da visualização principal para a qual a ponta se destina.

na visualização onde deseja que a visualização de rolagem fique, coloque um UIView simples, que você usa como um espaço reservado. (isso é simplesmente para que você possa projetar visualmente sua localização. se você estiver apenas usando a visualização inteira, pode pular esta etapa e usar o segundo trecho de código que forneci no final desta resposta).

você pode então preencher a visualização de rolagem com controles, exibindo-a visualmente como você deseja. forneça as propriedades placeholder e scrollview dentro de seu controlador de visualização para que você possa acessá-las em tempo de execução.

em tempo de execução, em - (void) viewDidLoad

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

alternativamente (se você não usou um marcador de posição):

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

finalmente, se você "perder" sua visualização de rolagem no construtor de interface (é possível fechá-la para que desapareça da grade de design), não entre em pânico. apenas clique nele na lista de objetos à esquerda da grade de design.


1
Obrigado - funcionou bem. Também é necessário declarar IBOutlets em YourViewController.h para o espaço reservado e visualizações de rolagem e conectá-los no Interface Builder. E, por último, dot.notation não foi apreciado pelo xCode para a 3ª linha, então usei a sintaxe normal de envio de mensagem - então tudo funcionou muito bem!
— jiy

não se preocupe. sempre há o perigo ao postar trechos de código de que algumas pessoas não possam usá-los para entender o conceito, em vez de esperar que o código "exato" funcione em todas as situações.
— não sincronizado de

Este é o método que realmente uso. Eu nem preciso redimensionar este programa. Acho que é assim que se pretende fazer. É a única resposta verdadeira.
— user4951

Depois de desenhá-lo para fora, vou apenas movê-lo para uma visão geral. Tada.
— user4951

Na verdade, comecei a usar o design de algumas visualizações fora de uma cena para rascunhos e isso torna a vida muito mais fácil em algumas situações, mesmo não relacionadas a esta. Obrigado por esta resposta.
— Benjamin

4

No Xcode 4.5 usando Autolayout, não tenho a seção Content Insets no meu inspetor de tamanho. Então, tive que adicioná-lo em Atributos de tempo de execução definidos pelo usuário e funcionou bem.

O que você adiciona em "Atributos de tempo de execução definidos pelo usuário" é keyPath == contentInset, que é do tipo "Rect" (UIEdgeInsets, que tem a mesma entrada de um Rect) e é definido como {top, left}, {bottom, right}. O contentSize define apenas a região da janela scrollview. contentInset define a área rolável.

Espero que isso ajude alguém na mesma situação.


Para UITextView, use "textContainerInset" keyPath
— Dima Deplov

4

Muitas das respostas acima são enganosas ou desatualizadas. A partir de 2017 (possivelmente muito antes) o construtor de interface oferece suporte a scrollviews com conteúdo dimensionado automaticamente. O truque é que o XCode dá um significado especial e fora do padrão às restrições entre a visualização da rolagem e o conteúdo dentro dela. Essas restrições "internas" não afetarão realmente o tamanho do conteúdo como você poderia esperar.

Isso significa que você pode, por exemplo, ter seu scrollview fixado na parte inferior da visualização principal com margem zero, e também ter o conteúdo do scrollview fixado na parte inferior da scrollview com margem zero, mas o conteúdo não será realmente esticado por isso. Em vez disso, o conteúdo terá seu tamanho autodeterminado (mais abaixo) e este também será o tamanho da área de rolagem dentro da visualização da rolagem.

Pense nisso assim - há uma assimetria nas restrições de vinculação a um scrollview: Restrições do scrollview ao mundo "externo" (pai) determinam o tamanho e a posição do scrollview como de costume. Mas as restrições "dentro" do scrollview realmente definem o tamanho e a posição da área de rolagem do scrollview, vinculando-a ao conteúdo.

Isso é totalmente não óbvio porque quando você vai definir as restrições, o XCode sempre sugerirá o espaçamento atual e pode nunca ocorrer a você alterar intencionalmente as restrições internas e externas de uma forma que entre em conflito. Mas você pode, e eles têm o significado descrito acima: um controla o layout de scrollview e outro controla o tamanho da área de conteúdo rolável.

Eu tropecei nisso por acidente e, em seguida, vendo como parecia funcionar, me levou a este artigo que explica tudo e cita a fonte de documentos da Apple para isso:

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

Uma última informação crítica, sobre o tamanho autodeterminado do conteúdo: você pode sentir que está em um beco sem saída aqui porque você normalmente dimensiona seu conteúdo para, por exemplo, a largura da visualização pai, mas neste caso o pai é a visualização em rolagem e conforme descrito acima - a restrição não afetará o tamanho do conteúdo. A resposta aqui é lembrar que você pode restringir itens a itens não diretamente vizinhos em sua hierarquia de visualização: por exemplo, você pode definir a largura de sua visualização de conteúdo para a largura da visualização principal em vez de tentar em vão fazer com que a visualização em rolagem o faça para voce.


2

Se você clicar no ícone Propriedades de qualquer View Controller no Interface Builder, você pode defini-lo para um tamanho "Freeform" em Simulated Metrics e alterar o tamanho da View principal para o seu tamanho de conteúdo desejado.

Desta forma, você pode criar o conteúdo do ScrollView como se fosse uma grande exibição. Como é apenas uma métrica simulada, seu View Controller será redimensionado para os limites da janela quando for carregado.


2

Configurar um UIScrollView por meio do Interface Builder não é intuitivo. Aqui está minha lista de verificação para configurá-lo:

  1. Selecione o arquivo XIB do UIViewController. No "Identity Inspector" do construtor de interface, altere o UIView para o tipo de classe UIScrollView

  2. Em "File Inspector", desmarque Autolayout

  3. Em "Attributes Inspector", altere o tamanho para Freeform. Você pode esticar a Visualização de rolagem manualmente ou pode especificar uma largura e altura personalizadas em "Inspetor de tamanho".

  4. Em "Identity Inspector", adicione um novo Atributo de tempo de execução definido pelo usuário chamado "contentSize" do tipo "Size" e altere-o para um valor como {320, 1000}. Você não pode mais definir isso programaticamente e, portanto, precisa desta etapa para que a Visualização de rolagem saiba que o conteúdo da Visualização de rolagem é maior do que a janela.


2

Apenas remova o autoLayout em seu scrollview. então o código é tão simples quanto este:

scrollviewName.contentSize = CGSizeMake(0, 650);

basta criar uma propriedade iboulet no arquivo .h e então sintetizar no arquivo .m. Certifique-se de que a rolagem esteja ativada.


1

Sim, st3fan está certo, a propriedade contentSize de UIScrollView deve ser definida. Mas você não deve desligar o autolayout para essa finalidade. Você pode facilmente configurar contentSize de UIScrollView com autolayout somente em IB, sem qualquer código.

É importante entender que, ao usar autolayout contentSize de UIScrollView, não é definido diretamente, ele é calculado com base nas restrições de todas as subvisualizações de UIScrollView. E tudo que você precisa é fornecer restrições adequadas para subvisualizações para ambas as direções.

Por exemplo, se você tiver apenas uma subvisualização, poderá definir sua altura e espaço de cima para baixo para superview (ou seja, scrollView em nosso caso) contentSize.height é calculado como a soma

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

contentSize.width é calculado de forma semelhante a partir de restrições horizontais.

Se houver muito poucas restrições para calcular o contentSize corretamente, um pequeno botão vermelho é mostrado próximo ao item View Controller Scene para informar sobre a ambigüidade do layout.

Se houver muitas subvisualizações, então pode ser uma "cadeia" de restrições: subvisualização superior para superior, alturas e espaços entre subvisualizações e subvisualização inferior para inferior, como na resposta de Danyal Aytekin .

Mas na prática, na maioria dos casos, é mais conveniente apenas adicionar uma visualização vazia com o tamanho necessário e definir os espaços superior, esquerdo, inferior e direito de scrollView como 0. Você pode usar esta visualização como "Visualização de conteúdo", ou seja, colocar todas as outras subvisualizações nela ou se você já tiver muitas subvisualizações e não quiser movê-las e configurar o layout novamente, você pode adicionar esta visão auxiliar às subvisualizações existentes e torná-la oculta.

Para tornar scrollView rolável, o contentSize calculado deve ser maior que o tamanho de scrollView.


1

Você pode ter UIScrollView no StoryBoard com Autolayouts. Basicamente, o que você precisa é:

  1. Adicionar UIScrollView
  2. Adicione todas as restrições a ele (como inserções das bordas superior, esquerda, direita, inferior)
  3. Adicionar um UIView de 'contêiner' ao UIScrollView
  4. Se você quiser apenas uma rolagem em uma direção (digamos, vertical): defina a altura explicitamente (para a instância, 600) e a largura do link para a largura de UIScrollView.
  5. Se você quiser rolagem bidirecional, defina a largura e a altura.

configuração de storyboard



0

Eu descobri uma maneira mais conveniente.

1: dimensione o tamanho da visualização de rolagem para conter toda a interface do usuário dentro dela.

2: Adicione um iboutlet da visualização de rolagem.

3: Em viewDidLoad, salve o frame.size da visualização de rolagem.
(por exemplo, _scrollSize = _scrollView.frame.size;)

4: Em viewWillAppear, defina contentSize pelo CGSize que você salvou antes.
(por exemplo, _scrollView.contentSize = _scrollSize;)

5: Concluído ~


0
  1. Adicionar UIViewController
  2. Em UIViewController 'Attribute Inspector -> Simulated Metrics' set size Freeform
  3. No UIViewController 'Size Inspector -> View Controller' defina a altura 800
  4. Adicionar UIScrollView em UIViewController
  5. Adicione todas as restrições a UIScrollView (superior, esquerda, direita, inferior) e adicione o alinhamento X = centro
  6. Adicionar UIView em UIScrollView
  7. Adicione todas as restrições ao UIView (superior, esquerda, direita, inferior) e adicione o alinhamento X = centro. Sim, o mesmo que para UIScrollView em # 3, mas para UIView
  8. Adicione restrição de altura ao UIView. Por exemplo 780
  9. Corre

Storyboard


0

Crie um novo projeto Xcode

Navegue até o arquivo Main.storyboard

Selecione ScrollView na biblioteca de objetos.

Defina o quadro para o ScrollView.

Adicione outra visualização para rolar a visualização e manter o mesmo quadro de ScrollView.

Agora, para definir sua altura e largura dinamicamente, você pode configurar um UIScrollView usando layout automático em XIB

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.