WKWebView是苹果在iOS 8之后推出的框架WebKit中的浏览器控件, 其加载速度比UIWebView快了许多, 但内存占用率却下降很多, 也解决了加载网页时的内存泄露问题.

WKWebView的属性

/// webView的自定义配置

@property (nonatomic,readonly, copy) WKWebViewConfiguration *configuration;

/// 导航代理

@property (nullable, nonatomic, weak)id navigationDelegate;

/// UI代理

@property (nullable, nonatomic, weak)id UIDelegate;;

/// 访问过网页历史列表

@property (nonatomic,readonly, strong) WKBackForwardList *backForwardList;

/// 自定义初始化

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

/// url加载webView视图

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

/// 文件加载webView视图

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));

/// HTMLString字符串加载webView视图

- (nullable WKNavigation *)loadHTMLString:(NSString *)stringbaseURL:(nullable NSURL *)baseURL;

/// NSData数据加载webView视图

- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));

/// 返回上一个网页节点

- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;

/// 网页的标题, 一般使用KVO动态获取

@property (nullable, nonatomic,readonly, copy) NSString *title;

/// 页面加载进度, 一般使用KVO动态获取

@property (nonatomic, readonly) double estimatedProgress;

/// 网页的URL地址

@property (nullable, nonatomic,readonly, copy) NSURL *URL;

/// 网页是否正在加载

@property (nonatomic,readonly, getter=isLoading) BOOL loading;

/// 加载的进度 范围为[0, 1]

@property (nonatomic,readonly)double estimatedProgress;

/// 网页链接是否安全

@property (nonatomic,readonly) BOOL hasOnlySecureContent;

/// 证书服务

@property (nonatomic,readonly, nullable) SecTrustRef serverTrust API_AVAILABLE(macosx(10.12), ios(10.0));

/// 是否可以返回

@property (nonatomic,readonly) BOOL canGoBack;

/// 是否可以前进

@property (nonatomic,readonly) BOOL canGoForward;

/// 返回到上一个网页

- (nullable WKNavigation *)goBack;

/// 前进到下一个网页

- (nullable WKNavigation *)goForward;

/// 重新加载

- (nullable WKNavigation *)reload;

/// 忽略缓存 重新加载

- (nullable WKNavigation *)reloadFromOrigin;

/// 停止加载

- (void)stopLoading;

/// 执行JavaScript

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void(^ _Nullable)(_Nullableid, NSError * _Nullable error))completionHandler;

/// 是否允许左右滑动,返回-前进操作 默认是NO

@property (nonatomic) BOOL allowsBackForwardNavigationGestures;

/// 自定义代理字符串

@property (nullable, nonatomic, copy) NSString *customUserAgent API_AVAILABLE(macosx(10.11), ios(9.0));

/// 在iOS上默认为NO,标识不允许链接预览

@property (nonatomic) BOOL allowsLinkPreview API_AVAILABLE(macosx(10.11), ios(9.0));

/// 滚动视图, WKWebView继承自UIView, 所以如果想设置scrollView的一些属性, 需要对此属性进行配置

@property (nonatomic,readonly, strong) UIScrollView *scrollView;

/// 是否支持放大手势,默认为NO

@property (nonatomic) BOOL allowsMagnification;

/// 放大因子,默认为1

@property (nonatomic) CGFloat magnification;

/// 据设置的缩放因子来缩放页面,并居中显示结果在指定的点

- (void)setMagnification:(CGFloat)magnification centeredAtPoint:(CGPoint)point;/// 证书列表@property (nonatomic,readonly, copy) NSArray *certificateChain API_DEPRECATED_WITH_REPLACEMENT("serverTrust", macosx(10.11,10.12), ios(9.0,10.0));

WKWebView的常用方法:

// 带配置信息的初始化方法

// configuration 配置信息

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration

// 加载请求

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

// 加载HTML

- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

// 返回上一级

- (nullable WKNavigation *)goBack;

// 前进下一级, 需要曾经打开过, 才能前进

- (nullable WKNavigation *)goForward;

// 刷新页面

- (nullable WKNavigation *)reload;

// 根据缓存有效期来刷新页面

- (nullable WKNavigation *)reloadFromOrigin;

// 停止加载页面

- (void)stopLoading;

// 执行JavaScript代码

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

WKWebView的使用

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];

config.selectionGranularity = WKSelectionGranularityDynamic;

