0

I have this code which allows the users to make upvote or downvote like stack overflow. My problem is that the Text("\(likes) UpVote").padding(.top, 8) does not refresh immediately, instead the user should change the perspective to get the refreshed upvote/downvote. How to improve that, so that the user can only click one time on one of them and it Changes them immediately?

This is how my code looks like:

import SwiftUI
import SDWebImageSwiftUI
import Firebase

struct PostCellCard : View {

    var user = ""
    var image = ""
    var id = ""
    var likes = ""
    var comments = ""
    var msg = ""
    var body : some View{

        VStack(alignment: .leading, content: {

            HStack{

                Image("person-icon-1675").resizable().frame(width: 35, height: 35).clipShape(Circle()).onTapGesture {
                    print("slide out menu ....")
                }
                HStack(alignment: .top){
                    VStack(alignment: .leading){
                        Text(user).fontWeight(.heavy)
                        Text(msg).padding(.top, 8)
                    }}
                Spacer()
                Button(action: {

                }) {

                    Image("menu").resizable().frame(width: 15, height: 15)
                }.foregroundColor(Color("darkAndWhite"))
            }
            if self.image != ""{
                AnimatedImage(url: URL(string: image)).resizable().frame(height: 250)
            }
            HStack{

                Button(action: {

                    let db = Firestore.firestore()
                    let like = Int.init(self.likes)!
                    db.collection("posts").document(self.id).updateData(["likes": "\(like - 1)"]) { (err) in

                        if err != nil{

                            print((err)!)
                            return
                        }

                        print("down updated....")
                    }

                }) {


                    Image(systemName: "arrow.down.to.line.alt").resizable().frame(width: 26, height: 26)
                }.foregroundColor(Color("darkAndWhite"))

                Button(action: {

                    let db = Firestore.firestore()
                    let like = Int.init(self.likes)!

                    db.collection("posts").document(self.id).updateData(["likes": "\(like + 1)"]) { (err) in
                        if err != nil{
                            print((err)!)
                            return
                        }

                        print("up updated....")
                    }

                }) {

                    Image(systemName: "arrow.up.to.line.alt").resizable().frame(width: 26, height: 26)
                }.foregroundColor(Color("darkAndWhite"))

                Spacer()

            }.padding(.top, 8)

            Text("\(likes) UpVote").padding(.top, 8)
            Text("\(likes) DownVote").padding(.top, 8)
            Text("View all \(comments) Comments")


        }).padding(8)
    }

}
Alex
  • 267
  • 1
  • 3
  • 18

2 Answers2

1

unfortunately i had to change a lot so that it was running ...so here is my code and it works - changes likes - of course you can make an int out of it and increase it instead of just setting a text

struct ContentView : View {

    var user = ""
    var image = ""
    var id = ""
    @State var likes = ""
    var comments = ""
    var msg = ""
    var body : some View{
        VStack {

            HStack{

                Image(systemName:"circle").resizable().frame(width: 35, height: 35).clipShape(Circle()).onTapGesture {
                    print("slide out menu ....")
                    self.likes = "tapped"
                }
                HStack(alignment: .top){
                    VStack(alignment: .leading){
                        Text(user).fontWeight(.heavy)
                        Text(msg).padding(.top, 8)
                    }}
                Spacer()
                Button(action: {
                    self.likes = "aha"
                }) {

                    Image(systemName:"circle").resizable().frame(width: 15, height: 15)
                }.foregroundColor(Color("darkAndWhite"))
            }
            if self.image != ""{
                Text("Animated Image")
                //   AnimatedImage(url: URL(string: image)).resizable().frame(height: 250)
            }
            HStack{

                Button(action: {

                    self.likes = "oho"
                    print("button action")
                }) {

                    Image(systemName: "circle").resizable().frame(width: 26, height: 26)
                }.foregroundColor(Color("darkAndWhite"))

                Button(action: {

                    let like = Int.init(self.likes)!
                    print("action")
                    self.likes = "uhu"
                }) {
                    Text("aha")
//                    Image(systemName: "arrow.up.to.line.alt").resizable().frame(width: 26, height: 26)
                }.foregroundColor(Color("darkAndWhite"))

                Spacer()

            }.padding(.top, 8)

            Text("\(likes) UpVote").padding(.top, 8)
            Text("\(likes) DownVote").padding(.top, 8)
            Text("View all \(comments) Comments")

        }.padding(8)
    }
}
Chris
  • 7,579
  • 3
  • 18
  • 38
0

You would use a property wrappers for your likes variable, so when you change the amount of likes, it will also change it on the Text as will.

What should work in your case is the @State property wrapper, which would look like this...

@State var likes = ""

For more information about property wrappers here's a good article explains them https://www.hackingwithswift.com/quick-start/swiftui/understanding-property-wrappers-in-swift-and-swiftui

Logarithm
  • 33
  • 4