Home > Net >  Swiftui Why is background not working until second row is tapped
Swiftui Why is background not working until second row is tapped

Time:07-25

I have a share view controller attached to a list . When a user taps on a list row the ShareView is supposed to pop and display the contents of the list that was tapped . The issue is when I start the app and tap on a list item the ShareView text is blank, if I tap on a second different item the it shows the content:

// example : start the app, click List 1 and see that no content displays, then Click List 2 and content is displayed .

How can I make it so that the first time you tap a list the content is displayed in ShareView controller . This is the small project

import SwiftUI

struct ContentView: View {
    let StringList = ["List 1","List 2","List 3","List 4","List 5"]
    @State var TextExample = ""
    @State var IsOpen = false
    var body: some View {
        List {
            ForEach(StringList, id: \.self) { string in
                Text(string)
                    .onTapGesture {
                        TextExample = string
                        IsOpen = true
                    }
            }
        }.background(SharingViewController(isPresenting: $IsOpen) {
            print("\(TextExample)")
            let av = UIActivityViewController(activityItems: [TextExample], applicationActivities: nil)
            av.completionWithItemsHandler = { _, _, _, _ in
                IsOpen = false // required for re-open !!!
               }
               
            return av
        })
    }
}

struct SharingViewController: UIViewControllerRepresentable {
    @Binding var isPresenting: Bool

    var content: () -> UIViewController

    func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

        if isPresenting  {
            uiViewController.present(content(), animated: true, completion: nil)

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Any suggestions would be great

CodePudding user response:

Im not sure if this is an old bug, but I saw this before.

However, I found that using @StateObject class and its sub variable @Published to bind the data instead of local @State variable solved this problem.

Below is the working code which I tested. Also, here is the proof video link: https://drive.google.com/file/d/1ItlOf33vasO9WFRDokUq_PXLzUpR8UBa/view?usp=sharing

class VM : ObservableObject {
  @Published var storedText = "" //added
}

struct ContentView: View {
@StateObject var viewModel = VM() //added
let StringList = ["List 1","List 2","List 3","List 4","List 5"]
@State var TextExample = ""
@State var IsOpen = false
var body: some View {
    List {
        ForEach(StringList, id: \.self) { string in
            Text(string)
                .onTapGesture {
                    viewModel.storedText = string //added
                    IsOpen = true
                }
        }
    }.background(
        SharingViewController(isPresenting: $IsOpen) {
        print("\(viewModel.storedText)") //added
        let av = UIActivityViewController(activityItems: [viewModel.storedText], applicationActivities: nil) //added
        av.completionWithItemsHandler = { _, _, _, _ in
            IsOpen = false // required for re-open !!!
           }
        return av
    })
}
}

struct SharingViewController: UIViewControllerRepresentable {
@Binding var isPresenting: Bool

var content: () -> UIViewController

func makeUIViewController(context: Context) -> UIViewController {
    UIViewController()
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

    if isPresenting  {
        uiViewController.present(content(), animated: true, completion: nil)

    }
}
}
  • Related