<feed xmlns="http://www.w3.org/2005/Atom"> <id>https://clive819.github.io/</id><title>Clive Liu</title><subtitle>Blog from Clive Liu, focusing on iOS development.</subtitle> <updated>2026-03-12T22:40:54-04:00</updated> <author> <name>Clive Liu</name> <uri>https://clive819.github.io/</uri> </author><link rel="self" type="application/atom+xml" href="https://clive819.github.io/feed.xml"/><link rel="alternate" type="text/html" hreflang="en" href="https://clive819.github.io/"/> <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator> <rights> © 2026 Clive Liu </rights> <icon>/assets/img/favicons/favicon.ico</icon> <logo>/assets/img/favicons/favicon-96x96.png</logo> <entry><title>SwiftUI Gotcha - @State wrappedValue Inside init()</title><link href="https://clive819.github.io/posts/swiftui-gotcha-state-wrapped-value-inside-init/" rel="alternate" type="text/html" title="SwiftUI Gotcha - @State wrappedValue Inside init()" /><published>2026-03-12T00:00:00-04:00</published> <updated>2026-03-12T00:00:00-04:00</updated> <id>https://clive819.github.io/posts/swiftui-gotcha-state-wrapped-value-inside-init/</id> <content type="text/html" src="https://clive819.github.io/posts/swiftui-gotcha-state-wrapped-value-inside-init/" /> <author> <name>Clive Liu</name> </author> <summary>You’ve probably heard the rule: SwiftUI only uses @State’s initial value once. After that, it ignores whatever you pass in subsequent init() calls. But what exactly happens to _state.wrappedValue inside init() when the view is re-initialized? Does it return the live SwiftUI-managed state, or the freshly-constructed default? This distinction matters — especially when you’re storing @Observable ...</summary> </entry> <entry><title>SwiftUI Custom Navigation Back Button</title><link href="https://clive819.github.io/posts/swiftui-custom-navigation-back-button/" rel="alternate" type="text/html" title="SwiftUI Custom Navigation Back Button" /><published>2026-01-02T00:00:00-05:00</published> <updated>2026-01-02T00:00:00-05:00</updated> <id>https://clive819.github.io/posts/swiftui-custom-navigation-back-button/</id> <content type="text/html" src="https://clive819.github.io/posts/swiftui-custom-navigation-back-button/" /> <author> <name>Clive Liu</name> </author> <summary>SwiftUI’s default NavigationStack and NavigationView provide a system back button, but customizing its appearance requires replacing it entirely. Unlike UIKit’s navigationItem.leftBarButtonItem, there’s no direct API to style the default back button. This guide shows how to implement a custom back button with full control over appearance and behavior while preserving the native swipe-to-dismiss...</summary> </entry> <entry><title>Lost Hours Integrating SwiftData</title><link href="https://clive819.github.io/posts/lost-hours-integrating-swiftdata/" rel="alternate" type="text/html" title="Lost Hours Integrating SwiftData" /><published>2025-11-27T00:00:00-05:00</published> <updated>2025-11-27T00:00:00-05:00</updated> <id>https://clive819.github.io/posts/lost-hours-integrating-swiftdata/</id> <content type="text/html" src="https://clive819.github.io/posts/lost-hours-integrating-swiftdata/" /> <author> <name>Clive Liu</name> </author> <summary>Debug vs. Release: When Code Only Crashes in Release extension ModelContext { func fetch&amp;lt;Model: PersistentModel &amp;amp; Identifiable&amp;lt;UUID&amp;gt;&amp;gt;(id: UUID) throws -&amp;gt; Model? { let predicate = #Predicate&amp;lt;Model&amp;gt; { model in model.id == id } return try self.fetch(FetchDescriptor(predicate: predicate)).first } } This helper runs perfectly in...</summary> </entry> <entry><title>Lost Hours Integrating Firebase Realtime Database</title><link href="https://clive819.github.io/posts/lost-hours-integrating-firebase-realtime-database/" rel="alternate" type="text/html" title="Lost Hours Integrating Firebase Realtime Database" /><published>2025-11-27T00:00:00-05:00</published> <updated>2025-11-27T00:00:00-05:00</updated> <id>https://clive819.github.io/posts/lost-hours-integrating-firebase-realtime-database/</id> <content type="text/html" src="https://clive819.github.io/posts/lost-hours-integrating-firebase-realtime-database/" /> <author> <name>Clive Liu</name> </author> <summary>Integrating Firebase Realtime Database with Swift’s Codable protocol should be straightforward, but a few non-obvious behaviors can lead to hours of frustrating debugging. Here are three key pitfalls to watch out for. Dictionary Keys Must Be Strings FirebaseDataEncoder.swift#L1290 Firebase Realtime Database requires that all dictionary keys be String types. If you attempt to encode a mod...</summary> </entry> <entry><title>Hiding SwiftUI View</title><link href="https://clive819.github.io/posts/hiding-swiftui-view/" rel="alternate" type="text/html" title="Hiding SwiftUI View" /><published>2025-09-05T00:00:00-04:00</published> <updated>2025-09-05T01:13:36-04:00</updated> <id>https://clive819.github.io/posts/hiding-swiftui-view/</id> <content type="text/html" src="https://clive819.github.io/posts/hiding-swiftui-view/" /> <author> <name>Clive Liu</name> </author> <summary>When building user interfaces, it’s common to show or hide views based on state. In SwiftUI, there are several options: A simple if-else statement The .hidden() modifier The .opacity(_:) modifier if-else if condition { MyView() } if condition { MyView() } else { MyOtherView() } Notes: The view’s structural identity changes when the condition toggles, which resets an...</summary> </entry> </feed>
