Code Monkey home page Code Monkey logo

rtrootnavigationcontroller's Introduction

RTRootNavigationController

CI Status Version License Platform

iOS 15

Apple has changed some behavior of UINavigationBar(see)on iOS 15, developers can override this on demands:

iOS 15 上苹果改变了导航条的部分默认行为,开发者可以自己重写:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // setup appearance
    if (@available(iOS 15.0, *)) {
        [[UINavigationBar appearance] setScrollEdgeAppearance:({
            UINavigationBarAppearance *app = [UINavigationBarAppearance new];
            [app configureWithDefaultBackground];
            // init app property
            // app.backgroundColor = xxx;
            // app.shadowColor = xxx;
            app;
        })];
    } else {
        // Fallback on earlier versions
    }

    return YES;
}

iPhone X

How many lines of code should I write to fit in iPhone X? Zero.

我需要写多少代码来适配 iPhone X?0。

iphone-x

Introduction

More and more apps use custom navigation bar for each different view controller, instead of one common, global navigation bar.

This project just help develops to solve this problem in a tricky way, develops use this navigation controller in a farmilar way just like you used to be, and you can have each view controller a individual navigation bar.

越来越多的应用为每一个 VC 设置单独的导航条,而不是之前那样使用一个全局统一的导航条,因为不同的 VC 有不同的视觉样式,前一个是蓝色的,后一个也许要做成红色、透明,或者干脆没有导航条。

虽然开发者可以在每个 VC- (void)viewWillAppear (想想为什么不是 - (void)viewDidLoad) 方法中设置自己所需的样式,但是在同一个导航条上来回修改,稍不注意就会导致样式混乱。另一种实现方式,是隐藏全局那个导航条,每个 VC 自己通过 addSubview:(UIView *)view 的方式自己设置导航条。这种实现是可行的,但是使用不方便了,如:

  • 无法使用 self.navigationItem.rightBarButtonItem 等来设置导航按钮,而必须自己手动往 navigationBar 上加;
  • 无法使用 self.title 来修改导航标题,而必须自己添加监听;
  • 无法方便地设置 navigationBarHidden
  • 无法方便地自动调整 contentInsets

等等。

本项目提供一种透明的方式,让开发者像以前一样使用导航器,同时,每个 push 进来的 VC 有自己独立的导航条。

Features

  • Custom navigation bar class support

  • Unwind support

  • Rotation support

  • Interactive pop enable and disable support

  • Interface Builder support

  • 每个 VC 支持自定义的 navigationBarClass

  • 支持 unwind(不知道什么是 unwind?请参考:这里

  • 支持转屏

  • 支持禁用交互式返回

  • 支持 Interface Builder

screenshot

scrreecap

Usage

As an advise, please set RTRootNavigationController as your rootViewController:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    UIViewController *yourController = ...;
    self.window.rootViewController = [[RTRootNavigationController alloc] initWithRootViewController:yourController];
    return YES;
}

you can implement following method to customize back bar button item (Recommended):

- (UIBarButtonItem *)rt_customBackItemWithTarget:(id)target
                                          action:(SEL)action
{
    return [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Back", nil)
                                            style:UIBarButtonItemStylePlain
                                           target:target
                                           action:action];
}

or just set useSystemBackBarButtonItem to YES and use the default one.

To run the example project, clone the repo, and run pod install from the Example directory first.

Notice(Only for below v0.6)

Your ViewController hierarchy will change to:

RTRootNavigationController
    `- RTContainerViewController
    |       `- RTContainerNavigationController
    |               `- YourViewController1
    `- RTContainerViewController
            `- RTContainerNavigationController
                    `- YourViewController2

So, if you access self.navigationController it returns a container navigation controller, and its viewControllers will always be 1, i.e. self. Instead, your have to use self.rt_navigationController.rt_viewController to get all siblings, as metioned Here and Here.

Requirements

  • iOS 7 and up
  • Xcode 7 and up

Installation

RTRootNavigationController is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "RTRootNavigationController"

Author

rickytan, [email protected]

Alternatives

Apps Integrated

License

RTRootNavigationController is available under the MIT license. See the LICENSE file for more info.

rtrootnavigationcontroller's People

Contributors

hztanxin avatar ivarwei avatar leavesster avatar rickyai avatar rickytan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rtrootnavigationcontroller's Issues

RTRootNavigationController导致主页面列表生命周期方法没执行

我的使用方法是这样的:在storyboard中把几个自定义tabbarController添加的NavigationController都改成
RTRootNavigationController,启动运行后各个页面都能右滑了。但是后来发现重新启动后主页面的viewDidAppear没执行到,而我的数据请求是放在viewDidAppear中载入的。

另外我的主页面是通过第三方框架VTMagic来切换加载的,这是一个导航菜单框架。我猜想的是RTRootNavigationController对UIViewController的扩展和VTMagic对UIViewController的扩展冲突了,导致VTMagic的生命周期方法执行失效。看了半天也没看出具体哪出问题了,所以想请教兄弟看一下到底哪出错了。谢谢!

