SwiftUI:在菜单中呈现多个 ShareLink

Dan*_*iel 8 menu ios swift swiftui

我想展示具有多个选项的共享菜单。我创建了一个菜单并添加了所有 ShareLink 视图。我可以点击共享按钮,但如果我选择共享链接,则不会发生任何情况。没有错误消息。

这是我能想到的创建这样一个“共享菜单”的唯一方法:

ToolbarItemGroup(placement: SwiftUI.ToolbarItemPlacement.navigationBarTrailing) {

    Menu {
          ShareLink(
               item: URL(string: "https://www.apple.com")!,
               preview: SharePreview(
                   "Test 123",
                    image: Image(systemName: "plus")
                    )
                )
               ShareLink(
                    item: URL(string: "https://www.microsoft.com")!,
                    preview: SharePreview(
                        "Tests 321",
                         image: Image(systemName: "minus")
                    )
                )

        } label: {
               Image(systemName: "square.and.arrow.up")
        }
}
Run Code Online (Sandbox Code Playgroud)

截屏

man*_*ani 6

ShareLink菜单内当前不起作用。从技术上讲,菜单是UIContextMenuActionsOnlyViewController显示在活动窗口上的新视图控制器 ( )。共享操作表需要一个视图控制器来呈现。当点击 aShareLink内部的 aMenu时,它会关闭菜单 VC 以及共享操作表。您可以通过在菜单打开时检查视图层次结构来验证这一点。

一种解决方法是手动创建 Button/MenuItem/s 并在基础视图中点击按钮时显示共享操作表;这避免了直接使用 ShareLink。

解决方法:

...
ToolbarItemGroup(placement: SwiftUI.ToolbarItemPlacement.navigationBarTrailing) {
  Menu {
    Button(action: {
      showShareSheet(url: URL("https://www.apple.com")!)
    }) {
      Label("Share1", systemImage: "square.and.arrow.up")
    }
    Button(action: {
      showShareSheet(url: URL(string: "https://www.microsoft.com")!)
    }) {
      Label("Share2", systemImage: "square.and.arrow.up")
    }
  } label: {
    Image(systemName: "square.and.arrow.up")
  }
}
...

// UIActivityViewController can be customised. 
// For examples, see https://www.hackingwithswift.com/articles/118/uiactivityviewcontroller-by-example
func showShareSheet(url: URL) {
  let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: nil)
  UIApplication.shared.currentUIWindow()?.rootViewController?.present(activityVC, animated: true, completion: nil)
}

// utility extension to easily get the window 
public extension UIApplication {
    func currentUIWindow() -> UIWindow? {
        let connectedScenes = UIApplication.shared.connectedScenes
            .filter { $0.activationState == .foregroundActive }
            .compactMap { $0 as? UIWindowScene }
        
        let window = connectedScenes.first?
            .windows
            .first { $0.isKeyWindow }

        return window
        
    }
}

Run Code Online (Sandbox Code Playgroud)