Skip to content

Instantly share code, notes, and snippets.

@shawnthroop
Created October 7, 2022 14:30
Show Gist options
  • Save shawnthroop/63827e0033e00374d496ed72e81a0736 to your computer and use it in GitHub Desktop.
Save shawnthroop/63827e0033e00374d496ed72e81a0736 to your computer and use it in GitHub Desktop.
A simple test app for demonstrating view update warnings occurring in iOS 16
import SwiftUI
struct ContentView: View {
var body: some View {
RootView()
.modifier(RootViewModifier())
}
}
enum RootTab: String {
case profile, mentions, timeline
var title: String {
rawValue.capitalized
}
}
struct RootView: View {
@EnvironmentObject private var interface: InterfaceStore
var body: some View {
TabView {
ForEach(interface.tabs, id: \.hashValue) { tab in
NavigationStack {
Text(tab.title)
.navigationTitle(tab.title)
.toolbar {
Button("Settings") {
interface.presentedSheet = .settings
}
}
}
.tabItem {
Text(tab.rawValue.capitalized)
}
}
}
}
}
struct RootViewModifier: ViewModifier {
@StateObject private var interface = InterfaceStore()
@StateObject private var user = UserStore()
func body(content: Content) -> some View {
content
.sheet(item: $interface.presentedSheet) { sheet in
switch sheet {
case .settings:
SettingsView()
}
}
.environmentObject(interface)
.environmentObject(user)
}
}
enum PresentedSheet: String, Identifiable {
case settings
var id: String {
rawValue
}
}
final class InterfaceStore: ObservableObject {
@Published var tabs = [RootTab.timeline, .mentions, .profile]
@Published var presentedSheet: PresentedSheet?
}
struct SettingsView: View {
@Environment(\.dismiss) private var dismiss
@EnvironmentObject private var user: UserStore
@State private var isShowingAuthentication = false
var body: some View {
NavigationStack {
List {
Section {
usersSection(user.users.sorted { $0.value > $1.value })
Button("Add Account") {
isShowingAuthentication = true
}
}
}
.navigationTitle("Settings")
.sheet(isPresented: $isShowingAuthentication) {
NavigationStack {
Form {
TextField("Username", text: .constant(""))
SecureField("Password", text: .constant(""))
}
.navigationTitle("Sign In")
}
}
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button {
dismiss()
} label: {
Text("Done")
}
}
}
}
}
func usersSection(_ users: [(UUID, String)]) -> some View {
ForEach(users, id: \.0) { id, username in
Button {
user.activeUserID = id // FIXME: selecting row causes view update warnings here
} label: {
Label(username, systemImage: user.activeUserID == id ? "checkmark.circle" : "circle")
}
}
.onDelete { indices in
for i in indices {
user.users.removeValue(forKey: users[i].0)
}
}
}
}
final class UserStore: ObservableObject {
@Published var activeUserID: UUID?
@Published var users: [UUID: String]
init() {
let activeID = UUID()
self._activeUserID = .init(initialValue: activeID)
self._users = .init(initialValue: [activeID: "billy", UUID(): "bobby"])
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
RootView()
.modifier(RootViewModifier())
}
}
import SwiftUI
// Minimum Deployment Target: 16.0
// Built with Xcode 14.1 beta 3 (14B5033e)
@main // FIXME: dismissing SettingsView causes view update warnings here
struct PublishedWarningsApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment