Внедрение протокола UIActivityItemSource
У меня есть эти методы протокола,
activityViewControllerPlaceholderItem:
и activityViewController:itemForActivityType:
но они никогда не вызываются. Как я могу сказать UIActivityViewController
для их вызова?
У меня также есть подкласс UIActivityItemProvider
, но я смущен тем, кто называет эти 2 метода. Я действительно ценю образец кода, поскольку я не могу найти что-либо в Интернете.:)
Ответы
Ответ 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 очень полезной.
Удачного кодирования!