与自定义类而不是 SLComposeServiceViewController 共享扩展

Posted

技术标签:

【中文标题】与自定义类而不是 SLComposeServiceViewController 共享扩展【英文标题】:Share extension with custom class instead of SLComposeServiceViewController 【发布时间】:2018-07-17 13:20:24 【问题描述】:

我目前正在使用共享扩展功能。

当我在这里搜索很多时,似乎总是使用 SLComposeServiceViewController 将带有一些文本内容的图像共享给特定的应用程序。

但我希望自定义 UIViewController 类加载从照片应用程序中选择的图像,在打开 mail extension on share sheet 时它与邮件编辑器一样。

所以我得到了这个示例,并按照下面的 git hub 链接(第二个)中的说明进行操作:

https://martinnormark.com/present-ios-8-share-extension-as-modal-view/ https://github.com/martinnormark/ShareByMail

是的,似乎4 years ago 如此迁移并转换为Swift 4.1 版本。在我修改了这些更改并调试它之后。它不像在 GitHub gif 上那样工作。是的,最初时,当我在共享表上触摸扩展应用程序时,我可以呈现和关闭控制器。但是在我解散并再次尝试呈现它之后,这一次它在 GitHub gif 上没有反应。

Martin 只显示和隐藏self.view of UINavigationController Y position value。一旦我按下了Cancel or save 栏按钮,然后我尝试通过共享表上的扩展触摸打开它,它不起作用,也没有反应。

这里是NSExtensionPrincipalClass - EntryViewController的来源

import UIKit  

@objc(EntryViewController)


class EntryViewController : UINavigationController 

init() 
    super.init(rootViewController: ShareViewController())


required init(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)!


override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) 
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    self.view.transform = CGAffineTransform(translationX: 0, y: self.view.frame.size.height)

    UIView.animate(withDuration: 0.25, animations:  () -> Void in
        self.view.transform = CGAffineTransform.identity
    , completion: nil)



import UIKit
import Social

class ShareViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()

    self.view.backgroundColor = .white
    self.navigationItem.title = "Share this"

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelButtonTapped(_:)))
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(self.saveButtonTapped(_:)))


@objc func saveButtonTapped(_ sender: UIBarButtonItem) 
    self.hideExtensionWithCompletionHandler(completion:  (Bool) -> Void in
        self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil)
    )


@objc func cancelButtonTapped(_ sender: UIBarButtonItem) 
    self.hideExtensionWithCompletionHandler(completion:  (Bool) -> Void in
        self.extensionContext!.cancelRequest(withError: NSError())
    )


func hideExtensionWithCompletionHandler(completion:(Bool) -> Void) 

    UIView.animate(withDuration: 0.20, animations:  () -> Void in
        self.navigationController!.view.transform = CGAffineTransform(translationX: 0, y: self.navigationController!.view.frame.size.height)
    , completion: nil)


如何查找和修复上述尝试中的问题或如何进行自定义 UIViewController 布局而不是使用SLComposeServiceViewController

【问题讨论】:

你为什么使用 'UINavigationController' ?有来自“ShareViewController”的推送吗? @KaushikMakwana 我按照此链接上的说明进行操作 - martinnormark.com/present-ios-8-share-extension-as-modal-view 您可以在此文本下查看使用 UINavigationController 的原因 伪造模态演示 不需要使用'UINavigationController',你可以直接使用'ShareViewController',很简单,你想在storyboard上设计什么布局。 @KaushikMakwana 为什么是storyboard?无法以编程方式设计自定义布局? 是的,您也可以通过编程方式设计它 【参考方案1】:

在您的视图控制器上(按钮操作方法)

目标 C

当你完成你的过程时调用它

[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];

当您/用户取消您的流程时调用它

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil];
[self.extensionContext cancelRequestWithError:error];

斯威夫特

当你完成你的过程时调用它

self.extensionContext?.completeRequestReturningItems([], completionHandler:nil)

当您/用户取消您的流程时调用它

let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
self.extensionContext!.cancelRequestWithError(cancelError)

如果您有任何 API 错误

self.extensionContext!.cancelRequestWithError(error as NSError)

更新

在您的代码中,您没有在此方法 hideExtensionWithCompletionHandler 处调用完成处理程序

func hideExtensionWithCompletionHandler(completion:@escaping (Bool) -> Void) 
    UIView.animate(withDuration: 0.20, animations:  () -> Void in
        self.navigationController!.view.transform = CGAffineTransform(translationX: 0, y: self.navigationController!.view.frame.size.height)
    , completion:  (_) -> Void in
        completion(true)
    )

【讨论】:

以上是关于与自定义类而不是 SLComposeServiceViewController 共享扩展的主要内容,如果未能解决你的问题,请参考以下文章

我可以为类而不是实例定义 __repr__ 吗? [复制]

SailsJs websocket与自定义路线而不是蓝图?

如何将 PropertyDescriptors 添加到类而不是覆盖它们?

如何使用来自目标c的同名类而不是swift

Android CollapsingToolbarLayout 与自定义视图

Flutter ReorderableListView 与自定义对象