config.allowsInlineMediaPlayback = YES;

WKPreferences *preferences = [WKPreferences new];

//是否支持JavaScript

preferences.javaScriptEnabled = YES;

//不通过用户交互,是否可以打开窗口

preferences.javaScriptCanOpenWindowsAutomatically = YES;

config.preferences = preferences;

// 创建UserContentController(提供JavaScript向webView发送消息的方法)

WKUserContentController* userContent = [[WKUserContentController alloc] init];

// 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除

[userContent addScriptMessageHandler:self name:@"NativeMethod"];

// 将UserConttentController设置到配置文件

config.userContentController = userContent;

WKWebView *webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight - 64) configuration:config];

[self.view addSubview:webview];

/* 加载服务器url的方法*/

NSString *url = @"https://www.baidu.com/";

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

[webview loadRequest:request];

webview.navigationDelegate = self;

webview.UIDelegate = self;

#pragma mark - WKNavigationDelegate

/* 页面开始加载 */

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{

}

/* 开始返回内容 */

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{

}

/* 页面加载完成 */

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{

}

/* 页面加载失败 */

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{

}

/* 在发送请求之前,决定是否跳转 */

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{

NSURL *url = navigationAction.request.URL;

NSString *urlStr = url.absoluteString;

NSLog(@"【load url】=== %@", urlStr);

//不允许跳转

//decisionHandler(WKNavigationActionPolicyCancel);

//return;

//允许跳转

decisionHandler(WKNavigationActionPolicyAllow);

}

/* 在收到响应后,决定是否跳转 */

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{

NSLog(@"===%@",navigationResponse.response.URL.absoluteString);

//允许跳转

decisionHandler(WKNavigationResponsePolicyAllow);

//不允许跳转

//decisionHandler(WKNavigationResponsePolicyCancel);

}

// 接收到服务器跳转请求之后调用

- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {

NSLog(@"-------接收到服务器跳转请求之后调用");

}

// 数据加载发生错误时调用

- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {

NSLog(@"----数据加载发生错误时调用");

}

// 需要响应身份验证时调用 同样在block中需要传入用户身份凭证

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {

//用户身份信息 NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证");

NSURLCredential *newCred = [NSURLCredential credentialWithUser:@"" password:@"" persistence:NSURLCredentialPersistenceNone];

// 为 challenge 的发送方提供 credential [[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge];

completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);

}

// 进程被终止时调用

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {

NSLog(@"----------进程被终止时调用");

}

自定义配置

WKUserContentController 是JavaScript与原生进行交互的桥梁, 主要使用的方法有:

// 注入JavaScript与原生交互协议

// JS 端可通过 window.webkit.messageHandlers..postMessage() 发送消息

- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name;

// 移除注入的协议, 在deinit方法中调用

- (void)removeScriptMessageHandlerForName:(NSString *)name;

实现WKScriptMessageHandler协议方法:

JavaScript调用原生方法

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {

// 判断是否是调用原生的

if([@"NativeMethod" isEqualToString:message.name]) {

// 判断message的内容,然后做相应的操作

if([@"close" isEqualToString:message.body]) {

}

}

}

在 message的name和body属性中我们可以获取到与JS调取原生的方法名和所传递的参数。

注意:上面将当前ViewController设置为MessageHandler之后需要在当前ViewController销毁前将其移除,否则会造成内存泄漏。

[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"NativeMethod"];

原生调用JS方法

// iosImg 为js方法名,后面跟的是参数

NSString *promptCode = [NSString stringWithFormat:@"iosImg('%@','%@')",self.picType,longStr];

[_webView evaluateJavaScript:promptCode completionHandler:^(id object,NSError *error) {

NSLog(@"=======%@",error);

}];

WKUIDelegate代理方法

web界面中有弹出警告框时调用

这个代理方法, 主要是用来处理使用系统的弹框来替换JS中的一些弹框的,比如: 警告框, 选择框, 输入框,

/**

webView中弹出警告框时调用, 只能有一个按钮

@param webView webView

@param message 提示信息

@param frame 可用于区分哪个窗口调用的

@param completionHandler 警告框消失的时候调用, 回调给JS

*/

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void(^)())completionHandler {

NSLog(@"-------web界面中有弹出警告框时调用");

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:(UIAlertControllerStyleAlert)];

UIAlertAction *ok = [UIAlertAction actionWithTitle:@"我知道了" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {

completionHandler();

}];

