【问题标题】:How to open Specific View controller on Widgets/ Today Extension click如何在小部件/今日扩展上打开特定视图控制器单击
【发布时间】:2018-03-07 11:17:40
【问题描述】:

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

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

【问题讨论】:

    标签: swift3 widget today-extension


    【解决方案1】:

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

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

    在这里,我将标签设为:1, 2, 3First, Second and Third UIButton

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

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

    在上面的代码中,标签将被添加到url方案中,以识别在UIButton按下时需要打开哪个UIViewController。所以网址看起来像:open://1

    3.包含应用的URL Types需要填写URL Scheme,即

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

    4.包含应用程序从扩展打开时,您可以在AppDelegate’sapplication(_ : url: sourceApplication: annotation: )方法中获取句柄。在这里,您可以处理要打开的控制器,即

    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 标识当前设置为UIButton's tag valueURL 中的主机组件,您可以使用它来唯一标识哪个UIButton被按下并相应地下一步要做什么。

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

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

    【讨论】:

    • 当然。如果它对您有用,请接受并支持答案。快乐编码..?
    • 所以我实现了这个并不断得到:线程 7:EXC_BAD_ACCESS(代码=1,地址=0x10)。最后通过简化所有内容让 url = URL(string: "open")! self.extensionContext.open(url) 并且只使用“open”作为没有标识符的方案。有效。然后我在所有相同的地方改变了开放的方式,并再次尝试了一些更独特的东西。它坏了。所以我把它改回打开状态,现在又坏了。
    【解决方案2】:

    为您的应用添加新方案

    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) }
    }
    

    than,在 AppDelegate 文件中添加方法 application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) 并在特定 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
    } 
    

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

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

    【讨论】:

    • 感谢重播,但我在小部件上的应用程序中有 3 个视图控制器单击打开特定视图控制器,每个视图控制器是否需要三个单独的 url 架构??
    • 没有。无需创建单独的 url 方案。通常,url 方案用于从小部件打开应用程序。 b'coz Apple 认为该小部件是您尝试从要从中打开的小部件中打开您的应用的其他应用。
    • 你能给我,例如,如果应用程序中有 3 个视图控制器,我想在小部件中的 3 个不同按钮上打开每个视图控制器
    • 请检查答案并参考以下链接以获取有关应用程序扩展的更多信息。 grokswift.com/notification-center-widget
    • 另一个问题我如何在今天的扩展中检查用户是否登录??
    【解决方案3】:

    Swift5

    Step1:选择项目>info>url types>添加url scheme

    第二步:进入按钮操作方法并使用此代码

    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
        }
    

    恭喜!你打开控制器。

    【讨论】:

      【解决方案4】:

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

      func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
      
        if let url = URLContexts.first?.url {
            //Do stuff with the url
        }
      
      }
      

      (而不是应用程序(_应用程序:UIApplication,打开url:URL,选项:[UIApplication.OpenURLOptionsKey:Any] = [:])-> 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
          }
      
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-08
        • 2020-12-17
        • 2023-03-19
        • 2014-10-15
        • 2017-03-31
        • 1970-01-01
        • 2014-07-25
        • 1970-01-01
        相关资源
        最近更新 更多