首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为从Nib或Storyboard生成的WKWebViewConfiguration设置自定义WKWebView

为从Nib或Storyboard生成的WKWebViewConfiguration设置自定义WKWebView
EN

Stack Overflow用户
提问于 2019-05-31 12:28:15
回答 2查看 6.5K关注 0票数 2

我想对我的应用程序使用自定义URL方案,但在配置URL方案时遇到了问题。

当我以编程方式创建WKWebView对象时(使用initWithFrame:.)我能够指定自己的WKWebViewConfiguration对象,但是当Nib/Storyboard中的WKWebView被自动创建时(通过initWithCoder:),我无法指定配置。配置是只读的,所以我不能在事实发生后更改它。如果可能的话,我非常希望避免以编程的方式创建WkWebView。

注意:有一个与此相关的现有问题(https://stackoverflow.com/questions/48451264/set-wkwebviewconfiguration-on-wkwebview-from-nib-or-storyboard),但在那里接受的答案只解决了实际程序的一个子集(它涉及添加用户脚本而不是配置对象,因此不能添加自定义的URL方案处理程序)。那里的其他答案要么无助于这个问题,所以我又提出了另一个问题。

更新:根据我收到的评论,我想在此作一些澄清。

WKWebViewConfiguration是一个“复制”属性,如下所定义:

*@属性(非原子、只读、复制) WKWebViewConfiguration配置;

我试着把它打印了好几遍,我发现它正在改变:

2019年-05-30 15:02:25.724312-0700 MyTest 916:72204配置= 0x101b06b50 2019年-05-30 15:02:25.724499-0700 MyTest 916:72204配置= 0x101a37110

使用LLDB得到相同的结果(每次不同):

打印self configuration $17 = 0x0000000102e0b990 打印self configuration $18 = 0x0000000102f3bd40

EN

回答 2

Stack Overflow用户

发布于 2019-06-12 01:40:21

创建一个包含WKWebView的自定义视图如何?您可以在Storyboard中使用此视图而不是WKWebView。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final class MyWebView: UIView {
    var webView: WKWebView!
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: config)
        addSubview(webView)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        webView.frame = bounds
    }
}

若要自定义Storyboard中的其他属性,请将@IBInspectable添加到包装视图中,并将值传递给内部配置。

