SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中不会更新

2024-05-14

我知道,这是“无法在 iOS XX 中工作”问题之一,但我完全陷入困境......

所以我有一个ObservableObject继承自的类NSObject,因为我需要听委托方法UISearchResultsUpdating.

class SearchBarListener: NSObject, UISearchResultsUpdating, ObservableObject {
    
    @Published var searchText: String = ""
    let searchController: UISearchController = UISearchController(searchResultsController: nil)
    
    override init() {
        super.init()
        self.searchController.searchResultsUpdater = self
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        
        /// Publish search bar text changes
        if let searchBarText = searchController.searchBar.text {
            print("text: \(searchBarText)")
            self.searchText = searchBarText
        }
    }
}

struct ContentView: View {
    @ObservedObject var searchBar = SearchBarListener()
    
    var body: some View {
        Text("Search text: \(searchBar.searchText)")
        .padding()

        /// more code that's not related 
    }
}

问题是,即使print("text: \(searchBarText)")打印效果很好,Text("Search text: \(searchBar.searchText)") 从未更新过(在 iOS 13 中)。在 iOS 14 中运行良好。


这是一个最小的可重现示例:

class SearchBarTester: NSObject, ObservableObject {

    @Published var searchText: String = ""

    override init() {
        super.init()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
            print("updated")
            self.searchText = "Updated"
        }
    }
}

struct ContentView: View {
    @ObservedObject var searchBar = SearchBarTester()
    
    var body: some View {
        NavigationView {
            Text("Search text: \(searchBar.searchText)")
            .padding()
        }
    }
}

5秒后,控制台打印出“updated”,但是Text没有改变。在 iOS 14 中,Text更改为“搜索文本:已更新”正如预期的那样。

但是,如果我不继承NSObject, bothiOS 13 和 iOS 14 可以使用!

class SearchBarTester: ObservableObject {

    @Published var searchText: String = ""

    init() {
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
            print("updated")
            self.searchText = "Updated"
        }
    }
}    

我认为这个问题与从类继承有关。也许这是 iOS 14 中修复的问题。但是有人知道发生了什么吗?


Edit

Thanks @Cuneyt https://stackoverflow.com/users/2739567/为了答案!这是最终起作用的代码:

import SwiftUI
import Combine /// make sure to import this

class SearchBarTester: NSObject, ObservableObject {

    let objectWillChange = PassthroughSubject<Void, Never>()
    @Published var searchText: String = "" {
        willSet {
            self.objectWillChange.send()
        }
    }

    override init() {
        super.init()

        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
            print("updated")
            self.searchText = "Updated"
        }
    }
}

它似乎在 iOS 13 上,如果您子类化一个对象并且不符合ObservableObject直接(如class SearchBarTester: ObservableObject),您需要添加以下样板代码:

@Published var searchText: String = "" {
    willSet {
        objectWillChange.send()
    }
}

但是,调用默认值objectWillChange仍然不起作用,因此您需要再次自己定义它:

