Skip to content

Commit 3d311fd

Browse files
dadachiclaude
andcommitted
Fix list reload blink and bump to 3.2.4
ShopListView and ItemTagListView flashed a full-screen LoadingView whenever they re-appeared (returning to a tab, popping back from a detail). Each .task/onChange reload sets the view-model state to .loading, which swapped already-populated content for the spinner and back — a visible blink. This makes .loading keep existing content on screen and only show LoadingView on a true cold start (.initial, or .loading with no data yet). Background refreshes now update in place. Ports the relevant subset of nativeapptemplate/NativeAppTemplate-iOS#87 — only the list views that exist in this substrate (no AccountListView here). - Blink fix in ShopListView, ItemTagListView - Bump to 3.2.4 (build 14) and update CHANGELOG - README: document the now-shared scheme (per #69) and the git update-index --skip-worktree approach for keeping a personal LAN IP out of git, replacing the stale "uncheck Shared" instructions Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 2905fc6 commit 3d311fd

5 files changed

Lines changed: 33 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [3.2.4] - 2026-06-10
11+
12+
### Fixed
13+
- List views (`ShopListView`, `ItemTagListView`) no longer blink a full-screen `LoadingView` over already-loaded data when they re-appear (returning to a tab, popping back from a detail). The `.loading` state now keeps existing content on screen and only shows `LoadingView` on a true cold start (`.initial`, or `.loading` with no data yet)
14+
1015
## [3.2.3] - 2026-05-08
1116

1217
### Fixed

NativeAppTemplate.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@
11971197
CODE_SIGN_ENTITLEMENTS = "";
11981198
CODE_SIGN_IDENTITY = "Apple Development";
11991199
CODE_SIGN_STYLE = Automatic;
1200-
CURRENT_PROJECT_VERSION = 13;
1200+
CURRENT_PROJECT_VERSION = 14;
12011201
DEVELOPMENT_ASSET_PATHS = "\"NativeAppTemplate/Preview Content\"";
12021202
ENABLE_PREVIEWS = YES;
12031203
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -1209,7 +1209,7 @@
12091209
"$(inherited)",
12101210
"@executable_path/Frameworks",
12111211
);
1212-
MARKETING_VERSION = 3.2.3;
1212+
MARKETING_VERSION = 3.2.4;
12131213
PRODUCT_BUNDLE_IDENTIFIER = "com.nativeapptemplate.NativeAppTemplateFree.ios${SAMPLE_CODE_DISAMBIGUATOR}";
12141214
"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = "com.nativeapptemplate.NativeAppTemplateFree.ios${SAMPLE_CODE_DISAMBIGUATOR}";
12151215
PRODUCT_NAME = NativeAppTemplate;
@@ -1233,7 +1233,7 @@
12331233
CODE_SIGN_ENTITLEMENTS = "";
12341234
CODE_SIGN_IDENTITY = "Apple Development";
12351235
CODE_SIGN_STYLE = Automatic;
1236-
CURRENT_PROJECT_VERSION = 13;
1236+
CURRENT_PROJECT_VERSION = 14;
12371237
DEVELOPMENT_ASSET_PATHS = "\"NativeAppTemplate/Preview Content\"";
12381238
ENABLE_PREVIEWS = YES;
12391239
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -1245,7 +1245,7 @@
12451245
"$(inherited)",
12461246
"@executable_path/Frameworks",
12471247
);
1248-
MARKETING_VERSION = 3.2.3;
1248+
MARKETING_VERSION = 3.2.4;
12491249
PRODUCT_BUNDLE_IDENTIFIER = "com.nativeapptemplate.NativeAppTemplateFree.ios${SAMPLE_CODE_DISAMBIGUATOR}";
12501250
"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = "com.nativeapptemplate.NativeAppTemplateFree.ios${SAMPLE_CODE_DISAMBIGUATOR}";
12511251
PRODUCT_NAME = NativeAppTemplate;

