使用 UIActivityViewController 发布,但避免裁剪?
Posting with UIActivityViewController, but avoiding cropping?
假设您构建了一张在不同设备上全屏显示的图像。然后,您可以使用 UIActivityViewController post 以正常方式 - 例如 - Instagram。
用户点击您的分享按钮,它会弹出通常的 iOS-sharing-thingy,
并且您可以 post 到 Instagram(当然假设用户是 Instagram 用户)。不用担心。
但通常图片在 Instagram 上会被裁剪 - 您会丢失一些顶部和底部。
真的有解决办法吗?
请注意,确实 - 假设您在 iPhone 上打开普通的照片应用程序,而在 Instagram 上打开 "share" 和 post ... 你输了一点顶部和底部!
当用户单击此 Instagram 图标时...
事实上,我有没有办法返回,了解用户的选择,并使图像大小合适?
有没有办法将选择的图像(各种尺寸)传递给 UIActivityViewController?
这是怎么回事,这似乎是一个基本的失败?
注意 - 我完全知道在进入 iOS-share-thingy 之前,我可以自己询问用户 "What size image would you like me to make?"
注意 - 我知道在某些情况下可以 post "directly" 在应用程序中说 Instagram,而无需使用 Apple 的共享系统;不过这很蹩脚。
为了节省任何人的打字时间,这里有一些干净的代码可以调出 iOS-共享系统...
@IBAction func userClickedOurShareButton()
{
let s:[AnyObject] = [buildImage()]
let ac = CleanerActivity(activityItems:s, applicationActivities:nil)
ac.popoverPresentationController?.sourceView = view
// needed so that iPads won't crash. sarcasm: thanks Apple
ac.excludedActivityTypes = [UIActivityType.assignToContact,
UIActivityType.saveToCameraRoll,
UIActivityType.addToReadingList,
UIActivityType.copyToPasteboard ]
// consider UIActivityTypeMessage also
if #available(iOS 9.0, *) {
ac.excludedActivityTypes?.append(UIActivityType.openInIBooks)
} else {
// Fallback on earlier versions
}
self.present(ac, animated:false, completion:nil)
}
class CleanerActivity: UIActivityViewController {
func _shouldExcludeActivityType(_ activity: UIActivity) -> Bool {
let activityTypesToExclude = [
"com.apple.reminders.RemindersEditorExtension",
"com.apple.mobilenotes.SharingExtension",
"com.google.Drive.ShareExtension",
"com.apple.mobileslideshow.StreamShareService"
]
if let actType = activity.activityType {
if activityTypesToExclude.contains(actType.rawValue) {
return true
}
else if super.excludedActivityTypes != nil {
return super.excludedActivityTypes!.contains(actType)
}
}
return false
}
免责声明:此解决方案涉及将 Instagram 的扩展标识符硬编码到您的应用程序中,这可能会也可能不会通过应用程序审查,并且将来可能会崩溃。尝试风险自负!
Apple 为此提供了一种称为 UIActivityItemProvider
的机制。您可以将覆盖 itemForActivityType
的 UIActivityItemProvider
的子类传递给 return,而不是将图像传递给您的 UIActivityViewController
,一个基于 activity 选择的类型的适当图像用户。
Apple 为许多常见的 activity 类型提供常量,但尚未包括 Instagram。您可以通过检查 activity 类型的原始值是否为 com.burbn.instagram.shareextension
来识别 Instagram。如果 Instagram 更改其扩展程序的 ID,这将中断。
这里有一个 UIActivityItemProvider
为 Instagram 提供不同的图像:
class DynamicImageProvider: UIActivityItemProvider {
let instagramImage: UIImage
let defaultImage: UIImage
init(instagramImage: UIImage, defaultImage: UIImage) {
self.instagramImage = instagramImage
self.defaultImage = defaultImage
super.init(placeholderItem: defaultImage)
}
override func activityViewController(_ activityViewController: UIActivityViewController,
itemForActivityType activityType: UIActivityType) -> Any? {
if activityType.rawValue == "com.burbn.instagram.shareextension" {
return instagramImage
}
else {
return defaultImage
}
}
}
然后更改 IBAction 的前两行:
let imageProvider = DynamicImageProvider(instagramImage:buildInstagramImage(), defaultImage:buildImage())
let ac = CleanerActivity(activityItems:[imageProvider], applicationActivities:nil)
假设您构建了一张在不同设备上全屏显示的图像。然后,您可以使用 UIActivityViewController post 以正常方式 - 例如 - Instagram。
用户点击您的分享按钮,它会弹出通常的 iOS-sharing-thingy,
并且您可以 post 到 Instagram(当然假设用户是 Instagram 用户)。不用担心。
但通常图片在 Instagram 上会被裁剪 - 您会丢失一些顶部和底部。
真的有解决办法吗?
请注意,确实 - 假设您在 iPhone 上打开普通的照片应用程序,而在 Instagram 上打开 "share" 和 post ... 你输了一点顶部和底部!
当用户单击此 Instagram 图标时...
事实上,我有没有办法返回,了解用户的选择,并使图像大小合适?
有没有办法将选择的图像(各种尺寸)传递给 UIActivityViewController?
这是怎么回事,这似乎是一个基本的失败?
注意 - 我完全知道在进入 iOS-share-thingy 之前,我可以自己询问用户 "What size image would you like me to make?"
注意 - 我知道在某些情况下可以 post "directly" 在应用程序中说 Instagram,而无需使用 Apple 的共享系统;不过这很蹩脚。
为了节省任何人的打字时间,这里有一些干净的代码可以调出 iOS-共享系统...
@IBAction func userClickedOurShareButton()
{
let s:[AnyObject] = [buildImage()]
let ac = CleanerActivity(activityItems:s, applicationActivities:nil)
ac.popoverPresentationController?.sourceView = view
// needed so that iPads won't crash. sarcasm: thanks Apple
ac.excludedActivityTypes = [UIActivityType.assignToContact,
UIActivityType.saveToCameraRoll,
UIActivityType.addToReadingList,
UIActivityType.copyToPasteboard ]
// consider UIActivityTypeMessage also
if #available(iOS 9.0, *) {
ac.excludedActivityTypes?.append(UIActivityType.openInIBooks)
} else {
// Fallback on earlier versions
}
self.present(ac, animated:false, completion:nil)
}
class CleanerActivity: UIActivityViewController {
func _shouldExcludeActivityType(_ activity: UIActivity) -> Bool {
let activityTypesToExclude = [
"com.apple.reminders.RemindersEditorExtension",
"com.apple.mobilenotes.SharingExtension",
"com.google.Drive.ShareExtension",
"com.apple.mobileslideshow.StreamShareService"
]
if let actType = activity.activityType {
if activityTypesToExclude.contains(actType.rawValue) {
return true
}
else if super.excludedActivityTypes != nil {
return super.excludedActivityTypes!.contains(actType)
}
}
return false
}
免责声明:此解决方案涉及将 Instagram 的扩展标识符硬编码到您的应用程序中,这可能会也可能不会通过应用程序审查,并且将来可能会崩溃。尝试风险自负!
Apple 为此提供了一种称为 UIActivityItemProvider
的机制。您可以将覆盖 itemForActivityType
的 UIActivityItemProvider
的子类传递给 return,而不是将图像传递给您的 UIActivityViewController
,一个基于 activity 选择的类型的适当图像用户。
Apple 为许多常见的 activity 类型提供常量,但尚未包括 Instagram。您可以通过检查 activity 类型的原始值是否为 com.burbn.instagram.shareextension
来识别 Instagram。如果 Instagram 更改其扩展程序的 ID,这将中断。
这里有一个 UIActivityItemProvider
为 Instagram 提供不同的图像:
class DynamicImageProvider: UIActivityItemProvider {
let instagramImage: UIImage
let defaultImage: UIImage
init(instagramImage: UIImage, defaultImage: UIImage) {
self.instagramImage = instagramImage
self.defaultImage = defaultImage
super.init(placeholderItem: defaultImage)
}
override func activityViewController(_ activityViewController: UIActivityViewController,
itemForActivityType activityType: UIActivityType) -> Any? {
if activityType.rawValue == "com.burbn.instagram.shareextension" {
return instagramImage
}
else {
return defaultImage
}
}
}
然后更改 IBAction 的前两行:
let imageProvider = DynamicImageProvider(instagramImage:buildInstagramImage(), defaultImage:buildImage())
let ac = CleanerActivity(activityItems:[imageProvider], applicationActivities:nil)