[alert addAction:ok];

[self presentViewController:alert animated:YES completion:nil];

}

下面这些方法是交互JavaScript的方法

// JavaScript调用confirm方法后回调的方法 confirm是js中的确定框,需要在block中把用户选择的情况传递进去

/** 对应js的confirm方法

webView中弹出选择框时调用, 两个按钮

@param webView webView description

@param message 提示信息

@param frame 可用于区分哪个窗口调用的

@param completionHandler 确认框消失的时候调用, 回调给JS, 参数为选择结果: YES or NO

*/

-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(BOOL))completionHandler {

NSLog(@"%@",message);

completionHandler(YES);

/*

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择" message:message preferredStyle:(UIAlertControllerStyleAlert)];

UIAlertAction *ok = [UIAlertAction actionWithTitle:@"同意" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {

completionHandler(YES);

}];

UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"不同意" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {

completionHandler(NO);

}];

[alert addAction:ok];

[alert addAction:cancel];

[self presentViewController:alert animated:YES completion:nil];

*/

}

// JavaScript调用prompt方法后回调的方法 prompt是js中的输入框 需要在block中把用户输入的信息传入

/** 对应js的prompt方法

webView中弹出输入框时调用, 两个按钮 和 一个输入框

@param webView webView description

@param prompt 提示信息

@param defaultText 默认提示文本

@param frame 可用于区分哪个窗口调用的

@param completionHandler 输入框消失的时候调用, 回调给JS, 参数为输入的内容

*/

-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(NSString * _Nullable))completionHandler{

NSLog(@"%@",prompt);

completionHandler(@"123");

/*

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请输入" message:prompt preferredStyle:(UIAlertControllerStyleAlert)];

[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {

textField.placeholder = @"请输入";

}];

UIAlertAction *ok = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {

UITextField *tf = [alert.textFields firstObject];

completionHandler(tf.text);

}];

UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {

completionHandler(defaultText);

}];

[alert addAction:ok];

[alert addAction:cancel];

[self presentViewController:alert animated:YES completion:nil];

*/

}

// 默认预览元素调用

- (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo {

NSLog(@"-----默认预览元素调用");

return YES;

}

// 返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。

- (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray> *)previewActions {

NSLog(@"----返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。");

return self;

}

// 允许应用程序向它创建的视图控制器弹出

- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController {

NSLog(@"----允许应用程序向它创建的视图控制器弹出");

}

// 显示一个文件上传面板。completionhandler完成处理程序调用后打开面板已被撤销。通过选择的网址,如果用户选择确定,否则为零。如果不实现此方法,Web视图将表现为如果用户选择了取消按钮。

- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(NSArray * _Nullable URLs))completionHandler {

NSLog(@"----显示一个文件上传面板");

}

创建新的webView时调用的方法

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {

NSLog(@"-----创建新的webView时调用的方法");

return webView;

}

关闭webView时调用的方法

- (void)webViewDidClose:(WKWebView *)webView {

NSLog(@"----关闭webView时调用的方法");

}

WKUserScript

WKUserScript用于往加载的页面中添加额外需要执行的JavaScript代码, 主要是一个初始化方法:

/*

source: 需要执行的JavaScript代码

injectionTime: 加入的位置, 是一个枚举

typedef NS_ENUM(NSInteger, WKUserScriptInjectionTime) {

WKUserScriptInjectionTimeAtDocumentStart,

WKUserScriptInjectionTimeAtDocumentEnd

} API_AVAILABLE(macosx(10.10), ios(8.0));

forMainFrameOnly: 是加入所有框架, 还是只加入主框架

*/

- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;

// 通过WKUserScript注入需要执行的JavaScript代码

- (void)addUserScript:(WKUserScript *)userScript;

// 移除所有注入的JavaScript代码

- (void)removeAllUserScripts;

WKWebsiteDataStore

iOS7.0只有UIWebView, 而iOS8.0是有WKWebView, 但8.0的WKWebView没有删除缓存方法。iOS9.0之后就开始支持啦。

所以使用时候一定要适配iOS9.0以上

WKWebsiteDataStore 提供了网站所能使用的数据类型,包括 cookies,硬盘缓存,内存缓存活在一些WebSQL的数据持久化和本地持久化。可通过 WKWebViewConfiguration类的属性 websiteDataStore 进行相关的设置。WKWebsiteDataStore 相关的API也比较简单:

// 默认的data store

