0

In my code, I have a value which counts calls from Navigation Links. This works fine but I want that if this count is over 1, the ContentView updates and add a cell. At the moment, I have to restart the app and then I have the new cell, but I want, that it updates directly. Is this possible? This is my code:

struct Website : Identifiable, Hashable, Comparable{
  static func < (lhs: Website, rhs: Website) -> Bool {
    lhs.name < rhs.name
  }
   
   
  var id = UUID()
  var url : String
  var name : String
  var image : String
  var calls : Int
   
}
struct websiteCallsCell : View{
  var website : Website
  @State var press = false
  @State var tap = false
  @State var isPresented = false
   
  var body: some View{
    NavigationLink(destination: WebView(website: website, url: URL(string: website.url)), label: {
      Text(website.name)
        .font(.system(size: 20, weight: .semibold, design: .rounded))
        .frame(width: UIScreen.main.bounds.width*0.85, height: 60)
        .background(
          ZStack {
            Color(press ? colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) : colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1))
             
            RoundedRectangle(cornerRadius: 16, style: .continuous)
              .foregroundColor(Color(press ? colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1) : colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)))
              .blur(radius: 4)
              .offset(x: -8, y: -8)
             
            RoundedRectangle(cornerRadius: 16, style: .continuous)
              .fill(
                LinearGradient(gradient: Gradient(colors: [Color( colorLiteral(red: 0.9019607843, green: 0.9294117647, blue: 0.9882352941, alpha: 1)), Color.white]), startPoint: .topLeading, endPoint: .bottomTrailing)
            )
              .padding(2)
              .blur(radius: 2)
          }
      )
        .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
        .overlay(
          HStack {
            AnimatedImage(url: URL(string: website.image))
              .font(.system(size: 24, weight: .light))
              .foregroundColor(Color.white.opacity(press ? 0 : 1))
              .frame(width: press ? 220 : 54, height: press ? 4 : 50)
              .background(Color( colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)))
              .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
              .shadow(color: Color( colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)).opacity(0.3), radius: 10, x: 10, y: 10)
              .offset(x: press ? 70 : -10, y: press ? 16 : 0)
             
            Spacer()
          }
      )
        .shadow(color: Color(press ? colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) : colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1)), radius: 20, x: 20, y: 20)
        .shadow(color: Color(press ? colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1) : colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), radius: 20, x: -20, y: -20)
        .scaleEffect(tap ? 1.2 : 1)
    })
           
           
         
         
       
  }
   
}

List{
          ForEach(websites){ website in
            if UserDefaults.standard.integer(forKey: "calls\(website.name)") > 0 && (UserDefaults.standard.integer(forKey: "lastCallsCount") < 8) {
              VStack{
              websiteCallsCell(website: website)
                lineSpacing(20)
                Spacer(minLength: 5)
              }
            }
          }
         
        }
  • Starting iOS 14, there is now a simple way to read and write to UserDefaults. Using a new property wrapper @AppStorage. please refer https://stackoverflow.com/a/59215110/2641380 stackoverflow answer, – SHS Dec 22 '20 at 14:30

1 Answers1

0

You are checking on UserDefaults , Which is not a publisher

I have two solutions fir that :

1- use @Environmentobject with a @Published var for clicks count , then check on it , in your ContentView

2- pass the State variable to the navigation link , and in the navigation link destination declare @Binding variable , and change it in each press , then check on it in your ContentView

struct websiteCallsCell : View {
var website : Website
@Binding var pressCount : Int
// other code
}

//

struct ContentView : View {
@State var pressCount = 0

}

//

List{
          ForEach(websites){ website in
            if pressCount > 0 && pressCount< 8 {
              VStack{
              websiteCallsCell(website: website, pressCount: self.$pressCount)
                lineSpacing(20)
                Spacer(minLength: 5)
              }
            }
          }
         
        }
Ouail Bellal
  • 1,554
  • 13
  • 27