Eu tenho um UIScrollView
que contém muitos UIImageView
s, UILabels, etc ... os rótulos são muito mais longos que o UIScrollView
, mas quando executo o aplicativo, não consigo clicar e rolar para baixo ...
Por que isso pode ser?
obrigado
Eu tenho um UIScrollView
que contém muitos UIImageView
s, UILabels, etc ... os rótulos são muito mais longos que o UIScrollView
, mas quando executo o aplicativo, não consigo clicar e rolar para baixo ...
Por que isso pode ser?
obrigado
Respostas:
É sempre bom mostrar um trecho completo de código de trabalho:
// in viewDidLoad (if using Autolayout check note below):
UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set
[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc
myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size
Swift 4.0
let myScrollView
let contentView
// scrollview won't scroll unless content size explicitly set
myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc
myScrollView.contentSize = contentView.frame.size //sets ScrollView content size
Não encontrei uma maneira de definir contentSize no IB (a partir do Xcode 5.0) .
Nota: Se você estiver usando o Autolayout, o melhor local para colocar esse código é dentro do -(void)viewDidLayoutSubviews
método.
myScrollView.delegate = self
TAMBÉM, se isso ainda não estiver funcionando, a resposta abaixo tem ótimos conselhos (vá para o seu xib / StoryBoard e verifique se o "AutoLayout" está desativado). Dica profissional: Você também pode incluir <UIScrollViewDelegate>
no seu arquivo .h se desejar fazer coisas como rolar programaticamente seu UIScrollView.
viewDidLayoutSubviews
fez funcionar para mim.
Se você não puder rolar a exibição mesmo depois de definir o contentSize corretamente, desmarque a opção "Usar AutoLayout" em Interface Builder -> File Inspector.
Você precisa definir a contentSize
propriedade da exibição de rolagem para que ela role corretamente.
Se você estiver usando autolayout, você precisa conjunto contentSize
no viewDidLayoutSubviews
fim para que possa ser aplicada depois da conclusão do autolayout.
O código pode ficar assim:
-(void)viewDidLayoutSubviews
{
// The scrollview needs to know the content size for it to work correctly
self.scrollView.contentSize = CGSizeMake(
self.scrollContent.frame.size.width,
self.scrollContent.frame.size.height + 300
);
}
contentSize
como contentView
, o tamanho de scrollView e contentView parece ser definido da mesma forma. Mas definir altura de contentSize
para um valor maior que a altura de contentView
, funcionou.
viewDidLayoutSubviews
pode ser chamado várias vezes durante um ciclo de vida, para que você corra o risco de aumentar a altura maior que o esperado.
A resposta acima está correta - para fazer a rolagem acontecer, é necessário definir o tamanho do conteúdo.
Se você estiver usando o construtor de interface, uma maneira elegante de fazer isso é com atributos de tempo de execução definidos pelo usuário. Por exemplo:
Tente redimensionar o tamanho do conteúdo para grandes números. Eu não conseguia entender por que minha exibição de rolagem não rola mesmo quando o tamanho do conteúdo parece ser maior que o tamanho do controle. Descobri que, se o tamanho do conteúdo for menor que o necessário, ele também não funcionará.
self.scrollView.contentSize = CGSizeMake(2000, 2000);
Em vez de 2000, você pode colocar seus próprios números grandes. E se funcionar, significa que o tamanho do seu conteúdo não é grande o suficiente quando você redimensiona.
O delegado não é necessário para que a exibição de rolagem funcione.
Verifique se a propriedade contentSize da exibição de rolagem está definida para o tamanho correto (por exemplo, uma grande o suficiente para abranger todo o seu conteúdo).
Desmarque a opção 'Usar Autolayout'.
Ambiente: xCode 5.0.2 Storyboards ios7
No meu caso, eu tive que definir delaysContentTouches
como true porque os objetos dentro do scrollView estavam todos capturando os eventos de toque e se manipulando, em vez de permitir que o próprio scrollView o tratasse.
Defina a contentSize
propriedade UIScrollview
no ViewDidLayoutSubviews
método Algo assim
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
A idéia de por que a exibição de rolagem não está rolando porque você define o tamanho do conteúdo para rolagem menor que o tamanho da exibição de rolagem, o que está errado. Você deve definir o tamanho do conteúdo maior que o tamanho da sua exibição de rolagem para navegar através dele durante a rolagem.
A mesma idéia com o zoom, você define os valores mínimo e máximo para o zoom, que serão aplicados por meio da ação de zoom.
bem-vinda :)
Uma pequena adição, todas as opções acima, são as reais razões pelas quais sua visualização de rolagem pode não estar rolando, mas às vezes irracionalmente esse pode ser o motivo, especialmente quando a visualização de rolagem é adicionada por meio do código e não do IB, você pode ter adicionado suas subvisões à visualização pai e não para o scrollview faz com que o subview não role
e mantenha o tamanho do conteúdo definido e maior que o quadro de visualização principal (duhh !!)
Eu fiz funcionar na minha primeira tentativa. Com layout automático e tudo, sem código adicional. Em seguida, uma exibição de coleção foi banal, travando em tempo de execução, não consegui encontrar o que estava errado, então excluí e recriei (estou usando o Xcode 10 Beta 4. Parecia um bug) e a rolagem desapareceu. A exibição de coleção funcionou novamente!
Muitas horas depois .. foi isso que o corrigiu para mim. Eu tinha o seguinte layout:
UIView
Está tudo nas restrições. Área segura é automaticamente definida pelo sistema. Na pior das hipóteses, remova todas as restrições para as visualizações de rolagem e conteúdo e não tenha IB redefinindo / criando-as para você. Faça-os manualmente, ele funciona.
basicamente, o conceito é fazer com que a visualização de conteúdo seja adequada ao Scrollview, que é adequado à Área segura.
Mas, como tal, não funcionou. A exibição de conteúdo perdeu a altura. Eu tentei tudo o que pude e o único que fez o truque foi uma altura de exibição de conteúdo criada, criando a exibição de conteúdo com controle de arrastar ... para si mesma . Isso definiu uma altura fixa, cujo valor foi calculado a partir do tamanho do controlador de exibição (definido como forma livre, mais longa que a tela real, para conter todas as minhas subvisões) e, finalmente, funcionou novamente!
Algo que não foi mencionado antes!
Verifique se a tomada estava conectada corretamente ao scrollView! Ele deve ter um círculo preenchido, mas mesmo se você tiver preenchido um círculo, o scrollView pode não estar conectado - verifique novamente! Passe o mouse sobre o círculo e veja se a visualização de rolagem real é destacada! (Este foi um caso para mim)
//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
Muitas vezes o código está correto se você seguiu um tutorial, mas o que muitos iniciantes não sabem é que o scrollView NÃO vai rolar normalmente pelo simulador. Supõe-se rolar apenas quando você pressiona o mouse e simultaneamente rola. Muitos usuários experientes de XCode / Swift / Obj-C estão acostumados a fazer isso e não sabem como isso poderia ser ignorado pelos iniciantes. Tchau :-)
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
// Do any additional setup after the view
}
override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 800)
}
Esse código funcionará perfeitamente bem desde que você faça o que eu disse acima
Se nenhuma das outras soluções funcionar para você, verifique duas vezes se a visualização de rolagem é realmente UIScrollView
no Interface Builder.
Em algum momento dos últimos dias, meu UIScrollView
tipo mudou espontaneamente para a UIView
, embora sua classe dissesse UIScrollView
no inspetor. Estou usando Xcode 5.1 (5B130a)
.
Você pode criar uma nova visualização de rolagem e copiar as medidas, configurações e restrições da visualização antiga ou alterar manualmente sua visualização para uma UIScrollView
no xib
arquivo. Fiz uma comparação e encontrei as seguintes diferenças:
Original:
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>
Após o tipo alterado espontaneamente:
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>
Então substituí a <view>
linha pela minha <scrollView>
linha original .
Também substitui a tag de fechamento da exibição </view>
por </scrollView>
.
Certifique-se de manter o ID igual à visualização atual, neste caso: id = "qRn-TP-cXd".
Eu também tive que liberar o xib do cache do Xcode excluindo os dados derivados do aplicativo:
Xcode->Window->Organizer->Projects
, escolha seu projeto, na linha Dados Derivados, clique em Excluir ...Ou se estiver usando um dispositivo:
Xcode->Window->Organizer->Device
, escolha seu dispositivo-> Aplicativos, escolha seu aplicativo, clique em (-)Agora limpe o projeto e remova o aplicativo do simulador / dispositivo:
Xcode->Product->Clean
Simulator/device->press
e mantenha pressionado o app->click
(X) para removê-loVocê poderá criar e executar seu aplicativo e ter a funcionalidade de rolagem novamente.
PS: Não precisei definir o tamanho do conteúdo da exibição de rolagem viewDidLayoutSubviews
ou desativar o layout automático, mas YMMV.
Se você scrollView
é uma sub-visualização de containerView
algum tipo, verifique se scrollView
está dentro do quadro ou dos limites do containerView
. Eu tinha o containerView.clipsToBounds = NO
que ainda me permitia ver o scrollView, mas porque scrollView
não estava dentro dos limites containerView
dele, não detectava eventos de toque.
Por exemplo:
containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;
Você poderá ver o scrollView, mas ele não receberá interações do usuário.
adicionar o código a seguir viewDidLayoutSubviews
funcionou para mim com o Autolayout. Depois de tentar todas as respostas:
- (void)viewDidLayoutSubviews
{
self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);
}
//set the height of content size as required
Adicione UIScrollViewDelegate
e adicione o seguinte código ao viewDidAppear
método corrigido para mim.
@interface testScrollViewController () <UIScrollViewDelegate>
-(void)viewDidAppear:(BOOL)animated {
self.scrollView.delegate = self;
self.scrollView.scrollEnabled = YES;
self.scrollView.contentSize = CGSizeMake(375, 800);
}
Meu problema foi resolvido por:
Depois de remover as restrições superior e / ou inferior vinculadas à área segura e / ou à visão geral, as visualizações dentro do scrollView podem rolar novamente e não ficam fixas na parte superior da parte inferior da tela!
Espero que isso pare outra pessoa de horas de dor com esse problema específico.
outro caso divertido:
scrollview.superview.userInteractionEnabled deve ser verdadeiro
Eu desperdicei 2 + horas perseguindo isso apenas para descobrir que o pai é UIImageView que, naturalmente, tem userInteractionEnabled == false
Depois de falhar com as respostas fornecidas neste tópico, me deparei com este artigo com a solução.
Há duas coisas não intuitivas sobre a configuração da exibição de rolagem com o layout automático:
Esta é a essência desse artigo. Para uma explicação completa, incluindo ilustrações, confira.
Descobri que, com esse problema de AutoLayout ... se eu apenas fizer o ViewController
uso em UIView
vez da UIScrollView
classe ... basta adicionar um UIScrollView
eu ... que funcione.
Eu tive o mesmo problema no IB.
Depois de definir o início, o final, o topo e o fundo do scrollView para seu superView. Fiz as seguintes alterações para tornar o containerView rolável, que funcionou.
Para fazer o scrollView rolar apenas na direção horizontal, faça a restrição com scrollView's centerY = ContainerView's centerY
e para torná-lo rolável verticalmente, faça o scrollX's centerX = ContainerView's centerX