iOS開發:給UIWebview的導航欄新增返回、關閉按鈕
在我們平日的開發中,不免有原生與H5的互動,比如說:從原生頁面的一個按鈕,點選之後跳轉到了一個H5的頁面A,A頁面中又有一個按鈕,點選之後,又載入了一個新的H5頁面B,從B點選一個按鈕,又載入一個新的H5頁面C,如果此時我們點選左上角的返回按鈕,會直接返回到我們的原生頁面;
是不是上面給使用者的體驗很不好(當然殘品經理會覺得是,我們都是無所謂的啦),此時我們想要重新定製返回按鈕,我們想要從C頁面判斷是否還有上一級H5頁面可供返回,如果有上一級頁面還是H5,點選左上角的返回則返回到B頁面,並且在B頁面的左上角加上一個關閉按鈕,這個關閉按鈕的作用主要是為了關閉所有的H5的頁面,直接返回到我們原生的頁面;如果我們不點選關閉按鈕,還是點選返回,則從B頁面返回到A頁面;再次點選返回,則關閉了H5的頁面,回到了原生的頁面;
說的也許有點兒繞,不過大致思想就是:先判斷當前的H5頁面是否可以返回:
//判斷當前H5是否可以返回
[self.webView canGoBack]
如果可以返回,則返回到上一個H5頁面,並在左上角新增一個關閉按鈕,如果不可以返回,則直接:
//回到原生頁面
[self.navigationController popViewControllerAnimated:YES];
下面是我的主要實現程式碼,我寫一個繼承與UIViewController的類,接受了UIWebviewDelegate,並定義了一個UIwebview的屬性,給外面留了一個方法,只需要傳遞一個URL,我們就可以載入;如果有地方需要載入H5的頁面,我們可以直接整合與這個類,這樣的好處在於方便維護;
當然我封裝的這個類,同時也是支援HTTPS的請求的;話不多說,程式碼如下:
建立一個類,繼承與UIViewController,.h中的程式碼
#import <UIKit/UIKit.h>
@interface SYWebViewController : UIViewController<UIWebViewDelegate, NSURLConnectionDelegate>
//定義一個屬性,方便外接呼叫
@property (nonatomic, strong) UIWebView *webView;
//宣告一個方法,外接呼叫時,只需要傳遞一個URL即可
- (void)loadHTML:(NSString *)htmlString;
@end
.m中的實現如下:
#import "SYWebViewController.h"
@interface NSURLRequest (InvalidSSLCertificate)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
@interface SYWebViewController ()
@property (nonatomic, strong) NSURLRequest *request;
//判斷是否是HTTPS的
@property (nonatomic, assign) BOOL isAuthed;
//返回按鈕
@property (nonatomic, strong) UIBarButtonItem *backItem;
//關閉按鈕
@property (nonatomic, strong) UIBarButtonItem *closeItem;
@end
@implementation SYWebViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 64)];
[self.view addSubview:self.webView];
[self addLeftButton];
}
//載入URL
- (void)loadHTML:(NSString *)htmlString
{
NSURL *url = [NSURL URLWithString:htmlString];
self.request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5.0];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
[self.webView loadRequest:self.request];
}
#pragma mark - UIWebViewDelegate
//開始載入
- (BOOL)webView:(UIWebView *)awebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString* scheme = [[request URL] scheme];
//判斷是不是https
if ([scheme isEqualToString:@"https"]) {
//如果是https:的話,那麼就用NSURLConnection來重發請求。從而在請求的過程當中吧要請求的URL做信任處理。
if (!self.isAuthed) {
NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
[awebView stopLoading];
return NO;
}
}
return YES;
}
//設定webview的title為導航欄的title
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
#pragma mark ================= NSURLConnectionDataDelegate <NSURLConnectionDelegate>
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0) {
self.isAuthed = YES;
//NSURLCredential 這個類是表示身份驗證憑據不可變物件。憑證的實際型別宣告的類的建構函式來確定。
NSURLCredential *cre = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:cre forAuthenticationChallenge:challenge];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"網路不給力");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.isAuthed = YES;
//webview 重新載入請求。
[self.webView loadRequest:self.request];
[connection cancel];
}
#pragma mark - 新增關閉按鈕
- (void)addLeftButton
{
self.navigationItem.leftBarButtonItem = self.backItem;
}
//點選返回的方法
- (void)backNative
{
//判斷是否有上一層H5頁面
if ([self.webView canGoBack]) {
//如果有則返回
[self.webView goBack];
//同時設定返回按鈕和關閉按鈕為導航欄左邊的按鈕
self.navigationItem.leftBarButtonItems = @[self.backItem, self.closeItem];
} else {
[self closeNative];
}
}
//關閉H5頁面,直接回到原生頁面
- (void)closeNative
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - init
- (UIBarButtonItem *)backItem
{
if (!_backItem) {
_backItem = [[UIBarButtonItem alloc] init];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//這是一張“<”的圖片,可以讓美工給切一張
UIImage *image = [UIImage imageNamed:@"sy_back"];
[btn setImage:image forState:UIControlStateNormal];
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(backNative) forControlEvents:UIControlEventTouchUpInside];
[btn.titleLabel setFont:[UIFont systemFontOfSize:17]];
[btn setTitleColor:[UIColor sy_backColor] forState:UIControlStateNormal];
//字型的多少為btn的大小
[btn sizeToFit];
//左對齊
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
//讓返回按鈕內容繼續向左邊偏移15,如果不設定的話,就會發現返回按鈕離螢幕的左邊的距離有點兒大,不美觀
btn.contentEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0);
btn.frame = CGRectMake(0, 0, 40, 40);
_backItem.customView = btn;
}
return _backItem;
}
- (UIBarButtonItem *)closeItem
{
if (!_closeItem) {
_closeItem = [[UIBarButtonItem alloc] initWithTitle:@"關閉" style:UIBarButtonItemStylePlain target:self action:@selector(closeNative)];
}
return _closeItem;
}
@end
具體的使用方法就是,建立一個類,繼承與這類:SYWebViewController
#import <UIKit/UIKit.h>
#import "SYWebViewController.h"
@interface SYFlashHTMLViewController : SYWebViewController
@end
然後在這個類的.m中的viewDidLoad中,呼叫父檢視載入URL的方法,即:
- (void)viewDidLoad {
[super viewDidLoad];
self.webView.delegate = self;
[self loadHTML:self.htmlString];
}
效果如下圖:開啟百度(圖片1),點選圖片進入(圖片2),點選返回返回到(圖片3),圖片1和圖片的區別在於多了個關閉按鈕:
[圖片上傳失敗...(image-2c7fcb-1520217790077)]
[圖片上傳失敗...(image-7e437a-1520217790077)]
[圖片上傳失敗...(image-35d61b-1520217790077)]
GitHub地址:Demo
純手打,喜歡點個贊,希望對看到的你有所幫助!
原作者:First灬DKS
連結:https://www.jianshu.com/p/fa070e790647
相關文章
- uniapp更改導航欄按鈕文字APP
- 分析微信(iOS 版)定製導航欄按鈕的思路iOS
- Jquery實現的Switch開關按鈕(仿iOS開關)jQueryiOS
- 手機直播原始碼,突出底部導航欄中間按鈕的樣式原始碼
- 關於iOS 狀態列、導航欄的幾處筆記iOS筆記
- 如何禁用控制檯視窗的關閉按鈕?
- iOS Tabbar中間新增凸起可旋轉按鈕iOStabBar
- (iOS)從0到Double系列 如何刻出一個可拖動的導航浮動按鈕iOS
- 2018-08-20 iOS導航欄的那些事iOS
- 聊天平臺原始碼,解決設定導航欄按鈕圖片變色問題原始碼
- 如何給 SAP Fiori Elements 應用新增自定義按鈕
- JavaScript 點選按鈕返回底部JavaScript
- iOS 11開發教程(二十一)iOS11應用檢視美化按鈕之實現按鈕的響應(1)iOS
- 簡易的iOS導航欄顏色漸變方案iOS
- CSS開關按鈕三例CSS
- iOS - 新增一個全域性懸浮按鈕(整合pods版)iOS
- [JS]bootstrapTable新增操作按鈕JSbootAPT
- layUI layer彈框按鈕 : 確認,取消,關閉事件UI事件
- javascript閉包的使用–按鈕切換JavaScript
- 58同城APP導航、按鈕、表單、圖示運用淺析APP
- UE4 如何關閉自動更新導航,手動更新導航
- iOS Navigation Bar 導航欄折騰記 (Swift&OC)iOSNavigationSwift
- iOS 記一次導航欄平滑過渡的實現iOS
- php短視訊系統,點選按鈕開啟wifi或者關閉wifiPHPWiFi
- 直播app原始碼,給elementUI的table表頭新增按鈕或者多選框APP原始碼UI
- JavaScript點選按鈕返回底部詳解JavaScript
- Flutter 導航欄AppBarFlutterAPP
- CSS3 checkbox開關按鈕效果CSSS3
- [小程式]高適應性的自定義導航欄開發思路
- 教程中使用bootstrap5之後,點選導航按鈕不展開的解決辦法boot
- 如何為資料行的新增操作按鈕
- qml 導航欄TabBar 工具欄ToolBartabBar
- odoo 給列表檢視新增按鈕實現資料檔案匯入Odoo
- 小程式沒有返回按鈕怎麼辦?
- iOS 自定義鍵盤字母按鈕iOS
- iOS Cell巢狀UIWebView(內附UIWebView詳解)iOS巢狀UIWebView
- 帶燈LED按鈕開關接線方法
- CSS3滑動開關按鈕效果CSSS3