【问题标题】:UIDocumentInteractionController Open Menu Cancelled CallbackUIDocumentInteractionController 打开菜单取消回调
【发布时间】:2014-03-05 14:37:19
【问题描述】:

我目前正在开发一个专门针对 iOS7 的应用程序,该应用程序利用在菜单中打开的 UIDocumentInteractionController 并且需要一种方法来在用户取消且未选择可用选项时通知我。

UIDocumentInteractionControllerDelegate 提供:

- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *) controller

但这并没有指定用户是点击了可用选项之一还是取消。

有什么想法吗?

【问题讨论】:

    标签: ios cocoa-touch ios7 uidocumentinteraction


    【解决方案1】:

    注意:这将不再适用于 iOS 8,仅适用于 iOS7 及更早版本

    要确定用户是否取消了菜单或选择了选项,您必须使用以下委托方法:

    1-

    - (void)documentInteractionController:(UIDocumentInteractionController *)controller
               didEndSendingToApplication:(NSString *)application
    {
        //get called only when the user selected an option and then the delegate method bellow get called
        // Set flag here _isOptionSelected = YES;
        _isOptionSelected = YES;
    }
    

    2-

    - (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
    {
        //called whether the user has selected option or not
        // check your flag here 
        if(_isOptionSelected == NO) {
            //the user has canceled the menu
         }
        _isOptionSelected = NO;
    }
    

    iOS 8

    对于 iOS 8 及更高版本,请使用此方法代替第 2 步中的方法:

    - (void)documentInteractionController:(UIDocumentInteractionController *)controller
               didEndSendingToApplication:(NSString *)application
    

    【讨论】:

    • 这不起作用,DidDismissOpenInMenuDidEndSendingToApplication 之前被调用。您需要改用WillBeginSendingToApplication
    • lukech 是对的。尽管有多次投票和赏金,但这个答案是正确的,但有缺陷。我认为 Basheer_CAD 有答案,但帖子有错字。您需要检查 WillBegin... 而不是 DidEnd... 以确定用户是否选择了应用程序。
    • 谢谢@BuvinJ,请编辑答案我会批准您的编辑,谢谢
    • 我提供了一个编辑。我尽量不要改变太多!它与我现在用于 iOS 5 到 8 的类似。
    • 我认为我的编辑被拒绝了,因为它们正在消失。我不知道那是怎么回事。我没有收到任何直接通知。
    【解决方案2】:

    这将适用于 iOS7 && iOS8

    BOOL didSelectOptionFromDocumentController = NO;//**set this to "NO" every time you present your documentInteractionController too
    
    -(void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
        didSelectOptionFromDocumentController = YES;
    }
    
    
    -(void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
        if (didSelectOptionFromDocumentController == NO) {//user cancelled.
            
        }
    }
    

    【讨论】:

      【解决方案3】:

      这适用于 iOS8 和 iOS9 的 3rd 方应用程序和系统应用程序!

      它不漂亮,但它有效。

      谁能告诉我这是否会通过 App Review?不确定,因为我指的是不可公开访问的类名(_UIDocumentActivityViewController)。 这是 Swift 2.2!

      NSObject Extension 获取类名字符串:

      extension NSObject {
          var theClassName: String {
              return NSStringFromClass(self.dynamicType)
          }
      }
      

      您从中调用 UIDocumentInteractionController 的 Viewcontroller:

      var appOpened = false
      var presentedVCMonitoringTimer: NSTimer!
      var docController: UIDocumentInteractionController!
      
      func openDocController() {
          docController = UIDocumentInteractionController(URL: yourURL!)
          docController.UTI = "your.UTI"
          docController.delegate = self
          docController.presentOptionsMenuFromRect(CGRectZero, inView: self.view, animated: true)
      
          // Check the class of the presentedViewController every 2 seconds
          presentedVCMonitoringTimer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(self.checkPresentedVC), userInfo: nil, repeats: true)
      }
      
      func checkPresentedVC() {
          if let navVC = UIApplication.sharedApplication().keyWindow?.rootViewController as? UINavigationController {
              print(navVC.presentedViewController?.theClassName)
              if navVC.presentedViewController != nil && (navVC.presentedViewController?.theClassName)! != "_UIDocumentActivityViewController" && (navVC.presentedViewController?.theClassName)! != self.theClassName {
                  // A system App was chosen from the 'Open In' dialog
                  // The presented ViewController is not the DocumentInteractionController (anymore) and it's not this viewcontroller anymore (could be for example the MFMailComposeViewController if the user chose the mail app)
                  appOpened = true
                  presentedVCMonitoringTimer?.invalidate()
                  presentedVCMonitoringTimer = nil
              }
          }
      }
      
      func documentInteractionControllerDidDismissOptionsMenu(controller: UIDocumentInteractionController) {
          print("dismissedOptionsMenu")
          presentedVCMonitoringTimer?.invalidate()
          presentedVCMonitoringTimer = nil
          if appOpened {
              // Do your thing. The cancel button was not pressed
              appOpened = false
          }
          else {
              // Do your thing. The cancel button was pressed
          }
      }
      
      func documentInteractionController(controller: UIDocumentInteractionController, willBeginSendingToApplication application: String?) {
          // A third party app was chosen from the 'Open In' menu.
          appOpened = true
          presentedVCMonitoringTimer?.invalidate()
          presentedVCMonitoringTimer = nil
      }
      

      【讨论】:

        【解决方案4】:

        对于 Swift 4,使用这个:

         func documentInteractionControllerDidDismissOpenInMenu(_ controller: UIDocumentInteractionController) {
        
                // this function get called when users finish their work, 
                // either for sharing thing within the same app or exit to other app will do
         }
        

        当用户将图片分享到 Facebook 和 Instagram 后,我会使用它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多