首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何取消UIActivityItemProvider而不显示活动?

如何取消UIActivityItemProvider而不显示活动?
EN

Stack Overflow用户
提问于 2014-02-26 17:59:03
回答 2查看 867关注 0票数 9

我使用UIActivityItemProvider子类来提供自定义数据。但有时获取数据会失败,我不想展示活动(例如message composer)。尝试了item方法中的[self cancel]return nil;,但message composer仍然显示(消息为空)。

EN

回答 2

Stack Overflow用户

发布于 2016-02-29 10:28:21

如果您在从-(Id)项返回之前关闭UIActivityViewController,它将不会显示用户选择的活动。

为此,您首先需要获取activityViewControllerPlaceholderItem中的activityViewController。在-(Id)项中,在dispatch_async中运行代码以更新进度,并在完成/错误时清除,这是我使用promise库所做的。

在您的UIActivityItemProvider子类中,执行类似于下面的示例的操作。

代码语言:javascript
复制
-(id) activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{ self.avc = activityViewController;
  return NSURL;
}

-(id)item
{ __block BOOL fileProcDone = NO;
  dispatch_async(dispatch_get_main_queue(), ^
  { self.pvc = [[ProgressAlertVC alloc] init];
    [self.vc presentViewController:self.pvc animated:YES completion:nil];
    [[[[self promiseMakeFile]
    progressed:^(float progress)
    { self.pvc.progress = progress;
    }]
    fulfilled:^(id result)
    { [self.pvc dismissViewControllerAnimated:YES completion:^
      { fileProcDone = YES;
      }];
    }]
    failed:^(NSError *error)
    { [self.pvc dismissViewControllerAnimated:YES completion:^
      { [self.vc dismissViewControllerAnimated:YES completion:^
        { fileProcDone = YES;
        }];
      }];
    }];
  });
  while (!fileProcDone)
  { [NSThread sleepForTimeInterval:0.1];
  }; 
  return NSURL;
}

这将导致来自activity扩展的控制台日志消息,但只要它们正确处理错误,事情就会好起来。如果从-(id)activityViewController: itemForActivityType:返回nil,则不会收到控制台错误,但即使此时关闭UIActivityViewController,也会得到用户选择的活动。

票数 5
EN

Stack Overflow用户

发布于 2016-11-02 09:20:06

您只需调用UIActivityItemProvider的cancel方法。因为UIActivityItemProvider是一个NSOperation,所以调用cancel会将操作标记为已取消。

在这一点上,您有几个选项来实际停止长时间运行的任务,具体取决于任务的结构。您可以覆盖cancel方法并在那里执行取消操作,只需确保也调用[super cancel]即可。第二个选项是在item方法中检查isCancelled的值。

一个示例项目提供程序

代码语言:javascript
复制
import UIKit
import Dispatch

class ItemProvider: UIActivityItemProvider {

    override public var item: Any {
        let semaphore = DispatchSemaphore(value: 0)

        let message = "This will stop the entire share flow until you press OK. It represents a long running task."
        let alert = UIAlertController.init(title: "Hello", message: message, preferredStyle: .alert)
        let action = UIAlertAction.init(title: "OK", style: .default, handler:
            { action in
                semaphore.signal()
        })
        let cancel = UIAlertAction.init(title: "CANCEL", style: .destructive, handler:
            { [weak self] action in
                self?.cancel()
                semaphore.signal()
        })

        alert.addAction(action)
        alert.addAction(cancel)

        //Truly, some hacking to for the purpose of demonstrating the solution
        DispatchQueue.main.async {
            UIApplication.shared.delegate?.window??.rootViewController?.presentedViewController!.present(alert, animated: true, completion: nil)
        }

        // We can block here, because our long running task is in another queue
        semaphore.wait()

        // Once the item is properly cancelled, it doesn't really matter what you return
        return NSURL.init(string: "blah") as Any
    }
}

在视图控制器中,像这样启动一个共享活动。

代码语言:javascript
复制
    let provider = ItemProvider.init(placeholderItem: "SomeString")
    let vc = UIActivityViewController.init(activityItems: [provider], applicationActivities: nil)

    self.present(vc, animated: true, completion: nil)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22037814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档