How to Integrate Uiactivityviewcontroller with Swiftui's Scrollview

How to integrate UIActivityViewController with SwiftUI's ScrollView?

Here is the approach that works (tested with Xcode 11.2/iOS 13.2)... The extra wrapper host controller is not needed, and it is better to use native SwiftUI instruments for presentation.

import SwiftUI

struct ActivityView: UIViewControllerRepresentable {
var url: String
@Binding var showing: Bool

func makeUIViewController(context: Context) -> UIActivityViewController {
let vc = UIActivityViewController(
activityItems: [NSURL(string: url)!],
applicationActivities: nil
)
vc.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
self.showing = false
}
return vc
}

func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
}
}

struct TestUIActivityView: View {
@State var showSheet = false

var body: some View {
ScrollView {
Group {
Button(action: {
self.showSheet.toggle()
}) {
Text("Open Activity View")
}
.sheet(isPresented: $showSheet) {
ActivityView(url: "https://www.wikipedia.org", showing: self.$showSheet)
}
}
}
}
}

struct TestUIActivityView_Previews: PreviewProvider {
static var previews: some View {
TestUIActivityView()
}
}

How to interpret VStack{ .. } from SwiftUI's official tutorial code?

If you look at the docs for VStack.init, you'll see that the last argument it accepts is indeed a closure. The magic here is that the closure is marked with @ViewBuilder.

@ViewBuilder is a kind of function builder. The idea is that you pass in a closure containing a bunch of expressions, and then the function builder will combine those expressions into a single value. It's kind of like returning an array, but in an arguably better-looking syntax. (it's not really an array though. The return type of the closure is decided by the function builder.)

In your code, you are returning an "array" of 4 views.

  1. MapView
  2. CircleImage
  3. another VStack
  4. Spacer

These will get passed to the ViewBuilder, and it combines all of them into a single View object.

And if you are wondering what the methods called on at the end of each view are doing, they are just methods that return slight modifications of the objects on which they are called. For example padding returns the same view, but with some padding applied.

SwiftUI - Half modal?

iOS 16+

It looks like half sheet is finally supported in iOS 16.

To manage the size of sheet we can use PresentationDetent and specifically presentationDetents(_:selection:)

Here's an example from the documentation:

struct ContentView: View {
@State private var showSettings = false
@State private var settingsDetent = PresentationDetent.medium

var body: some View {
Button("View Settings") {
showSettings = true
}
.sheet(isPresented: $showSettings) {
SettingsView()
.presentationDetents:(
[.medium, .large],
selection: $settingsDetent
)
}
}
}

Note that if you provide more that one detent, people can drag the sheet to resize it.

Here are possible values for PresentationDetent:

  • large
  • medium
  • fraction(CGFloat)
  • height(CGFloat)
  • custom<D>(D.Type)


Related Topics



Leave a reply



Submit