SwiftUI - 结构绑定(bind)未按预期更新 UI

标签 swift xcode binding swiftui

我有一个 SwiftUI 问题,它看起来没有得到回答或与另一个问题重复,而 SwiftUI 是相当新的。

根据我的理解,下面的代码显示切换 Button 控件的背景。喜欢的次数按预期增加,但状态更改似乎没有传递到 Book 结构。

我读到的所有内容都是在预览中,您需要使用: .constant(x) 在 PreviewProvider 的 View 中。

但是,它不起作用,带有 likes 的 Button 不是前景颜色,也不是背景颜色。

调试应用程序时,book isLiked 的结果确实发生了变化。但是前景色/背景色没有。

这是 View 的代码。

import SwiftUI

struct BookDetailView: View {

  @Binding var book: Book
    @State var likes: Int = 0
  var body: some View {
    VStack {

      Text(book.title)
      Image(book.imageName)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .scaledToFit()

        Button(action: {
            self.book.isLiked.toggle()
            self.likes = self.likes + 1
        }) {
            Text("👍 Like \(likes)")
                .padding()
                .foregroundColor(self.book.isLiked ? .secondary : .primary)
                .background(self.book.isLiked ? Color.rayWenderlichGreen : Color.white)
                .cornerRadius(10)
        }
    }
  }
}

struct BookDetailView_Previews: PreviewProvider {

  static var previews: some View {
    BookDetailView(book: .constant(Book.demoBooks.randomElement()!))
  }
}

这是实际的书本模型

import SwiftUI

struct Book: Identifiable {
  var id = UUID()
  var title: String
  var imageName: String
  var isLiked = false
}

extension Book: Equatable {
  static func == (lhs: Book, rhs: Book) -> Bool {
    return lhs.id == rhs.id
  }
}

我花了一些时间试图理解为什么会发生这种情况,看起来它可能只是 SwiftUI 的一个错误。

有什么想法或建议吗?

最佳答案

我无法测试,因为没有提供 Book 类型,但如果它是一个结构,下面应该可以工作(注意:.constant 绑定(bind)是常量,它不会修改包装值,你需要一个活着的)

struct BookDetailView_Previews: PreviewProvider {
  struct TestView: View {
     @State private var book = Book.demoBooks.randomElement()!
     var body: some View {
       BookDetailView(book: $book)
     }
  }
  static var previews: some View {
    TestView()
  }
}

更新:现在有了修复 - 原因是制作的 equatable book 没有考虑到已更改的 isLiked 状态,因此 View 没有检测到任何更改并且不会更新。

解决方案是删除该扩展名或使其考虑所有应指示修改值的字段,如下所示

extension Book: Equatable {
  static func == (lhs: Book, rhs: Book) -> Bool {
    lhs.id == rhs.id && lhs.isLiked == rhs.isLiked
  }
}

经过测试并适用于 Xcode 11.4/iOS 13.4

关于SwiftUI - 结构绑定(bind)未按预期更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62067465/

相关文章:

ios - X 天后删除核心数据

ios - Swift 改变 UISearchBar 的高度

objective-c - 具有动态宽度的 UILabel - 水平对齐

objective-c - 关于@synthesize 的问题

wpf - 列表框未虚拟化

.net - WPF:绑定(bind)到 ListBoxItem.IsSelected 不适用于屏幕外项目

ios - UILongPressGestureRecognizer 被解雇了两次

swift - tvOS 13 顶架 - NSExtensionPrincipalClass `product_module_name.ContentProvider` 必须实现至少一个公共(public)协议(protocol)

ios - XCode swift HTTPS : String(data: data! 编码:NSUTF8StringEncoding ) 返回 nil

wpf - 相对源和弹出