+ (WKWebsiteDataStore *)defaultDataStore;

// 如果为webView设置了这个data Store,则不会有数据缓存被写入文件

// 当需要实现隐私浏览的时候,可使用这个

+ (WKWebsiteDataStore *)nonPersistentDataStore;

// 是否是可缓存数据的,只读

@property (nonatomic, readonly, getter=isPersistent) BOOL persistent;

// 获取所有可使用的数据类型

+ (NSSet *)allWebsiteDataTypes;

// 查找指定类型的缓存数据

// 回调的值是WKWebsiteDataRecord的集合

- (void)fetchDataRecordsOfTypes:(NSSet *)dataTypes completionHandler:(void (^)(NSArray *))completionHandler;

// 删除指定的纪录

// 这里的参数是通过上面的方法查找到的WKWebsiteDataRecord实例获取的

- (void)removeDataOfTypes:(NSSet *)dataTypes forDataRecords:(NSArray *)dataRecords completionHandler:(void (^)(void))completionHandler;

// 删除某时间后修改的某类型的数据

- (void)removeDataOfTypes:(NSSet *)websiteDataTypes modifiedSince:(NSDate *)date completionHandler:(void (^)(void))completionHandler;

// 保存的HTTP cookies

@property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore

dataTyle

// 硬盘缓存

WKWebsiteDataTypeDiskCache,

// HTML离线web应用程序缓存

WKWebsiteDataTypeOfflineWebApplicationCache,

// 内存缓存

WKWebsiteDataTypeMemoryCache,

// 本地缓存

WKWebsiteDataTypeLocalStorage,

// cookies

WKWebsiteDataTypeCookies,

// HTML会话存储

WKWebsiteDataTypeSessionStorage,

// IndexedDB 数据库

WKWebsiteDataTypeIndexedDBDatabases,

// WebSQL 数据库

WKWebsiteDataTypeWebSQLDatabases

WKWebsiteDataRecord

// 展示名称, 通常是域名

@property (nonatomic, readonly, copy) NSString *displayName;

// 包含的数据类型

@property (nonatomic, readonly, copy) NSSet *dataTypes;

简单应用

删除指定时间的所有类型数据

例:删除所有

NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];

NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];

[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{

// Done

NSLog(@"释放");

}];

查找删除

WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];

[dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray * _Nonnull records) {

for (WKWebsiteDataRecord *record in records) {

[dataStore removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{

// done

}];

}

}];

查找删除特定的内容

WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];

[dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray * _Nonnull records) {

for (WKWebsiteDataRecord *record in records) {

if ([record.displayName isEqualToString:@"baidu"]) {

[dataStore removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{

// done

}];

}

}

}];

因URL中含有中文加载网页白屏显示的解决方法就是将中文符号UTF8转码。

看需要有时可以对url进行两次UTF8编码,第一次编码,中文会被转码成16进制,但是每个字符前面会有一个%号,这个%号会被看成转义字符影响浏览器的解析,所以还需要再编码一次。

[@"中文" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

获取h5中的标题 添加进度条

获取h5中的标题和添加进度条放到一起展示看起来更明朗一点,在初始化wenview时,添加两个观察者分别用来监听webview 的estimatedProgress和title属性:

webview.navigationDelegate = self;

webview.UIDelegate = self;

[webview addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];

[webview addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];

@property (nonatomic,weak) CALayer *progressLayer;

-(void)setupProgress{

UIView *progress = [[UIView alloc]init];

progress.frame = CGRectMake(0, 0, KScreenWidth, 3);

progress.backgroundColor = [UIColor clearColor];

[self.view addSubview:progress];

CALayer *layer = [CALayer layer];

layer.frame = CGRectMake(0, 0, 0, 3);

layer.backgroundColor = [UIColor greenColor].CGColor;

[progress.layer addSublayer:layer];

self.progressLayer = layer;

}

实现观察者的回调方法:

#pragma mark - KVO回馈

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

if ([keyPath isEqualToString:@"estimatedProgress"]) {

self.progressLayer.opacity = 1;

if ([change[@"new"] floatValue]

return;

}

self.progressLayer.frame = CGRectMake(0, 0, KScreenWidth*[change[@"new"] floatValue], 3);

if ([change[@"new"]floatValue] == 1.0) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

self.progressLayer.opacity = 0;

self.progressLayer.frame = CGRectMake(0, 0, 0, 3);

});

}

}else if ([keyPath isEqualToString:@"title"]){

self.title = change[@"new"];

}

}

