ios - reacciona - no puedo hacer click en el escritorio windows 10
UIPageViewController evita que la vista de mi tabla se desplace hacia arriba al tocar la barra de estado (5)
Creo que la mejor solución sería utilizar los siguientes dos métodos del protocolo UIPageViewControllerDelegate (versión rápida y sucia, teniendo en cuenta que solo hay un controlador de vista en la pantalla):
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
((UITableViewController *)pendingViewControllers[0].tableView).scrollsToTop = YES;
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
((UITableViewController *)previousViewControllers[0].tableView).scrollsToTop = NO;
}
Editar: utilizar mejor el enfoque descrito en el último párrafo de la respuesta aceptada
Busqué antes de publicar esta pregunta, pero no pude encontrar nada.
Estoy teniendo un gran problema. Tengo un tipo de desplazamiento UIPageViewController como base de mi aplicación, con 3 controladores de vista.
Uno de los controladores de vista (listTableView) tiene una vista de tabla y un controlador de visualización de búsqueda.
El problema es que no puedo desplazarme hasta la parte superior de la vista de tabla al tocar la barra de estado como una vista de tabla normal. Creo que el UIPageViewController está interfiriendo con esto, pero no tengo idea de cómo solucionarlo, pero sé que necesito que mi aplicación no se rompa.
Aprecio cualquier ayuda ofrecida.
Sé que alguien pedirá el código, aunque en este caso es irrelvant, pero aquí está para crear el UIPageViewController:
#import "MainViewController.h"
@interface MainViewController ()
@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSArray *contentViewControllers;
@end
@implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageView"];
self.pageViewController.dataSource = self;
UIViewController *settings = [self.storyboard instantiateViewControllerWithIdentifier:@"Settings"];
UIViewController *listTableView = [self.storyboard instantiateViewControllerWithIdentifier:@"List"];
UIViewController *first = [self.storyboard instantiateViewControllerWithIdentifier:@"First"];
self.contentViewControllers = [NSArray arrayWithObjects:settings,listTableView,first,nil];
[self.pageViewController setViewControllers:@[first] direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
self.view.backgroundColor = [UIColor colorWithRed:(248.0/255.0) green:(248.0/255.0) blue:(248.0/255.0) alpha:1.0];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [self.contentViewControllers indexOfObject:viewController];
if (index == 0) {
return nil;
}
return self.contentViewControllers[index - 1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [self.contentViewControllers indexOfObject:viewController];
if (index >= self.contentViewControllers.count - 1) {
return nil;
}
return self.contentViewControllers[index + 1];
}
En mi caso tuve un UITableView
en los controladores de vista de los hijos de UIPageViewController
. Retirando las sugerencias de Leo Natan, agregando esto a la vista de mi hijo, el controlador hizo el trabajo:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tableView.scrollsToTop = YES;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tableView.scrollsToTop = NO;
}
Como se mencionó anteriormente, los UIScrollView
la competencia en los controladores de vista secundarios interferirán con el método de delegado scrollsToTop de cada uno. Este código asegura que solo uno de ellos tenga scrollsToTop habilitado a la vez.
Los documentos de iOS 7 en -scrollToTop
dicen
En el iPhone, el gesto de desplazamiento hacia arriba no tiene ningún efecto si hay más de una vista de desplazamiento en pantalla que tiene scrollToTop establecido en YES.
Estoy usando un UIPageViewController de manera similar a ti; uno de mis controladores de página es un UITableViewController. Así que me two-scrollviews-onscreen-no-scrolltotop
política de two-scrollviews-onscreen-no-scrolltotop
.
La idea de Kyle de implementar su propio comportamiento scrollToTop a través de un botón invisible es probablemente su apuesta más confiable en esta situación.
Utilicé esto:
for v in view.subviews {
if v.isKindOfClass(UIScrollView) {
(v as! UIScrollView).scrollsToTop = false
}
}
Pero si todavía hay otras vistas de desplazamiento que pueden desplazarse hacia arriba, la suya no funcionará. Utilice este script para conocer sus otras vistas de scrolls: https://.com/a/33443757/2589276 , luego deshabilite su scroll a la parte superior.
Luego, en el controlador de visualización donde desea desplazarse hacia arriba para trabajar, agregue estos:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
tableView.scrollsToTop = true
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
tableView.scrollsToTop = false
}
Solución
Después del chat, descubrimos algo interesante. El controlador de vista de página mantiene las vistas de otros controladores de vista dentro de la jerarquía de vistas, por lo que también capturan el comportamiento scrollsToTop
e interfieren. Esto significa que debe deshabilitar scrollsToTop
para cada vista desplazable dentro de viewWillDisappear:
de los controladores de vista que desaparecen (y habilitar nuevamente en viewWillAppear:
.
Investigación original
La forma rápida y sencilla: la vista de desplazamiento es la única subvista de la vista de UIPageViewController
:
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
Inspeccionando en depurador:
(lldb) po [self.pageViewController.view recursiveDescription]
<_UIPageViewControllerContentView: 0x8d7c390; frame = (0 0; 320 480); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x8d7c4a0>>
| <_UIQueuingScrollView: 0xa912800; frame = (0 0; 320 480); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x8d7cc90>; layer = <CALayer: 0x8d7c7e0>; contentOffset: {320, 0}>
| | <UIView: 0x8d7da00; frame = (0 0; 320 480); layer = <CALayer: 0x8d7da60>>
| | <UIView: 0x8d7dab0; frame = (320 0; 320 480); layer = <CALayer: 0x8d7db10>>
| | <UIView: 0x8d7db40; frame = (640 0; 320 480); layer = <CALayer: 0x8d7dba0>>
Puedes usar varios métodos para llegar a esa vista de desplazamiento. Lo más fácil es iterar self.pageViewController.view.subviews
y encontrar el que es una subclase de UIScrollView
. Dado que es la única subvista, su bucle terminará después de una iteración.
¿Es esta solución óptima? No. ¿Es propenso al error? En teoría, claro. ¿Es probable que cambie? No es probable, ya que la jerarquía de vistas es bastante lógica. Al menos, le brinda una solución rápida, en lugar de tener que lidiar con el cambio de la estructura completa de la aplicación debido a un pequeño descuido de Apple (que brinda al usuario acceso a la vista de desplazamiento).
Debería abrir una solicitud de función con Apple en https://bugreport.apple.com .