Commit 424569aa4aa870d9d9ec67d75491e219522c91d9
1 parent
147088f4
no message
Showing
16 changed files
with
755 additions
and
25 deletions
Example/CNLiveBalanceModule.xcodeproj/project.pbxproj
| ... | ... | @@ -8,6 +8,11 @@ |
| 8 | 8 | |
| 9 | 9 | /* Begin PBXBuildFile section */ |
| 10 | 10 | 008EDC6D9F59708FC31D66E2 /* Pods_CNLiveBalanceModule_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF1592377FBDD3732275DFDB /* Pods_CNLiveBalanceModule_Example.framework */; }; |
| 11 | + 08ADA66223A381E100072772 /* CNLiveBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08ADA66123A381E100072772 /* CNLiveBaseViewController.m */; }; | |
| 12 | + 08CA954D23A4609F001B1A99 /* CNLiveWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08CA954B23A4609F001B1A99 /* CNLiveWebView.m */; }; | |
| 13 | + 08CA955023A47090001B1A99 /* CNLiveBaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08CA954F23A47090001B1A99 /* CNLiveBaseNavigationController.m */; }; | |
| 14 | + 08CA955923A4B492001B1A99 /* CNLiveBaseWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08CA955723A4B492001B1A99 /* CNLiveBaseWebViewController.m */; }; | |
| 15 | + 08CA955C23A4B552001B1A99 /* CNLiveInteractionWebController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08CA955A23A4B552001B1A99 /* CNLiveInteractionWebController.m */; }; | |
| 11 | 16 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; |
| 12 | 17 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; |
| 13 | 18 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; |
| ... | ... | @@ -37,6 +42,16 @@ |
| 37 | 42 | /* End PBXContainerItemProxy section */ |
| 38 | 43 | |
| 39 | 44 | /* Begin PBXFileReference section */ |
| 45 | + 08ADA66023A381E100072772 /* CNLiveBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveBaseViewController.h; sourceTree = "<group>"; }; | |
| 46 | + 08ADA66123A381E100072772 /* CNLiveBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveBaseViewController.m; sourceTree = "<group>"; }; | |
| 47 | + 08CA954B23A4609F001B1A99 /* CNLiveWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveWebView.m; sourceTree = "<group>"; }; | |
| 48 | + 08CA954C23A4609F001B1A99 /* CNLiveWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveWebView.h; sourceTree = "<group>"; }; | |
| 49 | + 08CA954E23A47090001B1A99 /* CNLiveBaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveBaseNavigationController.h; sourceTree = "<group>"; }; | |
| 50 | + 08CA954F23A47090001B1A99 /* CNLiveBaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveBaseNavigationController.m; sourceTree = "<group>"; }; | |
| 51 | + 08CA955723A4B492001B1A99 /* CNLiveBaseWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveBaseWebViewController.m; sourceTree = "<group>"; }; | |
| 52 | + 08CA955823A4B492001B1A99 /* CNLiveBaseWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveBaseWebViewController.h; sourceTree = "<group>"; }; | |
| 53 | + 08CA955A23A4B552001B1A99 /* CNLiveInteractionWebController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveInteractionWebController.m; sourceTree = "<group>"; }; | |
| 54 | + 08CA955B23A4B552001B1A99 /* CNLiveInteractionWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveInteractionWebController.h; sourceTree = "<group>"; }; | |
| 40 | 55 | 0D75FC30984EA4E2CA7EBB7D /* Pods-CNLiveBalanceModule_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveBalanceModule_Example.debug.xcconfig"; path = "Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example.debug.xcconfig"; sourceTree = "<group>"; }; |
| 41 | 56 | 17A0C3C4449A3213C9347BB9 /* Pods-CNLiveBalanceModule_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveBalanceModule_Tests.release.xcconfig"; path = "Target Support Files/Pods-CNLiveBalanceModule_Tests/Pods-CNLiveBalanceModule_Tests.release.xcconfig"; sourceTree = "<group>"; }; |
| 42 | 57 | 2D5F9D4C44F18F703DCFAC06 /* Pods-CNLiveBalanceModule_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveBalanceModule_Example.release.xcconfig"; path = "Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example.release.xcconfig"; sourceTree = "<group>"; }; |
| ... | ... | @@ -148,6 +163,16 @@ |
| 148 | 163 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, |
| 149 | 164 | 6003F5A5195388D20070C39A /* CNLIVEViewController.h */, |
| 150 | 165 | 6003F5A6195388D20070C39A /* CNLIVEViewController.m */, |
| 166 | + 08ADA66023A381E100072772 /* CNLiveBaseViewController.h */, | |
| 167 | + 08ADA66123A381E100072772 /* CNLiveBaseViewController.m */, | |
| 168 | + 08CA954E23A47090001B1A99 /* CNLiveBaseNavigationController.h */, | |
| 169 | + 08CA954F23A47090001B1A99 /* CNLiveBaseNavigationController.m */, | |
| 170 | + 08CA954C23A4609F001B1A99 /* CNLiveWebView.h */, | |
| 171 | + 08CA954B23A4609F001B1A99 /* CNLiveWebView.m */, | |
| 172 | + 08CA955823A4B492001B1A99 /* CNLiveBaseWebViewController.h */, | |
| 173 | + 08CA955723A4B492001B1A99 /* CNLiveBaseWebViewController.m */, | |
| 174 | + 08CA955B23A4B552001B1A99 /* CNLiveInteractionWebController.h */, | |
| 175 | + 08CA955A23A4B552001B1A99 /* CNLiveInteractionWebController.m */, | |
| 151 | 176 | 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */, |
| 152 | 177 | 6003F5A8195388D20070C39A /* Images.xcassets */, |
| 153 | 178 | 6003F594195388D20070C39A /* Supporting Files */, |
| ... | ... | @@ -208,7 +233,7 @@ |
| 208 | 233 | 6003F587195388D20070C39A /* Frameworks */, |
| 209 | 234 | 6003F588195388D20070C39A /* Resources */, |
| 210 | 235 | 3A0063CF6C529372DB2CB00A /* [CP] Embed Pods Frameworks */, |
| 211 | - 562D30DC483DBD077FFE17EC /* [CP] Copy Pods Resources */, | |
| 236 | + EADFDDE3396F8FE72696E151 /* [CP] Copy Pods Resources */, | |
| 212 | 237 | ); |
| 213 | 238 | buildRules = ( |
| 214 | 239 | ); |
| ... | ... | @@ -348,6 +373,7 @@ |
| 348 | 373 | "${BUILT_PRODUCTS_DIR}/PGPickerView/PGPickerView.framework", |
| 349 | 374 | "${BUILT_PRODUCTS_DIR}/QMUIKit/QMUIKit.framework", |
| 350 | 375 | "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", |
| 376 | + "${BUILT_PRODUCTS_DIR}/WebViewJavascriptBridge/WebViewJavascriptBridge.framework", | |
| 351 | 377 | "${BUILT_PRODUCTS_DIR}/YYKit/YYKit.framework", |
| 352 | 378 | ); |
| 353 | 379 | name = "[CP] Embed Pods Frameworks"; |
| ... | ... | @@ -372,6 +398,7 @@ |
| 372 | 398 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PGPickerView.framework", |
| 373 | 399 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QMUIKit.framework", |
| 374 | 400 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", |
| 401 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebViewJavascriptBridge.framework", | |
| 375 | 402 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYKit.framework", |
| 376 | 403 | ); |
| 377 | 404 | runOnlyForDeploymentPostprocessing = 0; |
| ... | ... | @@ -379,44 +406,44 @@ |
| 379 | 406 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example-frameworks.sh\"\n"; |
| 380 | 407 | showEnvVarsInLog = 0; |
| 381 | 408 | }; |
| 382 | - 562D30DC483DBD077FFE17EC /* [CP] Copy Pods Resources */ = { | |
| 409 | + E8746ACFF48907801CC338D9 /* [CP] Check Pods Manifest.lock */ = { | |
| 383 | 410 | isa = PBXShellScriptBuildPhase; |
| 384 | 411 | buildActionMask = 2147483647; |
| 385 | 412 | files = ( |
| 386 | 413 | ); |
| 414 | + inputFileListPaths = ( | |
| 415 | + ); | |
| 387 | 416 | inputPaths = ( |
| 388 | - "${PODS_ROOT}/Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example-resources.sh", | |
| 389 | - "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveBalanceModule/CNLiveBalanceModule.bundle", | |
| 417 | + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | |
| 418 | + "${PODS_ROOT}/Manifest.lock", | |
| 419 | + ); | |
| 420 | + name = "[CP] Check Pods Manifest.lock"; | |
| 421 | + outputFileListPaths = ( | |
| 390 | 422 | ); |
| 391 | - name = "[CP] Copy Pods Resources"; | |
| 392 | 423 | outputPaths = ( |
| 393 | - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CNLiveBalanceModule.bundle", | |
| 424 | + "$(DERIVED_FILE_DIR)/Pods-CNLiveBalanceModule_Example-checkManifestLockResult.txt", | |
| 394 | 425 | ); |
| 395 | 426 | runOnlyForDeploymentPostprocessing = 0; |
| 396 | 427 | shellPath = /bin/sh; |
| 397 | - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example-resources.sh\"\n"; | |
| 428 | + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | |
| 398 | 429 | showEnvVarsInLog = 0; |
| 399 | 430 | }; |
| 400 | - E8746ACFF48907801CC338D9 /* [CP] Check Pods Manifest.lock */ = { | |
| 431 | + EADFDDE3396F8FE72696E151 /* [CP] Copy Pods Resources */ = { | |
| 401 | 432 | isa = PBXShellScriptBuildPhase; |
| 402 | 433 | buildActionMask = 2147483647; |
| 403 | 434 | files = ( |
| 404 | 435 | ); |
| 405 | - inputFileListPaths = ( | |
| 406 | - ); | |
| 407 | 436 | inputPaths = ( |
| 408 | - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | |
| 409 | - "${PODS_ROOT}/Manifest.lock", | |
| 410 | - ); | |
| 411 | - name = "[CP] Check Pods Manifest.lock"; | |
| 412 | - outputFileListPaths = ( | |
| 437 | + "${PODS_ROOT}/Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example-resources.sh", | |
| 438 | + "${PODS_CONFIGURATION_BUILD_DIR}/CNLiveBalanceModule/CNLiveBalanceModule.bundle", | |
| 413 | 439 | ); |
| 440 | + name = "[CP] Copy Pods Resources"; | |
| 414 | 441 | outputPaths = ( |
| 415 | - "$(DERIVED_FILE_DIR)/Pods-CNLiveBalanceModule_Example-checkManifestLockResult.txt", | |
| 442 | + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CNLiveBalanceModule.bundle", | |
| 416 | 443 | ); |
| 417 | 444 | runOnlyForDeploymentPostprocessing = 0; |
| 418 | 445 | shellPath = /bin/sh; |
| 419 | - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | |
| 446 | + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CNLiveBalanceModule_Example/Pods-CNLiveBalanceModule_Example-resources.sh\"\n"; | |
| 420 | 447 | showEnvVarsInLog = 0; |
| 421 | 448 | }; |
| 422 | 449 | /* End PBXShellScriptBuildPhase section */ |
| ... | ... | @@ -426,9 +453,14 @@ |
| 426 | 453 | isa = PBXSourcesBuildPhase; |
| 427 | 454 | buildActionMask = 2147483647; |
| 428 | 455 | files = ( |
| 456 | + 08ADA66223A381E100072772 /* CNLiveBaseViewController.m in Sources */, | |
| 457 | + 08CA955923A4B492001B1A99 /* CNLiveBaseWebViewController.m in Sources */, | |
| 429 | 458 | 6003F59E195388D20070C39A /* CNLIVEAppDelegate.m in Sources */, |
| 430 | 459 | 6003F5A7195388D20070C39A /* CNLIVEViewController.m in Sources */, |
| 460 | + 08CA955C23A4B552001B1A99 /* CNLiveInteractionWebController.m in Sources */, | |
| 431 | 461 | 6003F59A195388D20070C39A /* main.m in Sources */, |
| 462 | + 08CA955023A47090001B1A99 /* CNLiveBaseNavigationController.m in Sources */, | |
| 463 | + 08CA954D23A4609F001B1A99 /* CNLiveWebView.m in Sources */, | |
| 432 | 464 | ); |
| 433 | 465 | runOnlyForDeploymentPostprocessing = 0; |
| 434 | 466 | }; | ... | ... |
Example/CNLiveBalanceModule/CNLIVEAppDelegate.m
| ... | ... | @@ -11,6 +11,10 @@ |
| 11 | 11 | #import "CNLiveEnvironment.h" |
| 12 | 12 | #import <CNLiveRequestBastKit/CNLiveNetworking.h> |
| 13 | 13 | #import "CNLiveBalanceController.h" |
| 14 | +#import "CNLiveBaseViewController.h" | |
| 15 | +#import "CNLiveBaseWebViewController.h" | |
| 16 | +#import "CNLiveInteractionWebController.h" | |
| 17 | +#import "CNLIVEViewController.h" | |
| 14 | 18 | |
| 15 | 19 | @implementation CNLIVEAppDelegate |
| 16 | 20 | - (void)networkParamAction{ |
| ... | ... | @@ -62,7 +66,12 @@ |
| 62 | 66 | }]; |
| 63 | 67 | [[NSUserDefaults standardUserDefaults] setObject:@"RkFYeLkl/u5S7tW8UcOkT3rfLTP/Ua8NIkdEsKlcolvl/yxTMNbAYXmmJyhKGpkj" forKey:@"CNLiveAuthToken"]; |
| 64 | 68 | |
| 65 | - CNLiveBalanceController *vc = [[CNLiveBalanceController alloc] initWithType:@"1" ID:CNUserShareModel.uid]; | |
| 69 | +// CNLiveBaseViewController *vc = [[CNLiveBaseViewController alloc] init]; | |
| 70 | +// CNLiveBalanceController *vc = [[CNLiveBalanceController alloc] initWithType:@"1" ID:CNUserShareModel.uid]; | |
| 71 | +// CNLIVEViewController *vc = [[CNLIVEViewController alloc] initWithUrl:@"http://www.baidu.com" title:@"asdasd" closeHidden:NO]; | |
| 72 | + | |
| 73 | + CNLIVEViewController *vc = [[CNLIVEViewController alloc] initWithUrl:@"http://wjjh5test.cnlive.com/cnComplaint.html" title:@"" closeHidden:NO]; | |
| 74 | + | |
| 66 | 75 | UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc]; |
| 67 | 76 | self.window.rootViewController = nav;//设置根视图控制器 |
| 68 | 77 | [self.window makeKeyAndVisible]; | ... | ... |
Example/CNLiveBalanceModule/CNLIVEViewController.h
| ... | ... | @@ -6,8 +6,8 @@ |
| 6 | 6 | // Copyright (c) 2019 153993236@qq.com. All rights reserved. |
| 7 | 7 | // |
| 8 | 8 | |
| 9 | -@import UIKit; | |
| 9 | +#import "CNLiveInteractionWebController.h" | |
| 10 | 10 | |
| 11 | -@interface CNLIVEViewController : UIViewController | |
| 11 | +@interface CNLIVEViewController : CNLiveInteractionWebController | |
| 12 | 12 | |
| 13 | 13 | @end | ... | ... |
Example/CNLiveBalanceModule/CNLIVEViewController.m
| ... | ... | @@ -7,6 +7,8 @@ |
| 7 | 7 | // |
| 8 | 8 | |
| 9 | 9 | #import "CNLIVEViewController.h" |
| 10 | +#import "WKWebViewJavascriptBridge.h" | |
| 11 | +#import "CNLiveWebView.h" | |
| 10 | 12 | |
| 11 | 13 | @interface CNLIVEViewController () |
| 12 | 14 | |
| ... | ... | @@ -14,10 +16,35 @@ |
| 14 | 16 | |
| 15 | 17 | @implementation CNLIVEViewController |
| 16 | 18 | |
| 17 | -- (void)viewDidLoad | |
| 18 | -{ | |
| 19 | - [super viewDidLoad]; | |
| 20 | - // Do any additional setup after loading the view, typically from a nib. | |
| 19 | +- (void)createSubViews { | |
| 20 | + [super createSubViews]; | |
| 21 | + [self interaction]; | |
| 22 | +} | |
| 23 | +- (void)interaction { | |
| 24 | + [super interaction]; | |
| 25 | + [self.bridge registerHandler:@"wjjHelpAndFeedbackImage" handler:^(id data, WVJBResponseCallback responseCallback) { | |
| 26 | + NSLog(@"ObjC Echo called with: %@", data); | |
| 27 | + responseCallback(data); | |
| 28 | + }]; | |
| 29 | + id dataDic = @{ | |
| 30 | + // @"imagePath": imagePath, | |
| 31 | + @"image" : @"asd" | |
| 32 | + }; | |
| 33 | + // 帮助与反馈->产品建议:App提交图片数据给h5展示 | |
| 34 | + [self.bridge callHandler:@"wjjCommitImageToJS" data:dataDic responseCallback:^(id responseData) { | |
| 35 | + NSLog(@"ObjC received response: %@", responseData); | |
| 36 | + }]; | |
| 37 | +} | |
| 38 | +#pragma mark - CNLiveWebViewDelegate | |
| 39 | +- (void)webView:(CNLiveWebView *)webView didFinishLoadWithURL:(NSURL *)url { | |
| 40 | + NSLog(@"CNLIVEViewController - didFinishLoad"); | |
| 41 | + if(self.title.length == 0){ | |
| 42 | + self.title = webView.title; | |
| 43 | + } | |
| 44 | +} | |
| 45 | + | |
| 46 | +- (void)webView:(CNLiveWebView *)webView didFailLoadWithError:(NSError *)error{ | |
| 47 | + | |
| 21 | 48 | } |
| 22 | 49 | |
| 23 | 50 | - (void)didReceiveMemoryWarning | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseNavigationController.h
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseNavigationController.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/14. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import <UIKit/UIKit.h> | |
| 10 | + | |
| 11 | +NS_ASSUME_NONNULL_BEGIN | |
| 12 | + | |
| 13 | +@interface CNLiveBaseNavigationController : UINavigationController | |
| 14 | + | |
| 15 | +@end | |
| 16 | + | |
| 17 | +NS_ASSUME_NONNULL_END | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseNavigationController.m
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseNavigationController.m | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/14. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "CNLiveBaseNavigationController.h" | |
| 10 | + | |
| 11 | +@interface CNLiveBaseNavigationController () | |
| 12 | + | |
| 13 | +@end | |
| 14 | + | |
| 15 | +@implementation CNLiveBaseNavigationController | |
| 16 | + | |
| 17 | +- (void)viewDidLoad { | |
| 18 | + [super viewDidLoad]; | |
| 19 | + // Do any additional setup after loading the view. | |
| 20 | +} | |
| 21 | + | |
| 22 | +/* | |
| 23 | +#pragma mark - Navigation | |
| 24 | + | |
| 25 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 26 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 27 | + // Get the new view controller using [segue destinationViewController]. | |
| 28 | + // Pass the selected object to the new view controller. | |
| 29 | +} | |
| 30 | +*/ | |
| 31 | + | |
| 32 | +@end | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseViewController.h
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseViewController.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/13. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import <UIKit/UIKit.h> | |
| 10 | + | |
| 11 | +NS_ASSUME_NONNULL_BEGIN | |
| 12 | + | |
| 13 | +@interface CNLiveBaseViewController : UIViewController | |
| 14 | +@property (nonatomic, assign) BOOL navigationHidden; | |
| 15 | + | |
| 16 | +// 子类重写添加子视图方法 | |
| 17 | +- (void)createSubViews; | |
| 18 | + | |
| 19 | +@end | |
| 20 | + | |
| 21 | +NS_ASSUME_NONNULL_END | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseViewController.m
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseViewController.m | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/13. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "CNLiveBaseViewController.h" | |
| 10 | +#import "CNLiveNavigationBar.h" | |
| 11 | + | |
| 12 | +@interface CNLiveBaseViewController () | |
| 13 | +@property (nonatomic, strong) CNLiveNavigationBar *navigationBar; | |
| 14 | + | |
| 15 | +@end | |
| 16 | + | |
| 17 | +@implementation CNLiveBaseViewController | |
| 18 | +#pragma mark - 生命周期 | |
| 19 | +- (void)viewWillAppear:(BOOL)animated { | |
| 20 | + [super viewWillAppear:animated]; | |
| 21 | + self.navigationController.navigationBarHidden = YES; | |
| 22 | +} | |
| 23 | + | |
| 24 | +- (void)viewDidLoad { | |
| 25 | + [super viewDidLoad]; | |
| 26 | + // Do any additional setup after loading the view. | |
| 27 | + self.view.backgroundColor = [UIColor whiteColor]; | |
| 28 | + self.automaticallyAdjustsScrollViewInsets = NO; | |
| 29 | + [self createSubViews]; | |
| 30 | +} | |
| 31 | + | |
| 32 | +#pragma mark - UI | |
| 33 | +- (void)createSubViews{ | |
| 34 | + [self.view addSubview:self.navigationBar]; | |
| 35 | +} | |
| 36 | + | |
| 37 | +#pragma mark - Setter方法 | |
| 38 | +- (void)setTitle:(NSString *)title{ | |
| 39 | + [super setTitle:title]; | |
| 40 | + self.navigationBar.title.text = title; | |
| 41 | +} | |
| 42 | + | |
| 43 | +- (void)setNavigationHidden:(BOOL)navigationHidden{ | |
| 44 | + _navigationHidden = navigationHidden; | |
| 45 | + _navigationBar.hidden = navigationHidden; | |
| 46 | +} | |
| 47 | +/* | |
| 48 | +#pragma mark - Navigation | |
| 49 | + | |
| 50 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 51 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 52 | + // Get the new view controller using [segue destinationViewController]. | |
| 53 | + // Pass the selected object to the new view controller. | |
| 54 | +} | |
| 55 | +*/ | |
| 56 | +#pragma mark - 响应方法 | |
| 57 | +- (void)goBack { | |
| 58 | + if (self.presentingViewController != nil) { | |
| 59 | + [self dismissViewControllerAnimated:YES completion:nil]; | |
| 60 | + } | |
| 61 | + else { | |
| 62 | + [self.navigationController popViewControllerAnimated:YES]; | |
| 63 | + } | |
| 64 | +} | |
| 65 | + | |
| 66 | +#pragma mark - 懒加载 | |
| 67 | +- (CNLiveNavigationBar *)navigationBar { | |
| 68 | + if (!_navigationBar) { | |
| 69 | + _navigationBar = [CNLiveNavigationBar navigationBar]; | |
| 70 | + _navigationBar.title.text = self.title; | |
| 71 | + __weak typeof(self) weakSelf = self; | |
| 72 | + _navigationBar.onClickLeftButton = ^{ | |
| 73 | + __strong typeof(weakSelf) strongSelf = weakSelf; | |
| 74 | + if(!strongSelf) return ; | |
| 75 | + [strongSelf goBack]; | |
| 76 | + }; | |
| 77 | + } | |
| 78 | + return _navigationBar; | |
| 79 | +} | |
| 80 | + | |
| 81 | +@end | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseWebViewController.h
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseWebViewController.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/7. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * 没有交互的WebView | |
| 11 | + */ | |
| 12 | + | |
| 13 | +#import "CNLiveBaseViewController.h" | |
| 14 | + | |
| 15 | +NS_ASSUME_NONNULL_BEGIN | |
| 16 | +@class CNLiveWebView; | |
| 17 | + | |
| 18 | +@interface CNLiveBaseWebViewController : CNLiveBaseViewController | |
| 19 | +@property (nonatomic, strong) CNLiveWebView *webView; | |
| 20 | + | |
| 21 | +- (instancetype)initWithUrl:(NSString *)url; | |
| 22 | +- (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title; | |
| 23 | +- (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title closeHidden:(BOOL)closeHidden; | |
| 24 | + | |
| 25 | +- (instancetype)init NS_UNAVAILABLE; | |
| 26 | ++ (instancetype)new NS_UNAVAILABLE; | |
| 27 | + | |
| 28 | +@end | |
| 29 | + | |
| 30 | +NS_ASSUME_NONNULL_END | ... | ... |
Example/CNLiveBalanceModule/CNLiveBaseWebViewController.m
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveBaseWebViewController.m | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/7. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "CNLiveBaseWebViewController.h" | |
| 10 | +#import <WebKit/WebKit.h> | |
| 11 | +#import "QMUIKit.h" | |
| 12 | +#import "CNLiveCategory.h" | |
| 13 | +#import "CNLiveWebView.h" | |
| 14 | +#import "CNLiveNavigationBar.h" | |
| 15 | + | |
| 16 | +@interface CNLiveBaseWebViewController ()<CNLiveWebViewDelegate> | |
| 17 | +@property (nonatomic, copy) NSString *url; | |
| 18 | + | |
| 19 | +@property (nonatomic, strong) UIButton *closeBtn; | |
| 20 | +@property (nonatomic, assign) BOOL closeHidden; | |
| 21 | + | |
| 22 | +@end | |
| 23 | + | |
| 24 | +@implementation CNLiveBaseWebViewController | |
| 25 | +static const NSInteger margin = 10; | |
| 26 | + | |
| 27 | +#pragma mark - 初始化 | |
| 28 | +- (instancetype)initWithUrl:(NSString *)url{ | |
| 29 | + return [self initWithUrl:url title:@"" closeHidden:YES]; | |
| 30 | +} | |
| 31 | +- (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title{ | |
| 32 | + return [self initWithUrl:url title:title closeHidden:YES]; | |
| 33 | +} | |
| 34 | +- (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title closeHidden:(BOOL)closeHidden { | |
| 35 | + self = [super init]; | |
| 36 | + if (self) { | |
| 37 | + self.url = url; | |
| 38 | + self.title = title; | |
| 39 | + self.closeHidden = closeHidden; | |
| 40 | + } | |
| 41 | + return self; | |
| 42 | +} | |
| 43 | + | |
| 44 | +#pragma mark - 加载数据 | |
| 45 | +- (void)setUrl:(NSString *)url{ | |
| 46 | + _url = url; | |
| 47 | + if ([url hasPrefix:@"http://"]||[url hasPrefix:@"https://"]) { | |
| 48 | + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0]; | |
| 49 | + [self.webView loadRequest:request]; | |
| 50 | + | |
| 51 | + } else { | |
| 52 | + [self.webView loadHTMLString:[self html:url]]; | |
| 53 | + } | |
| 54 | + | |
| 55 | +} | |
| 56 | + | |
| 57 | +- (NSString *)html:(NSString *)url{ | |
| 58 | + return [NSString stringWithFormat:@"<div style=\"font-size:45px\">%@</div>",url]; | |
| 59 | +} | |
| 60 | + | |
| 61 | +- (void)createSubViews { | |
| 62 | + [super createSubViews]; | |
| 63 | + if(!self.closeHidden&&!self.navigationHidden){ | |
| 64 | + [self.view addSubview:self.closeBtn]; | |
| 65 | + } | |
| 66 | + [self.view addSubview:self.webView]; | |
| 67 | +} | |
| 68 | + | |
| 69 | +#pragma mark - CNLiveWebViewDelegate | |
| 70 | +- (void)webView:(CNLiveWebView *)webView didFinishLoadWithURL:(NSURL *)url { | |
| 71 | + NSLog(@"CNLiveWebViewController - didFinishLoad"); | |
| 72 | + if(self.title.length == 0){ | |
| 73 | + self.title = webView.title; | |
| 74 | + } | |
| 75 | +} | |
| 76 | + | |
| 77 | +- (void)webView:(CNLiveWebView *)webView didFailLoadWithError:(NSError *)error{ | |
| 78 | + | |
| 79 | +} | |
| 80 | + | |
| 81 | +#pragma mark - 响应方法 | |
| 82 | +//回退goBack | |
| 83 | +- (void)goBack { | |
| 84 | + if ([self.webView canGoBack]) { | |
| 85 | + [self.webView goBack]; | |
| 86 | + } | |
| 87 | + else { | |
| 88 | + [self closeDidClicked]; | |
| 89 | + } | |
| 90 | +} | |
| 91 | + | |
| 92 | +//关闭pop | |
| 93 | +- (void)closeDidClicked { | |
| 94 | + if (self.presentingViewController != nil) { | |
| 95 | + [self dismissViewControllerAnimated:YES completion:nil]; | |
| 96 | + } | |
| 97 | + else { | |
| 98 | + [self.navigationController popViewControllerAnimated:YES]; | |
| 99 | + } | |
| 100 | +} | |
| 101 | + | |
| 102 | +/* | |
| 103 | +#pragma mark - Navigation | |
| 104 | + | |
| 105 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 106 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 107 | + // Get the new view controller using [segue destinationViewController]. | |
| 108 | + // Pass the selected object to the new view controller. | |
| 109 | +} | |
| 110 | +*/ | |
| 111 | + | |
| 112 | +#pragma mark - 懒加载 | |
| 113 | +- (UIButton *)closeBtn{ | |
| 114 | + if(!_closeBtn){ | |
| 115 | + _closeBtn = [UIButton buttonWithType:UIButtonTypeCustom]; | |
| 116 | + _closeBtn.adjustsImageWhenHighlighted = NO; | |
| 117 | + _closeBtn.frame = CGRectMake(NavigationBarHeight+margin, StatusBarHeight, NavigationBarHeight, NavigationBarHeight); | |
| 118 | + UIImage *image = [self getImageWithImageName:@"cnlive_black_close" bundleName:@"CNLiveCustomControl" targetClass:[CNLiveNavigationBar class]]; | |
| 119 | + [_closeBtn setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal]; | |
| 120 | + [_closeBtn addTarget:self action:@selector(closeDidClicked) forControlEvents:UIControlEventTouchUpInside]; | |
| 121 | + [_closeBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; | |
| 122 | + _closeBtn.hidden = self.closeHidden; | |
| 123 | + } | |
| 124 | + return _closeBtn; | |
| 125 | +} | |
| 126 | + | |
| 127 | +- (CNLiveWebView *)webView{ | |
| 128 | + if(!_webView){ | |
| 129 | + _webView = [CNLiveWebView webViewWithFrame:CGRectMake(0, NavigationContentTop, SCREEN_WIDTH, SCREEN_HEIGHT-NavigationContentTop)]; | |
| 130 | + _webView.delegate = self; | |
| 131 | + } | |
| 132 | + return _webView; | |
| 133 | +} | |
| 134 | + | |
| 135 | +@end | ... | ... |
Example/CNLiveBalanceModule/CNLiveInteractionWebController.h
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveInteractionWebController.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/14. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * 有交互的WebView | |
| 11 | + */ | |
| 12 | + | |
| 13 | +#import "CNLiveBaseWebViewController.h" | |
| 14 | + | |
| 15 | +NS_ASSUME_NONNULL_BEGIN | |
| 16 | +@class WKWebViewJavascriptBridge; | |
| 17 | + | |
| 18 | +@interface CNLiveInteractionWebController : CNLiveBaseWebViewController | |
| 19 | +@property (nonatomic, strong) WKWebViewJavascriptBridge *bridge; | |
| 20 | + | |
| 21 | +/* | |
| 22 | + 注意:初始化方法 | |
| 23 | + - (instancetype)initWithUrl:(NSString *)url; | |
| 24 | + - (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title; | |
| 25 | + - (instancetype)initWithUrl:(NSString *)url title:(nullable NSString *)title closeHidden:(BOOL)closeHidden; | |
| 26 | + */ | |
| 27 | + | |
| 28 | + | |
| 29 | +/* | |
| 30 | + * 子类重写添加交互方法 | |
| 31 | + */ | |
| 32 | +- (void)interaction; | |
| 33 | + | |
| 34 | +@end | |
| 35 | + | |
| 36 | +NS_ASSUME_NONNULL_END | ... | ... |
Example/CNLiveBalanceModule/CNLiveInteractionWebController.m
0 → 100644
| 1 | +// | |
| 2 | +// CNLiveInteractionWebController.m | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/12/14. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "CNLiveInteractionWebController.h" | |
| 10 | +#import "WKWebViewJavascriptBridge.h" | |
| 11 | +#import "CNLiveWebView.h" | |
| 12 | + | |
| 13 | +@interface CNLiveInteractionWebController () | |
| 14 | + | |
| 15 | +@end | |
| 16 | + | |
| 17 | +@implementation CNLiveInteractionWebController | |
| 18 | + | |
| 19 | +- (void)createSubViews { | |
| 20 | + [super createSubViews]; | |
| 21 | + [self interaction]; | |
| 22 | +} | |
| 23 | + | |
| 24 | +- (void)interaction { | |
| 25 | + [WKWebViewJavascriptBridge enableLogging]; | |
| 26 | + self.bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView.wkWebView]; | |
| 27 | + [self.bridge setWebViewDelegate:self.webView]; | |
| 28 | +} | |
| 29 | + | |
| 30 | +#pragma mark - CNLiveWebViewDelegate | |
| 31 | +- (void)webView:(CNLiveWebView *)webView didFinishLoadWithURL:(NSURL *)url { | |
| 32 | + NSLog(@"CNLiveWebInteractionController - didFinishLoad"); | |
| 33 | + if(self.title.length == 0){ | |
| 34 | + self.title = webView.title; | |
| 35 | + } | |
| 36 | + | |
| 37 | +} | |
| 38 | + | |
| 39 | +- (void)webView:(CNLiveWebView *)webView didFailLoadWithError:(NSError *)error{ | |
| 40 | + | |
| 41 | +} | |
| 42 | + | |
| 43 | +/* | |
| 44 | +#pragma mark - Navigation | |
| 45 | + | |
| 46 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 47 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 48 | + // Get the new view controller using [segue destinationViewController]. | |
| 49 | + // Pass the selected object to the new view controller. | |
| 50 | +} | |
| 51 | +*/ | |
| 52 | + | |
| 53 | +@end | ... | ... |
Example/CNLiveBalanceModule/CNLiveWebView.h
0 → 100755
| 1 | +// | |
| 2 | +// CNLiveWebView.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/9/12. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * 自定义WebView | |
| 11 | + */ | |
| 12 | + | |
| 13 | +#import <UIKit/UIKit.h> | |
| 14 | +#import <WebKit/WebKit.h> | |
| 15 | + | |
| 16 | +NS_ASSUME_NONNULL_BEGIN | |
| 17 | +@class CNLiveWebView; | |
| 18 | + | |
| 19 | +@protocol CNLiveWebViewDelegate <NSObject> | |
| 20 | +@optional | |
| 21 | +/** 页面开始加载时调用 */ | |
| 22 | +- (void)webViewDidStartLoad:(CNLiveWebView *)webView; | |
| 23 | +/** 内容开始返回时调用 */ | |
| 24 | +- (void)webView:(CNLiveWebView *)webView didCommitWithURL:(NSURL *)url; | |
| 25 | +/** 页面加载失败时调用 */ | |
| 26 | +- (void)webView:(CNLiveWebView *)webView didFinishLoadWithURL:(NSURL *)url; | |
| 27 | +/** 页面加载完成之后调用 */ | |
| 28 | +- (void)webView:(CNLiveWebView *)webView didFailLoadWithError:(NSError *)error; | |
| 29 | + | |
| 30 | +@end | |
| 31 | + | |
| 32 | +@interface CNLiveWebView : UIView | |
| 33 | +@property (nonatomic, strong) WKWebView *wkWebView; | |
| 34 | +@property (nonatomic, strong) UIProgressView *progressView; | |
| 35 | + | |
| 36 | +/** CNLiveWebViewDelegate */ | |
| 37 | +@property (nonatomic, weak) id<CNLiveWebViewDelegate> delegate; | |
| 38 | +/** 进度条颜色(默认蓝色) */ | |
| 39 | +@property (nonatomic, strong) UIColor *progressViewColor; | |
| 40 | +/** 导航栏标题 */ | |
| 41 | +@property (nonatomic, copy) NSString *title; | |
| 42 | + | |
| 43 | +@property (nonatomic, readonly) BOOL canGoBack; | |
| 44 | +/** 向后 */ | |
| 45 | +- (nullable WKNavigation *)goBack; | |
| 46 | + | |
| 47 | +@property (nonatomic, readonly) BOOL canGoForward; | |
| 48 | +/** 向前 */ | |
| 49 | +- (nullable WKNavigation *)goForward; | |
| 50 | +/** 刷新数据 */ | |
| 51 | +- (void)reloadData; | |
| 52 | + | |
| 53 | +/** 类方法创建 XWWebView */ | |
| 54 | ++ (instancetype)webViewWithFrame:(CGRect)frame; | |
| 55 | +/** 加载 web */ | |
| 56 | +- (void)loadRequest:(NSURLRequest *)request; | |
| 57 | +/** 加载 HTML */ | |
| 58 | +- (void)loadHTMLString:(NSString *)HTMLString; | |
| 59 | + | |
| 60 | +@end | |
| 61 | +NS_ASSUME_NONNULL_END | ... | ... |
Example/CNLiveBalanceModule/CNLiveWebView.m
0 → 100755
| 1 | +// | |
| 2 | +// CNLiveWebView.h | |
| 3 | +// CNLiveBaseClass | |
| 4 | +// | |
| 5 | +// Created by CNLive-zxw on 2019/9/12. | |
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | +// | |
| 8 | + | |
| 9 | +#import "CNLiveWebView.h" | |
| 10 | +#import "QMUIKit.h" | |
| 11 | + | |
| 12 | +@interface CNLiveWebView () <WKNavigationDelegate, WKUIDelegate> | |
| 13 | + | |
| 14 | +@end | |
| 15 | + | |
| 16 | +@implementation CNLiveWebView | |
| 17 | +static CGFloat const progressViewHeight = 1; | |
| 18 | + | |
| 19 | +#pragma mark - 初始化 | |
| 20 | +- (instancetype)initWithFrame:(CGRect)frame { | |
| 21 | + if (self = [super initWithFrame:frame]) { | |
| 22 | + if (@available(iOS 11, *)) { | |
| 23 | + self.wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic; | |
| 24 | + } | |
| 25 | + [self addSubview:self.wkWebView]; | |
| 26 | + [self addSubview:self.progressView]; | |
| 27 | + } | |
| 28 | + return self; | |
| 29 | +} | |
| 30 | + | |
| 31 | ++ (instancetype)webViewWithFrame:(CGRect)frame { | |
| 32 | + return [[self alloc] initWithFrame:frame]; | |
| 33 | +} | |
| 34 | + | |
| 35 | +// dealloc | |
| 36 | +- (void)dealloc { | |
| 37 | + [_wkWebView stopLoading]; | |
| 38 | + [_wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))]; | |
| 39 | + _wkWebView.navigationDelegate = nil; | |
| 40 | + _wkWebView = nil; | |
| 41 | +} | |
| 42 | + | |
| 43 | +#pragma mark - Setter方法 | |
| 44 | +- (void)setProgressViewColor:(UIColor *)progressViewColor { | |
| 45 | + _progressViewColor = progressViewColor; | |
| 46 | + if (progressViewColor) { | |
| 47 | + _progressView.tintColor = progressViewColor; | |
| 48 | + } | |
| 49 | +} | |
| 50 | + | |
| 51 | +#pragma mark - Getter方法 | |
| 52 | +- (BOOL)canGoBack{ | |
| 53 | + return self.wkWebView.goBack; | |
| 54 | +} | |
| 55 | + | |
| 56 | +- (BOOL)canGoForward{ | |
| 57 | + return self.wkWebView.canGoForward; | |
| 58 | +} | |
| 59 | + | |
| 60 | +#pragma mark - 工具方法 | |
| 61 | +// 向后 | |
| 62 | +- (nullable WKNavigation *)goBack{ | |
| 63 | + return [self.wkWebView goBack]; | |
| 64 | +} | |
| 65 | +// 向前 | |
| 66 | +- (nullable WKNavigation *)goForward{ | |
| 67 | + return [self.wkWebView goForward]; | |
| 68 | +} | |
| 69 | +// 刷新数据 | |
| 70 | +- (void)reloadData { | |
| 71 | + [self.wkWebView reload]; | |
| 72 | +} | |
| 73 | +// 加载 web | |
| 74 | +- (void)loadRequest:(NSURLRequest *)request { | |
| 75 | + [self.wkWebView loadRequest:request]; | |
| 76 | +} | |
| 77 | +// 加载 HTML | |
| 78 | +- (void)loadHTMLString:(NSString *)HTMLString { | |
| 79 | + [self.wkWebView loadHTMLString:HTMLString baseURL:nil]; | |
| 80 | +} | |
| 81 | + | |
| 82 | +#pragma mark - KVO | |
| 83 | +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { | |
| 84 | + if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.wkWebView) { | |
| 85 | + self.progressView.alpha = 1.0; | |
| 86 | + BOOL animated = self.wkWebView.estimatedProgress > self.progressView.progress; | |
| 87 | + [self.progressView setProgress:self.wkWebView.estimatedProgress animated:animated]; | |
| 88 | + if(self.wkWebView.estimatedProgress >= 0.97) { | |
| 89 | + [UIView animateWithDuration:0.1 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{ | |
| 90 | + self.progressView.alpha = 0.0; | |
| 91 | + } completion:^(BOOL finished) { | |
| 92 | + [self.progressView setProgress:0.0 animated:NO]; | |
| 93 | + }]; | |
| 94 | + } | |
| 95 | + } else { | |
| 96 | + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; | |
| 97 | + } | |
| 98 | +} | |
| 99 | + | |
| 100 | +#pragma mark - WKNavigationDelegate | |
| 101 | +// 在发送请求之前,决定是否跳转 | |
| 102 | +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ | |
| 103 | + //允许跳转 | |
| 104 | + decisionHandler(WKNavigationActionPolicyAllow); | |
| 105 | +} | |
| 106 | +// 在收到响应后,决定是否跳转 | |
| 107 | +- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ | |
| 108 | + //允许跳转 | |
| 109 | + decisionHandler(WKNavigationResponsePolicyAllow); | |
| 110 | + //不允许跳转 | |
| 111 | + //decisionHandler(WKNavigationResponsePolicyCancel); | |
| 112 | +} | |
| 113 | +// 页面开始加载时调用 | |
| 114 | +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { | |
| 115 | + if (self.delegate && [self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { | |
| 116 | + [self.delegate webViewDidStartLoad:self]; | |
| 117 | + } | |
| 118 | +} | |
| 119 | +// 当内容开始返回时调用 | |
| 120 | +- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { | |
| 121 | + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didCommitWithURL:)]) { | |
| 122 | + [self.delegate webView:self didCommitWithURL:self.wkWebView.URL]; | |
| 123 | + } | |
| 124 | +} | |
| 125 | +// 页面加载完成之后调用 | |
| 126 | +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { | |
| 127 | + if(!self.title){ | |
| 128 | + self.title = self.wkWebView.title; | |
| 129 | + } | |
| 130 | + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFinishLoadWithURL:)]) { | |
| 131 | + [self.delegate webView:self didFinishLoadWithURL:self.wkWebView.URL]; | |
| 132 | + } | |
| 133 | + self.progressView.alpha = 0.0; | |
| 134 | +} | |
| 135 | +// 页面加载失败时调用 | |
| 136 | +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { | |
| 137 | + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { | |
| 138 | + [self.delegate webView:self didFailLoadWithError:error]; | |
| 139 | + } | |
| 140 | + self.progressView.alpha = 0.0; | |
| 141 | +} | |
| 142 | +// 页面加载失败时调用 | |
| 143 | +- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error{ | |
| 144 | + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) { | |
| 145 | + [self.delegate webView:self didFailLoadWithError:error]; | |
| 146 | + } | |
| 147 | + self.progressView.alpha = 0.0; | |
| 148 | +} | |
| 149 | +// 接收到服务器跳转请求之后调用(重定向) | |
| 150 | +- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{ | |
| 151 | + | |
| 152 | +} | |
| 153 | + | |
| 154 | +#pragma mark - 懒加载 | |
| 155 | +- (WKWebView *)wkWebView { | |
| 156 | + if (!_wkWebView) { | |
| 157 | + NSMutableString *javascript = [NSMutableString string]; | |
| 158 | + [javascript appendString:@"document.documentElement.style.webkitTouchCallout='none';"];//禁止长按 | |
| 159 | + [javascript appendString:@"document.documentElement.style.webkitUserSelect='none';"];//禁止选择 | |
| 160 | + WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES]; | |
| 161 | + WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; | |
| 162 | + configuration.allowsInlineMediaPlayback = YES; | |
| 163 | + WKPreferences *preferences = [WKPreferences new]; | |
| 164 | + //很重要,如果没有设置这个则不会回调createWebViewWithConfiguration方法,也不会回应window.open()方法 | |
| 165 | + preferences.javaScriptCanOpenWindowsAutomatically = YES; | |
| 166 | + configuration.preferences = preferences; | |
| 167 | + _wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, progressViewHeight, self.frame.size.width, self.frame.size.height-progressViewHeight) configuration:configuration]; | |
| 168 | + [_wkWebView.configuration.userContentController addUserScript:noneSelectScript]; | |
| 169 | + _wkWebView.allowsLinkPreview = NO; | |
| 170 | + _wkWebView.UIDelegate = self; | |
| 171 | + _wkWebView.navigationDelegate = self; | |
| 172 | + [_wkWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:nil]; | |
| 173 | + } | |
| 174 | + return _wkWebView; | |
| 175 | +} | |
| 176 | + | |
| 177 | +- (UIProgressView *)progressView { | |
| 178 | + if (!_progressView) { | |
| 179 | + _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; | |
| 180 | + _progressView.trackTintColor = [UIColor clearColor]; | |
| 181 | + // 高度默认有导航栏且有穿透效果 | |
| 182 | + _progressView.frame = CGRectMake(0, 0, self.frame.size.width, progressViewHeight); | |
| 183 | + // 设置进度条颜色 | |
| 184 | + _progressView.tintColor = [UIColor colorWithRed:19/255.0 green:204/255.0 blue:12/255.0 alpha:1.0]; | |
| 185 | + _progressView.progressTintColor = [UIColor colorWithRed:19/255.0 green:204/255.0 blue:12/255.0 alpha:1.0]; | |
| 186 | + } | |
| 187 | + return _progressView; | |
| 188 | +} | |
| 189 | + | |
| 190 | +@end | ... | ... |
Example/CNLiveBalanceModule/Images.xcassets/Contents.json
0 → 100644
Example/Podfile