[[RTContainerNavigationController alloc] initWithRootViewController:vc2]

tabController.viewControllers = @[[[RTContainerNavigationController alloc] initWithRootViewController:vc1],
[[RTContainerNavigationController alloc] initWithRootViewController:vc2],
[[RTContainerNavigationController alloc] initWithRootViewController:vc3],
[[RTContainerNavigationController alloc] initWithRootViewController:vc4]];
self.window.rootViewController = [[RTRootNavigationController alloc] initWithRootViewControllerNoWrapping:tabController];

  1. vc1,vc2,vc3, vc4 无法使用到UIViewController (RTRootNavigationController)中的rt_navigationBarClass
  2. UIViewController中无法获得UITabBarController

如何在首页隐藏NavigationBar

  • 层级结构

     RTRootNavigationController->UITabBarController	-->RTRootNavigationController---》VC1
     						-->RTRootNavigationController---》VC2
     				  	        -->RTRootNavigationController---》VC3
    

说明:
第一级RTRootNavigationController是为了方便Routable来弹出其他ViewController,因此需要隐藏
第二级UITabBarController分成三个页面,每一个页面对应自己一个RTRootNavigationController

需求:

  • 第一级RTRootNavigationController隐藏(首页隐藏NavigationBar)。
  • 其他根据需求来决定是否隐藏。

代码:

  • AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

     TabBarController *tabbarController = [[TabBarController alloc] init];
     RTRootNavigationController *nav = [[RTRootNavigationController alloc] initWithRootViewController:tabbarController];
     [nav setNavigationBarHidden:YES];
     self.window.rootViewController = nav;

使用UINavigationBar appearance无法修改导航栏样式

我在AppDelegate里使用UINavigationbar appearance无法修改导航栏的样式:
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:58/255.0 green:58/255.0 blue:58/255.0 alpha:1.0]]; [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor],NSForegroundColorAttributeName ,[UIFont systemFontOfSize:20.0], NSFontAttributeName, nil]];
没有任何效果

怎样让storyboard的单个页面支持右滑

我原先是tabbar加载的,storyboard指定了一个RTRootNavigationController,然后它的viewcontroller是现在要打开的页面,这样是没问题的。但是现在页面结构变了,要在主页面中单独打开这个页面,也就没有RTRootNavigationController这一层了,那要怎样让这个单个页面支持右滑?

如何修改rootvc的导航栏颜色

下载你的Demo,注释掉appdelegate的代码,使用包含tabbarController的例子,然后发现Root那个tabbar的根控制器是RTStaticTableViewController,我想要修改这个控制器的导航栏背景色,或者自定义导航栏样式,在该.m文件中添加rt_navigationBarClass这个方法,返回一个自定义UINavigationBar类,但是没有效果,请问,在这种情况下,如何修改根控制器的导航栏背景?

和RDVTabBarController一起使用时有问题

我的项目结构是:根视图是RDVTabBarController(算是一种自定义tabbarcontroller),他的ViewControllers是RTRootNavigationController,当push到一个隐藏了底部tabbar的ViewController里时,底部就会留出来空白,当我慢慢的侧滑返回又取消时,就会填充满。
图片传不上来,我整理了demo:https://github.com/songhailiang/RTNavigationDemo
请帮我看一下,应该怎么处理,万分感谢。

RTRootNavigationController右滑手势和自定义UIScrollView右滑冲突

我自定义了一个UIScrollView用于图片查看模式,可以左右滚动查看图片。
在这个VC中RTRootNavigationController的右滑无法响应,然后我使用两种方法设置代理来解决都没用,这个问题该怎么解?

方法一:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // 首先判断otherGestureRecognizer是不是系统pop手势
    if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
        // 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边
        if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {
            return YES;
        }
    }

    return YES;
}

方法二:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{

    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
        [gestureRecognizer requireGestureRecognizerToFail:otherGestureRecognizer];
        return NO;
    }
    return YES;
}

一用UIAlertController就挂掉

