ios 收到远程通知,点击跳转到对应的消息界面

立冬

现在有一个需求,有通知过来,app处于前台时,弹出一个alert,点击确定跳转到对应的界面,在这里我设了一个定时器,模拟接收到通知弹出alert,通知的集成代码这边就不多做介绍了,想了解集成我的上篇文章中有简单的介绍,下面开始分两种情况

1. self.window.rootViewController是导航控制器

appdelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // MainTabbarVC为tabbarController
    MainTabbarVC *main = [[MainTabbarVC alloc] init];
    UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:main];
    self.window.rootViewController = nvc;
    [self.window makeKeyAndVisible];
// 设定一个弹出alert的定时器
    time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
    return YES;
}

- (void)showAlert
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"是否去消息界面" message:@"请选择" preferredStyle:UIAlertControllerStyleAlert];    
    UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //  点击确定,处理页面跳转
        ViewController *viewC = [[ViewController alloc] init];
        NSLog(@"点击了确定,push");
    }];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];  
    [alertController addAction:alertAction];
    [alertController addAction:cancelAction];    
//    MainTabbarVC *main = [[MainTabbarVC alloc] init];
//    [main presentViewController:alertController animated:YES completion:nil];
//    HomeViewController *home = [[HomeViewController alloc] init];
//    [home presentViewController:alertController animated:YES completion:nil];  // 主页
// 以上两种方法无法弹出alert

// 用rootViewController弹出laert
[self.window.rootViewController presentViewController:alertController animated:YES completion:nil];

    [time invalidate]; // 取消定时器
}
弹出alert

接下来着重说一下跳转的方法

1.用self.window.rootViewController去push

ViewController *viewC = [[ViewController alloc] init];
[(UINavigationController *)self.window.rootViewController pushViewController:viewC animated:YES]; // 这里需要强制转化一下,这个方法不推荐,当项目中业务逻辑比较复杂的时候,此方法可能会导致很多bug,待会会介绍另外一种写法

self.window.rootViewController实际上是MainTabbarVC

打断点,用po命令查看

下面看一下MainTabbarVC里面的代码

#import "MainTabbarVC.h"
#import "HomeViewController.h"
#import "SettingViewController.h"

@interface MainTabbarVC ()

@end

@implementation MainTabbarVC

// 程序进入隐藏appdelegate里面创建的navigation ,这一步很关键,不然进入主页面,看到的navigation将是在appdelegate里面创建的,不利于管理
- (void)viewWillAppear:(BOOL)animated{    
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}
- (void)viewDidLoad {
    [super viewDidLoad];    
    [self creatControllers];
}

- (void)creatControllers
{
    HomeViewController *home = [[HomeViewController alloc] init];
    UINavigationController *homeNAV = [[UINavigationController alloc] initWithRootViewController:home];
    home.title = @"主页";
    
    SettingViewController *setting = [[SettingViewController alloc] init];
    UINavigationController *settingNAV = [[UINavigationController alloc] initWithRootViewController:setting];
    setting.title = @"设置";
    
    self.viewControllers = @[homeNAV,settingNAV];
    
}

跳转后的页面效果


跳转后的viewController

1.2 刚才说了上面的push方法不推荐,下面推荐一个比较合理的方法在Appdelegate.m中

#import "AppDelegate.h"
#import "MainTabbarVC.h"
#import "ViewController.h"
@interface AppDelegate ()
{
     NSTimer *time;
}
@end
static AppDelegate *__delegate = nil;
@implementation AppDelegate
AppDelegate *myDelegate(void){
    return __delegate;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    MainTabbarVC *main = [[MainTabbarVC alloc] init];
    self.window.rootViewController = main;
    __delegate = self;
    _masterTabbarController = main;    
    [self.window makeKeyAndVisible];  
    time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
    return YES;
}

// alert中push
 UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        // 跳转页面 跳转到消息列表页面
        ViewController *viewC = [[ViewController alloc] init];
        [AppDelegate mastePushViewController:viewC];
    }];


// push方法
+ (void)mastePushViewController:(UIViewController *)controller
{
    UINavigationController *nvc = myDelegate().masterTabbarController.selectedViewController;
    [nvc pushViewController:controller animated:YES];
}

push之后的效果如下


直接拿到tabbarController的navigation

viewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
// 显示隐藏的导航栏
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = NO;   
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor cyanColor];
    self.title = @"viewController";
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
@end

2. self.window.rootViewController不是导航控制器

appdelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
    MainTabbarVC *main = [[MainTabbarVC alloc] init];
    self.window.rootViewController = main;
    [self.window makeKeyAndVisible];
    time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
    return YES;
}

这种情况下,利用以上跳转方法,程序会crash,下面是奔溃信息


奔溃信息

主要是说MainTabbarVC没有push方法,我们知道没有导航控制器是不可能用push,所以这里我们建一个navigationController,然后在跳转的时候隐藏创建的这个

AppDelegate.h

AppDelegate.h加一个navigation

AppDelegate.m


#import "AppDelegate.h"
#import "MainTabbarVC.h"
#import "ViewController.h"

@interface AppDelegate ()
{
    NSTimer *time;
}

@end

static AppDelegate *__delegate = nil;

@implementation AppDelegate

AppDelegate *myDelegate(void){
    return __delegate;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    MainTabbarVC *main = [[MainTabbarVC alloc] init];
    self.myNavigationController = [[UINavigationController alloc] initWithRootViewController:main];
    __delegate = self;
// push的时候隐藏navigationBarHidden
    self.myNavigationController.navigationBarHidden = YES;
    self.window.rootViewController = main;
    
    [self.window makeKeyAndVisible];
    
    time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
    return YES;
}

+ (void)myPushViewController:(UIViewController *)controller
{
    UINavigationController *nvc = myDelegate().myNavigationController;
    [nvc pushViewController:controller animated:YES];
}

弹出的alert

- (void)showAlert
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"是否去消息界面" message:@"请选择" preferredStyle:UIAlertControllerStyleAlert];    
    UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        // 跳转页面 跳转到消息列表页面
        ViewController *viewC = [[ViewController alloc] init];
       [AppDelegate myPushViewController:viewC];
        NSLog(@"点击了确定,准备push");
    }];    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];    
    [alertController addAction:alertAction];
    [alertController addAction:cancelAction];    
    [self.myNavigationController presentViewController:alertAction animated:YES completion:nil];
//    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];  // 因为self.window.rootViewController = self.myNavigationController,所以这两个方法是一样的    
    [time invalidate];
}

核心代码:


创建navigation

弹框的代码

弹出alert

这里遇到接收推送后跳转消息界面,可以重新封装一个类,将下面这个方法放到封装的类中,可以全局调用此方法处理消息跳转

+ (void)myPushViewController:(UIViewController *)controller
{
    UINavigationController *nvc = myDelegate().myNavigationController;
    [nvc pushViewController:controller animated:YES];
}
// 当然,你也可以不用那么繁琐,直接用[self .myNavigationController pushViewController:controller animated:YES];  // push到想要跳转的控制器即可

3、不管是不是导航控制器,我么都可以使用通知,然后通知首页进行跳转,在appdelegate里面,发送通知,代码如下

// 这里是接收到远程推送,点击通知之后,在需要做特定跳转的方法里面的
HomeTBVC *home = [[HomeTBVC alloc] init];  // 初始化一下首页试图控制器
            //是推送打开
            NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
            [center postNotificationName:@"appdelegatePushMessage" object:nil userInfo:userInfo];  // userInfo为通知内容

4、在首页试图控制器下添加代码

// 添加监听
[center addObserver:self selector:@selector(pushToWebView:) name:@"appdelegatePushMessage" object:nil];

// 跳转到相应的页面,这里的notificaiton.userInfo为远程通知内容
- (void)pushToWebView:(NSNotification *)notification{
    WebViewVC *webVC = [WebViewVC new];
    webVC.messageDic = notification.userInfo;
    webVC.strUrl = notification.userInfo[@"webUrl"];
    [self.navigationController pushViewController:webVC animated:YES];
}

至此:

可以看出appdelegate里面没有导航控制器(navigation)的时候,可以选择创建一个临时的navigation,在进入tabbarController的时候隐藏;或者直接拿到tabbarcontroller里面创建的navigation,这种方法在跳转之后底部tabbar不会消失,如果不想要tabbar,可以再push的页面中隐藏tabbar

现实有很多拘束,但是代码的世界里,你可以尽情遨游,加油everyone

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容