今天在做一個音樂播放器的項目,發現這個點擊退出程序的功能不能實現終於找到了一些有用的資料,就去網上看了半天資料,下面是退出程序的代碼:
在動畫里面可以自己添加一些,動畫,達到相應的效果。
AppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow *window = app.window; [UIView animateWithDuration:1.0f animations:^{ window.alpha = 0; window.frame = CGRectMake(0, window.bounds.size.width, 0, 0); } completion:^(BOOL finished) { exit(0); }];
在一個程序中打開另一個應用程序 參考
應用之間跳轉的原理:
在iOS中打開一個應用程序只需要拿到這個應用程序的協議頭即可,所以我們只需配置應用程序的協議頭即可。
假設有應用A和應用B兩個應用,現在需要從應用A跳轉到應用B中。
-
原理:通過設置跳轉到應用B的URL Schemes(自定義的協議頭),應用B將其自身“綁定”到一個自定義URL Schemes上,就可以從應用A中利用應用B的URL Schemes啟動應用B了。
具體怎么做呢,下面一步步來教你,先來個簡單點的:從應用A跳轉到應用B。設置App-B的URL Schemes
應用A跳轉到應用B
-
首先我們用Xcode創建兩個iOS應用程序項目,項目名稱分別為App-A、App-B。
-
選擇項目App-B -> TARGETS -> Info -> URL Types -> URL Schemes,設置App-B的URL Schemes為AppB。
在應用程序App-A中添加一個用來點擊跳轉的Button,並監聽點擊事件,添加跳轉代碼。
//添加跳轉按鈕 - (IBAction)jumpToAppB:(id)sender { // 1.獲取應用程序App-B的URL Scheme NSURL *appBUrl = [NSURL URLWithString:@"AppB://"]; // 2.判斷手機中是否安裝了對應程序 if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) { // 3. 打開應用程序App-B [[UIApplication sharedApplication] openURL:appBUrl]; } else { NSLog(@"沒有安裝"); } }
注意:
-
如果是iOS9之前的模擬器或是真機,那么在相同的模擬器中先后運行App-B、App-A,點擊按鈕,就可以實現跳轉了。
-
如果是iOS9之后的模擬器或是真機,那么則需要再在應用程序App-A中將App-B的URL Schemes添加到白名單中,原因和做法如下。
-
iOS9引入了白名單的概念。
-
在iOS9中,如果使用
canOpenURL:
方法,該方法所涉及到的 URL Schemes 必須在"Info.plist"中將它們列為白名單,否則不能使用。key叫做LSApplicationQueriesSchemes ,鍵值內容是對應應用程序的URL Schemes。
-
具體做法就是在App-A的Info文件中,添加LSApplicationQueriesSchemes數組,然后添加鍵值為AppB的字符串。
添加白名單之后在相同的模擬器中先后運行App-B、App-A,點擊按鈕,就可以實現跳轉了。
假設有兩個程序如下: App_a、App_b,我們要是現在 App_a 里觸發某個事件去打開 App_b,具體實現如下所示:
建立一個新的項目 App_a 步驟如下所示:
在 App_a 中設置跳轉按鈕,如下所示:
並做好關聯,在 ViewController.m 中的代碼如下所示:
#import "ViewController.h" #import "AppDelegate.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } // 跳轉到 App——b - (IBAction)backToApp_b_method:(UIButton *)sender { // 1.獲取應用程序App-B的URL Scheme // 下面代碼是跳轉的關鍵代碼;AppB:// 就是我們第二個 APP 的 URL Schemes 。 NSString *urlStr = @"AppB://"; NSURL *url = [NSURL URLWithString:urlStr]; // 2.判斷手機中是否安裝了對應程序 if ([[UIApplication sharedApplication] canOpenURL:url]) { // 3. 打開應用程序App-B [[UIApplication sharedApplication] openURL:url]; } else { NSLog(@"沒有安裝"); } } // 退出 App——a 程序 - (IBAction)exitApp_a_method:(UIButton *)sender { AppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow *window = app.window; [UIView animateWithDuration:1.0f animations:^{ window.alpha = 0; window.frame = CGRectMake(0, window.bounds.size.width, 0, 0); } completion:^(BOOL finished) { exit(0); }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
在 App_a 的 info 文件中設置如下:
我們這里已經將錯誤的 URL Schemes 改為正確的 如下所示:
在 App_b 中也做如上的設置,新建 App_b ,設置 info.plist 文件, 在 info.plist 文件里添加 LSApplicationQueriesSchemes 數組,在數組中插入一個字符串元素為 App_a 就是一個能夠打開的 App 的名字, 在 URL Types 里新增 URL (AppB) 並綁定 App_b 的 bundleID (com.jw.AppB) 如下圖所示。
在 App_b 的 Main 文件里也做幾個按鈕,用於跳轉到 App_a 中 並做好sb 與代碼的關聯,代碼如下:
#import "ViewController.h" #import "AppDelegate.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } // 跳轉到 App——a 程序 - (IBAction)backToApp_a_method:(UIButton *)sender { // 下面代碼是跳轉的關鍵代碼;App_a:// 就是我們第一個 APP 的 URL Schemes 。 NSString *urlStr = @"AppA://"; NSURL *url = [NSURL URLWithString:urlStr]; [[UIApplication sharedApplication] openURL:url]; } // 退出 App——b 程序 - (IBAction)exitApp_b_method:(UIButton *)sender { AppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow *window = app.window; [UIView animateWithDuration:1.0f animations:^{ window.alpha = 0; window.frame = CGRectMake(0, window.bounds.size.width, 0, 0); } completion:^(BOOL finished) { exit(0); }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
此時運行兩個 App ,我們在 App_a 的頁面中點擊跳轉到 App_b 就能夠實現頁面的跳轉了。
應用App_a跳轉到應用App_b的特定界面
很多時候,我們做應用程序之間的跳轉並不只是跳轉到其他程序就可以了,而是要跳轉到其他程序的特定頁面上。比如我們在瀏覽網頁時,會有分享到微信朋友圈或是分享給微信朋友,這就需要跳轉到微信朋友圈界面或是微信朋友選擇界面。
具體如何做呢?
1、首先我們先來為App-b搭建兩個頁面 FFPageViewController 和 HHPageViewController 。這里用導航控制器 Push 兩個 ViewController,通過Push 來進入 FFPaeViewControler 所以將 FFPageViewController 的頁面標示綁定為 FFPage,通過Storyboard Segue設置HHPageViewController的標識符綁定,"HHPage"。之所以這樣做,是為了實現兩種技術下的頁面跳轉。如下所示:
代碼為:
Appdelegate.m 文件修改代碼如下:
#import "AppDelegate.h" #import "ViewController.h" #import "FFPageViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{ // 1.獲取導航欄控制器 UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController; // 2.獲得主控制器 ViewController *mainVc = [rootNav.childViewControllers firstObject]; // 保存完整的App-A的URL給主控制器 mainVc.urlString = url.absoluteString; // 3.每次跳轉前必須是在跟控制器(細節) [rootNav popToRootViewControllerAnimated:NO]; // 4.根據字符串關鍵字來跳轉到不同頁面 if ([url.absoluteString containsString:@"FFPage"]) { // 跳轉到應用App_b的FFPage頁面 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"FFPageViewController" bundle:[NSBundle mainBundle]]; FFPageViewController * ffPage = [storyboard instantiateViewControllerWithIdentifier:@"FFPageViewController"]; ffPage.urlString = mainVc.urlString;//傳遞原來的App 的 URL scheme [mainVc.navigationController pushViewController:ffPage animated:YES]; } else if ([url.absoluteString containsString:@"HHPageSegue"]) { // 跳轉到應用App_b的HHViewController頁面 // 根據segue標示進行跳轉 [mainVc performSegueWithIdentifier:@"HHPageSegue" sender:nil]; } return YES; } @end
ViewController.h文件修改
#import <UIKit/UIKit.h> @interface ViewController : UIViewController // 用來保存App_a完整的URL @property (nonatomic, copy) NSString *urlString; @end
ViewController.m文件修改
#import "ViewController.h" #import "AppDelegate.h" #import "HHViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } // 跳轉到 App——a 程序 - (IBAction)backToApp_a_method:(UIButton *)sender { // 1.獲取應用程序App-A的URL Scheme // 下面代碼是跳轉的關鍵代碼;App_a:// 就是我們第一個 APP 的 URL Schemes 。 NSString *urlStr = @"AppA://"; NSURL *url = [NSURL URLWithString:urlStr]; // 2.判斷手機中是否安裝了對應程序 if ([[UIApplication sharedApplication] canOpenURL:url]) { // 3. 打開應用程序App-A [[UIApplication sharedApplication] openURL:url]; } else { NSLog(@"沒有安裝"); } } // 退出 App——b 程序 - (IBAction)exitApp_b_method:(UIButton *)sender { AppDelegate *app = (id)[UIApplication sharedApplication].delegate; UIWindow *window = app.window; [UIView animateWithDuration:1.0f animations:^{ window.alpha = 0; window.frame = CGRectMake(0, window.bounds.size.width, 0, 0); } completion:^(BOOL finished) { exit(0); }]; } // 使用 segue 進行跳轉 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"HHPageSegue"]) { // 獲得將要跳轉的界面HHViewController的控制器 HHViewController *HHPage = segue.destinationViewController; // 保存完整的App_a的URL給跳轉界面HHViewController,方便后期能夠返回的操作等....這里不再寫了 HHPage.urlString = self.urlString; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
FFPageViewController.h 文件
#import <UIKit/UIKit.h> @interface FFPageViewController : UIViewController // 用來保存App_a完整的URL @property (nonatomic, copy) NSString *urlString; @end
FFPageViewController.m 文件
#import "FFPageViewController.h" @interface FFPageViewController () @end @implementation FFPageViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } // 返回 App_a 程序 - (IBAction)backToApp_aMethod:(UIButton *)sender { // 1.拿到對應應用程序的 URL Schemes NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject]; NSString *urlString = [urlSchemeString stringByAppendingString:@"://"]; // 1.獲取對應應用程序的URL NSURL *url = [NSURL URLWithString:urlString]; // 2.判斷是否可以打開 if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; }else { NSLog(@"沒有安裝原來的程序,着說不通啊,你是咋跳轉過來的昂?"); } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
在 HHViewController.h 文件里添加屬性 urlString 字段。
在 HHViewController.m 文件里添加如下代碼,並與 StoryBoard 文件關聯:
// 返回 App_a 程序 - (IBAction)backTo_App_aMethod:(UIButton *)sender { // 1.拿到對應應用程序的URL Scheme NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject]; NSString *urlString = [urlSchemeString stringByAppendingString:@"://"]; // 1.獲取對應應用程序的URL NSURL *url = [NSURL URLWithString:urlString]; // 2.判斷是否可以打開 if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; }else { NSLog(@"沒有安裝原來的程序,着說不通啊,你是咋跳轉過來的昂?"); } }
2、然后再在 App_a 中添加一些用來跳轉的頁面,並進行關聯,如下所示:
3、注意,從應用程序 App_b 跳回 App_a 的實現原理如下:
步驟分析:
-
我們想要從應用B再跳轉回應用A,那么在跳轉到應用B的時候,還應將應用A的URL Schemes傳遞過來。這樣我們才能判斷應該跳轉回哪個應用程序。
-
這樣我們指定一個傳遞URL的規則:
協議頭://應用B的URL Schemes?應用A的URL Schemes
。即:AppB://Page1?AppA
。 -
說明:
-
AppB是跳轉過來的應用App-B的URL Schemes;
-
Page1是用來區別跳轉頁面的標識;
-
? 是分割符;
-
AppA是跳轉回的應用App-A的URL Schemes
-
-
-
我們根據傳遞來的數據,進行反跳回去。
-
之前我們在應用App-B中通過
AppDelegate
執行不同頁面的跳轉。在對應方法中我們可以拿到完整的URL,在主控制器ViewController中設定一個屬性,將該URL保存在主控制器中。 -
在主控制器中我們可以通過
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
方法獲取將要跳轉的頁面控制器。 -
在將要跳轉的頁面控制器中定義一個屬性,用於接受、截取出跳轉回的應用(即App-A)的URL Schemes,執行跳轉。
-
4、實現效果圖如下:
首先運行兩個程序,保證安裝成功。