无法使用SwiftUI中的@State属性包装器更新视图

时间:2020-05-04 19:44:00

标签: swift swiftui

使用@State包装器不会更新视图。 该视图无需使用@State包装器即可更新,但必须手动进行。

import SwiftUI

struct SwiftUIView: View {
    @ObservedObject var people: People
    var body: some View {
        VStack {
            ForEach(people.peoples){ person in
                HStack{
                    Text("\(person.age)")
                    if person.ismale {
                        Text("Male")
                    } else {
                        Text("Female")
                    }
                    Button(action:{ person.age += 1}){
                        Text("Age+1")
                    }
                }
            }
        }
    }
}

struct Person: Identifiable{
    var id = UUID()
    @State var age: Int
    var ismale = true
}

class People: ObservableObject {
    @Published var peoples: [Person]
    init() {
        self.peoples = [
            Person(age: 10),
            Person(age: 12, ismale: false)
        ]
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView(people: People())
    }
}

由于某种原因,单击该按钮时,该视图没有更改。

如果我将其更改为

Button(action:{ **self.people.peoples[0].age += 1** }){
       Text("Age+1")
}
...

struct Person: Identifiable{
    var id = UUID()
    **var age: Int**
    var ismale = true
}

它会更新,但是按钮不会是动态的。但是,如果我在ForEach循环中执行person.age += 1,而没有使用@State包装器来进行可变年龄。

错误:“变异运算符的左侧不可更改:'person'是'let'常量”

我以为我了解Struct,Class,@ State的意思是什么...我想不是...感谢任何解决方案。

1 个答案:

答案 0 :(得分:0)

using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.SqlServer; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; namespace EfCore3Test { public class Person { public int Id { get; set; } public string Name { get; set; } public DateTime ModifiedAt { get; set; } } public class Db : DbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Person>().Property(p => p.ModifiedAt).HasDefaultValueSql("getdate()").ValueGeneratedOnAddOrUpdate(); modelBuilder.Entity<Person>().Property(b => b.ModifiedAt).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save); } private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder => { builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole(); }); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLoggerFactory(loggerFactory) .UseSqlServer("Server=.;database=EfCore3Test;Integrated Security=true", o => o.UseRelationalNulls()); base.OnConfiguring(optionsBuilder); } } class Program { static void Main(string[] args) { using var db = new Db(); db.Database.EnsureDeleted(); db.Database.EnsureCreated(); var p = new Person() { Name = "Fred" }; db.Set<Person>().Add(p); db.SaveChanges(); p.Name = "Fred2"; p.ModifiedAt = DateTime.Now.AddDays(-7); db.Set<Person>().Update(p); db.SaveChanges(); } } } } 通过引用传递,因此您不需要info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (0ms) [Parameters=[@p2='?' (DbType = Int32), @p0='?' (DbType = DateTime2), @p1='?' (Size = 4000)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Person] SET [ModifiedAt] = @p0, [Name] = @p1 WHERE [Id] = @p2; SELECT @@ROWCOUNT; ObservableObject`已经收到更新。

这是struct结构

@State' as the

还有Person。我删除了struct Person: Identifiable{ var id = UUID() var age: Int var ismale = true } 语句,使代码更加简洁。

SwiftUIView