ios wkwebview弹框_iOS 加载WKWebView相关推荐

  1. ios wkwebview弹框_iOS WKWebView的使用

    级别:★☆☆☆☆ 标签:「WKWebView」「WKWebView加载新页面失败」「WKWebView 弹框没有显示」「WKWebView 打开其他应用」 作者: WYW 审校: QiShare团队 ...

  2. ios wkwebview弹框_iOS WKWebView的javascript alert 不弹的解决方案

    1.将WKWebView的WKUIDelegate设置成self. 2.将一下三个方法拷贝到项目中. - (void)webView:(WKWebView *)webView runJavaScrip ...

  3. android 仿ios 底部弹出,项目需求讨论-仿ios底部弹框实现及分析

    hi,在项目开发中,有时候需要仿照ios的底部弹框做效果,比如我们在iPhone上面关闭定位的时候,就会弹出ios特有的底部弹框: 屏幕快照 2017-10-09 08.20.30 PM.png 弹框 ...

  4. win10老是弹出计算机管理器,win10系统Ie11老是弹出“管理加载项”提示框取消的处理办法...

    有时候可能会遇到对win10系统IE11老是弹出"管理加载项"提示框取消进行设置,如果我们需要对win10系统IE11老是弹出"管理加载项"提示框取消进行设置时 ...

  5. 学习Mac开发第四弹 通过NSImageView加载图片

    学习Mac开发第四弹 通过NSImageView加载图片 创建NSImageView 1 . 拖拽大法好 Autolayout 创建一个宽高160 *160 的NSImageView 创建是正方形的 ...

  6. iOS开发UI篇—懒加载

    iOS开发UI篇-懒加载 1.懒加载基本 懒加载--也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了, ...

  7. [html] iOS下页面如何启动加载时显示画面图片?如何设置大小?它有什么好处?

    [html] iOS下页面如何启动加载时显示画面图片?如何设置大小?它有什么好处? <link rel="apple-touch-startup-image" href=&q ...

  8. IOS精品源码,仿探探UIButton封装iOS提示弹框迅速引导页自定义导航栏

    1.仿 探探UI Swift ,重用机制 2.超强UIButton封装 3.一行代码集成UIPickerView,界面完全自定义 4.iOS提示弹框 5.swift UITableView / UIC ...

  9. 微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题

    微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题 参考文章: (1)微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题 (2)https://www.cnblogs.com/co ...

最新文章

  1. AI公司为什么集体造“芯”?寻求商业变现新途径
  2. 神策数据易向文:打造券商上层数据应用的坚实基础
  3. [HDU3691 Nubulsa Expo]
  4. Golang——HTTP编程请求和响应实现
  5. (转) Hadoop1.2.1安装
  6. 用户故事与敏捷方法笔记---搜集故事
  7. SQL server 数据库 实验一
  8. 用批处理的方式解压文件
  9. python布尔值使用_Python布尔值--True和False
  10. 【多智能体感知与协同调度】
  11. 计算机窗口弹出多个窗口,电脑怎么打开多个微信窗口
  12. 石头、纸、剪刀小游戏(剪刀石头布?)
  13. M*LMM缩略图文件管理模式模块开发(一个含有listview和gridview浏览模式的文件管理器)
  14. Windows系统删除蓝牙图标
  15. 完成一个重要的互联网进化心理学实验
  16. 【Pytorch】常见的人脸身份识别损失函数
  17. Angelababy 首攻好莱坞 获封最闪亮新星
  18. Halcon编程实验-(4)车牌号数字+字母的识别【目的:OCR识别的应用】
  19. Velocity在JavaWeb中的简单应用
  20. 加工中心编程技术讲座文库

热门文章

  1. 惠惠软件|小程序在餐饮行业的应用经验
  2. 通过ip地址实现城市定位
  3. SQL server 修改表数据
  4. Aurix TC3xx系列MCU GTM模块介绍
  5. java期末考试试题及答案_(完整word版)java期末考试试题(含答案)
  6. 计算机主机响是什么原因,电脑疑问_电脑主机响是什么原因-太平洋IT百科手机版...
  7. SQLServer 跨服务器 查询数据
  8. 阿里字体图标的下载使用
  9. python写传奇脚本_python – 如何将图形传奇带到前面?
  10. github创建分支,并将其合并到主分支