I try to create a Facebook button but when I call it in the VStack it says: 'Referencing initializer 'init(alignment:spacing:content:)' on 'VStack' requires that 'FBLoginButton' conform to 'View'', So why isn't it working because FBLoginButton is a button after all.
here's the code:
struct ContentView: View {
var body: some View {
VStack(alignment: .center) {
FBLoginButton(frame: CGRectMake(0, 0, 100, 100), permissions: ["email"])
}
}
}
First of all needs to create class which implements UIViewRepresentable protocol.
import FBSDKLoginKit
import SwiftUI
struct FacebookLoginButton: UIViewRepresentable {
typealias UIViewType = FBLoginButton
func makeUIView(context: Context) -> UIViewType {
FBLoginButton()
}
func updateUIView(_ uiView: FBLoginButton, context: Context) { }
}
After all this FacebookLoginButton can be used in SwiftUI like this:
var body: some View {
FacebookLoginButton()
}
Facebook SDK still uses UIKit, and FBLoginButton is UIView from UIKit, not View" from SwiftUI.
You need to use loginmanger which does most of the work and embed it inside swiftui Button.
Check link below which will be helpful.
https://gist.github.com/zydeico/8bb9c772e944d1490335e1615aaf4960
Related
I have an iOS app which needs to capture user's signature
UI should be like this
I tried this using pencilKit as follows but,
It shows all the tools I don't need them to be visible
SwiftUIView
struct HandSignatureView: View {
var body: some View {
VStack {
Text("Place Your Signature Here")
.font(.title2)
.foregroundColor(.blue)
SignaturePadView()
}
.preferredColorScheme(.light)
}
}
UIViewRepresentable
struct SignaturePadView : UIViewRepresentable {
var canvasView = PKCanvasView()
let picker = PKToolPicker.init()
func makeUIView(context: Context) -> PKCanvasView {
self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
self.canvasView.becomeFirstResponder()
return canvasView
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
picker.addObserver(canvasView)
picker.setVisible(true, forFirstResponder: uiView)
DispatchQueue.main.async {
uiView.becomeFirstResponder()
}
}
}
This is the output I Got
picker.setVisible(false, forFirstResponder: uiView)
Hides tools but it draws nothing
If there's any good library I can use please be kind enough to share
Any Help will be appreciated Thank You !
To get a preview of a UIViewRepresentable struct, I have the following code:
import SwiftUI
import WidgetKit
struct ViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
return UIView()
}
func updateUIView(_ uiView: UIView, context: Context) {
}
typealias UIViewType = UIView
}
struct ViewRepresentable_Previews: PreviewProvider {
static var previews: some View {
ViewRepresentable().previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
It outputs the following diagnostics.
RemoteHumanReadableError: Failed to update preview
invalid TimelineEntries
The error is "Cannot preview in this file – Failed to update preview"
How do you solve this error?
UIKit views wrapped in UIViewRepresentable will not work in WidgetKit.
Source: https://developer.apple.com/forums/thread/653471?answerId=619627022#619627022
I have a swiftUI view that calls a UIViewRepresentable view. In the SwiftUI view I am toggling the state of #State boolean value.
In my UIViewRepresentable view I have created a binding that gets past from the main SwiftUI view. The problem is the binding never gets update or at least the updateView function is not getting called in the UIViewRepresentable view. I fell like I must be doing something wrong but I am just overlooking it. Here is an example of what I am trying to do.
import Foundation
import SwiftUI
struct BindingTest: UIViewRepresentable {
#Binding var status: Bool
func makeUIView(context: Context) -> UIActivityIndicatorView {
let activityIndicator = UIActivityIndicatorView()
activityIndicator.style = .large
return activityIndicator
}
func updateUIView(_ uiView: UIViewType, context: Context) {
print("Hello")
}
}
import SwiftUI
struct ChartView: View {
#State var status = false
var body: some View {
VStack{
Spacer()
Button(action: {
status = !status
}) {
Text("Change")
}
BindingTest(status: $status)
}
}
}
I am using Xcode 12.5 and Swift 5.4
Looks like SwiftUI is doing some cleverness under the hood that isn't immediately obvious to us. Because you don't actually use your binding in updateUIView, it's not actually getting called.
However, if you update your code to the following:
func updateUIView(_ uiView: UIViewType, context: Context) {
print("Hello \(status)")
}
then you'll see that it does, in fact, get called.
PS - you can use status.toggle() instead of status = !status
I am working on a SwiftUI project, the functionalities it required is to make a Rich Text Editor on IOS.
The approach I am following is fairly simple, I used cbess/RichTextEditor link originally written in UIKit and import it into SwiftUI. To run the imported UIView, I wrap the view inside one UIViewRpresentable and add it into the ContentView struct of SwiftUI.
Now, I want to publish the data inside UIView and assign it to one of #state ContentView owns.
The code structure look similar to this:
For the ContentView (SwiftUI)
struct ContentView: View {
#State var textHtml: String = "" //I want all changes come from UIView be stored inside this
var body: some View {
VStack {
Cbess(
frameEditor: CGRect(x: 0, y: 40, width: 360, height: 400)
)
}
}
}
For the UiViewRepresentable
struct Cbess : UIViewRepresentable{
let frameEditor : CGRect
func makeUIView(context: Context) -> UIView {
let frameEditor = RichEditorView(frame: frameEditor)
let uiView : UIView = UIView()
uiView.addSubview(editorView)
return uiView
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
For the UiView(Simplified)
#objcMembers open class RichEditorView: UIView, {
var contentHTML : String // This variable get updated regularly
}
One additional question is that I want to make a Rich Text Editor by solely SwiftUI. How can I achieve it? Can you give me some keywords? Some Repo?
Any help is very appreciated! Thanks for read this whole question.
Use #Binding and delegate.
UIViewRepresentable view
struct Cbess : UIViewRepresentable {
#Binding var textHtml: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> RichEditorView {
let editorView = RichEditorView()
editorView.delegate = context.coordinator
return editorView
}
func updateUIView(_ uiView: RichEditorView, context: Context) {
}
class Coordinator: NSObject, RichEditorDelegate {
var parent: Cbess
init(_ parent: Cbess) {
self.parent = parent
}
// Use delegate here
func richEditor(_ editor: RichEditorView, contentDidChange content: String) {
self.parent.textHtml = content
print(content)
}
}
}
Your content view:
struct ContentView: View {
#State var textHtml: String = ""
var body: some View {
VStack {
Cbess(textHtml: $textHtml)
.frame(width: 360, height: 400)
Text("Print----\n\(textHtml)")
}
}
}
I'm using SwiftUI and RealityKit to make an AR app. I am trying to transition from a nonAR camera mode ARView to a regular ARView using a NavigationLink, but I'm running into a SIGABRT and see the following error whenever I select the link:
validateTextureDimensions, line 1227: error 'MTLTextureDescriptor has width (4294967295) greater than the maximum allowed size of 16384.'
I've reproduced this behavior in a fresh RealityKit app with these simple views:
// ContentView (nonAR ARView)
import SwiftUI
import RealityKit
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
ARViewContainer().edgesIgnoringSafeArea(.all)
NavigationLink(destination: ContentView2()) {
Text("Go!")
}
}
}
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero, cameraMode: .nonAR, automaticallyConfigureSession: true)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
// ContentView2 (AR ARView)
import SwiftUI
import RealityKit
struct ContentView2: View {
var body: some View {
return ARViewContainer2().edgesIgnoringSafeArea(.all)
}
}
struct ARViewContainer2: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
It seems like some cleanup needs to be performed with the first nonAR ARView before navigating but I'm not sure what the best way to manage that is. I saw the answer in this post and I tried adding a #Binding to ARViewContainer that I set in the parent view to flag to that the uiview should be removed in updateUIView before navigating, but I'm still hitting the crash :/ Any help here would be greatly appreciated!
I ended up resolving this for the time being by using a SceneKit view in place of the nonAR AR view.