UIWebview互動之自己定義傳值跳轉

來源:互聯網
上載者:User

標籤:argument   ret   nsarray   attribute   技術   app   字串   att   onclick   

UIWebview常常會用到和原生頁面的跳轉。有的可能還須要傳值跳轉。自己寫了一個自己定義跳轉的webview,能夠跳轉到指定控制器並傳值,這須要和後台協商好。html中怎樣傳值跳轉,即:html中的跳轉按鈕關聯的js方法怎樣書寫。

html中的書寫

html中的測試代碼例如以下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><script type="text/javascript">    //以下為寫死的資料直接跳轉,原則上後台能動態給出相應的值並通過點擊事件傳值到原生方法中,達到傳值並跳轉原生頁面的效果。    //controllerName相應的名字為原生頁面控制器的類名    //controllerProperties則是字典,包括了上面控制器相應的屬性名稱和值。相當於索引值對,即須要傳給原生頁面的值    //A控制器須要傳的值    var controllerNameA = "AViewController";    var controllerPropertiesA = { "prodId": "1001", "prodName": "吸塵器", "prodPrice": "50元" };    //B控制器須要傳的值    var controllerNameB = "BViewController";    var controllerPropertiesB = { "petId": "1002", "petName": "趴趴熊", "petPrice": "100萬" };    //C控制器須要傳的值    var controllerNameC = "CViewController";    var controllerPropertiesC = { "personId": "1003", "personName": "Tom", "personSex": "變態" };    //這裡定義了跳轉方法。點擊事件會運行以下的方法並傳至給原生方法    function jumpToController(controllerName,controllerProperties) {    }</script><body bgcolor="#555555">    <!--以下為3個跳轉到相應頁面的按鈕--><button type="button"  onclick="jumpToController(controllerNameA,controllerPropertiesA)">點擊傳至並跳轉到A控制器</button><button type="button"  onclick="jumpToController(controllerNameB,controllerPropertiesB)">點擊傳至並跳轉到B控制器</button><button type="button"  onclick="jumpToController(controllerNameC,controllerPropertiesC)">點擊傳至並跳轉到C控制器</button></body></html>

上面的jumpToController方法即為跳轉方法,點擊按鈕後會相應的把值傳到方法中並運行大括弧內種的內容,內容裡面什麼都沒有,這並不重要。我們的目的僅僅是把值傳到方法裡。原生頁面通過JavaScriptCore能夠知道運行了這種方法和傳過來的值足已,由於跳轉頁面僅僅須要控制器名和相應的屬性值。

原生頁面中
  • 首先須要定義3個控制器。

    AViewController,BViewController,CViewController。裡面定義好測試的屬性(事實上應該是先做的控制器,html依據原生頁面的詳細類名和屬性來傳值),這裡我們以A屬性為例:

#import <UIKit/UIKit.h>@interface AViewController : UIViewController@property(nonatomic, copy) NSString *prodId;@property(nonatomic, copy) NSString *prodName;@property(nonatomic, copy) NSString *prodPrice;@end
  • 控制器中m檔案輸出資料。

    在進入頁面後列印這些屬性,假設最後有值傳過來。那麼列印出來的肯定不是空值。

#import "AViewController.h"@interface AViewController ()@end@implementation AViewController- (void)viewDidLoad {    [super viewDidLoad];    self.title = @"A";    self.view.backgroundColor = [UIColor grayColor];    NSLog(@"屬性各自是prodId:%@,prodName:%@,prodPrice:%@", self.prodId, self.prodName, self.prodPrice);    // Do any additional setup after loading the view.}
  • 初始頁面加入JSContext屬性並載入html檔案。

    這裡載入之前寫的那個html檔案:

#import "ViewController.h"#import <JavaScriptCore/JavaScriptCore.h>#import <objc/Runtime.h>@interface ViewController () <UIWebViewDelegate>@property(nonatomic, weak) IBOutlet UIWebView *webView;@property(nonatomic, weak) JSContext *context;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    [self webViewConfig];    // Do any additional setup after loading the view, typically from a nib.}/**設定本地網頁,並讀取之*/- (void)webViewConfig {    self.title = @"初始頁面";    NSString *path = [[NSBundle mainBundle] pathForResource:@"jstest" ofType:@"html"];    NSLog(@"%@", path);    NSURL *url = [[NSURL alloc] initFileURLWithPath:path];    NSLog(@"%@", url);    NSURLRequest *request = [NSURLRequest requestWithURL:url];    self.webView.delegate = self;    [self.webView loadRequest:request];}
  • 關鍵點,擷取到全域的js環境並拿到值進行跳轉。

    須要寫在webViewDidFinishLoad裡,代碼例如以下:

/**設定JS環境。這裡須要在網頁讀取之後*/- (void)webViewDidFinishLoad:(UIWebView *)webView {    /**擷取全域的js環境*/    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];    /**描寫敘述html裡的方法jumpToController怎樣運行*/    self.context[@"jumpToController"] = ^{        /**args為擷取這種方法傳過來的參數,得到的是JSValue對象,和後台協商好。傳過來就僅僅有一個字串和一個字典,字串放控制器名稱,字典的key和value相應屬性名稱和其值*/        NSArray *args = [JSContext currentArguments];        Class controllerClass = nil;        NSDictionary *parameters = nil;        /**遍曆從js傳過來的值,這裡僅僅有兩個,一個字串一個字典,字串為類名,字典為須要的屬性*/        for (JSValue *jsVal in args) {            /**傳過來的值是字串,說明是控制器名字*/            if ([jsVal isString]) {                NSString *controllerName = [jsVal toString];                controllerClass = NSClassFromString(controllerName);            }            /**傳過來的值是對象,說明存的是參數,那麼使用字典接收*/            if ([jsVal isObject]) {                parameters = [jsVal toDictionary];            }        }        /**拿到類名和屬性,直接組建控制器賦值(務必保證傳過來的字串是正確的控制器類名)*/        UIViewController *viewController = (UIViewController *) [[controllerClass alloc] init];//既然已經是傳的正確的控制器名。那麼這裡一定能夠強轉成功。

/**給控制器賦值*/ [viewController setValuesForKeysWithDictionary:parameters]; /**頁面跳轉*/ dispatch_async(dispatch_get_main_queue(), ^{ [self.navigationController pushViewController:viewController animated:YES]; }); };}

  • A介面進入後,顯示列印結果,即為html中傳的值。(請忽略介面不是xcode細節)。

原則上來講,html中的傳值,是一樣能夠做到動態傳的。也即是說能夠動態傳值跳轉,這個demo事實上能夠進一步進行封裝,加上傳入條等,作為一個基礎網頁控制器。
demo:https://github.com/JeffreyWW/JFJSCoreTest
歡迎交流,QQ:25105483

UIWebview互動之自己定義傳值跳轉

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.