错误信息如下:
2016-08-29 10:47:52.136 RTRootNavigationController_Example[53635:10524179] *** Assertion failure in -[UIAlertController supportedInterfaceOrientations], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/UIAlertController.m:542
2016-08-29 10:47:52.141 RTRootNavigationController_Example[53635:10524179] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIAlertController:supportedInterfaceOrientations was invoked recursively!'
*** First throw call stack:
(
0 CoreFoundation 0x000000010a1aad85 exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000109c1edeb objc_exception_throw + 48
2 CoreFoundation 0x000000010a1aabea +[NSException raise:format:arguments:] + 106
3 Foundation 0x0000000107c03d5a -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
4 UIKit 0x0000000108302313 -[UIAlertController supportedInterfaceOrientations] + 316
5 RTRootNavigationController_Example 0x0000000107a9c7f6 -[RTRootNavigationController supportedInterfaceOrientations] + 70
6 UIKit 0x0000000108302258 -[UIAlertController supportedInterfaceOrientations] + 129
7 UIKit 0x0000000108193d6c -[UIViewController __supportedInterfaceOrientations] + 701
8 UIKit 0x00000001081943c5 -[UIViewController __withSupportedInterfaceOrientation:apply:] + 45
9 UIKit 0x0000000108194c59 -[UIViewController setInterfaceOrientation:] + 145
10 UIKit 0x000000010817d9a3 -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] + 1458
11 UIKit 0x000000010808f58c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1609
12 UIKit 0x0000000108084562 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 155
13 Foundation 0x0000000107b8d3d3 -[NSISEngine withBehaviors:performModifications:] + 155
14 UIKit 0x0000000108084480 -[UIView(Hierarchy) _postMovedFromSuperview:] + 575
15 UIKit 0x000000010809226c -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1967
16 UIKit 0x00000001082ebd63 -[_UIAlertControllerPresentationController presentationTransitionWillBegin] + 208
17 UIKit 0x000000010814af44 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke + 2035
18 UIKit 0x0000000108148b76 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 309
19 UIKit 0x0000000107fe6f62 _runAfterCACommitDeferredBlocks + 317
20 UIKit 0x0000000107ffae4c _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
21 UIKit 0x0000000108007147 _afterCACommitHandler + 90
22 CoreFoundation 0x000000010a0cfc37 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 23
23 CoreFoundation 0x000000010a0cfba7 __CFRunLoopDoObservers + 391
24 CoreFoundation 0x000000010a0c57fb __CFRunLoopRun + 1147
25 CoreFoundation 0x000000010a0c50f8 CFRunLoopRunSpecific + 488
26 GraphicsServices 0x000000010c48dad2 GSEventRunModal + 161
27 UIKit 0x0000000107fdaf09 UIApplicationMain + 171
28 RTRootNavigationController_Example 0x0000000107a9527f main + 111
29 libdyld.dylib 0x000000010b3e792d start + 1
30 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

如何pop到指定页面,

如何pop到指定页面,
A - push -B
B - Push -C
C- Push - D

D 物理按钮怎么pop到A
D 返回按钮还需要支持pop到C

跟其他的三方库有冲突

因为要做一个类似天猫商品类别筛选的悬浮VIEW在bar的下面,随着table的滑动这个view悬浮在屏幕顶端,找到了TLYShyNavBar这个第三方,会出现bar减少20像素的问题。

最外层是UITabBarController,removeViewController,会出现一块navigationbar

RTAppDelegate

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    使用该方法里面的代码运行,即可出现我所说的效果,
    在 root 页面上 ——》点击“push and remove” ——》点击“push to next ……”,在最后的页面,点击返回按钮,会回到tabViewController, 观察navigationbar的位置,有多出来的一层navigationbar。

RTRootNavigationController右滑手势和自定义UIScrollView右滑冲突

我自定义了一个UIScrollView用于图片查看模式,可以左右滚动查看图片。
在这个VC中RTRootNavigationController的右滑无法响应,然后我使用两种方法设置代理来解决都没用,这个问题该怎么解?

方法一:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 首先判断otherGestureRecognizer是不是系统pop手势
if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
// 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {
return YES;
}
}

return YES;

}

方法二:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{

return YES;

}

  • (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
    [gestureRecognizer requireGestureRecognizerToFail:otherGestureRecognizer];
    return NO;
    }
    return YES;
    }

rt_disableInteractivePop 被多次设置后无作用

我在demo的RTWebViewController界面中,添加了一个按钮,事件是每次点击,当前controller的rt_disableInteractivePop置非,
即:self.rt_disableInteractivePop = !self.rt_disableInteractivePop

在执行这个方法前能划出屏幕的情况下,执行之后,依旧能够划出屏幕(正常应该不能再划出了);
反之亦然;

真实的使用场景例如在 WKWebview 中,设置webview 的allowsBackForwardNavigationGestures 为yes,如果 webivew 的 canGoBack 的值是 YES,此时就不应该触发滑动退出页面的事件,而应该触发webview的goBack事件(类似微信的webview)

根据我的观察,存在以下几种情况
1.在viewDidLoad方法中设置 rt_disableInteractivePop 的值会生效;
2.WKWebview有缓存后,根据webview的状态(是否能goBack)在主线程重新设置rt_disableInteractivePop的值会生效;

swift 3 的使用问题

在swift 3 中 ,在VC的viewDidLoad下调用,不管是
self.navigationController
还是
self.rt_navigationController
都会中断在

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated
{
    if (self.navigationController)
        [self.navigationController setViewControllers:viewControllers
                                             animated:animated];
    else
        [super setViewControllers:viewControllers animated:animated];
}

中的倒数第二行,不知道怎么在swift 3 下对VC的navigationBar进行自定义.
还有新建一个类继承RTRootNavigationController和UINavigationControllerDelegate的时候,意在自动以过场动画,也会有如上的中断.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.