如何在 Widgets/Today Extension click 上打开特定视图控制器

How to open Specific View controller on Widgets/ Today Extension click

我试图在点击小部件时打开特定的视图控制器,但无法打开它,我可以使用 url 架构打开应用程序,但我想打开特定的视图控制器我该怎么做这是使用 url 模式打开应用程序的代码:

@IBAction func open_app(_ sender: Any) { extensionContext?.open(URL(string: "open://")! , completionHandler: nil) } 单击按钮我正在使用 url 架构成功运行应用程序。但现在我想在该点击上打开特定的视图控制器我该怎么做?

为您的应用添加新方案

enter image description here

如上图所示...

然后,在你的 Today Extension 的 IBAction 下面写一段代码

@IBAction func btnFirstWidgetAction() {
    let url: URL? = URL(string: "schemename://secondViewController")!
    if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}

@IBAction func btnSecondWidgetAction() {
    let url: URL? = URL(string: "schemename://secondViewController")!
    if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}

@IBAction func btnThirdWidgetAction() {
    let url: URL? = URL(string: "schemename://thirdViewController")!
    if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}

比,添加方法application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [: ]) 在 AppDelegate 文件中,并在此方法中编写代码以在特定 ViewController 中重定向。

//call when tap on Extension and get url that is set into a ToadyExtension swift file...
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    let urlPath : String = url.absoluteString
    print(urlPath)

    if self.isContainString(urlPath, subString: "firstViewController") {
        //here go to firstViewController view controller
    }
    else if self.isContainString(urlPath, subString: "firstViewController") {
        //here go to secondViewController view controller
    }
    else {
        //here go to thirdViewController view controller
    }

    return true
} 

此方法用于检查您的字符串是否包含在小部件按钮操作中作为子字符串。如果包含则为 true 否则为 false

 func isContainString(_ string: String, subString: String) -> Bool {
    if (string as NSString).range(of: subString).location != NSNotFound { return true }
    else { return false }
}

根据您的要求,我创建了一个示例以使其正常工作。

1. 首先在TodayViewController界面,创建3个不同的UIButtons,并给它们tag 值来唯一标识它们。

这里我给了 tags 作为:1, 2, 3 to First, Second and Third UIButton.

2. 接下来您需要编写代码以从 Today Extension 打开您的 Containing App。在 TodayViewController 中创建一个 @IBAction 并将其连接到所有三个 UIButtons.

@IBAction func openAppController(_ sender: UIButton)
{
    if let url = URL(string: "open://\(sender.tag)")
    {
        self.extensionContext?.open(url, completionHandler: nil)
    }
}

在上面的代码中,tag会被添加到url scheme中来标识哪个UIViewController需要在 UIButton 按下时打开。所以 url 看起来像这样: open://1

3.Containing App 的 URL Types 需要为 URL Scheme 创建一个条目,即

从上面的屏幕截图可以明显看出,无需为要从扩展中打开的每个 url 进行输入。 URLs 具有相同的 url scheme 只有一个条目.

4.包含的应用程序从扩展中打开时,可以在AppDelegate’s [=29]中获取句柄=] 方法。在这里,您可以处理打开哪个控制器,即

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
    if url.scheme == "open"
    {
        switch url.host
        {
        case "1":
            //Open First View Controller

        case "2":
            //Open Second View Controller

        case "3":
            //Open Third View Controller

        default:
            break
        }
    }
    return true
}

url.scheme 标识 URL 的方案,即 openurl.host 标识 URL 中当前设置为 UIButton's tag value,您可以使用它来唯一标识按下了哪个 UIButton 以及相应的下一步要删除的内容。

更多关于Today Extensions,您可以参考:https://hackernoon.com/app-extensions-and-today-extensions-widget-in-ios-10-e2d9fd9957a8

如果您仍然遇到与此相关的任何问题,请告诉我。

Swift5

第一步:select项目>信息>url类型>添加url方案

step2:转到按钮操作方法并使用此代码

let tag = 1
        if let url = URL(string: "open://\(tag)")
        {
            self.extensionContext?.open(url, completionHandler: nil)
        }

第 3 步:欢迎您获得宿主应用程序的控制权,只需将其添加到应用程序委托方法中

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
    {
        if url.scheme == "open"
        {
            switch url.host
            {
            case "1":
              let storyboard = UIStoryboard(name: "Main", bundle: nil)
                  let vc = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
                  self.window?.rootViewController = vc
                  self.window?.makeKeyAndVisible()
            default:
                break
            }
        }
        return true
    }

恭喜!你打开控制器。

在 xCode11 中,如果您使用的是 sceneDelegate,请遵循 Malik 和 Mahesh 描述的相同逻辑,但在 SceneDelegate 中使用以下函数:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

  if let url = URLContexts.first?.url {
      //Do stuff with the url
  }

}

(而不是应用程序(_ app:UIApplication,打开 url:URL,选项:[UIApplication.OpenURLOptionsKey:任何] = [:])-> Bool)

详情:

第一个:

在您的项目中添加一个 url 方案 -> 信息 -> url 类型 -> 添加 url 方案。在这里,您可以通过仅填写“URL 方案”字段(例如您的应用程序名称)来开始。

第二个:

在您的扩展程序中,使用以下函数(例如通过按钮调用):

let urlString = "MyAppName://host/path"
if let url = URL(string: urlString)
{

   self?.extensionContext?.open(url, completionHandler: nil)

 }

第三名:

在 Scene Delegate 中实现您的逻辑:

 func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

    if let url = URLContexts.first?.url {
      //Do stuff with the url
    }

 }