2

我对 iOS 开发比较陌生,目前使用 Swift 开发原型 ResearchKit 应用程序。其中一个要求是将 a 嵌入WKWebViewORKTask三个步骤组成的:ORKQuestionStepORKWebViewStepORKCompletionStep。我似乎找不到太多关于如何子类化ORKStepORKStepViewController使用 Swift 创建自定义步骤的信息。有人可以指导我正确的方向如何子类化ORKStepORKStepViewController显示WKWebView使用 Swift 吗?

先感谢您!

4

2 回答 2

1

朱元在ResearchKit-Users邮件列表中的回答:

我想你可以:

  1. 创建ORKActiveStep并正确配置它。
  2. 实现- (void)taskViewController:(ORKTaskViewController *)taskViewController stepViewControllerWillAppear:(ORKStepViewController *)stepViewController委托方法。
  3. 通过它的属性注入你webView的。ORKActiveStepViewControllercustomView
于 2015-08-06T11:45:47.607 回答
1

我已经构建了自己的 ORKWebView,如下所示。我很高兴关于如何改进它的评论。

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 字符串吗?

于 2016-06-27T10:00:19.910 回答