UIView. Como faço para restringir escala para uma dimensão única
-
07-07-2019 - |
Pergunta
Eu tenho uma instância de UIScrollView contendo uma instância de UIView. O UIView é apenas um recipiente para uma variedade de casos horizonal UIImageView. - O zoom é fornecido pelo UIScrollView e UIScrollViewDelegate. Gostaria de restringir zoom para ocorrer apenas ao longo do eixo horizontal sem scalling vertical a todos. Como eu faço isso?
Existe uma maneira, por exemplo, a subclasse UIView e substituir o método apropriado para evitar escalonamento vertical? Eu gosto desta abordagem, mas eu sou incerto sobre qual método para substituir eo que isso método substituído deve realmente fazer.
Cheers, Doug
Solução
À semelhança do que eu descrevo em esta resposta , você pode criar uma subclasse UIView e substituir o -setTransform: método de acesso para ajustar a transformação que o UIScrollView irá tentar aplicar a sua UIView. Defina esta UIView para hospedar seus subviews conteúdo e torná-lo o subexibição do UIScrollView.
Dentro de sua substituído -setTransform :, você precisará tomar na transformação que o UIScrollView gostaria de aplicar e ajustá-lo para que o dimensionamento só tem efeito em uma direção. Desde o documentação sobre como matrizes CGAffineTransform são construídos , eu acredito que a seguinte implementação deve limitar a sua escala para ser apenas ao longo da direção horizontal:
- (void)setTransform:(CGAffineTransform)newValue;
{
CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
constrainedTransform.a = newValue.a;
[super setTransform:constrainedTransform];
}
Outras dicas
Usando OS 3.0, você pode dizer o zoom para aproximar a um rect na scrollview. Eu tenho isso na minha lógica que detecta torneiras.
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:CGPointMake(tapPoint.x, tapPoint.y) inScrollView:scrollView];
[scrollView zoomToRect:zoomRect animated:YES];
O para o outro, você terá que esticar seus pontos de vista de imagem pela relação que o novo quadro tem contra o original, e centralizá-lo no mesmo ponto central. Você pode fazer isso em uma animação cronometrado o mesmo que a animação zoom de modo que parece certo, mas acho que essa será a única maneira de fazê-lo.
Em scrollViewDidZoom: , ajuste as variáveis ??da sua exibição de conteúdo com base em zoomScale , de reset zoomScale para 1,0, em seguida, fazer setNeedsDisplay na exibição de conteúdo. Lidar com o zoom real (em qualquer direção que você quiser) no do seu ponto de vista de conteúdo drawRect:.
The Ugly Detalhes:
-
Enquanto o zoom estiver em andamento, as mudanças UIScollView contentOffset e contentScale , para salvar esses valores anteriores em scrollViewWillBeginZooming: e em scrollViewDidZoom:. para que possa calcular um novo contentOffset -se de acordo com o zoom
-
Uma vez que alterar zoomScale irá disparar imediatamente outra scrollViewDidZoom: , você deve definir um BOOL antes (e depois claro) redefinir o zoomScale . Teste a BOOL no início do scrollViewDidZoom:. e retorno se true
-
Você pode precisar de inibição scrollViewDidScroll: , enquanto o zoom está em andamento (teste de um BOOL; colocá-lo em scrollViewWillBeginZooming: e limpe-o em scrollViewDidEndZooming:. ) para que seus próprios contentOffsets são usados ??enquanto o zoom está em andamento