Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Post

Replies

Boosts

Views

Activity

MKGeoJSONDecoder and Single Points
https://developer.apple.com/documentation/mapkit/mkgeojsondecoder?changes=__9&language=objc I am trying to use this decoder to obtain single points form a geojson file. I am able to do this successfully however, when using MapKit for iOS 17+ I am unable to use a ForEach to iterate through these points (stored in an array) and display these on the map as a custom annotation or even a marker. MapAnnotation(coordinate: point.coordinate) { VStack { Image(systemName: "mappin.circle.fill") .resizable() .frame(width: 25, height: 25) .foregroundColor(.purple) if let title = point.title { Text(title) .font(.caption) .foregroundColor(.purple) .padding(2) .background(Color.white.opacity(0.8)) .cornerRadius(3) } } }
0
0
121
2d
@Binding bools within a VStack getting conflated
I am running into an issue where two distinct bool bindings are both being toggled when I toggle only one of them. My component looks like VStack { Checkbox(label: "Checkbox 1", isOn: $stateVar1) Checkbox(label: "Checkbox 2", isOn: $stateVar2) } where my CheckBox component looks like struct Checkbox: View { let label: String @Binding var isOn: Bool var body: some View { Button { isOn.toggle() } label: { HStack { Image(systemName: isOn ? "checkmark.square" : "square") Text(label) } .foregroundStyle(.black) } } } If I click on one checkbox, both of them get toggled. However, if I simply remove the checkboxes from the VStack, then I am able to toggle them both independently. I believe this is a bug with bool Bindings, but if anyone can point out why I am mistaken that would be much appreciated :)
1
0
140
3d
On macOS SwiftUI.TimelineView() inside NSViewController is causing AutoLayout recalculations
I have a complex app that requires the main SwiftUI view of the app to be embedded inside an NSHostingView which is a subview of an NSViewController's view. Then this NSViewController is wrapped using NSViewControllerRepresentable to be presented using SwiftUI's Window. And if I have a TimelineView inside my SwiftUI view hierarchy, it causes constant recalculation of the layout. Here's a simplified demo code: @main struct DogApp: App { private let dogViewController = DogViewController() var body: some Scene { Window("Dog", id: "main") { DogViewControllerUI() } } } private struct DogViewControllerUI: NSViewControllerRepresentable { let dogViewController = DogViewController () func makeNSViewController(context: Context) -> NSViewController { dogViewController } func updateNSViewController(_ nsViewController: NSViewController, context: Context) {} func sizeThatFits(_ proposal: ProposedViewSize, nsViewController: NSViewController, context: Context) -> CGSize? { debugPrint("sizeThatFits", proposal) return nil } } public class DogViewController: NSViewController { public override func viewDidLoad() { super.viewDidLoad() let mainView = MainView() let hostingView = NSHostingView(rootView: mainView) view.addSubview(hostingView) hostingView.translatesAutoresizingMaskIntoConstraints = false hostingView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true hostingView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true hostingView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true hostingView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true } } struct MainView: View { var body: some View { VStack { TimelineView(.animation) { _ in Color.random .frame(width: 100, height: 100) } } } } extension Color { static var random: Color { Color( red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1) ) } } When running it's printing out this repeatedly (multiple times a second). "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(559.0), height: Optional(528.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(0.0), height: Optional(0.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(559.0), height: Optional(528.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(0.0), height: Optional(0.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(559.0), height: Optional(528.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(0.0), height: Optional(0.0)) "sizeThatFits" SwiftUI.ProposedViewSize(width: Optional(559.0), height: Optional(528.0)) If I run an equivalent code for an iPad, it only prints twice. If I comment out TimelineView on macOS, then it only prints out the above logs when resizing the app window. The main reason this is an issue is that it's clearly causing dramatic degradation in performance. I was told to submit a bug report after I submitted TSI so a SwiftUI engineer could investigate it. Case-ID: 7461887. FB13810482. This was back in May but I received no response. LLMs are no help, and I've experimented with all sorts of workarounds. My last hope is this forum, maybe someone has an idea of what might be going on and why the recalculation is happening constantly on macOS.
1
0
202
4w
Issue with TabView in Split Screen
Below is a basic test app to resemble an actual app I am working on to hopefully better describe an issue I am having with tab view. It seems only in split screen when I am triggering something onAppear that would cause another view to update, or another view updates on its own, the focus gets pulled to that newly updated view instead of staying on the view you are currently on. This seems to only happen with views that are listed in the more tab. In any other orientation other than 50/50 split this does not happen. Any help would be appreciated. struct ContentView: View { @State var selectedTab = 0 var body: some View { NavigationStack { NavigationLink(value: 0) { Text("ENTER") }.navigationDestination(for: Int.self) { num in TabsView(selectedTab: $selectedTab) } } } } struct TabsView: View { @Binding var selectedTab: Int @State var yikes: Int = 0 var body: some View { if #available(iOS 18.0, *) { TabView(selection: $selectedTab) { MyFlightsView(yikes: $yikes) .tabItem { Label("My Flights", systemImage: "airplane.circle") }.tag(0) FlightplanView() .tabItem { Label("Flight Plan", systemImage: "doc.plaintext") }.tag(1) PreFlightView() .tabItem { Label("Pre Flight", systemImage: "airplane.departure") }.tag(2) CruiseView(yikes: $yikes) .tabItem { Label("Cruise", systemImage: "airplane") }.tag(3) PostFlightView() .tabItem { Label("Post Flight", systemImage: "airplane.arrival") }.tag(4) MoreView() .tabItem { Label("More", systemImage: "ellipsis") }.tag(5) NotificationsView() .tabItem { Label("Notifications", systemImage: "bell") }.tag(6) }.tabViewStyle(.sidebarAdaptable) } } }
1
0
189
3d
How can I optimize SwiftUI CPU load on frequent updates
Dear Sirs, I'm writing an audio application that should show up to 128 horizontal peakmeters (width for each is about 150, height is 8) stacked inside a ScrollViewReader. For the actual value of the peakmeter I have a binding to a CGFloat value. The peakmeter works as expected and is refreshing correct. For testing I added a timer to my swift application that is firing every 0.05 secs, meaning I want to show 20 values per second. Inside the timer func I'm just creating random CGFloat values in range of 0...1 for the bound values. The peakmeters refresh and flicker as expected but I can see a CPU load of 40-50% in the activity monitor on my MacBook Air with Apple M2 even when compiled in release mode. I think this is quite high and I'd like to reduce this CPU load. Should this be possible? I.e. I thought about blocking the refresh until I've set all values? How could this be done and would it help? What else could I do? Thanks and best regards, JFreyberger
7
0
833
May ’24
MacOS Scale to view
on iOS you can choose to scale to view to have the app resize the screen easily in the developer environment. Scale to view is however not easily done on MacOS using NS to solve on MacOS now. Is it possible for the Apple developer team to make this easier for the Developer, as I understand it is for iOS applications?
0
0
157
3d
What is a performant way to change view offset as user scrolls?
I added a background view to my SwiftUI List, and would like to move it up as user scrolls (similar to the effect of that of the Health app). I can't add it onto the background of a List row, because List unconditionally clips content to a row, and I would like the view to extend past a insetted row's bounds (scrollClipDisabled does not work on List). So I added the view as the background view of the entire List. Currently, I am achieving this by monitoring contentOffset using the new onScrollGeometryChange(for:of:action:) modifier, updating a state variable that controls the offset of the background view. The code looks something like this: struct ContentView: View { @State private var backgroundOffset: CGFloat = 0 var body: some View { List { ... } .background { backgroundView .offset(y: backgroundOffset) } .onScrollGeometryChange(for: ScrollGeometry.self) { geometry in geometry } action: { oldValue, newValue in let contentOffsetY = newValue.contentOffset.y let contentInsetY = newValue.contentInsets.top if contentOffsetY <= -contentInsetY { backgroundOffset = 0 } else { backgroundOffset = -(contentOffsetY + contentInsetY) } } } } However, this results in bad scrolling performance. I am guessing this is due to backgroundOffset being updated too frequently, and thus refreshing the views too often? If so, what is a more performant approach to achieve the desired effect? Thanks!
3
0
604
Aug ’24
Xcode 16: SwiftUI plain Button & UIImageView not working
It looks like Xcode 16 has changed this behaviour so I'm not sure if this is a bug or not. When a SwiftUI Button wraps a UIImageView and the button style is .plain the button doesn't work without setting isUserInteractionEnabled. struct ContentView: View { var body: some View { Button { print("Hello World!") } label: { UITestImage() } .buttonStyle(.plain) } } struct UITestImage: UIViewRepresentable { func makeUIView(context: Context) -> UIImageView { let view = UIImageView() // view.isUserInteractionEnabled = true // Fix view.image = UIImage(systemName: "plus") view.contentMode = .scaleAspectFit view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) view.setContentCompressionResistancePriority(.defaultLow, for: .vertical) view.layoutMargins = .zero return view } public func updateUIView(_ uiView: UIImageView, context: Context) {} } This feels unexpected, is this a bug?
2
1
729
Jun ’24
fullScreenCover not dismissed if binding changes rapidly.
I'm working on an app targeting iOS 15+ using SwiftUI. The app has several Views that load data from an API in their onAppear() method. While the loading operation is in progress, these views show a loading overlay via .fullScreenCover(). While most of the time this works as expected, I've discovered that if the API operation completes before the overlay's .onAppear() has fired, the overlay gets stuck on screen, i.e. does not dismiss. This bug occurs both in the simulator and on device. This is a simplified version of my implementation: struct MyDataView: View { @EnvironmentObject var store:Store var Content: some View { // ... } @ViewBuilder var body: some View { let showLoadingOverlay = Binding( get: { store.state.loading }, set: { _ in } ) Content .onAppear { store.dispatch(LoadData) } .fullScreenCover(isPresented: showLoadingOverlay) { LoadingOverlay() } } } Log messages tell me that my store is updating correctly, i.e. the booleans all operate as expected. Adding log output to the binding's getter always prints the correct value. Adding a breakpoint to the binding's getter makes the problem disappear. I've found that the chronology of events that lead to this bug is: MyDataView.onAppear() LoadData Binding: true Overlay starts animating in LoadData finishes Binding: false Overlay fires it's onAppear I.e. whenever loading finishes before the fullScreenCover's onAppear is fired, the overlay get's stuck on screen. As long as loading takes at least as long as it takes the overlay to appear, the bug does not occur. It appears to be a race condition between the .fullScreenCover appearing and the binding changing to false. I've found that the bug can be avoided if loading is triggered in the overlay's .onAppear(). However, I would like to avoid this workaround because the overlay is not supposed to carry out data loading tasks.
2
1
1.2k
Dec ’21
Swiftui Charts
I have a SwiftUI LineMark chart that inverts the y axis when the data the chart is plotting is all zeros. I'm expecting the y axis 0 to be at the bottom but when the data is all zeros it's at the top. Below is an example demonstrating the problem: import SwiftUI import Charts struct ChartView: View { let data: [Double] = [0,0,0,0,0] var body: some View { Chart { ForEach(data.indices, id: \.self) { index in LineMark( x: .value("Index", index), y: .value("Value", data[index]) ) } } .chartYAxis { AxisMarks(values: [0, 10, 20, 30, 40, 50]) { value in AxisValueLabel() AxisTick() AxisGridLine() } } .padding() } } I can't use .chartYScale(domain: ) because it overrides the chartYAxis where the real code creates custom a leading and trailing y axis. Does anyone have any suggestions how I may fix this?
5
0
329
1w
Swift Charts: How to prevent scroll position jump when loading more data dynamically
I'm implementing infinite scrolling with Swift Charts where additional historical data loads when scrolling near the beginning of the dataset. However, when new data is loaded, the chart's scroll position jumps unexpectedly. Current behavior: Initially loads 10 data points, displaying the latest 5 When scrolling backwards with only 3 points remaining off-screen, triggers loading of 10 more historical points After loading, the scroll position jumps to the 3rd position of the new dataset instead of maintaining the current view Expected behavior: Scroll position should remain stable when new data is loaded User's current view should not change during data loading Here's my implementation logic using some mock data: import SwiftUI import Charts struct DataPoint: Identifiable { let id = UUID() let date: Date let value: Double } class ChartViewModel: ObservableObject { @Published var dataPoints: [DataPoint] = [] private var isLoading = false init() { loadMoreData() } func loadMoreData() { guard !isLoading else { return } isLoading = true let newData = self.generateDataPoints( endDate: self.dataPoints.first?.date ?? Date(), count: 10 ) self.dataPoints.insert(contentsOf: newData, at: 0) self.isLoading = false print("\(dataPoints.count) data points.") } private func generateDataPoints(endDate: Date, count: Int) -> [DataPoint] { var points: [DataPoint] = [] let calendar = Calendar.current for i in 0..<count { let date = calendar.date( byAdding: .day, value: -i, to: endDate ) ?? endDate let value = Double.random(in: 0...100) points.append(DataPoint(date: date, value: value)) } return points.sorted { $0.date < $1.date } } } struct ScrollableChart: View { @StateObject private var viewModel = ChartViewModel() @State private var scrollPosition: Date @State private var scrollDebounceTask: Task<Void, Never>? init() { self.scrollPosition = .now.addingTimeInterval(-4*24*3600) } var body: some View { Chart(viewModel.dataPoints) { point in BarMark( x: .value("Time", point.date, unit: .day), y: .value("Value", point.value) ) } .chartScrollableAxes(.horizontal) .chartXVisibleDomain(length: 5 * 24 * 3600) .chartScrollPosition(x: $scrollPosition) .chartXScale(domain: .automatic(includesZero: false)) .frame(height: 300) .onChange(of: scrollPosition) { oldPosition, newPosition in scrollDebounceTask?.cancel() scrollDebounceTask = Task { try? await Task.sleep(for: .milliseconds(300)) if !Task.isCancelled { checkAndLoadMoreData(currentPosition: newPosition) } } } } private func checkAndLoadMoreData(currentPosition: Date?) { guard let currentPosition, let earliestDataPoint = viewModel.dataPoints.first?.date else { return } let timeInterval = currentPosition.timeIntervalSince(earliestDataPoint) if timeInterval <= 3 * 24 * 3600 { viewModel.loadMoreData() } } } I attempted to compensate for this jump by adding: scrollPosition = scrollPosition.addingTimeInterval(10 * 24 * 3600) after viewModel.loadMoreData(). However, this caused the chart to jump in the opposite direction by 10 days, rather than maintaining the current position. What's the problem with my code and how to fix it?
5
0
199
1w
Navigation split view selection property is set to nil when selecting list item
I am making a SwiftUI Mac app that uses navigation split view and the Observation framework. The split view has a sidebar list, a detail view, and a selection property to store the selected item in the list. I set the initial selection to the first item in the list using the .onAppear modifier. When I select an item from the list, I get the desired behavior. The detail view shows the contents of the selected item. But the selection property’s value changes to nil. Because selection is nil, I am unable to remove items from the list. Model Code struct Wiki { var pages: [Page] = [] } @Observable class Page: Identifiable, Equatable, Hashable { let id = UUID() var title: String = "Page" var text: String static func == (lhs: Page, rhs: Page) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) hasher.combine(title) hasher.combine(text) } } Split View Code struct ContentView: View { @Binding var wiki: Wiki @State private var selection: Page? = nil var body: some View { NavigationSplitView { PageList(wiki: $wiki, selection: $selection) .navigationSplitViewColumnWidth(ideal: 192) } detail: { if let selection { PageView(page: selection) } else { Text("Select a page to view its contents.") } } .onAppear { selection = wiki.pages.first } } } List Code struct PageList: View { @Binding var wiki: Wiki @Binding var selection: Page? var body: some View { VStack { Text("Pages") .font(.title) List($wiki.pages, selection: $selection) { $page in NavigationLink { PageView(page: page) } label: { TextField("", text: $page.title) } } .padding() } } } Detail View Code struct PageView: View { @Bindable var page: Page var body: some View { TextEditor(text: $page.text) } } I tried changing selection in the list view from @Binding to @Bindable, but I get the following build error: 'init(wrappedValue:)' is unavailable: The wrapped value must be an object that conforms to Observable What fix do I have to make to get the selection property to not be nil when I select an item from the list?
2
0
651
4d
Multipeer Connectivity with iOS devices
I used the Multipeer Connectivity Framework to allow players of my game app to see the highest score along with their own score as the game progresses. It works fine running in 3 or 4 simulators in Xcode. However, I was just told by two Apple support reps that bluetooth connectivity is not allowed between two Apple devices, other than for watches, AirPods, headphones, etc. My question is: can two iPhones or iPads connect for peer-to-peer play? Can they play offline? If the answer is yes to either or both of those questions, how do I get that to happen since I get an error message when trying to connect two iPhones via bluetooth even though they can see each other in the Other Devices list? If the answer is no, then why does Apple provide a Multipeer Connectivity Framework and simulate that type of device to device connection with the Xcode simulators?
0
0
103
4d
Scroll to Top gesture breaks when setting List or ScrollView background
When a ScrollView or List is nested in a TabView, you can press on the tab button and the scroll view will scroll to top. import SwiftUI struct SwiftUIView: View { let items = (1...100).map { "Item \($0)" } var body: some View { TabView { Tab("home", systemImage: "house") { ScrollView { ForEach(items, id: \.self) { item in Text(item) .frame(maxWidth: .infinity, alignment: .center) } } } } } } #Preview { SwiftUIView() } But if we add a background to the ScrollView, the scroll to top gesture breaks. import SwiftUI struct SwiftUIView: View { let items = (1...100).map { "Item \($0)" } var body: some View { TabView { Tab("home", systemImage: "house") { ScrollView { ForEach(items, id: \.self) { item in Text(item) .frame(maxWidth: .infinity, alignment: .center) } } // Set background on ScrollView. .background(Color.red) } } } } #Preview { SwiftUIView() } I made a similar post on StackOverflow, but haven't been able to find a proper solution. This feels like a bug of some sort in SwiftUI.
1
1
175
4d
Button taps in scroll views are not cancelled on scroll inside sheets
When you touch down on a button in a scroll view, you can cancel the tap by scrolling. In SwiftUI, this works correctly when the scroll view is not inside a dismissible sheet. However, if the scroll view is inside a sheet that can be dismissed with a drag gesture, scrolling does not cancel the button touch, and after scrolling, the button tap is activated. This happens whether the modal is presented from SwiftUI using the sheet modifier, or wrapped in a UIHostingController and presented from UIKit. This is a huge usability issue for modals with scrollable content that have buttons inside of them. Video of behavior: https://youtube.com/shorts/w6eqsmTrYiU Easily reproducible with this code: import SwiftUI struct ContentView: View { @State private var isPresentingSheet = false var body: some View { ScrollView { LazyVStack { ForEach(0..<100, id: \.self) { index in Button { isPresentingSheet = true } label: { Text("Button \(index)") .padding(.horizontal) .padding(.vertical, 5) .frame(maxWidth: .infinity, alignment: .leading) } } } .padding() } .sheet(isPresented: $isPresentingSheet) { ContentView() } } }
1
2
846
6d
Control Widget SF image cannot stably display
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have three ExampleControlWidget which is about the type egA egB and egC, it should all be showed but now they only show the text and placeholder. I'm aware of the images should be SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out? public enum ControlWidgetType: Sendable { case egA case egB case egC public var imageName: String { switch self { case .egA: return "egA" case .egB: return "egB" case .egC: return "egC" } } } struct ExampleControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: kind, provider: Provider() ) { example in ControlWidgetToggle( example.name, isOn: example.state.isOn, action: ExampleControlWidgetIntent(id: example.id), valueLabel: { isOn in ExampleControlWidgetView( statusText: isOn ? Localization.on.text : Localization.off.text, bundle: bundle, widgetType: .egA //or .egB .egC ) .symbolEffect(.pulse) } ) .disabled(example.state.isDisabled) } .promptsForUserConfiguration() } } public struct ExampleControlWidgetView: View { private let statusText: String private let bundle: Bundle private var widgetType: ControlWidgetType = .egA public init(statusText: String, bundle: Bundle, widgetType: ControlWidgetType) { self.statusText = statusText self.bundle = bundle self.widgetType = widgetType } public var body: some View { Label( statusText, image: .init( name: widgetType.imageName, // the SF Symbol image id bundled in the Widget extension bundle: bundle ) ) } } This is the normal display: These are the display that do not show properly: The results has no rules at all, I have tried to completely uninstall the APP and reinstall but the result is same.
0
0
115
4d
SwiftUI infinite loop issue with @Environment(\.verticalSizeClass)
I see SwiftUI body being repeatedly called in an infinite loop in the presence of Environment variables like horizontalSizeClass or verticalSizeClass. This happens after device is rotated from portrait to landscape and then back to portrait mode. The deinit method of TestPlayerVM is repeatedly called. Minimally reproducible sample code is pasted below. The infinite loop is not seen if I remove size class environment references, OR, if I skip addPlayerObservers call in the TestPlayerVM initialiser. import AVKit import Combine struct InfiniteLoopView: View { @Environment(\.verticalSizeClass) var verticalSizeClass @Environment(\.horizontalSizeClass) var horizontalSizeClass @State private var openPlayer = false @State var playerURL: URL = URL(fileURLWithPath: Bundle.main.path(forResource: "Test_Video", ofType: ".mov")!) var body: some View { PlayerView(playerURL: playerURL) .ignoresSafeArea() } } struct PlayerView: View { @Environment(\.dismiss) var dismiss var playerURL:URL @State var playerVM = TestPlayerVM() var body: some View { VideoPlayer(player: playerVM.player) .ignoresSafeArea() .background { Color.black } .task { let playerItem = AVPlayerItem(url: playerURL) playerVM.playerItem = playerItem } } } @Observable class TestPlayerVM { private(set) public var player: AVPlayer = AVPlayer() var playerItem:AVPlayerItem? { didSet { player.replaceCurrentItem(with: playerItem) } } private var cancellable = Set<AnyCancellable>() init() { addPlayerObservers() } deinit { print("Deinit Video player manager") removeAllObservers() } private func removeAllObservers() { cancellable.removeAll() } private func addPlayerObservers() { player.publisher(for: \.timeControlStatus, options: [.initial, .new]) .receive(on: DispatchQueue.main) .sink { timeControlStatus in print("Player time control status \(timeControlStatus)") } .store(in: &cancellable) } }
2
0
186
5d
Does LazyVStack and LazyVGrid release views from memory inside a ScrollView?
I am using LazyVStack inside a ScrollView. I understand that lazy views are rendered only when they come into view. However, I haven’t heard much about memory deallocation. I observed that in iOS 18 and later, when scrolling up, the bottom-most views are deallocated from memory, whereas in iOS 17, they are not (Example 1). Additionally, I noticed a similar behavior when switching views using a switch. When switching views by pressing a button, the view was intermittently deinitialized. (Example 2). Example 1) struct ContentView: View { var body: some View { ScrollView { LazyVStack { ForEach(0..<40) { index in CellView(index: index) } } } .padding() } } struct CellView: View { let index: Int @StateObject var viewModel = CellViewModel() var body: some View { Rectangle() .fill(Color.accentColor) .frame(width: 300, height: 300) .overlay { Text("\(index)") } .onAppear { viewModel.index = index } } } class CellViewModel: ObservableObject { @Published var index = 0 init() { print("init") } deinit { print("\(index) deinit") } } #Preview { ContentView() } Example 2 struct ContentView: View { @State var index = 0 var body: some View { LazyVStack { Button(action: { if index > 5 { index = 0 } else { index += 1 } }) { Text("plus index") } MidCellView(index: index) } .padding() } } struct MidCellView: View { let index: Int var body: some View { switch index { case 1: CellView(index: 1) case 2: CellView(index: 2) case 3: CellView(index: 3) case 4: CellView(index: 4) default: CellView(index: 0) } } } struct CellView: View { let index: Int @StateObject var viewModel = CellViewModel() var body: some View { Rectangle() .fill(Color.accentColor) .frame(width: 300, height: 300) .overlay { Text("\(index)") } .onAppear { viewModel.index = index } } } class CellViewModel: ObservableObject { @Published var index = 0 init() { print("init") } deinit { print("\(index) deinit") } } -------------------- init init init init init 2 deinit 3 deinit 4 deinit init
2
0
176
6d
SOLVED: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x10313ae30)
I'm trying to make a timetable app for my Apple Watch, and it has all actually been going pretty smoothly until this random error started showing up when I try to build my application. Here's a code snippet: // all on top level: class globalStorage { static let shared = globalStorage() // line 27 @State @AppStorage(runningKey) var termRunningGB = false @State @AppStorage(ghostWeekKey) var ghostWeekGB = false @State @AppStorage(startDateKey) var startDateGB = Date.now var currentCourse: Course = getCurrentClass(date: .now) } let storage = globalStorage.shared // << ERRORING HERE (line // ... @main struct myApp: App { /* ... */ } Can anybody tell me what is happening? (And, of course, how to fix it?) Furthermore, upon removing the offending line (let storage = globalStorage.shared) (and replacing all callers of said variable with 'globalStorage.shared' to bypass the variable) the error has decided to settle on line 27, where i define the 'shared' thing in the class. [ I just went back to try more solutions, I have resolved it but forgot to give my solution here. Now I've forgotten how I fixed it. I do know that I moved currentCourse out of the class, that most likely was it I think.] All of this code is on GitHub: https://github.com/the-trumpeter/Timetaber-for-iWatch
0
0
160
4d
iOS 18 SwiftUI navigation bar problem
Okay I know, fill a bug... but here is a super simple app that will demostrate that the navigation bar chnages from Dark scheme to light scheme when you tap back after it goes to the second view. import SwiftUI struct ContentView: View { var body: some View { NavigationStack { NavigationLink { Text("Tap back and notice the navigation title changes to black text instead of white") .toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(Color.orange, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } label: { VStack { Text("First page is the sweetest") } .padding() } .navigationTitle("First Page") .toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(Color.orange, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } } } #Preview { ContentView() }
6
8
3.2k
Sep ’24