Last active
April 11, 2024 05:06
-
-
Save andrew-levy/6bada5b2f39311a87e48978c3c89d6f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ExpoModulesCore | |
import UIKit | |
import SwiftUI | |
import React | |
class SwiftuiView: ExpoView { | |
var name = "" { | |
didSet { | |
updateView(withName: name, withOptions: options) | |
} | |
} | |
var options: [String] = [] { | |
didSet { | |
updateView(withName: name, withOptions: options) | |
} | |
} | |
let hostingController = UIHostingController(rootView: MySwiftUIView()) | |
required init(appContext: AppContext? = nil) { | |
super.init(appContext: appContext) | |
hostingController.view.translatesAutoresizingMaskIntoConstraints = false | |
addSubview(hostingController.view) | |
NSLayoutConstraint.activate([ | |
hostingController.view.topAnchor.constraint(equalTo: self.topAnchor), | |
hostingController.view.bottomAnchor.constraint(equalTo: self.bottomAnchor), | |
hostingController.view.leftAnchor.constraint(equalTo: self.leftAnchor), | |
hostingController.view.rightAnchor.constraint(equalTo: self.rightAnchor) | |
]) | |
} | |
// Update the hosting controller's root view with updated prop values | |
func updateView(withName name: String, withOptions options: [String]) { | |
hostingController.rootView = MySwiftUIView(name: name, options: options) | |
} | |
} | |
struct MySwiftUIView: View { | |
var name = "" | |
var options: [String] = [] | |
@State var isOpen = false | |
@State var picker = 0 | |
@State var slider = 50.0 | |
@State var isScaled = false | |
var body: some View { | |
NavigationView { | |
if #available(iOS 14.0, *) { | |
ScrollView { | |
VStack(spacing: 20) { | |
Text("SwiftUI + Expo!") | |
.font(.largeTitle) | |
.scaleEffect(isScaled ? 1.5 : 1.0) | |
.foregroundColor(isScaled ? .purple : .black) | |
Button("Animations work too!") { | |
withAnimation { | |
isScaled.toggle() | |
} | |
} | |
NavigationLink("To Details") { | |
Text("Details") | |
} | |
Picker("Picker", selection: $picker, content: { | |
ForEach(Array(options.enumerated()), id: \.1) { index, option in | |
Text(option) | |
.tag(index) | |
} | |
}).pickerStyle(.segmented) | |
if #available(iOS 16.0, *) { | |
Button("Toggle Sheet") { | |
isOpen.toggle() | |
}.sheet(isPresented: $isOpen) { | |
Text("Sheet content") | |
.presentationDetents([.medium, .large]) | |
}.padding(.bottom, 100) | |
} | |
} | |
}.navigationTitle(Text("Home")) | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ExpoModulesCore | |
import SwiftUI | |
public class SwiftuiViewModule: Module { | |
public func definition() -> ModuleDefinition { | |
Name("SwiftuiForm") | |
View(SwiftuiView.self) { | |
Prop("name") { (view, name: String) in | |
view.name = name | |
} | |
Prop("options") { (view, options: [String]) in | |
view.options = options | |
} | |
} | |
} | |
} |
@nandorojo Thanks. I tried doing this, but I get this runtime error. I'm probably missing something small
"Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600002d1cac0 \"UIView:0x130c1a0a0.top\"> and <NSLayoutYAxisAnchor:0x600002d1f880 \"SwiftuiForm.SwiftuiView:0x124d6c650.top\"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal."
Hmm I see yeah it probably needs a different approach since it’s a VC (I don’t know much about Swift). I wonder if there’s a way to make it stretch the bounds there
@nandorojo This actually worked. Just needed to call addSubview(vc.view)
before setting the constraints. Thanks again!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could this just stretch the bounds of
ExpoView
, since the Expo view is controlled by thestyle
prop? Maybe like this?