我正在 swiftUI 中编码,我正在尝试创建一个按钮,该按钮首先生成新图像,然后打开一个可以共享新图像的 ShareSheet。但是,对于下面的代码,仅共享描述。有人可以帮我解决问题吗?
import SwiftUI
import UIKit
struct ShareSheetViewTESTER: UIViewControllerRepresentable {
var imageToShare: UIImage
var descriptionToShare: String
var itemsToShare: [Any] {
return [imageToShare, descriptionToShare]
}
func makeUIViewController(context: Context) -> UIActivityViewController {
let activityVC = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
return activityVC
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
}
}
struct FriendsView: View {
@State private var showShareSheet = false
@State private var image = UIImage(named: "Kort")!
@State private var description = "Some text here"
@State private var generatedImage: UIImage?
var body: some View {
VStack {
Button(action: {
generateImage()
self.showShareSheet = true
}) {
Image(systemName: "square.and.arrow.up")
.frame(width: 25, height: 25)
}
.sheet(isPresented: $showShareSheet) {
ShareSheetViewTESTER(imageToShare: generatedImage ?? self.image, descriptionToShare: self.description)
}
}
}
func generateImage() {
if let imageFromBundle = UIImage(named: "Kort") {
let textToOverlay = "Text to be put on the photo"
let imageRenderer = UIGraphicsImageRenderer(size: imageFromBundle.size)
let generatedImage = imageRenderer.image { context in
imageFromBundle.draw(at: .zero)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byWordWrapping
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 20),
.foregroundColor: UIColor.black,
.paragraphStyle: paragraphStyle
]
let textNSString = textToOverlay as NSString
let textSize = textNSString.boundingRect(with: CGSize(width: imageFromBundle.size.width, height: .greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: attributes, context: nil).size
let textRect = CGRect(x: 0, y: 170, width: imageFromBundle.size.width, height: textSize.height)
textNSString.draw(in: textRect, withAttributes: attributes)
}
self.generatedImage = generatedImage
}
}
}
struct FriendsView_Previews: PreviewProvider {
static var previews: some View {
FriendsView()
}
}
我尝试了其他几种解决方案,但没有任何效果。如果有人能在这里帮助我,我会非常高兴。
图像和描述似乎已正确共享(例如,在 SwiftUI 预览中保存到文件时),但共享表中的预览不包含共享图像。此问题的出现是由于
UIActivityViewController
管理共享项目的呈现方式所致。为了保证共享内容在共享表预览中准确显示,可以实现一个符合UIActivityItemSource
协议的自定义类。这种方法增强了对共享内容及其元数据的控制。
这是一个完善的解决方案:
import UIKit
import LinkPresentation
// Custom class representing the item to be shared
final class ActivityItem: NSObject {
let name: String
let image: UIImage
init(name: String, image: UIImage) {
self.name = name
self.image = image
}
}
// Conforming to UIActivityItemSource for customized sharing
extension ActivityItem: UIActivityItemSource {
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return image
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return image
}
// Providing metadata for link presentation
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let metaData = LPLinkMetadata()
metaData.title = name
metaData.imageProvider = NSItemProvider(object: image)
return metaData
}
}
调整
itemsToShare
中的 ShareSheetViewTESTER
属性以包含 ActivityItem
的实例:
var itemsToShare: [Any] {
[ActivityItem(name: descriptionToShare, image: imageToShare), descriptionToShare]
}
此修改可确保
UIActivityViewController
接收的图像格式能够正确处理以在共享表中共享和预览,同时保持在文件保存场景中观察到的正确共享功能。