NativeAppTemplate/UI/Shop List/ShopListView.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,16 @@ private extension ShopListView {
6363
var contentView: some View {
6464
@ViewBuilder var contentView: some View {
6565
switch viewModel.state {
66-
case .initial, .loading:
66+
case .initial:
6767
LoadingView()
68+
case .loading:
69+
// Keep showing the existing list while refreshing so re-appearance
70+
// reloads don't blink a full-screen LoadingView over loaded data.
71+
if viewModel.isEmpty {
72+
LoadingView()
73+
} else {
74+
shopListView
75+
}
6876
case .hasData:
6977
shopListView
7078
case .failed:

NativeAppTemplate/UI/Shop Settings/ItemTag List/ItemTagListView.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ private extension ItemTagListView {
3131
LoadingView()
3232
} else {
3333
switch viewModel.state {
34-
case .initial, .loading:
34+
case .initial:
3535
LoadingView()
36+
case .loading:
37+
// Keep showing the existing list while refreshing so re-appearance
38+
// reloads don't blink a full-screen LoadingView over loaded data.
39+
if viewModel.isEmpty {
40+
LoadingView()
41+
} else {
42+
itemTagListView
43+
}
3644
case .hasData:
3745
itemTagListView
3846
case .failed:

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,16 @@ NATIVEAPPTEMPLATE_API_PORT = 3000
149149

150150
> **Note:** Never use `127.0.0.1`, `localhost`, or `0.0.0.0` for `NATIVEAPPTEMPLATE_API_DOMAIN` — those resolve to the iOS Simulator/device itself, not your Mac. Use your Mac's LAN IP (e.g., `192.168.1.6`) so the simulator or a physical device can reach the API server.
151151
152-
Keep the scheme in `xcuserdata` (per-developer, gitignored), not `xcshareddata`. In Xcode, open **Product → Scheme → Manage Schemes…**, find `NativeAppTemplate`, and **uncheck "Shared"**. This moves the scheme (with your local env vars) to `xcuserdata/<user>.xcuserdatad/xcschemes/` so your API settings are not committed. If Xcode staged a deletion of the previously shared scheme, restore it with:
152+
The `NativeAppTemplate` scheme is **shared** (committed at `NativeAppTemplate.xcodeproj/xcshareddata/xcschemes/NativeAppTemplate.xcscheme`) so fresh clones and generated copies open with these env vars already wired — without it, Xcode's auto-created default omits the injection and Debug builds silently fall back to `https://api.nativeapptemplate.com`. The committed `NATIVEAPPTEMPLATE_API_DOMAIN` is just an example value (`192.168.1.11`); edit it to your own Mac's LAN IP.
153+
154+
Because the scheme is committed, keep your personal LAN IP out of git. After editing the value locally, tell git to ignore your changes to the file:
153155

154156
```bash
155-
git restore --source=HEAD --staged --worktree NativeAppTemplate.xcodeproj/xcshareddata/xcschemes/NativeAppTemplate.xcscheme
157+
git update-index --skip-worktree NativeAppTemplate.xcodeproj/xcshareddata/xcschemes/NativeAppTemplate.xcscheme
156158
```
157159

160+
To resume tracking it (e.g. before intentionally committing a scheme change), run `git update-index --no-skip-worktree <same path>`.
161+
158162
Debug builds read these at launch via `ProcessInfo.processInfo.environment` in `Constants.swift`; when unset, they fall back to the production defaults (`https://api.nativeapptemplate.com`). Release builds always use the production defaults.
159163

160164
In practice, only Xcode injects these env vars (via the scheme), so a Debug build launched any other way — tapped from the Home Screen (SpringBoard), opened on a physical device after Xcode disconnects, etc. — sees them unset and falls through to the production defaults. The hardcoded fallbacks are what keep the app working without Xcode in the loop.

0 commit comments

Comments
 (0)