let objectWillChange = PassthroughSubject<Void, Never>()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中不会更新 的相关文章

  • Swift - 带循环的多个链 http 请求

    两天以来 我感觉我正在搜索整个网络来解决多个 http 请求的问题 所以我的工作流程如下所示 将图像上传到服务器 响应 XML 格式和任务 ID 使用任务 ID 向服务器发出 GET 请求 以检查该任务的状态 响应 XML 格式 其中状态可
  • 如何在 iOS 11 上的 Swift 中获取 FLAC 文件元数据?

    我需要获取 FLAC 文件的元数据 我尝试了以下代码 let item AVPlayerItem url URL fileURLWithPath path let commonMetadata item asset commonMetada
  • 编程界面方向更改不适用于 iOS

    因此 我有一个项目 当用户按下按钮时 我需要强制改变方向 我创建了一个github 上的示例应用程序 https github com vradenburg ForcedOrientationChange来演示这个问题 interface
  • iOS 8 启动图像文件 - 导航栏和状态栏

    我正在使用 Interface Builder 制作 iOS 8 的启动图像文件 我想要的启动图像非常简单 我认为与 设置 应用程序相同 顶部的导航栏带有一个空的分组 TableView 无标题等 请注意 我通常不使用 Interface
  • 如何在 Objective-C 的动画中使视图振动? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有一个名为 qShake 的 UIView 当用户犯错误时 我希望该视图在一个小空间内短时间内从左到右晃动 我将如何创建动画来做到这一点
  • 如何从 iOS 本机共享功能中删除某些选项? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一款 iOS 游戏 想知道如何删除 iOS 在自动共享时提供的一些本机选项 例如 分配给联系人 和 打印 我对此做了很多研究 我
  • Firebase 查询 - 查找包含字符串的子项

    我在使用 Firebase 查询时遇到了一些问题 我想查询对象 其中对象子值包含特定字符串 到目前为止 我有一些看起来像这样的东西 Firebase ref Firebase alloc initWithUrl https dinosaur
  • 检查是否安装了 Google 地图 - iOS 10.2.1

    我刚刚将手机升级到 iOS 10 2 1 在我的 Swift 应用程序 使用 3 0 中 我试图检查手机上是否安装了 Google 地图 如果是 请在 Google 地图中打开该地址 UIApplication shared canOpen
  • UITableView 部分始终保持在视图内

    我有一个包含 3 个部分的 UITableView 第 1 节 该部分的标题是 Players 内容恰好是 1 个单元格 包含 1 4 个玩家姓名的水平列表 第 2 节 该部分的标题是 回合 内容是 X 个单元格 每个单元格包含每个玩家在第
  • 身份验证后如何退出 Google

    所以我的应用程序可以选择使用 Google 登录 单击 Google 提供的按钮后 将打开一个 Web 视图并让用户输入其凭据 允许应用程序访问其信息后 应用程序将用户登录并将 SignInViewController 更改为 TabBar
  • NSAttributedString 到 NSData 'NSAttributedString' 没有可见的 @interface 声明选择器 'RTFDFromRange:documentAttributes:

    我正在尝试转换NSAttributedString to NSData using RTFDFromRange方法 得到这个 No visible interface for NSAttributedString declares the
  • CSS 背景在 iOS 中拉伸以填充高度,但滚动上有空白

    这个 CSS 让我的背景在 iOS 中填充 100 的屏幕高度 但有一个小问题 当你向下滚动时 最初有空白 然后当你松开手指并停止滚动时 背景图像会 调整 并填充 100再次屏幕高度的 如果您继续滚动 该问题不会在同一页面上再次出现 只是第
  • iOS 11 /“Apps-prefs=root”功能在更新到 Swift 3 后不起作用

    我对 Swift 编程还很陌生 我制作了一个简单的测试应用程序 可以通过特定按钮以编程方式打开设置 不幸的是 更新按钮后 没有打开所需的设置页面 在本例中为 wifi 页面 而是仅打开通用设置屏幕 有人可以帮助我了解 swift 4 中究竟
  • 同一视图中的多个 UIAlertView

    我有两个带有确定 取消按钮的 UIAlertView 我通过以下方式捕获用户响应 void alertView UIAlertView alertView didDismissWithButtonIndex NSInteger button
  • Objective-c:如何检测视图上的双击?

    我正在开发一个应用程序 其中视图上有多个控件 但我想在用户双击视图时启用它们 您可以以双击为例 但在设备中我想在双击时捕获事件 您需要添加一个UITapGestureRecognizer到您想要点击的视图 像这样 void viewDidL
  • 缩进 UILabel 的第二行(swift)

    var testLabel UILabel frame CGRectMake 8 0 tableView frame width 8 100 let testDesc dsfdddfdsfdsfsdfdsfdsfdsfdsfdsfsdfds
  • 如何在 iOS 上反转使用 CoreGraphics 渲染的 pdf 上的文本颜色?

    我正在使用开源 PDF 查看库 VFR PDF Readerhttps github com vfr Reader https github com vfr Reader 我正在尝试实现 夜间模式 或黑色背景与白色文本 我可以将背景设置为我
  • Measure 应用程序是否有可用的 URL 方案?

    我想推出新的测量应用程序 在 iOS 12 上 在我的应用程序中 这可能吗 应用程序是否有可用的 URL 方案可用于此目的 或者还有其他方法可以做到吗 Thanks 您似乎无法打开此应用程序 In the 文档存档 https develo
  • 通过更改其优先级值来动画布局约束

    我有一个包含大量文本的标签 有一个用于折叠和展开标签高度的切换开关 此处名为 里拉套房 所以它会截断文本的结尾 我精心设置了垂直内容拥抱优先级和压缩阻力 因此内在尺寸比压缩阻力具有更高的优先级 高度限制 直接位于标签右侧的可选约束 设置为常
  • SwiftUI 中的计算 (NSObject) 属性不会更新视图

    所以 我想要一个Text它根据我的 CoreData 模型的内容更改其内容 为此 我在 Xcode beta 4 中使用了计算属性 但它似乎不再起作用了 这是一个错误还是还有其他我没有看到的问题 我真正遇到的问题是我的视图 和计算的属性 似

随机推荐