Подтвердить что ты не робот

Внедрение протокола UIActivityItemSource

У меня есть эти методы протокола,

activityViewControllerPlaceholderItem: и activityViewController:itemForActivityType:

но они никогда не вызываются. Как я могу сказать UIActivityViewController для их вызова?

У меня также есть подкласс UIActivityItemProvider, но я смущен тем, кто называет эти 2 метода. Я действительно ценю образец кода, поскольку я не могу найти что-либо в Интернете.:)

4b9b3361

Ответ 1

Согласно документации. Массив элементов активности, которые вы передаете в
-initWithActivityItems:applicationActivities: может быть массивом объектов данных, таких как строки или изображения, или может быть массивом объектов, реализующих протокол UIActivityItemSource.

Если вы передадите массив объектов, реализующих протокол UIActivityItemSource, то ваш экземпляр UIActivityViewController вызовет эти методы в ваших элементах активности. Эти объекты необязательно должны быть подклассами UIActivityItemProvider. UIActivityItemProvider - это просто класс, соответствующий этому протоколу.

Ответ 2

Вы можете реализовать протокол везде, где хотите, даже ваш диспетчер представлений в порядке. Просто создайте экземпляр ActivityViewController с помощью initWithActivityItems:@[self].

Ответ 3

Ответ JotWee помог мне.

Нет необходимости в подклассе, методы протокола UIActivityItemSource могут быть реализованы в контроллере view, где реализована кнопка совместного доступа.

Очень важно добавить self в массив элементов активности, как это (как предлагал JotWee):

NSArray *activityItems = [NSArray arrayWithObjects:self, url, image, nil];

Вот моя окончательная реализация:

ViewController.h

@interface ViewController : UIViewController <UIActivityItemSource>

ViewController.m

- (void)shareBarButtonItemClick:(UIBarButtonItem *)sender
{
    NSURL *url = [NSURL URLWithString:@"http://example.com"];
    NSURL *imageUrl = [NSURL URLWithString:@"http://example.com/images/1.jpg"];
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];

    NSArray *activityItems = [NSArray arrayWithObjects:self, url, image, nil];

    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];

    [self presentViewController:activityViewController animated:YES completion:nil];
}

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
    return @"Summary Text";
}

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
    return @"";
}

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType
{
    return @"Subject";
}

Ответ 4

Отрываясь от того, что предоставили JotWee и Sihad Begovic, здесь версия Swift 5.0 для создания вашего ViewController принимает протокол UIActivityItemSource и использует share barButtonItem для запуска совместного использования объектов с другими приложениями на вашем iPhone (ах) и (или) iPad (s) ):

Внутри метода viewDidLoad вашего класса ViewController реализуйте следующее:

 navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareBarButtonItemClicked(_:)))

И где-то за пределами вашего метода viewDidLoad, но внутри вашего класса ViewController, давайте реализуем метод shareBarButtonItemClicked как shareBarButtonItemClicked ниже:

@objc func shareBarButtonItemClicked(_ sender: UIBarButtonItem) {
    //Here, iOS requires that you use self for your array of items 
    let items = [self]
    let activityVC = UIActivityViewController(activityItems: items, applicationActivities: nil)

    //App activities to be excluded from sharing to
    activityVC.excludedActivityTypes = [
        UIActivityType.airDrop,
        UIActivityType.print,
        UIActivityType.saveToCameraRoll,
        UIActivityType.addToReadingList
    ]

    if UIDevice.current.userInterfaceIdiom == .pad {
        if activityVC.responds(to: #selector(getter: UIViewController.popoverPresentationController)) {
            activityVC.popoverPresentationController?.barButtonItem = sender
        }
    }

    self.present(activityVC, animated: true, completion: nil)
}

Теперь здесь, где все становится интересным. Нам нужно, чтобы ваш класс ViewController соответствовал протоколу UIActivityItemSource и реализовал его обязательные методы, как UIActivityItemSource ниже:

extension ReferAFriendViewController: UIActivityItemSource {
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
    return String(describing: "Sharing my awesome app")
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
    return String(describing: "Sharing my awesome app")
}

// Now you can modify and use the same above method if you want different messages/info to be presented for different apps user selects to share with. 
// The Secret is utilizing the activityType parameter. 
// You just have to uncomment below method and swap it with above method.

/*
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
    if activityType == .postToTwitter {
    return "Download #MyAwesomeApp via @vickSwift."
    } else if activityType == .mail {
        return String(describing: "My awesome app is lit. So download it")
    } else {
        return String(describing: "Download my awesome app")
    }
}
*/

// Now note that when you share your app via a mail app, you might need to provide 'subject' line. 
// In fact, the 'UIActivityItemSource' protocol provide us an optional delegate method to accomplish just that; implemented below: 
func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivityType?) -> String {
    return String(describing: "My Awesome app email subject title")
}
}

И так вы принимаете свой класс для соответствия протоколу UIActivityItemSource и реализации его методов. Для получения дополнительной информации я считаю эту веб-статью с веб- сайта HackingWithSwift очень полезной.

Удачного кодирования!