下面的代码缺少故事板中WKWebView所具有的一些属性,但是可以实现类似于此的其他属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final class MyWebView: UIView {
    @IBInspectable var userAgent: String?
    @IBInspectable var appName: String? {
        didSet {
            config.applicationNameForUserAgent = appName
        }
    }
    private var types: WKDataDetectorTypes = [
        .phoneNumber,
        .link,
        .address,
        .calendarEvent,
        .trackingNumber,
        .flightNumber,
        .lookupSuggestion
    ]
    @IBInspectable var phoneNumber: Bool = true {
        didSet {
            if phoneNumber {
                types.insert(.phoneNumber)
            } else {
                types.remove(.phoneNumber)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var link: Bool = true {
        didSet {
            if link {
                types.insert(.link)
            } else {
                types.remove(.link)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var address: Bool = true {
        didSet {
            if address {
                types.insert(.address)
            } else {
                types.remove(.address)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var calendarEvent: Bool = true {
        didSet {
            if calendarEvent {
                types.insert(.calendarEvent)
            } else {
                types.remove(.calendarEvent)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var trackingNumber: Bool = true {
        didSet {
            if trackingNumber {
                types.insert(.trackingNumber)
            } else {
                types.remove(.trackingNumber)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var flightNumber: Bool = true {
        didSet {
            if flightNumber {
                types.insert(.flightNumber)

            } else {
                types.remove(.flightNumber)
            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var lookupSuggestion: Bool = true {
        didSet {
            if phoneNumber {
                types.insert(.lookupSuggestion)
            } else {
                types.remove(.lookupSuggestion)

            }
            config.dataDetectorTypes = types
        }
    }
    @IBInspectable var javaScriptEnabled: Bool = true {
        didSet {
            config.preferences.javaScriptEnabled = javaScriptEnabled
        }
    }
    @IBInspectable var canAutoOpenWindows: Bool = false {
        didSet {
            config.preferences.javaScriptCanOpenWindowsAutomatically = canAutoOpenWindows
        }
    }

    lazy var webView: WKWebView = {
        let webView = WKWebView(frame: .zero, configuration: config)
        webView.customUserAgent = userAgent
        addSubview(webView)
        return webView
    }()
    private var config = WKWebViewConfiguration()

    override func layoutSubviews() {
        super.layoutSubviews()
        webView.frame = bounds
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-06-05 11:26:57

所以,我做了一些测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface  ViewController  ()

@property   (strong)    IBOutlet    WKWebView   *webView ;

@end

@implementation ViewController

- (void)    awakeFromNib
{
    static  BOOL    hasBeenDone    = NO ;   //  because otherwise, awakeFromNib is called twice

    if (!hasBeenDone)
    {
        hasBeenDone = YES ;
    
        //  Create the scheme handler
        SchemeHandler           *mySchemeHandler    = [SchemeHandler new] ;
        NSLog(@"scheme handler : %lx",mySchemeHandler) ;
    
        if (!(self.webView))
        {
            //  Case 1 - we don't have a web view from the StoryBoard, we need to create it
            NSLog(@"Case 1") ;

            //  Add the scheme
            WKWebViewConfiguration  *configuration      = [WKWebViewConfiguration new] ;
            [configuration setURLSchemeHandler:mySchemeHandler
                              forURLScheme:@"stef"] ;
        
            //  Create and set the web view
            self.webView                                = [[WKWebView alloc] initWithFrame:NSZeroRect
                                                                             configuration:configuration] ;
        }
        else
        {
            //  Case 2 - we have a web view from the story board, just set the URL scheme handler
            //  of the configuration
            NSLog(@"Case 2") ;

            WKWebViewConfiguration  *configuration      = self.webView.configuration ;
            [configuration setURLSchemeHandler:mySchemeHandler
                              forURLScheme:@"stef"] ;
        }
        
        //  Log the view configuration
        NSLog(@"View configuration : %lx",self.webView.configuration) ;
        NSLog(@"URL handler for scheme : %lx",[self.webView.configuration     urlSchemeHandlerForURLScheme:@"stef"]) ;
    }
}


- (void)    viewDidLoad
{
    [super viewDidLoad] ;

    //  Log the view configuration
    NSLog(@"View configuration : %lx",self.webView.configuration) ;
    NSLog(@"URL handler for scheme : %lx",[self.webView.configuration urlSchemeHandlerForURLScheme:@"stef"]) ;

    //  Start loading a URL with the scheme - this should log "start" if everything works fine
    NSURL           *url        = [NSURL URLWithString:@"stef://willIWinTheBounty?"] ;
    NSURLRequest    *urlRequest = [NSURLRequest requestWithURL:url] ;
    [self.webView loadRequest:urlRequest] ;
}

@end

如果在情节提要中使用IBOutlet webView unset运行该代码(案例1),则代码将创建web视图,将其配置为方案,一切都很好。

方案处理程序: 600000008e30 案例1 视图配置: 600003d0c780 方案的URL处理程序: 600000008e30 视图配置: 600003d0c780 方案的URL处理程序: 600000008e30 方案处理程序启动

如果您在情节提要中使用IBOutlet webView集运行该代码(案例2),那么setURLSchemeHandler:forURLScheme:确实无法工作。在这种情况下,urlSchemeHandlerForURLScheme:返回零的日志。

方案处理程序: 600000005160 案例2 视图配置: 600003d08d20 方案的URL处理程序:0 视图配置: 600003d08d20 方案的URL处理程序:0 注意,方案处理程序start不被调用。

原因并不是通过getter获得不同的副本,因为配置日志表明它保持不变。只是,尽管调用了setURLSchemeHandler:forURLScheme,但没有设置方案处理程序。

因此,我想唯一的解决方案是用例1。根据您的视图设置,插入视图可能或多或少是困难的。我建议在您的故事板上有一个空的“母亲”视图,并使用以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface  ViewController  ()

@property   (weak)      IBOutlet    NSView      *webViewMother ;
@property   (strong)                WKWebView   *webView ;

@end


@implementation ViewController

- (void)    awakeFromNib
{
    static  BOOL    hasBeenDone    = NO ;   //  because otherwise, awakeFromNib is called twice

    if (!hasBeenDone)
    {
        hasBeenDone = YES ;
    
        //  Create the scheme handler
        SchemeHandler           *mySchemeHandler    = [SchemeHandler new] ;

        //  Create the configuration
        WKWebViewConfiguration  *configuration      = [WKWebViewConfiguration new] ;
        [configuration setURLSchemeHandler:mySchemeHandler
                          forURLScheme:@"stef"] ;
    
        //  Create the web view at the size of its mother view
    self.webView                                = [[WKWebView alloc]     initWithFrame:self.webViewMother.frame
                                                                         configuration:configuration] ;
        [self.webViewMother addSubview:self.webView] ;

    //  Log the view configuration
    NSLog(@"View configuration : %lx",self.webView.configuration) ;
    NSLog(@"URL handler for scheme : %lx",[self.webView.configuration     urlSchemeHandlerForURLScheme:@"stef"]) ;
    }

}

@end

对我来说工作很好,但是如果你有你的网页视图的子视图的话,可能会很棘手。

视图配置: 600003d082d0 方案的URL处理程序: 600000004c90 视图配置: 600003d082d0 方案的URL处理程序: 600000004c90 方案处理程序启动

请注意,通过调用,配置保持不变。

编辑:添加了运行日志

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56401374

复制
相关文章
Xib、Nib、Storyboard下修改控件边框颜色、大小、圆角
问题: 今天有一个页面有很多uibutton,所以就用xib搭了界面,然后问题来了,如何在xib下修改控件的边框颜色和大小、圆角?我之前知道利用IB面板下的“UserDefined Runtime A
傅_hc
2018/06/28
2.4K0
iOS中WebKit框架应用与解析 原
        在iOS8之前,在应用中嵌入网页通常需要使用UIWebView这样一个类,这个类通过URL或者HTML文件来加载网页视图,功能十分有限,只能作为辅助嵌入原生应用程序中。虽然UIWebView也可以做原生与JavaScript交互的相关处理,然而也有很大的局限性,JavaScript要调用原生方法通常需要约定好协议之后通过Request来传递。WebKit框架中添加了一些原生与JavaScript交互的方法,增强了网页视图与原生的交互能力。并且WebKit框架中采用导航堆栈的模型来管理网页的跳转,开发者也可以更加容易的控制和管理网页的渲染。关于UIWebView的相关使用,在前面的博客中有详细介绍,地址如下。
珲少
2018/08/15
2K0
iOS中WebKit框架应用与解析
                                                                            原
分享超详细 WKWebView 开发和使用经验
根据需求需要将老项目中的 WebView 替换成 WKWebView,期间查阅了不少文档和资料,之前也发布了几篇 WKWebView 相关的优秀文章。
网罗开发
2021/08/13
5K0
WKWebView详解
WKWebView主要涉及到以下类或协议,各部分可能互相依赖,文章按照apple文档的划分对每一个模块进行了详细的解释。
殷源
2018/01/31
20.7K9
WKWebView音视频媒体播放处理
由于H5的video未设置autoplay、playsinline属性。我们需自己注入,才能实现效果。
conanma
2021/10/28
4.4K0
WKWebView的使用
WKWebView的使用 前言 最近项目中的UIWebView被替换为了WKWebView,因此来总结一下WKWebView的使用。 示例Demo:WKWebView的使用 本文将从以下几方面介绍WKWebView: 1、WKWebView涉及的一些类 2、WKWebView涉及的代理方法 3、网页内容加载进度条的实现 4、JS和OC的交互 5、本地HTML文件的实现 一、WKWebView涉及的一些类 WKWebView:网页的渲染与展示 注意: #import <WebKit/WebKi
且行且珍惜_iOS
2018/06/19
3K0
Swift与JS通过WKWebView互调
创建WKWebView lazy var webView: WKWebView = { // 创建WKPreferences let preferences = WKPreferences() // 开启js preferences.javaScriptEnabled = true // 创建WKWebViewConfiguration let configuration = WKWebViewConfiguration() // 设置WKWebVie
YungFan
2020/12/25
2.7K0
WKWebView
我们要通过JS与webview内容交互,就需要到这个类了,它的所有属性及方法说明如下:
用户2491699
2018/08/09
3.3K0
WKWebView
UIWebView自iOS2就有,WKWebView从iOS8.0(2014年9月WWDC)才有,毫无疑问,WKWebView相对UIWebVIew要优秀得多,主要表现在以下几点:
拉维
2019/08/12
6K0
WKWebView
iOS14开发-网络
上传数据需要服务端配合,不同的服务端代码可能会不一样,下面的上传代码适用于本人所写的服务端代码。
YungFan
2021/06/24
2.4K0
iOS界面黑白实现
a. 针对图片的处理:大部分图片的显示都是最后都是调用UIImageView的setImage方法,所以hook这个方法,在显示前生成灰色的图片,然后在赋值,代码如下:
莫空9081
2022/12/12
1.5K0
iOS下JS与OC互相调用(二)--WKWebView 拦截URL
在上篇文章中讲述了使用UIWebView拦截URL的方式来处理JS与OC交互。 由于UIWebView比较耗内存,性能上不太好,而苹果在iOS 8中推出了WKWebView。 同样的用WKWebView也可以拦截URL,做JS 与OC交互。关于WKWebView与UIWebView的对比,大家请自动百度或者google。
Haley_Wong
2018/08/22
3.6K0
iOS下JS与OC互相调用(二)--WKWebView 拦截URL
WKWebView崩溃记录——SIGSEGV(11)
在QA测试疯狂把玩App时,突然出现了crash问题,而且还是一个概率非常小的偶发crash。吓得我立马跑到bugly上查看crash记录。在通过符号表转换后,我得到了以下crash时的堆栈信息。
我只不过是出来写写代码
2019/06/20
3.2K1
WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制
发布于 2017-10-26 04:55 更新于 2018-02-19 22:41
walterlv
2018/09/18
1.2K0
WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制
iOS 使用WKWebView
页面禁用长按事件 方式一 禁用长按选择 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { //页面加载完成时 webView.evaluateJavaScript( "document.documentElement.style.webkitUserSelect='none';", completionHandler: nil ); webView.evaluateJavaScri
码客说
2019/10/21
1.6K0
关于IB_DESIGNABLE / IBInspectable的那些需要注意的事
IB_DESIGNABLE / IBInspectable 这两个关键字是在WWDC 2014年"What's New in Interface Builder"这个Session里面,用Swift讲过一个例子。也是随着Xcode 6 新加入的关键字。
一缕殇流化隐半边冰霜
2018/08/30
1.6K0
关于IB_DESIGNABLE / IBInspectable的那些需要注意的事
iOS WKWebView设置cookie方法总结
这个问题首先你要明白,WKWebView有自己的进程,使用自己的存储空间来存储cookie和cache,WKWebView会忽视NSURLCache、NSHTTPCookieStorage、NSCredentialStorage这些默认的网络存储, 其他的网络类如NSURLConnection是无法访问到的。 同时WKWebView发起的资源请求也是不经过NSURLProtocol的,导致无法自定义请求。
且行且珍惜_iOS
2021/09/07
6.3K0
iOS:WKWebView JS 交互这点事
WKWebView 适用于iOS8之后的系统 引用 #import <WebKit/WebKit.h> 1.OC调用JS NSString *jsmethod = [NSString stringWithFormat:@"mymethd(\"%@\")",data]; //data(NSDate)为要传给js的数据 [self.wkWebView evaluateJavaScript:jsmethod completionHandler:^(id _Nullable result,
菜菜不吃蔡
2018/08/03
1.7K0
【iOS 开发】iOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)
创建一个 HelloWorld 项目, 在这个 IOS 项目中有四个目录 : 如下图;
韩曙亮
2023/03/27
5K0
【iOS 开发】iOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)
iOS小技能:WKWebView与JS的交互
由于目前UIWebView 已经被抛弃了,因此推荐使用WKWebView的WKScriptMessageHandler实现iOS与JS交互
公众号iOS逆向
2022/12/19
7.4K0
iOS小技能:WKWebView与JS的交互

相似问题

从Nib中启动Storyboard?

11

从Storyboard而不是nib加载自定义TableViewCell

13

如何从StoryBoard内部连接到nib?

14

目标C,从.nib过渡到.storyboard

11

使用Storyboard而不是Nib

16
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文