- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个简单的 watchOS 6.2.8 SwiftUI 应用程序,我在其中向用户显示消息列表。
这些消息被建模为类并具有标题、正文和类别名称。我还有一个类别对象,它是这些消息的 View ,仅显示特定的类别名称。
I specifically mention watchOS 6.2.8 because it seems SwiftUI behaves a bit different there than on other platforms.
class Message: Identifiable {
let identifier: String
let date: Date
let title: String
let body: String
let category: String
var id: String {
identifier
}
init(identifier: String, date: Date, title: String, body: String, category: String) {
self.identifier = identifier
self.date = date
self.title = title
self.body = body
self.category = category
}
}
class Category: ObservableObject, Identifiable {
let name: String
@Published var messages: [Message] = []
var id: String {
name
}
init(name: String, messages: [Message] = []) {
self.name = name
self.messages = messages
}
}
Category 本身是一个 @ObservableObject
并发布 messages
,这样当一个类别被更新时(比如在后台),显示类别消息列表的 View 也会更新。 (这很好用)
为了存储这些消息,我有一个简单的 MessageStore
,它是一个 @ObservableObject
,如下所示:
class MessageStore: ObservableObject {
@Published var messages: [Message] = []
@Published var categories: [Category] = []
static let sharedInstance = MessageStore()
func insert(message: Message) throws { ... mutage messages and categories ... }
func delete(message: Message) throws { ... mutage messages and categories ... }
}
(为简单起见,我使用单例,因为环境对象在 watchOS 上无法正确传递存在问题)
故事使消息
和类别
保持同步。添加具有类别名称集的新 Message 时,它还会在 categories
列表中创建或更新 Category
对象。
在我的主要观点中,我提出了两件事:
NavigationLink
转到 View 以显示所有消息NavigationLink
,它会转到一个 View 以仅显示该特定类别中的消息。这一切都有效,令人惊讶。但是发生了一件我不明白的非常奇怪的事情。 (第一个 SwiftUI 项目)
当我进入所有消息列表并删除所有包含特定类别的消息时,当我导航回主视图时发生了意想不到的事情。
首先我观察到该类别已从列表中正确删除。
但随后,主视图自动快速导航到“所有消息”列表,然后返回。
最后一部分快把我逼疯了..我不明白为什么会这样。从数据的角度来看,一切看起来都很好——消息和类别都被删除了。在自动导航之后,最终的 UI 状态看起来也不错——所有消息的消息计数是正确的,现在消息为零的类别不再显示在列表中。
这是主要 ContentView
和 AllMessagesView
的代码。如果有帮助,我当然可以在这里发布完整的代码。
struct AllMessagesView: View {
@ObservedObject var messageStore = MessageStore.sharedInstance
@ViewBuilder
var body: some View {
if messageStore.messages.count == 0 {
Text("No messages").multilineTextAlignment(.center)
.navigationBarTitle("All Messages")
} else {
List {
ForEach(messageStore.messages) { message in
MessageCellView(message: message)
}.onDelete(perform: deleteMessages)
}
.navigationBarTitle("All Messages")
}
}
func deleteMessages(at offsets: IndexSet) {
for index in offsets {
do {
try messageStore.delete(message: messageStore.messages[index])
} catch {
NSLog("Failed to delete message: \(error.localizedDescription)")
}
}
}
}
//
struct CategoryMessagesView: View {
@ObservedObject var messageStore = MessageStore.sharedInstance
@ObservedObject var category: Category
var body: some View {
Group {
if category.messages.count == 0 {
Text("No messages in category “\(category.name)”").multilineTextAlignment(.center)
} else {
List {
ForEach(category.messages) { message in
MessageCellView(message: message)
}.onDelete(perform: deleteMessages)
}
}
}.navigationBarTitle(category.name)
}
func deleteMessages(at offsets: IndexSet) {
for index in offsets {
do {
try messageStore.delete(message: category.messages[index])
} catch {
NSLog("Cannot delete message: \(error.localizedDescription)")
}
}
}
}
struct ContentView: View {
@ObservedObject var messageStore = MessageStore.sharedInstance
var body: some View {
List {
Section {
NavigationLink(destination: AllMessagesView()) {
HStack {
Image(systemName: "tray.2")
Text("All Messages")
Spacer()
Text("\(messageStore.messages.count)")
.font(messageCountFont())
.bold()
.layoutPriority(1)
.foregroundColor(.green)
}
}
}
Section {
Group {
if messageStore.categories.count > 0 {
Section {
ForEach(messageStore.categories) { category in
NavigationLink(destination: CategoryMessagesView(category: category)) {
HStack {
Image(systemName: "tray") // .foregroundColor(.green)
Text("\(category.name)").lineLimit(1).truncationMode(.tail)
Spacer()
Text("\(category.messages.count)")
.font(self.messageCountFont())
.bold()
.layoutPriority(1)
.foregroundColor(.green)
}
}
}
}
} else {
EmptyView()
}
}
}
}
}
// TODO This is pretty inefficient
func messageCountFont() -> Font {
let font = UIFont.preferredFont(forTextStyle: .caption1)
return Font(font.withSize(font.pointSize * 0.75))
}
}
抱歉,我知道这是很多代码,但我觉得我需要提供足够的上下文和可见性来展示这里发生的事情。
完整项目位于 https://github.com/st3fan/LearningSwiftUI/tree/master/MasterDetail - 我不认为更多的代码是相关的,但如果是,请告诉我,我会把它移到这里的问题中。
最佳答案
问题出在更新的 ForEach
中,这会导致重新创建 List
并因此断开链接。这看起来像是 SwiftUI 缺陷,因此值得向 Apple 提交反馈。
经过测试的解决方法是将“所有消息”导航链接移出列表(看起来有点不同,但可能是合适的)。使用 Xcode 12/watchOS 7.0 测试
struct ContentView: View {
@ObservedObject var messageStore = MessageStore.sharedInstance
var body: some View {
VStack {
NavigationLink(destination: AllMessagesView()) {
HStack {
Image(systemName: "tray.2")
Text("All Messages")
Spacer()
Text("\(messageStore.messages.count)")
.font(messageCountFont())
.bold()
.layoutPriority(1)
.foregroundColor(.green)
}
}
List {
ForEach(messageStore.categories) { category in
NavigationLink(destination: CategoryMessagesView(category: category)) {
HStack {
Image(systemName: "tray") // .foregroundColor(.green)
Text("\(category.name)").lineLimit(1).truncationMode(.tail)
Spacer()
Text("\(category.messages.count)")
.font(self.messageCountFont())
.bold()
.layoutPriority(1)
.foregroundColor(.green)
}
}
}
}
}
}
// ... other code
关于swiftui - watchOS 上使用 SwiftUI 的意外(自动)导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62971563/
我有一个现有的 WatchOS 2 应用程序。我想升级它并添加一些 WatchOS 3 功能,所以我安装了 Xcode 8 beta 3。我的问题是我是否需要为 WatchOS 3 项目创建另一个目标
我正在尝试构建一个应用程序,它支持 watch OS2 上的多个复杂功能系列,例如模块化大、实用大、圆形小等,每个都显示来自应用程序的各种有意义的信息。我知道复杂性与我们自 OS1 以来在用户交互方面
我的 iOS 和 watchOS 应用程序之间有一个共享框架,其中包含一个带有一些命名颜色的 Assets 目录。我想在我的 watchOS 应用程序中访问命名颜色。在 iOS 中,我可以使用 UIC
我在 watchOS 5 和 Apple Watch Series 4 上遇到了一些问题,因为它们没有正确使用它们的tintColor。相反,它们仅显示白色文本。同一张脸上的其他第 3 方并发症显示出
在昨天的 WWDC 上,Apple 宣布在 watchOS 5 中支持 WebKit。我已经下载了 Xcode 10,但在 Interface Builder 或 Frameworks and Lib
我正在考虑更新到 watchOS 6 的独立应用程序 (as Apple suggests),但我不清楚安装了我的应用程序的旧 watchOS 版本的用户会发生什么。更具体地说: 如果用户在其 wat
我有一个仅针对 watchOS 6 及更高版本的 watchOS Xcode 项目,它是用 SwiftUI 编写的,并且它的所有依赖项都由 Swift Package Manager 处理。我注意到在
我知道 Apple watchOS 2.0 应用程序需要一些修改(特别是在双向通信方面).... 但是,对于已经在 App Store 中为 1.0 编写的所有 Watch 应用程序,它们会在没有修改
Previous 我使用 NSUserDefaults 在 watch 和应用程序之间共享基本变量。 我的目标是在 watch 上显示存储在 iPhone 应用程序 NSUserDefaults 上的
想要在 watchOS 下运行应用程序,在 Xcode beta 下出现错误:域:IDELaunchErrorDomain 代码:15 失败原因:构建和运行启动失败,因为系统似乎无法识别要运行的应用程
我有一个公共(public)交通应用程序,其中包含火车的实时出发数据。我想添加一个复杂功能,显示下一趟火车的出发时间。 是否可以显示(或刷新)复杂功能的实时数据?例如,显示“到 X 站 3 分钟”。根
我正在为营养跟踪应用程序构建并发症。我想使用提供多个较小的并发症,以便用户可以跟踪他们的营养。 例如: 'MyApp - 碳水化合物' 'MyApp - 蛋白质' 'MyApp - 胖子' 通过这种方
我希望有人能够帮助我理解在我的 WatchOS 2 应用程序中尝试实现 NSURLSession 时遇到的问题。 无论出于何种原因,我收到错误; Error Domain=NSCocoaErrorDo
我想让界面像健康应用一样在全屏高度上可滚动,并且不允许在中间停止滚动,这可能吗? 例如,我有两个按钮,我希望它们在屏幕上可见,另一个在滚动后显示。主要部分是,如果滚动开始,它将自行继续,直到第二个按钮
在 watchOS 中,如果应用程序中嵌入了自定义字体,则该字体肯定可以在 WkInterfaceLabel、WKInterfaceButton 等上使用。 该字体适用于 watchOS 的通知 Vi
现在我没有开发者帐户,所以我曾经使用 Xcode 在 Apple Watch Series 3 上安装 watch 应用程序。在过去的几个月中,我观察到即使我每天运行该应用程序,我的应用程序通常也会在
我做了一个应用程序。我向应用程序发送推送通知。我也想在 watchos 上收到它们。我必须为 watchOs 制作一个项目并制作一个应用程序吗?或者我在 watchOs 上自动收到来自 iPhone
问题:Apple Watch 上创建的通知只是间歇性地提醒用户它们的存在。从屏幕顶部向下滑动时,通知中心会显示已收到通知。为什么我们不是每次都收到警报? 我们正在使用 Apple 推荐的方法(如 UN
我有一个 Core Data 应用程序。这就像一个比方说一个新闻应用程序。每个条目都有名称、ID、日期、发布者、详细信息等。主 iOS 应用程序可以有很多新闻条目。我只想展示 WatchOS 应用程序
在 Xcode 中,有一个地方可以设置界面 Controller 关闭时的 Action : override func didDeactivate() { // This method
我是一名优秀的程序员,十分优秀!