使用 WKWebView 创建自定义 ORKStep
Posted
技术标签:
【中文标题】使用 WKWebView 创建自定义 ORKStep【英文标题】:Creating custom ORKStep with WKWebView 【发布时间】:2015-10-26 16:13:43 【问题描述】:我对 ios 开发比较陌生,目前正在使用 Swift 开发原型 ResearchKit 应用程序。其中一项要求是将WKWebView
嵌入到由三个步骤组成的ORKTask
中:ORKQuestionStep
、ORKWebViewStep
、ORKCompletionStep
。我似乎找不到太多关于如何使用 Swift 创建自定义步骤的子类 ORKStep
和 ORKStepViewController
的信息。有人可以指导我如何使用 Swift 子类化 ORKStep
和 ORKStepViewController
以显示 WKWebView
吗?
提前谢谢你!
【问题讨论】:
【参考方案1】:ResearchKit-Users邮件列表中的朱元回答:
我猜你可以:
创建一个
ORKActiveStep
并正确配置它。 实现- (void)taskViewController:(ORKTaskViewController *)taskViewController stepViewControllerWillAppear:(ORKStepViewController *)stepViewController
委托方法。 通过customView
属性将webView
注入ORKActiveStepViewController
。
【讨论】:
【参考方案2】:我已经构建了自己的 ORKWebView,如下所示。我很高兴 cmets 如何改进它。
1.子类化 ORKActiveStep
class javascript_Step : ORKActiveStep
static func stepViewControllerClass ( ) -> Javascript_Step_View_Controller.Type
return Javascript_Step_View_Controller.self
2。子类 ORKActiveStepViewController
在这里您将修改您的 WebView 及其组件。 为了退出 WebView 并传递结果,我使用 Javascript。
import Foundation
import ResearchKit
import WebKit
class Javascript_Step_View_Controller : ORKActiveStepViewController, WKScriptMessageHandler
weak var webView: WKWebView!
var html : String = "<!DOCTYPE html><html><head> <meta charset=\"UTF-8\"> <title>JS Widget</title> <style type=\"text/css\"> h1 color: red </style></head><body> <h1>Test</h1> <input type=\"button\" value=\"Say hello\" onClick=\"Finish_This_Widget('Result is String')\" /> <script type=\"text/javascript\"> function Finish_This_Widget(string) App.Finish_Widget(string) </script></body></html>"
// Here the result message posted by Javascript can be handled
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
if let result = message.body as? String
print("userContentController: \(result)")
// With the incoming reult of your webview, the ORKActiveStep timer will be started
start()
override func viewDidLoad()
super.viewDidLoad()
// Here you set the function name to call from javascript
let controller = WKUserContentController()
controller.addScriptMessageHandler(self, name: "Finish_Widget")
let config = WKWebViewConfiguration()
config.userContentController = controller
let frame = CGRectMake(20, 20, 200, 200)
let webView = WKWebView(frame: frame, configuration: config)
self.customView = webView
// Set the view constraints (warning message with following unproper settings)
self.customView?.superview!.translatesAutoresizingMaskIntoConstraints = false
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": webView])) view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[demoView]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["demoView": webView]))
// Load the html string
webView.loadHTMLString(html, baseURL: NSBundle.mainBundle().bundleURL)
webView.translatesAutoresizingMaskIntoConstraints = false
self.webView = webView
3.使用您的 WebViewStep 加载任务
在第 2 步中,我们看到了 start() 函数调用,我们需要能够完成该步骤并切换到下一个步骤。这就是为什么我们希望计时器在我们启动后立即结束。
// This functions gives you the Step you can work with finanlly
func Javascript_Widget_Step ( identifier : String, title : String, text : String ) -> ORKActiveStep
let active_Step = Javascript_Step(identifier: identifier)
// Set title and text for the step (which is optional)
active_Step.title = title
active_Step.text = text
// set stepduration to a minimum -> after javascript function call, step will be finished
active_Step.stepDuration = 0.001
// if this is false, it will not switch to the next step after the javascript call automatically
active_Step.shouldContinueOnFinish = true
return active_Step
未决问题
如何注入 html?如果我不想要一个始终具有相同 html 的静态 WebView,那么我可以从外部设置 html 字符串吗?
【讨论】:
一种间接的解决方案是通过 NSUserDefaults 加载 html 字符串。如果您知道更好的解决方案,我将不胜感激!以上是关于使用 WKWebView 创建自定义 ORKStep的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:使用 WkWebView 突出显示具有不同颜色的文本
Swift:WKWebView 中 UIRefreshControl 的自定义操作