swiftbindingswiftuioption-typeforced-unwrapping

How Do I Only Initialize ONE Of My Class's Properties?


I have a class with three properties, topic, navBarHidden and viewModel and I need to initialize the viewmodel with one of the class's properties, topic. But I don't need to initialize the other properties, ```topic. I have to initialize the view model because it makes a necessary API call.

Here's a snippet of the code.

struct TopicCell: View {
    @Binding var navBarHidden : Bool?
    @State var topic: Topic?
    @ObservedObject var viewModel : TopicCellViewModel
    
    init() {
        self.viewModel = TopicCellViewModel(topic: self.topic!)
    }
    
}

At first topic and navBarHidden weren't optionals, but then I'd have to initialize them, which I don't want to do. All the data that will initialize them needs to be passed in. So I made them optionals, which makes me not have to initialize them, then I just force unwrap the optionals.

But this gives me one issue.

NavigationLink( 
destination: DebateChatView(navBarHidden: $navBarHidden, topic: $topic, subtopic:
 .constant(SubTopic(dictionary: ["id": "", "topic": "Random Subtopic", "title": topic!.title, 
"bool": false , "messages": MOCK_MESSAGEZ])))

Notice the two binding variables, of topic and navBarHidden. These don't work now, because DebateChatView is expecting bound normal data, not bound optionals. But $topic! doesn't work. So, can someone please tell me the best way to fix this issue?


Solution

  • As you said values are to be decided when they are passed by parent, you can initialise target view to accept those parameters and simply assign the values.

    import SwiftUI
    
    struct TopicCell: View {
        @Binding var navBarHidden : Bool
        @State var topic: Topic
        @ObservedObject var viewModel : TopicCellViewModel
        
        init(topic:Topic,barHidden:Binding<Bool>) {
            _navBarHidden = barHidden
            _topic = State(wrappedValue: topic)
            self.viewModel = TopicCellViewModel(topic:topic)
        }
        
        var body: some View{
            NavigationView{
                ForEach(0..<5) { index in
                   
                        // Some stuff
                   
                }
            }
        }
    }
    
    struct CellView:View {
        @State var isBarHidden = false
        
        var body: some View{
            TopicCell(topic: Topic(name: "someName"), barHidden: $isBarHidden)
        }
    }
    
    struct Topic{
        var name:String
    }
    
    class TopicCellViewModel:ObservableObject{
        var topic:Topic
        
        init(topic:Topic) {
            self.topic = topic
        }
    }