Closed easongtd closed 8 years ago
另外兄弟如果方便的话,能否提供QQ方便描述解决相关问题,谢谢!
层级结构说明一下
层级结构是这样的:在AppDelegate的didFinishLaunchingWithOptions方法中通过返回storyboard返回实例加载主容器ECSlidingViewController rootVC;并设置为rootViewController。 UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; rootVC = [story instantiateViewControllerWithIdentifier:@"ECSlidingVC"]; self.window.rootViewController = rootVC;
第二层是自定义的tabBarController tabBarVc = (MainTabBarController *)rootVC.topViewController; tabBarVc.delegate =self;
然后在MainTabBarController定义四个UINavigationController,并分别从storyboard返回NavigationController的实例,并添加到这个MainTabBarController的viewControllers中。 UINavigationController newsVC; UINavigationController wechatVC; UINavigationController mineVC; UINavigationController videoVC;
newsVC = [self.storyboard instantiateViewControllerWithIdentifier:@"NewsMainVCNav"];
self.viewControllers=@[newsVC, videoVC, wechatVC, mineVC];
第三层是各个NavigationController下的子页面主控制器,例如现在生命周期出问题的新闻模块的主页面NewsMainViewController,它继承VTMagic的控制器VTMagicController @interface NewsMainViewController : VTMagicController
第四层是子页面主控制器下的具体页面VC:NewsViewController,其它几个tabBarController的子模块都是一样的结构。现在就是NewsViewController的viewDidAppear方法没执行了。 同时在切换菜单时会调用VTMagic的代理方法来返回NewsViewController的实例:
(UIViewController )magicView:(VTMagicView )magicView viewControllerAtPage:(NSUInteger)pageIndex { ChannelEntity *menuInfo = _menuList[pageIndex];
static NSString gridId = @"grid.identifier"; NewsViewController newsVC = [magicView dequeueReusablePageWithIdentifier:gridId]; if (!newsVC) { newsVC = [self.storyboard instantiateViewControllerWithIdentifier:@"NewsVC"]; }
newsVC.menuInfo = menuInfo; return newsVC; }
我怀疑是不是第三层这里和RTRootNavigationController冲突了?还是说我使用方法还不对?
MainTabBarController
是不是继承自 UITabBarController
?还是完全自己实现的?ECSlidingViewController
是继承自哪的?MainTabBarController是继承自UITabBarController的,不是自己实现。没引入这个项目前使用VTMagic这个导航菜单第三方库控制页面的切换是正常的,已经经过好几个版本的验证都是正常的,没问题。
ECSlidingViewController是一个第三方库,继承自UIViewController,是以前外包写的旧有代码。做为整个APP的总容器。
然后我再说一下详细的情况: 1.如果是在真机上删除APP,重新Build运行,第一次是正常的,各个页面右滑退出去,新闻页面push多级后右滑切换回去都正常。
2.但是如果退出APP后,再重新打开后NewsMainViewController新闻页面主控制器VC右上角的logo消失没有了,顶部系统的手机信号,电量状态栏变为黑色,正常是白色的。同时NewsViewController页面生命周期方法viewDidAppear没执行,数据没加载进来,手动下拉刷新是可以的,点击新闻详情页也能右滑,但是切换到其它导航菜单页面同样没有执行viewDidAppear,手动下拉刷新也是有数据,也可以右滑。
3.这个时候如果切换tabBarController到其它模块,再切换回新闻主控制器NewsMainViewController后,神奇地又恢复正常了,切换导航菜单页面生命周期方法都能正常执行,数据也加载出来,切回其它菜单页面同样也正常,右滑功能也都正常。 但是退出APP重新进又和第二点说的情况一样了,再切其它tabBabController后再切回来又恢复正常。
出于上面的情况,所以我才猜想是不是RTRootNavigationController和VTMagic两个框架同时对UIViewController做的扩展,是不是哪里有冲突,或者我对RTRootNavigationController的用法哪里有错误。
您可以尝试在 ECSlidingViewController
,MainTabBarController
,NewsMainViewController
以及 NewsViewController
的 - (void)viewDidAppear
方法中都加个断点,看看哪个没有进,然后把 MainTabBarController
下的四个 Navigation 改回系统的,再试试,看区别在哪
调试了一下正常时这四个Controller的viewDidAppear都会执行,改成RTRootNavigationController后,删除APP重新安装第二次运行只执行了前面三个ECSlidingViewController,MainTabBarController,NewsMainViewController的viewDidAppear,最后一个NewsViewController的viewDidAppear不执行
还有一点区别是:VTMagic他自己的代理方法viewDidAppear是有执行的,但是在这里shouldForwardAppearanceMethods判断状态的时候没通过,导致VC的beginAppearanceTransition:和endAppearanceTransition没执行,这也应该就是为什么NewsViewController的viewDidAppear没执行的原因,按照这么说RTRootNavigationController是不是改变了VC的生命周期状态导致的,但具体哪里哪里有问题始终没理解。看下面加粗的代码:
(UIViewController )contentView:(VTContentView )contentView viewControllerAtPage:(NSUInteger)pageIndex { if (!_magicFlags.dataSourceViewController) { return nil; }
UIViewController *viewController = [_dataSource magicView:self viewControllerAtPage:pageIndex]; if (viewController && ![viewController.parentViewController isEqual:_magicController]) { [_magicController addChildViewController:viewController]; [contentView addSubview:viewController.view]; [viewController didMoveToParentViewController:_magicController]; // 设置默认的currentViewController,并触发viewDidAppear if (pageIndex == _currentPage && VTSwitchEventLoad == _switchEvent) { [self resetCurrentViewController:viewController]; } } return viewController; }
(void)resetCurrentViewController:(UIViewController *)viewController { [_magicController setCurrentPage:_currentPage]; [_magicController setCurrentViewController:viewController]; viewController.view.frame = [_contentView frameOfViewControllerAtPage:_currentPage]; if (_magicFlags.viewControllerDidAppear) { [_delegate magicView:self viewDidAppear:viewController atPage:_currentPage]; }
if ([self shouldForwardAppearanceMethods]) { [viewController beginAppearanceTransition:YES animated:NO]; if (VTAppearanceStateWillAppear != _magicController.appearanceState) { [viewController endAppearanceTransition]; } } }
另外纠正一下上面第二条的执行情况:第二次运行只执行了前面两个ECSlidingViewController,MainTabBarController的viewDidAppear方法,后面两个NewsMainViewController和NewsViewController的viewDidAppear方法并没有执行。大致原因就是上面说的情况。兄弟你看这是什么原因引起的?
兄弟有空帮我看看哦,实在看不出哪有冲突,谢谢
G20 放假期间看看吧
你最好建个集成了 ECSlidingViewController 和 VSMagic 及本项目的 demo 工程给我,vc 都用空页面好了
整个工程发给你好了,空页面应该是重现不了问题,因为这里牵涉网络请求和缓存等真实环境。 兄弟提供个QQ和邮箱,有200来M
另外主页面导航栏顶部的系统状态栏颜色,在切换时也是有问题的。例如主页面A默认是白色的,切换到B详情页面再切回去后,A页面的系统状态栏变为黑色了。B详情页的状态栏是黑色的。正常的切回A页面,状态栏应该重新变为白色。 可能问题和上面的是同一原因。
这真的好么…… hidden
兄弟我下午准备给你发代码,又重新copy了一个工程做了一次,上面的问题神奇的好了,不会出现第二次运行viewDidAppear的问题。整体测了一下基本没问题,感觉比FDFullscreenPopGesture好很多,FDFullscreenPopGesture会导致很多错乱。 另外我想请教两个问题:
1.苹果官方使用边缘侧滑应该有他的道理,估计也是全盘评估各种可能性后,觉得边缘侧滑最保险。 不过我看腾讯新闻和今日头条的新闻详情页都支持全屏右滑,用户体验好很多,我想他们这么做肯定是因为新闻详情页基本上是新闻内容占大篇幅,这样也避免了和tableView右滑的冲突。而我们做的也是新闻资讯APP,VC右滑和tableView左滑手势(不是右滑)共存的页面只有一个,按理说一个左滑,一个右滑也不会冲突。
RTRootNavigationController做为第三方开源框架从设计上肯定是要避免冲突,如果我想在RTRootNavigationController的基础上添加支持全屏右滑的特性,应该要怎么修改原来的代码来支持全屏右滑?
2.确实每个VC都有单独的导航条,有效避免了像FDFullscreenPopGesture切换时导致导航条错乱的问题。这一点确实要有所取舍的,稳定才是王道,对于老项目中的各种不规范的导航条设计,各种写法来说RTRootNavigationController就是救命稻草,确实好用。
FDFullscreenPopGesture我在前几天也用了一下,貌似对iOS 7支持并不好。 另外请教一下兄弟FDFullscreenPopGesture在从有bar的新闻详情页切换到有bar的列表页时,这里是按住切换时,新闻详情页的导航条变成了灰色,原来正常的是白色的,导航条按钮也都消失了,这是什么原因导致的? 我反复调试了一下都没解决。 我想把这个BUG解决了,把两个版本都给产品经理看看,对比一下。谢谢!
FDFullscreenPopGesture
的实现是 swizzle 了 - (void)viewWillAppear:
,它自动帮你在里面做了 - (void)setNavigationBarHidden:animated:
操作。所以我想应该不是变灰色了,而是透明了,交互式返回时所有动画都会被差值。透明应该是什么颜色都没有啊,但我确实看到的是灰色。如果像你说的被透明了,返回的所有动画都会被差值,那我这个问题应该怎么解决呢?
新闻详情和列表页都是有 Bar 的,详情页是白的,然后列表页是透明吗?
列表页外层包了一层主控制器,这个是有bar的背景是红色的,详情页是白色的
估计就是白色到红色插值时出现的灰色了,因为是同一个 Bar,这个暂时不知道怎么搞
等于说这个时候他们共用一个Bar,过渡时颜色取差值,又不是渐变颜色? 如果是这样那也太不靠谱了,取差值肯定不精准。 但问题时FDFullscreenPopGesture这么多人在用,难道就都没碰到这个明天的BUG?
对了兄弟,我按照#17加了全屏手势后,在按住右滑时被切换的VC也可以按着滑动了,导航条是跟随不动的。这个在全屏右滑时怎么禁止,本身被切换的VC的滑动。
全屏右滑时,如果本身VC也可以按住滑动,往下滑就会看到下面VC,这样太难看。正常的应该是全屏拖动右滑,但本身的VC是滑不动的。
我觉得是#17这种方式添加全屏右滑还存在问题,会导致VC背景透明掉了,按住拖动就能看到下面VC。而且我的详情页上面部分是一个webView,下拉不仅会导致上面提到的问题,而且下拉scrollView顶部还会闪屏。不知道这全屏右滑还有没有其它方法能实现?
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return NO;
}
我的使用方法是这样的:在storyboard中把几个自定义tabbarController添加的NavigationController都改成 RTRootNavigationController,启动运行后各个页面都能右滑了。但是后来发现重新启动后主页面的viewDidAppear没执行到,而我的数据请求是放在viewDidAppear中载入的。
另外我的主页面是通过第三方框架VTMagic来切换加载的,这是一个导航菜单框架。我猜想的是RTRootNavigationController对UIViewController的扩展和VTMagic对UIViewController的扩展冲突了,导致VTMagic的生命周期方法执行失效。看了半天也没看出具体哪出问题了,所以想请教兄弟看一下到底哪出错了。谢谢!