如果用户按下取消,UIActivityViewController 完成处理程序仍会调用操作

Posted

技术标签:

【中文标题】如果用户按下取消,UIActivityViewController 完成处理程序仍会调用操作【英文标题】:UIActivityViewController completion handler still calls action if user presses cancel 【发布时间】:2014-02-28 00:42:05 【问题描述】:

在我的 UIActivityViewController 中,我使用完成处理程序来执行“成功共享”通知。它可以工作,但我唯一的问题是,如果用户按下取消,它仍然会显示通知。

这是我的完成处理程序代码,

[controller setCompletionHandler:^(NSString *activityType, BOOL completed) 


    CWStatusBarNotification *notification = [CWStatusBarNotification new];
    [notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
                                          forDuration:3.0f];

    notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
    notification.notificationLabelTextColor = [UIColor whiteColor];



];

感谢您的帮助!

【问题讨论】:

建议:不要显示“共享成功”通知。这可能很烦人。 我的设计师想要它,我不同意,但他是负责人:/ 【参考方案1】:

注意:completionHandler 属性在 ios8 中已被弃用,因此无法再知道共享操作的结果。 https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622010-completionhandler

更新: 就像 adruzh 说的,在 iOS8 上有一个新的 completionHandler,Apple 忘记在文档中提到了:

[activityController setCompletionWithItemsHandler:
    ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) 
];

https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622022-completionwithitemshandler

【讨论】:

看起来像文档中的一个错误 - 有一个新的处理程序,它在 UIKit 更改中被引用【参考方案2】:

这就是 completed 参数的用途:

[controller setCompletionHandler:^(NSString *activityType, BOOL completed) 
    if (!completed) return;

    CWStatusBarNotification *notification = [CWStatusBarNotification new];
    [notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
                                     forDuration:3.0f];

    notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
    notification.notificationLabelTextColor = [UIColor whiteColor];
];

【讨论】:

【参考方案3】:

对于 Swift,这对我们有用:

    ...

    // Configure UIActivityViewController
    let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityViewController.excludedActivityTypes = [UIActivityTypeAirDrop,
        UIActivityTypeAddToReadingList,
        UIActivityTypeAssignToContact,
        UIActivityTypePrint,
        UIActivityTypeCopyToPasteboard]

    // Show UIActivityViewController
    presentViewController(activityViewController, animated: true, completion: nil)

    // Define completion handler
    activityViewController.completionWithItemsHandler = doneSharingHandler

    ...

func doneSharingHandler(activityType: String!, completed: Bool, returnedItems: [AnyObject]!, error: NSError!) 
    // Return if cancelled
    if (!completed) 
        return
    

    // If here, log which activity occurred
    println("Shared video activity: \(activityType)")

【讨论】:

【参考方案4】:

Swift 5 - 下面的函数涵盖了大部分 UIActivityViewController 属性。它对我有用,并认为它可能对你们也有帮助。

func performShareAction() 
        let itemsToShare : [Any] = ["Hello World"]
        let activityView = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
        
        // Apps that you want to exclude sharing the items
        let excludedActivityTypes : [UIActivity.ActivityType] = [
            .addToReadingList,
            .assignToContact,
            .copyToPasteboard,
            .mail,
            .markupAsPDF,
            .message,
            .openInIBooks,
            .postToFacebook,
            .postToFlickr,
            .postToTencentWeibo,
            .postToTwitter,
            .postToVimeo,
            .postToWeibo,
            .print,
            .saveToCameraRoll
        ]

        activityView.excludedActivityTypes = excludedActivityTypes
        self.present(activityView, animated: true, completion: nil)
        
        activityView.completionWithItemsHandler =  activityType, completed, items, error in
            
            // Event Cancelled
            if !completed 
                print("Content Sharing was cancelled.")
                return
            
            
            // Content Shared on particular activity
            print("Shared on activity type: \(String(describing: activityType?.rawValue))")
            
            // Detect app on which the items are shared
            if let type = activityType 
                switch type 
                case .addToReadingList: print("Added To Reading List"); break
                case .airDrop: print("AirDropped to Other Device"); break
                case .assignToContact: print("Assigned To Contact"); break
                case .copyToPasteboard: print("Copied To Pasteboard"); break
                case .mail: print("Mailed"); break
                case .markupAsPDF: print("Marked-Up As PDF"); break
                case .message: print("Messaged"); break
                case .openInIBooks: print("Opened In iBooks"); break
                case .postToFacebook: print("Posted To Facebook"); break
                case .postToFlickr: print("Posted To Flickr"); break
                case .postToTencentWeibo: print("Posted To Tencent Weibo"); break
                case .postToTwitter: print("Posted To Twitter"); break
                case .postToVimeo: print("Posted To Vimeo"); break
                case .postToWeibo: print("Posted To Weibo"); break
                case .print: print("Printed"); break
                case .saveToCameraRoll: print("Saved To Camera Roll"); break
                default: print("Shared with new app"); break
                
            
        
    

【讨论】:

【参考方案5】:

对于现有的 Swifties,以下是在 Swift 中编写代码以及一些共享服务检测的方法:

activityViewController.completionHandler = (activityType, completed:Bool) in
    if !completed 
        //cancelled
        return
    

    //shared successfully

    //below is how you would detect for different sharing services
    var activity:String = "other"
    if activityType == UIActivityTypePostToTwitter 
        activity = "twitter"
    
    if activityType == UIActivityTypeMail 
        activity = "mail"
    
    //more code here if you like

【讨论】:

completionHandler 在 iOS 8 中已弃用。对于 iOS 8,请使用 completionWithItemsHandler【参考方案6】:

completed 参数将是NO 是用户取消。

[controller setCompletionHandler:^(NSString *activityType, BOOL completed) 
    if (completed) 
        CWStatusBarNotification *notification = [CWStatusBarNotification new];
        [notification displayNotificationWithMessage:@"✓ Successfully Shared Centre!"
                                          forDuration:3.0f];

        notification.notificationLabelBackgroundColor = [UIColor colorWithRed:38.0f/255.0f green:81.0f/255.0f blue:123.0f/255.0f alpha:1.0f];
        notification.notificationLabelTextColor = [UIColor whiteColor];
    
];

【讨论】:

【参考方案7】:

SWIFT 2.0, iOS 8.0 >,你应该像这样使用完成处理程序:

self.presentViewController(activityVC, animated: true, completion: nil)

activityVC.completionWithItemsHandler = (activityType, completed:Bool, returnedItems:[AnyObject]?, error: NSError?) in
     //do some action

在这里查看我的答案:https://***.com/a/34581940/1109892

【讨论】:

【参考方案8】:

斯威夫特 3

   func completionHandler(activityType: UIActivityType?, shared: Bool, items: [Any]?, error: Error?) 
        if (shared) 
            print("Cool user shared some stuff")
        
        else 
            print("Bad user canceled sharing :(")
        
    

    activityController.completionWithItemsHandler = completionHandler

【讨论】:

以上是关于如果用户按下取消,UIActivityViewController 完成处理程序仍会调用操作的主要内容,如果未能解决你的问题,请参考以下文章

了解用户在应用内购买期间何时按下了取消按钮

检测在 VB6 输入框中按下的取消

当用户按下其他控件/空格时,如何取消对UITextField的聚焦?

当用户在文本框中按下返回时,我可以取消回发吗?

VB SaveFileDialog 如果取消则

vba inputBox:如何用空文本框区分“取消”和“确定”之间的区别