ios - example - uisearchbar swift 4
Cross Directional UIScrollViews-¿Puedo modificar el comportamiento de desplazamiento? (7)
Así es cómo funcionan las vistas de desplazamiento: una vista de desplazamiento está habilitada la búsqueda en la dirección horizontal. Cada ''página'' de esta vista de desplazamiento contiene un UITableView que se desplaza verticalmente. Sin modificaciones, esto funciona bien, pero no perfectamente.
El comportamiento no es el correcto: cuando el usuario se desplaza hacia arriba y hacia abajo en la vista de tabla, pero luego quiere pasar rápidamente a la página siguiente, el deslizamiento / deslizamiento horizontal no funcionará inicialmente; no funcionará hasta que la vista de tabla esté estacionaria. (incluso si el deslizamiento es muy claramente horizontal).
Cómo debería funcionar: si el deslizamiento es claramente horizontal, me gustaría que la página cambie incluso si la vista de tabla sigue desplazándose / rebotando, ya que esto es lo que el usuario esperará también.
¿Cómo puedo cambiar este comportamiento? ¿Cuál es la forma más fácil o mejor?
NOTA Por varias razones, un UIPageViewController como se indica en algunas respuestas no funcionará. ¿Cómo puedo hacer esto con UIScrollViews direccionales (/ una es una vista de tabla, pero se entiende la idea)? He estado golpeándome la cabeza contra la pared durante horas. Si crees que puedes hacerlo, haré una recompensa más que feliz.
¿Intentó los métodos: directionalLockEnabled
de su tabla y desplazamiento y configurarlos en horizontal para uno y vertical para el otro?
Editar:
1) Lo que quieres hacer es muy complicado ya que el toque espera un tiempo (como 0.1s) para saber cuál será tu movimiento. Y si su mesa se está moviendo, tomará su toque inmediatamente, sea lo que sea (porque se supone que es un movimiento reactivo).
No veo ninguna otra solución para ti, pero anulo el movimiento táctil desde cero para detectar inmediatamente el tipo de movimiento que deseas (como si el movimiento fuera horizontal) pero será más que difícil hacerlo bien.
2) Otra solución que puedo aconsejarte es hacer que tu mesa tenga margen izquierdo y derecho, donde puedes tocar el desplazamiento principal (las páginas son muy) y luego, incluso si tu tabla se desplaza, si tocas aquí, solo tu desplazamiento de paginación ser tocado. Es más simple, pero podría no encajar con tu diseño, tal vez ...
De acuerdo con mi comprensión de la pregunta, solo mientras se está desplazando tableView, queremos cambiar el comportamiento predeterminado. Todo el otro comportamiento será el mismo.
SubClass UITableView
. UITableView
s son subClass de UIScrollView
s. En la UITableView
implemente un método de delegado de UIScrollView
UIGestureRecognizer
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
//Edit 1
//return self.isDecelerating;
//return self.isDecelerating | self.bounces; //If we want to simultaneous gesture on bounce and scrolling
//Edit 2
return self.isDecelerating || self.contentOffset.y < 0 || self.contentOffset.y > MAX(0, self.contentSize.height - self.bounds.size.height); // @Jordan edited - we don''t need to always enable simultaneous gesture for bounce enabled tableViews
}
Como solo queremos cambiar el comportamiento predeterminado de los gestos mientras TableView se desacelera.
Ahora cambie toda la clase de UITableView a su tableViewSubClass recién creado y ejecute el proyecto, deslizar debería funcionar mientras se está desplazando tableView. :]
Pero el deslizamiento se ve un poco demasiado sensible mientras TableView se está desplazando. Vamos a deslizar un poco restrictivo.
Subclase UIScrollView
. En la subclase UIScrollView
implemente otro método de delegado de UIGestureRecognizer
gestureRecognizerShouldBegin:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:self];
if (abs(velocity.y) * 2 < abs(velocity.x)) {
return YES;
}
}
return NO;
}
Queremos que el "deslizamiento sea claramente horizontal". El código anterior solo permite el inicio del gesto si la velocidad del gesto en el eje x es el doble que en el eje y. [Siéntase libre de aumentar el valor codificado "2" si le gusta. Cuanto mayor sea el valor, el deslizamiento debe ser más horizontal.]
Ahora cambie la clase `UiScrollView ''(que tiene múltiples TableViews) a su ScrollViewSubClass. Ejecute el proyecto. :]
He hecho un proyecto en gitHub https://github.com/rishi420/SwipeWhileScroll
En lugar de usar UIScrollView
como un contenedor para estas vistas múltiples de tabla, intente usar un UIPageViewController
.
Incluso puede integrar esto en su configuración de controlador de vista existente como un child view controller
(reemplazando directamente a UIScrollView
).
Además, es probable que desee implementar los métodos necesarios de UIPageViewControllerDataSource
y posiblemente uno o más de los métodos de UIPageViewControllerDelegate
.
Me enfrenté a lo mismo recientemente. Mi UIScrollview
estaba en modo de búsqueda y cada página contenía una UITableView
y, como me describió, funcionaba pero no como esperabas que funcionara. Así es como lo resolvió.
Primero deshabilité el desplazamiento del UIScrollview
Luego agregué un UISwipeGestureRecognizer
al UISwipeGestureRecognizer
real para los UITableView
hacia la izquierda y hacia la derecha.
La acción para esos golpes fue:
[scroll setContentOffset:CGPointMake(currentPointX + 320, PointY) animated:YES];
//Or
[scroll setContentOffset:CGPointMake(currentPointX - 320 , PointY) animated:YES];
Esto funciona a la perfección, el único UITableVIew
es que si el usuario arrastra su dedo en la UITableVIew
que se considerará como un golpe. No podrá ver la mitad de la pantalla A y la mitad de la pantalla B en la misma pantalla.
Podría subclasificar su vista de desplazamiento y sus vistas de tabla, y agregar este método de delegado de reconocimiento de gestos a cada uno de ellos ...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
No puedo estar seguro de que esto sea exactamente lo que buscas, pero puede que se acerque.
Use UIPageViewController
y en el método -viewDidLoad
(o cualquier otro método que mejor se adapte a sus necesidades o diseño) obtenga la subvista UIScrollView
UIPageViewController y asígnele un delegado. Tenga en cuenta que su propiedad de delegado no será nula. De manera opcional, puede asignarlo a otra referencia y luego asignarle su objeto, que se ajusta a UIScrollViewDelegate
. Por ejemplo:
id<UIScrollViewDelegate> originalPageScrollViewDelegate = ((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]).delegate;
[((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]) setDelegate:self];
Para que pueda implementar los métodos UIScrollViewDelegate
con facilidad. Y su UIPageViewController
llamará a su delegado -scrollViewDidScroll:
método.
Por cierto, es posible que deba mantener el delegado original y responder a los métodos delegados con ese objeto. Puede ver una implementación de ejemplo en la clase ViewPagerController
en mi proyecto de control de UI here
Aunque a Apple no le gusta demasiado este método:
Importante: no debe incrustar objetos UIWebView o UITableView en objetos UIScrollView. Si lo hace, puede producirse un comportamiento inesperado porque los eventos táctiles de los dos objetos pueden mezclarse y manejarse de forma incorrecta.
He encontrado una excelente manera de lograr esto.
Esta es una solución completa para el problema. Para desplazarse por UIScrollView
mientras se desplaza su UITableView
, deberá deshabilitar la interacción que tenga.
- (void)viewDidLoad
{
[super viewDidLoad];
_myScrollView.contentSize = CGSizeMake(2000, 0);
data = [[NSMutableArray alloc]init];
for(int i=0;i<30;i++)
{
[data addObject:[NSString stringWithFormat:@"%d",i]];
}
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGestureRecognizer:tap];
}
- (void)handleTap:(UITapGestureRecognizer *)recognizer
{
[_myTableView setContentOffset:_myTableView.contentOffset animated:NO];
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = YES;
}
Para resumir el código anterior, si UITableView
está desplazándose, establezca userInteractionEnabled
en NO
para que UIScrollView
detecte el deslizamiento. Si UITableView
se desplaza y el usuario toca en la pantalla, userInteractionEnabled
se establecerá en SÍ.