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

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

Looking on feedback on the UI Design
Hi everyone, I'm developing a simple iOS app that solves quadratic equations using SwiftUI. I've attached a screenshot of the current interface. I'd appreciate feedback on the UI and user experience, especially from the perspective of Apple's Human Interface Guidelines. Thanks!
Topic: Design SubTopic: General Tags:
1
0
26
11h
Unexpected behavior in the interaction between LazyVStack and GeometryReader
Hello! I'd like to share a problem and its potential solution. Steps to reproduce: The issue can be reproduced with the following minimal example: struct TestConditionalScrollView: View { var body: some View { ConditionalScrollView { LazyVStack(spacing: 16) { Text("Text 1") .frame(height: 20) Text("Text 2") .frame(height: 30) Text("Text 3") .frame(height: 40) Text("Text 4") .frame(height: 500) Text("Text 5") .frame(height: 400) } .padding() } } } struct ConditionalScrollView<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } @State private var contentHeight: CGFloat = 0 var body: some View { GeometryReader { geo in _ = print("Height: \(contentHeight)") return Group { if contentHeight > geo.size.height { ScrollView { measuredContent } } else { measuredContent } } } } private var measuredContent: some View { content .background( GeometryReader { geo in Color.clear .preference( key: ContentHeightKey.self, value: geo.size.height ) } ) .onPreferenceChange(ContentHeightKey.self) { contentHeight = $0 } } } struct ContentHeightKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = max(value, nextValue()) } } If we hit the breakpoint on the following line: _ = print("Height: (contentHeight)") the output looks like this: Problems observed Different values are reported, and it is unclear where those values originate from. The selected execution branch appears to change multiple times during the layout process. Possible reason As Rens Breur mentioned in the WWDC26 session "Dive into lazy stacks and scrolling with SwiftUI", LazyVStack relies on estimated layout information during certain phases of the layout process. I do not want to rely on or investigate SwiftUI's non-public implementation details, but I would like to explain what I believe is happening internally. To do that, let me show how the value reaches the GeometryReader closure: Step 1 In AttributeGraph, the GeometryReader<...> node and the LazyVStack node appear to be connected as shown below: Step 2 When the LazyVStack node is updated, the layout process appears to follow roughly this logic: `SwiftUICore 'SwiftUI.ForEachState.forEachItem:` n = number of cells to evaluate (initially n == 2) For first n cells: SwiftUICore`SwiftUI.ViewLayoutEngine.sizeThatFits(...) SwiftUI.EstimationCache.add(...) The total size of the lazy stack is then estimated: SwiftUI.LazyStack<...>.sizeThatFits(...): averageCellInfo = EstimationCache.average averageCellInfo.height = (firstCellHeight + secondCellHeight) / 2 totalHeight = firstCellHeight + secondCellHeight + averageCellInfo.height * remainingCells For the sample project, this produces an estimated height of 189. This value then appears to be cached inside a LazyLayoutComputer node. Step 3 When GeometryReader is updated and its closure executes, geo.size.height appears to be resolved from the cached value stored by LazyLayoutComputer. As a result, the reported height is: 189 + 32 (padding) = 221 Step 4 My assumption is that LazyVStack subsequently validates the estimated layout against the actual layout results. It seems to compare: The maximum Y position of the last list's cell The cached sizeThatFits value If those values differ sufficiently, the transaction is not committed and another layout pass is triggered. During a later pass, the real sizes become available and GeometryReader eventually reports the final correct value. If this interpretation is correct, the behavior shown in the logs would be expected: followed later by: Possible solution I could not find a public SwiftUI API that provides an accurate content size during the initial layout pass. I tried the following options: LazyVStack + GeometryReader LazyVStack + ViewThatFits LazyVStack + .scrollBounceBehavior(...) At the same time, SwiftUI itself appears to have information about layout validity. For example, the layout logs contain entries such as: placed(...) -> ... invalid: true This suggests that SwiftUI can determine when an estimated layout result is no longer valid and requires additional layout passes. If SwiftUI knows that the current layout is invalid, is there a way to access this information from within a GeometryReader closure or by some other means? Otherwise, clients may perform layout calculations based on invalid geometry, which can result in a broken dependent layout. Have a good day!
0
0
14
12h
iOS 26 Beta bug - keyboard toolbar with bottom safe area inset
Hello! I have experienced a weird bug in iOS 26 Beta (8) and previous beta versions. The safe area inset is not correctly aligned with the keyboard toolbar on real devices and simulators. When you focus a new textfield the bottom safe area is correctly placed aligned the keyboard toolbar. On real devices the safe area inset view is covered slightly by the keyboard toolbar, which is even worse than on the simulator. Here's a clip from a simulator: Here's the code that reproduced the bug I experienced in our app. #Preview { NavigationStack { ScrollView { TextField("", text: .constant("")) .padding() .background(Color.secondary) TextField("", text: .constant("")) .padding() .background(Color.green) } .padding() .safeAreaInset(edge: .bottom, content: { Color.red .frame(maxWidth: .infinity) .frame(height: 40) }) .toolbar { ToolbarItem(placement: .keyboard) { Button {} label: { Text("test") } } } } }
4
12
1.3k
1d
SwiftUI Button with Image view label has smaller hit target
[Also submitted as FB20213961] SwiftUI Button with a label: closure containing only an Image view has a smaller tap target than buttons created with a Label or the convenience initializer. The hit area shrinks to the image bounds instead of preserving the standard minimum tappable size. SCREEN RECORDING On a physical device, the difference is obvious—it’s easy to miss the button. Sometimes it even shows the button-tapped bounce animation but doesn’t trigger the action. SYSTEM INFO Xcode Version 26.0 (17A321) macOS 15.6.1 (24G90) iOS 26.0 (23A340) SAMPLE CODE The following snippet shows the difference in hit targets between the convenience initializer, a Label, and an Image (the latter two in a label: closure). // ✅ Hit target is entire button Button("Button 1", systemImage: "1.square.fill") { print("Button 1 tapped") } // ✅ Hit target is entire button Button { print("Button 2 tapped") } label: { Label("Button 2", systemImage: "2.square.fill") } // ❌ Hit target is smaller than button Button { print("Button 3 tapped") } label: { Image(systemName: "3.square.fill") }
7
4
756
2d
SwiftUI animation is laggy in NSStatusItem since macOS 26 Tahoe
My app is a bit of a special case and relies on a custom view in a NSStatusItem. I use a NSHostingView and add it as a subview to my NSStatusItem's .button property. Since macOS 26 Tahoe, even simple animations like a .frame change of a Circle won't animate smoothly even though the same SwiftUI animates normally in a WindowGroup. class AppDelegate: NSObject, NSApplicationDelegate { private let statusItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) func applicationDidFinishLaunching(_ aNotification: Notification) { let subview = NSHostingView(rootView: AnimationView()) let view = self.statusItem.button view?.addSubview(subview) subview.translatesAutoresizingMaskIntoConstraints = false guard let view = view else { return } NSLayoutConstraint.activate([ subview.centerXAnchor.constraint(equalTo: view.centerXAnchor), subview.centerYAnchor.constraint(equalTo: view.centerYAnchor), subview.widthAnchor.constraint(equalToConstant: 22), subview.heightAnchor.constraint(equalToConstant: 22) ]) } } struct AnimationView: View { @State private var isTapped = false @State private var size: CGSize = .init(width: 4, height: 4) var body: some View { Circle() .fill(.pink) .frame(width: size.width, height: size.height) .frame(width: 20, height: 20) // .frame(maxHeight: .infinity) // .padding(.horizontal, 9) // .frame(height: 22) .contentShape(Rectangle()) // .background(Color.blue.opacity(0.5)) .onTapGesture { withAnimation(.interactiveSpring(response: 0.85, dampingFraction: 0.26, blendDuration: 0.45)) { // withAnimation(.spring()) { if isTapped { size = .init(width: 4, height: 4) } else { size = .init(width: 16, height: 16) } } isTapped.toggle() }} } Example project: https://app.box.com/s/q28upunrgkxyyd97ovslgud9yitqaxfk
1
0
186
2d
Tab bar animates from first tab to restored selection at launch with .tabBarMinimizeBehavior(.onScrollDown)
[Submitted as FB23998635] On iPhone, applying .tabBarMinimizeBehavior(.onScrollDown) to a SwiftUI TabView causes the native tab bar to briefly show the first declared tab before animating to the already-restored selection during app launch. The selected tab is persisted with @AppStorage and is already restored before the TabView is presented. The sample contains no explicit animations, transactions, navigation containers, loading states, asynchronous work, or post-launch selection changes. Removing .tabBarMinimizeBehavior(.onScrollDown) eliminates the launch animation entirely. Likewise, starting with .tabBarMinimizeBehavior(.never) and changing it to .onScrollDown after a one-second delay also eliminates the issue. The behavior reproduces with three simple tabs and a direct @AppStorage selection binding. ENVIRONMENT • iOS 26 & 27 REPRO STEPS Build and run the attached sample. Select the "Two" tab. Force-quit the app. Relaunch the app. Observe the tab bar during launch. ACTUAL The tab indicator initially appears on "One", the first declared tab, then animates to the correctly restored "Two" selection. EXPECTED The restored tab should be selected and stationary from the first visible frame, with no launch animation. SAMPLE CODE struct ContentView: View { private enum AppTab: String, Hashable { case one case two case three } @AppStorage("selectedGenericTab") private var selectedTab: AppTab = .three var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: AppTab.one) { ReproTabContent(title: "One", color: .orange) } Tab("Two", systemImage: "2.circle", value: AppTab.two) { ReproTabContent(title: "Two", color: .blue) } Tab("Three", systemImage: "3.circle", value: AppTab.three) { ReproTabContent(title: "Three", color: .green) } } .tabBarMinimizeBehavior(.onScrollDown) } } private struct ReproTabContent: View { let title: String let color: Color var body: some View { ZStack { color.opacity(0.2) .ignoresSafeArea() Text(title) .font(.largeTitle) } } }
2
0
357
2d
SwiftUI template in Instruments 26.4.1 shows empty channels on iOS 26.4.2 device — even with a minimal TimelineView repro
Hi all, I've hit a reproducible issue where the presence of the SwiftUI instrument in a template prevents any data from being recorded, including from the other instruments in the same template. Removing the SwiftUI instrument immediately restores normal recording. Environment Host: macOS 26.4.1 (25E253), Mac mini Xcode / Instruments 26.4.1 (17E202) Device: iPhone 17, iOS 26.4.2 (23E261) (physical device, USB-attached) Symptom Recording the same app, same device, same session, only varying the template contents: SwiftUI template (as-is) => All lanes empty across the entire recording Same template with the SwiftUI instrument removed => Data collected normally (Time Profiler samples, Hangs, etc.) So it seems not an issue with the SwiftUI lanes specifically being empty — including the SwiftUI instrument appears to silence the entire recording. Steps to reproduce Open Instruments → pick the SwiftUI template (or build a custom template that includes the SwiftUI instrument alongside, e.g., Time Profiler). Target the device, attach to the running app. Record for ~10s, interact with the app. Stop. Result: every lane is empty. Edit the template, remove the SwiftUI instrument, re-record with no other changes. Result: normal data appears in the remaining instruments. Questions Is this a known regression in Instruments 26.4.1 on iOS 26.4.x? Is there a workaround to use the SwiftUI instrument on this OS combo (different Xcode build, runtime flag, entitlement)? Does it work for anyone on iOS 26.4.x + Xcode 26.4.1, or is everyone seeing this? I can file a Feedback if confirmed as a bug — wanted to check here first in case I'm missing a setup step. Thanks!
3
2
785
3d
Animations become choppy in NSStatusItem when other window contains ScrollView
Feedback ID: FB23984230 This issue for some reason does not happen on my external 165 Hz display, but happens on my built-in MacBook Air display (60Hz). See attached example project: Contains two parts NSStatusItem with animation that triggers during ‘.onTapGesture()’ a window with ContentView that contains List and ScrollView while any ScrollView / List is in the view hierarchy in ContentView, triggering an animation in NSStatusItem (on a built-in MacBook display) is very choppy once removing ScrollView / List from view hierarchy from ContentView, animation in NSStatusItem is very smooth Project: Link macOS 26.5.2 (25F84)
0
0
244
4d
SimCtl
Summary xcrun simctl install <valid.app> fails even though the app's Info.plist contains a correct, well-formed CFBundleIdentifier — verified independently with plutil -p. The app builds successfully via xcodebuild twice, under two different signing configurations. This is purely an install-time failure. ERROR · EVERY ATTEMPT An error was encountered processing the command (domain=IXErrorDomain, code=13): Simulator device failed to install the application. Missing bundle ID. Underlying error (domain=IXErrorDomain, code=13): Failed to get bundle ID from /QuestionsWeCarry.app Missing bundle ID. Environment MACOS 26.5.2 · Build 25F84 XCODE 26.6 · Build 17F113 SIMULATOR RUNTIME iOS 26.5 (23F77) HARDWARE Apple M5 KERNEL Darwin 25.5.0 arm64 XCODE.APP / SIMULATOR PLATFORM both freshly installed Xcode.app and the iOS Simulator platform were both freshly installed immediately before this was discovered — this may be a first-run / first-boot issue specific to this Xcode 26.6 + iOS 26.5 combination. Project being built A SwiftUI iOS app target generated via XcodeGen from project.yml, depending on a local Swift Package with four library products. Nothing exotic — no third-party SDKs, no CocoaPods, no entitlements file. PROJECT.YML — RELEVANT TARGET BLOCK PROJECT.YML targets: QuestionsWeCarry: type: application platform: iOS deploymentTarget: "17.0" sources: - path: App/Sources - path: App/Resources type: folder buildPhase: resources info: path: App/Info.plist properties: CFBundleDisplayName: "Questions We Carry" UILaunchScreen: {} ITSAppUsesNonExemptEncryption: false UIApplicationSceneManifest: UIApplicationSupportsMultipleScenes: false settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.brodywolfstudio.questionswecarry MARKETING_VERSION: "1.0.0" CURRENT_PROJECT_VERSION: "1" SWIFT_VERSION: "5.10" TARGETED_DEVICE_FAMILY: "1,2" CODE_SIGN_STYLE: Manual CODE_SIGN_IDENTITY: "-" CODE_SIGNING_REQUIRED: NO CODE_SIGNING_ALLOWED: YES dependencies: - package: QWCKit product: QWCCore - package: QWCKit product: QWCEngine - package: QWCKit product: QWCStore - package: QWCKit product: QWCUI BUILD COMMAND THAT SUCCEEDS SHELL xcodebuild -project QuestionsWeCarry.xcodeproj -scheme QuestionsWeCarry -configuration Debug -destination "platform=iOS Simulator,id=" -derivedDataPath DerivedData build Result: BUILD SUCCEEDED, produces DerivedData/Build/Products/Debug-iphonesimulator/QuestionsWeCarry.app. INFO.PLIST INSIDE THE BUILT .APP (VIA PLUTIL -P) INFO.PLIST { "BuildMachineOSBuild" => "25F84" "CFBundleDevelopmentRegion" => "en" "CFBundleDisplayName" => "Questions We Carry" "CFBundleExecutable" => "QuestionsWeCarry" "CFBundleIdentifier" => "com.brodywolfstudio.questionswecarry" "CFBundleInfoDictionaryVersion" => "6.0" "CFBundleName" => "QuestionsWeCarry" "CFBundlePackageType" => "APPL" "CFBundleShortVersionString" => "1.0" "CFBundleSupportedPlatforms" => [ 0 => "iPhoneSimulator" ] "CFBundleVersion" => "1" "DTCompiler" => "com.apple.compilers.llvm.clang.1_0" "DTPlatformBuild" => "23F81a" "DTPlatformName" => "iphonesimulator" "DTPlatformVersion" => "26.5" "DTSDKBuild" => "23F81a" "DTSDKName" => "iphonesimulator26.5" "DTXcode" => "2660" "DTXcodeBuild" => "17F113" "ITSAppUsesNonExemptEncryption" => false "MinimumOSVersion" => "17.0" "UIApplicationSceneManifest" => { "UIApplicationSupportsMultipleScenes" => false } "UIDeviceFamily" => [ 0 => 1 1 => 2 ] "UILaunchScreen" => { } } CFBundleIdentifier is present, correctly formed, and matches PRODUCT_BUNDLE_IDENTIFIER. file confirms this is a valid Apple binary property list, not corrupted. CODESIGN -DV ON THE BUILT APP CODESIGN -DV Executable=/QuestionsWeCarry.app/QuestionsWeCarry Identifier=QuestionsWeCarry-******* Format=bundle with Mach-O thin (arm64) CodeDirectory v=20400 size=338 flags=0x2(adhoc) hashes=3+3 location=embedded Signature=adhoc Info.plist=not bound TeamIdentifier=not set Sealed Resources version=2 rules=13 files=4 Internal requirements count=0 size=12 Note Info.plist=not bound — unclear whether this is expected for an ad-hoc-signed bundle app (as opposed to a framework), or is itself a symptom of the underlying problem. Reproduction Minimal, reproducible with the plain command-line tool — no Claude tooling involved in this step: SHELL xcrun simctl install "iPhone 17 Pro" "/DerivedData/Build/Products/Debug-iphonesimulator/QuestionsWeCarry.app" Result (100% reproducible, every attempt): STDERR An error was encountered processing the command (domain=IXErrorDomain, code=13): Simulator device failed to install the application. Missing bundle ID. Underlying error (domain=IXErrorDomain, code=13): Failed to get bundle ID from /QuestionsWeCarry.app Missing bundle ID. Also reproduced with xcrun simctl launch, which fails as a consequence: Isolation steps taken All of the following were tried, and none changed the outcome — the exact same "Missing bundle ID" error occurs every time: 01 Two signing configurations — unsigned/linker-signed (Sealed Resources=none) vs. proper ad-hoc sign (Sealed Resources version=2 rules=13 files=4), plus a manual codesign --force --deep --sign - re-sign pass. Same failure every time. 02 Two simulator destinations — generic/platform=iOS Simulator and a concrete device id for iPhone 17 Pro. 03 Two never-before-used simulator devices — iPhone 17 Pro and iPhone Air — ruling out per-device CoreSimulator state corruption. 04 Erase + cold boot — simctl shutdown, erase, boot immediately before a fresh install attempt. 05 Real Simulator.app GUI running — not just a headless simctl boot — ruled out a CoreSimulatorService/GUI dependency. 06 Path with no spaces — copied the .app out of a path containing "Application Support" — ruled out a path-quoting issue. The build itself is never in question — xcodebuild reports BUILD SUCCEEDED every time; only the subsequent simctl install step fails. What I'd like feedback on Is this a known issue with this specific Xcode 26.6 / iOS 26.5 Simulator runtime combination — both very recently installed, so possibly a fresh-install/first-boot bug? Is there a required build setting for this Xcode version not yet reflected in commonly-documented XcodeGen/xcodebuild recipes — e.g. an entitlements file now required even for simulator-only, no-team builds, or a different expected code-signing identity/format? Is Info.plist=not bound in the codesign -dv output actually abnormal for an app bundle (as opposed to a framework), and could that be the root cause simctl is choking on?
0
0
108
6d
WatchBlocks v1.5 is now available: a sandbox game built for Apple Watch
Hi everyone! After about 4-5 months of development, I released WatchBlocks v1.5 today. The project started as an experiment to answer a simple question: Could you build a real sandbox survival game that runs well on Apple Watch? It eventually grew into a cross-platform game supporting Apple Watch, iPhone, iPad, and Mac. Some of the technical challenges I enjoyed solving included: Optimizing rendering and gameplay for watchOS. Designing controls around the Digital Crown and the watch display. Building multiplayer across Apple platforms. Creating a content system that lets players make and share their own blocks, items, mobs, and biomes. The new update also transitions the game to a free-to-start model, making it easier for people to try it before deciding whether to unlock the full experience. I’d love to hear from other developers building for watchOS. It’s a platform that doesn’t get much attention for games, but I think there’s a lot of untapped potential. If anyone has questions about developing games for Apple Watch, I’m happy to answer them. App Store: https://apps.apple.com/us/app/watchblocks-craft-build/id6760209351
0
0
471
6d
What's the preferred way enable scroll behind tab bar in nested ScrollView in SwiftUI
I am having a root TabView with tabs. One of the tabs has a TabBar with page style as the root view and each Page has a ScrollView. Unfortunately the scroll view get's clipped by the parent TabView size. But I want to make the ScrollView content to go behind the root TabView's tab bar like it would work if I would have the ScrollView as direct child to the root TabBar I tried using ignoreSafeArea on the page style TabView and there are other weird bugs, it stops reacting to the Binding pageIndex I am having as a State. The custom page index view disappears Sample code: https://github.com/BProg/TabViewScrollViewBug.git
2
0
83
6d
SwiftUI's `scrollTo(id:anchor:)` doesn't work if the ScrollView is scrolling
Can somebody tell me if I'm doing something wrong or SwiftUI's scrollTo(id:anchor:) just doesn't work if the ScrollView is scrolling? I have a trivial example that demonstrates the issue: import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct Item: Identifiable { let id = UUID() let timestamp: Date let text: String } struct ContentView: View { @State private var items: [Item] = (0...10_000).map{ .init(timestamp: Date(), text: "Row \($0)") } @State private var scrollPosition = ScrollPosition(idType: Item.ID.self) @State private var newMessage: String = "" var body: some View { ScrollView { LazyVStack { ForEach(items) { item in ItemView(item: item) } }.scrollTargetLayout() } .defaultScrollAnchor(.bottom, for: .initialOffset) .scrollPosition($scrollPosition, anchor: .bottom) .safeAreaBar(edge: .bottom) { HStack { TextField("Type here", text: $newMessage, axis: .vertical) .textFieldStyle(.roundedBorder) Button("Send", action: { let trimmed = newMessage.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } newMessage = "" items.append(.init(timestamp: .now, text: trimmed)) withAnimation(.smooth) { scrollPosition.scrollTo(id: items.last!.id, anchor: .bottom) } }) }.padding() } } } struct ItemView: View { let item: Item var body: some View { VStack(alignment: .leading) { Text(item.text) Text(item.timestamp.formatted()) }.padding() .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))) } } #Preview { ContentView() }
2
0
125
6d
SwiftUI `List` incorrectly reuses stale `Equatable` objects when redrawing
Hi, We have found a nasty issue with SwiftUI List and Equatable reference types. In such scenarios List might resurface stale objects from some internal cache when inserting new equal instances, which can lead to outdated cells on screen. Detailed information can be found in our bug report (FB23923342). Since List is quite a widespread component we thought dropping a few lines here in addition to our report could be helpful, especially if you have been bitten by this issue in the past.
0
0
94
1w
Live Activity (ActivityKit) always defaults to dark colorScheme on iOS 27
Environment: iOS Version: iOS 27.0 Framework: ActivityKit Xcode Version: Xcode 26.1 Issue Description: In iOS 27, Live Activities fail to adapt to the system colorScheme. Regardless of whether the system theme is set to Light or Dark mode, @Environment(.colorScheme) inside the Live Activity view always returns .dark. This behavior worked as expected on iOS 26, where the Live Activity correctly responded to light/dark mode changes and rendered the appropriate theme. Expected Behavior: The Live Activity view should respect the system's current colorScheme (returning .light when the system is in Light Mode) on iOS 27, consistent with the behavior on iOS 26. Actual Behavior: The Live Activity view strictly defaults to .dark mode on iOS 27, even when the device is explicitly set to Light Mode. struct LockScreenView<T: BaseLiveActivityAttributes>: View { let context: ActivityViewContext<T> @Environment(\.colorScheme) var colorScheme var isLight: Bool { colorScheme == .light } var body: some View { Color(isLight ? .white : .black) .overlay(alignment: .topTrailing) { VStack(alignment: .trailing, spacing: 2) { Text("colorScheme: \(String(describing: colorScheme))") } .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.yellow) .padding(4) .background(Color.black.opacity(0.6)) .cornerRadius(4) .padding(.trailing, 8) .padding(.top, 4) } } } Any insights or workarounds would be greatly appreciated. Thanks!
0
0
157
1w
SwiftUI, macOS, PDFView, The "Remove Highlight" context menu does not work
I'm using PDFKitView: NSViewRepresentable to present the pdf page in SwiftUI. Seems we already have some useful built-in functions in the context menu. However, the highlight manipulation functions are not functional - I can neither delete the highlight annotation nor change the color/type of the current pointed highlight annotation. The "Add Note" and other page display changing functions work well.
2
1
1k
1w
Introducing My Independent App Portfolio — Games, Education and Utilities
Hello Apple Developer Community, My name is Chris, and I’m an independent developer building games, educational tools, and utility apps for Apple platforms. I’d like to share some of the applications I have released so far: ADVENT Text Game for Mac A retro-inspired text adventure designed specifically for macOS. View on the App Store ADVENT Text Game for iPhone and iPad Explore mysterious caves, discover hidden passages, collect treasures, and solve puzzles in a classic-inspired text adventure. View on the App Store iFrappe View on the App Store China Driving Exam Trainer A study and practice application for learners preparing for the Chinese driving licence theory examination. View on the App Store Ur: The Royal Game A digital interpretation of the ancient Royal Game of Ur. View on the App Store I’m also currently developing Steel Maze, a retro maze-based tank battle game for iPhone, iPad, and Mac. Each project has helped me explore different parts of Apple development, including SwiftUI, SpriteKit, Mac Catalyst, responsive layouts, Game Center, gameplay design, and App Store distribution. I would be happy to receive feedback from other developers and connect with people working on similar independent projects. You can find my current app portfolio here: CK My Apps Thank you for taking a look!
1
0
178
1w
iOS 27 beta 1: .scrollEdgeEffectStyle(.soft) renders fully transparent above safeAreaBar
Feedback ID: FB23086400 On iOS 27 beta 1, .scrollEdgeEffectStyle(.soft, for: .top) on a List underneath a custom .safeAreaBar(edge: .top) no longer renders the progressive fade-blur. The top edge is fully transparent — scrolled rows pass under the bar with no visual treatment at all, as if scrollEdgeEffectDisabled() had been applied. What I've verified so far: .hard renders correctly in the exact same hierarchy; only .soft is affected. The same binary works correctly on iOS 26.x Xcode preview. I'm building with Xcode 26.3 (iOS 26 SDK). Minimal reproduction: import SwiftUI struct EdgeEffectRepro: View { enum Style: String, CaseIterable, Identifiable { case automatic, soft, hard var id: Self { self } var value: ScrollEdgeEffectStyle { switch self { case .automatic: .automatic case .soft: .soft case .hard: .hard } } } @State private var style: Style = .soft @State private var useSystemBarOnly = false var body: some View { NavigationStack { List(0..<60, id: \.self) { i in Text("Row \(i)") .frame(maxWidth: .infinity, alignment: .leading) .listRowBackground( i.isMultiple(of: 2) ? Color.orange.opacity(0.45) : Color.teal.opacity(0.45) ) } .scrollIndicators(.hidden) .scrollEdgeEffectStyle(style.value, for: .top) .safeAreaBar(edge: .top) { if !useSystemBarOnly { VStack(spacing: 8) { HStack { Text("Custom Top Bar") .font(.system(size: 28, weight: .bold)) Spacer() } HStack { Text("Second row (e.g. date range picker)") .font(.caption) .foregroundStyle(.secondary) Spacer() } } .padding(.horizontal) } } .safeAreaInset(edge: .bottom) { VStack(spacing: 8) { Picker("Edge effect style", selection: $style) { ForEach(Style.allCases) { Text($0.rawValue).tag($0) } } .pickerStyle(.segmented) Toggle("System bar only (control group)", isOn: $useSystemBarOnly) .font(.caption) } .padding() .background(.regularMaterial) } .navigationTitle("EdgeEffect Repro") .navigationBarTitleDisplayMode(.inline) } } } Steps: run on iOS 27 beta 1, set the picker to soft, scroll rows under the bar. Expected: fade-blur as on iOS 26. Actual: fully transparent. Switch to hard: renders fine.
4
7
666
1w
UIDesignRequiresCompatibility support clarification.
Hello, Could someone from Apple clarify the support and behavior of the UIDesignRequiresCompatibility property? The UIDesignRequiresCompatibility documentation states that this property will be ignored for builds targeting iOS 27 or later. I have a couple of questions: Does "builds targeting iOS 27 or later" refer to an app that was built using Xcode 27 or later? iOS 27 is expected to be released in Fall 2026. Suppose that after iOS 27 is released, I create a new build using Xcode 26, with UIDesignRequiresCompatibility set to true, and install that build on an iOS 27 device. Will UIDesignRequiresCompatibility still be honored in this scenario, or will it be ignored and the app will use the Liquid Glass UI? Thanks!
1
0
155
1w
Looking on feedback on the UI Design
Hi everyone, I'm developing a simple iOS app that solves quadratic equations using SwiftUI. I've attached a screenshot of the current interface. I'd appreciate feedback on the UI and user experience, especially from the perspective of Apple's Human Interface Guidelines. Thanks!
Topic: Design SubTopic: General Tags:
Replies
1
Boosts
0
Views
26
Activity
11h
Unexpected behavior in the interaction between LazyVStack and GeometryReader
Hello! I'd like to share a problem and its potential solution. Steps to reproduce: The issue can be reproduced with the following minimal example: struct TestConditionalScrollView: View { var body: some View { ConditionalScrollView { LazyVStack(spacing: 16) { Text("Text 1") .frame(height: 20) Text("Text 2") .frame(height: 30) Text("Text 3") .frame(height: 40) Text("Text 4") .frame(height: 500) Text("Text 5") .frame(height: 400) } .padding() } } } struct ConditionalScrollView<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } @State private var contentHeight: CGFloat = 0 var body: some View { GeometryReader { geo in _ = print("Height: \(contentHeight)") return Group { if contentHeight > geo.size.height { ScrollView { measuredContent } } else { measuredContent } } } } private var measuredContent: some View { content .background( GeometryReader { geo in Color.clear .preference( key: ContentHeightKey.self, value: geo.size.height ) } ) .onPreferenceChange(ContentHeightKey.self) { contentHeight = $0 } } } struct ContentHeightKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = max(value, nextValue()) } } If we hit the breakpoint on the following line: _ = print("Height: (contentHeight)") the output looks like this: Problems observed Different values are reported, and it is unclear where those values originate from. The selected execution branch appears to change multiple times during the layout process. Possible reason As Rens Breur mentioned in the WWDC26 session "Dive into lazy stacks and scrolling with SwiftUI", LazyVStack relies on estimated layout information during certain phases of the layout process. I do not want to rely on or investigate SwiftUI's non-public implementation details, but I would like to explain what I believe is happening internally. To do that, let me show how the value reaches the GeometryReader closure: Step 1 In AttributeGraph, the GeometryReader<...> node and the LazyVStack node appear to be connected as shown below: Step 2 When the LazyVStack node is updated, the layout process appears to follow roughly this logic: `SwiftUICore 'SwiftUI.ForEachState.forEachItem:` n = number of cells to evaluate (initially n == 2) For first n cells: SwiftUICore`SwiftUI.ViewLayoutEngine.sizeThatFits(...) SwiftUI.EstimationCache.add(...) The total size of the lazy stack is then estimated: SwiftUI.LazyStack<...>.sizeThatFits(...): averageCellInfo = EstimationCache.average averageCellInfo.height = (firstCellHeight + secondCellHeight) / 2 totalHeight = firstCellHeight + secondCellHeight + averageCellInfo.height * remainingCells For the sample project, this produces an estimated height of 189. This value then appears to be cached inside a LazyLayoutComputer node. Step 3 When GeometryReader is updated and its closure executes, geo.size.height appears to be resolved from the cached value stored by LazyLayoutComputer. As a result, the reported height is: 189 + 32 (padding) = 221 Step 4 My assumption is that LazyVStack subsequently validates the estimated layout against the actual layout results. It seems to compare: The maximum Y position of the last list's cell The cached sizeThatFits value If those values differ sufficiently, the transaction is not committed and another layout pass is triggered. During a later pass, the real sizes become available and GeometryReader eventually reports the final correct value. If this interpretation is correct, the behavior shown in the logs would be expected: followed later by: Possible solution I could not find a public SwiftUI API that provides an accurate content size during the initial layout pass. I tried the following options: LazyVStack + GeometryReader LazyVStack + ViewThatFits LazyVStack + .scrollBounceBehavior(...) At the same time, SwiftUI itself appears to have information about layout validity. For example, the layout logs contain entries such as: placed(...) -> ... invalid: true This suggests that SwiftUI can determine when an estimated layout result is no longer valid and requires additional layout passes. If SwiftUI knows that the current layout is invalid, is there a way to access this information from within a GeometryReader closure or by some other means? Otherwise, clients may perform layout calculations based on invalid geometry, which can result in a broken dependent layout. Have a good day!
Replies
0
Boosts
0
Views
14
Activity
12h
iOS 26 Beta bug - keyboard toolbar with bottom safe area inset
Hello! I have experienced a weird bug in iOS 26 Beta (8) and previous beta versions. The safe area inset is not correctly aligned with the keyboard toolbar on real devices and simulators. When you focus a new textfield the bottom safe area is correctly placed aligned the keyboard toolbar. On real devices the safe area inset view is covered slightly by the keyboard toolbar, which is even worse than on the simulator. Here's a clip from a simulator: Here's the code that reproduced the bug I experienced in our app. #Preview { NavigationStack { ScrollView { TextField("", text: .constant("")) .padding() .background(Color.secondary) TextField("", text: .constant("")) .padding() .background(Color.green) } .padding() .safeAreaInset(edge: .bottom, content: { Color.red .frame(maxWidth: .infinity) .frame(height: 40) }) .toolbar { ToolbarItem(placement: .keyboard) { Button {} label: { Text("test") } } } } }
Replies
4
Boosts
12
Views
1.3k
Activity
1d
Accessing SwiftData document package?
I would very much like to store some additional data in my SwiftData document package, outside of SwiftData. Metadata about the document that doesn't lend itself well to the underlying RDBMS nature of SwiftData. Is that possible?
Replies
1
Boosts
1
Views
931
Activity
1d
SwiftUI Button with Image view label has smaller hit target
[Also submitted as FB20213961] SwiftUI Button with a label: closure containing only an Image view has a smaller tap target than buttons created with a Label or the convenience initializer. The hit area shrinks to the image bounds instead of preserving the standard minimum tappable size. SCREEN RECORDING On a physical device, the difference is obvious—it’s easy to miss the button. Sometimes it even shows the button-tapped bounce animation but doesn’t trigger the action. SYSTEM INFO Xcode Version 26.0 (17A321) macOS 15.6.1 (24G90) iOS 26.0 (23A340) SAMPLE CODE The following snippet shows the difference in hit targets between the convenience initializer, a Label, and an Image (the latter two in a label: closure). // ✅ Hit target is entire button Button("Button 1", systemImage: "1.square.fill") { print("Button 1 tapped") } // ✅ Hit target is entire button Button { print("Button 2 tapped") } label: { Label("Button 2", systemImage: "2.square.fill") } // ❌ Hit target is smaller than button Button { print("Button 3 tapped") } label: { Image(systemName: "3.square.fill") }
Replies
7
Boosts
4
Views
756
Activity
2d
SwiftUI animation is laggy in NSStatusItem since macOS 26 Tahoe
My app is a bit of a special case and relies on a custom view in a NSStatusItem. I use a NSHostingView and add it as a subview to my NSStatusItem's .button property. Since macOS 26 Tahoe, even simple animations like a .frame change of a Circle won't animate smoothly even though the same SwiftUI animates normally in a WindowGroup. class AppDelegate: NSObject, NSApplicationDelegate { private let statusItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) func applicationDidFinishLaunching(_ aNotification: Notification) { let subview = NSHostingView(rootView: AnimationView()) let view = self.statusItem.button view?.addSubview(subview) subview.translatesAutoresizingMaskIntoConstraints = false guard let view = view else { return } NSLayoutConstraint.activate([ subview.centerXAnchor.constraint(equalTo: view.centerXAnchor), subview.centerYAnchor.constraint(equalTo: view.centerYAnchor), subview.widthAnchor.constraint(equalToConstant: 22), subview.heightAnchor.constraint(equalToConstant: 22) ]) } } struct AnimationView: View { @State private var isTapped = false @State private var size: CGSize = .init(width: 4, height: 4) var body: some View { Circle() .fill(.pink) .frame(width: size.width, height: size.height) .frame(width: 20, height: 20) // .frame(maxHeight: .infinity) // .padding(.horizontal, 9) // .frame(height: 22) .contentShape(Rectangle()) // .background(Color.blue.opacity(0.5)) .onTapGesture { withAnimation(.interactiveSpring(response: 0.85, dampingFraction: 0.26, blendDuration: 0.45)) { // withAnimation(.spring()) { if isTapped { size = .init(width: 4, height: 4) } else { size = .init(width: 16, height: 16) } } isTapped.toggle() }} } Example project: https://app.box.com/s/q28upunrgkxyyd97ovslgud9yitqaxfk
Replies
1
Boosts
0
Views
186
Activity
2d
Tab bar animates from first tab to restored selection at launch with .tabBarMinimizeBehavior(.onScrollDown)
[Submitted as FB23998635] On iPhone, applying .tabBarMinimizeBehavior(.onScrollDown) to a SwiftUI TabView causes the native tab bar to briefly show the first declared tab before animating to the already-restored selection during app launch. The selected tab is persisted with @AppStorage and is already restored before the TabView is presented. The sample contains no explicit animations, transactions, navigation containers, loading states, asynchronous work, or post-launch selection changes. Removing .tabBarMinimizeBehavior(.onScrollDown) eliminates the launch animation entirely. Likewise, starting with .tabBarMinimizeBehavior(.never) and changing it to .onScrollDown after a one-second delay also eliminates the issue. The behavior reproduces with three simple tabs and a direct @AppStorage selection binding. ENVIRONMENT • iOS 26 & 27 REPRO STEPS Build and run the attached sample. Select the "Two" tab. Force-quit the app. Relaunch the app. Observe the tab bar during launch. ACTUAL The tab indicator initially appears on "One", the first declared tab, then animates to the correctly restored "Two" selection. EXPECTED The restored tab should be selected and stationary from the first visible frame, with no launch animation. SAMPLE CODE struct ContentView: View { private enum AppTab: String, Hashable { case one case two case three } @AppStorage("selectedGenericTab") private var selectedTab: AppTab = .three var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: AppTab.one) { ReproTabContent(title: "One", color: .orange) } Tab("Two", systemImage: "2.circle", value: AppTab.two) { ReproTabContent(title: "Two", color: .blue) } Tab("Three", systemImage: "3.circle", value: AppTab.three) { ReproTabContent(title: "Three", color: .green) } } .tabBarMinimizeBehavior(.onScrollDown) } } private struct ReproTabContent: View { let title: String let color: Color var body: some View { ZStack { color.opacity(0.2) .ignoresSafeArea() Text(title) .font(.largeTitle) } } }
Replies
2
Boosts
0
Views
357
Activity
2d
SwiftUI template in Instruments 26.4.1 shows empty channels on iOS 26.4.2 device — even with a minimal TimelineView repro
Hi all, I've hit a reproducible issue where the presence of the SwiftUI instrument in a template prevents any data from being recorded, including from the other instruments in the same template. Removing the SwiftUI instrument immediately restores normal recording. Environment Host: macOS 26.4.1 (25E253), Mac mini Xcode / Instruments 26.4.1 (17E202) Device: iPhone 17, iOS 26.4.2 (23E261) (physical device, USB-attached) Symptom Recording the same app, same device, same session, only varying the template contents: SwiftUI template (as-is) => All lanes empty across the entire recording Same template with the SwiftUI instrument removed => Data collected normally (Time Profiler samples, Hangs, etc.) So it seems not an issue with the SwiftUI lanes specifically being empty — including the SwiftUI instrument appears to silence the entire recording. Steps to reproduce Open Instruments → pick the SwiftUI template (or build a custom template that includes the SwiftUI instrument alongside, e.g., Time Profiler). Target the device, attach to the running app. Record for ~10s, interact with the app. Stop. Result: every lane is empty. Edit the template, remove the SwiftUI instrument, re-record with no other changes. Result: normal data appears in the remaining instruments. Questions Is this a known regression in Instruments 26.4.1 on iOS 26.4.x? Is there a workaround to use the SwiftUI instrument on this OS combo (different Xcode build, runtime flag, entitlement)? Does it work for anyone on iOS 26.4.x + Xcode 26.4.1, or is everyone seeing this? I can file a Feedback if confirmed as a bug — wanted to check here first in case I'm missing a setup step. Thanks!
Replies
3
Boosts
2
Views
785
Activity
3d
Animations become choppy in NSStatusItem when other window contains ScrollView
Feedback ID: FB23984230 This issue for some reason does not happen on my external 165 Hz display, but happens on my built-in MacBook Air display (60Hz). See attached example project: Contains two parts NSStatusItem with animation that triggers during ‘.onTapGesture()’ a window with ContentView that contains List and ScrollView while any ScrollView / List is in the view hierarchy in ContentView, triggering an animation in NSStatusItem (on a built-in MacBook display) is very choppy once removing ScrollView / List from view hierarchy from ContentView, animation in NSStatusItem is very smooth Project: Link macOS 26.5.2 (25F84)
Replies
0
Boosts
0
Views
244
Activity
4d
SimCtl
Summary xcrun simctl install <valid.app> fails even though the app's Info.plist contains a correct, well-formed CFBundleIdentifier — verified independently with plutil -p. The app builds successfully via xcodebuild twice, under two different signing configurations. This is purely an install-time failure. ERROR · EVERY ATTEMPT An error was encountered processing the command (domain=IXErrorDomain, code=13): Simulator device failed to install the application. Missing bundle ID. Underlying error (domain=IXErrorDomain, code=13): Failed to get bundle ID from /QuestionsWeCarry.app Missing bundle ID. Environment MACOS 26.5.2 · Build 25F84 XCODE 26.6 · Build 17F113 SIMULATOR RUNTIME iOS 26.5 (23F77) HARDWARE Apple M5 KERNEL Darwin 25.5.0 arm64 XCODE.APP / SIMULATOR PLATFORM both freshly installed Xcode.app and the iOS Simulator platform were both freshly installed immediately before this was discovered — this may be a first-run / first-boot issue specific to this Xcode 26.6 + iOS 26.5 combination. Project being built A SwiftUI iOS app target generated via XcodeGen from project.yml, depending on a local Swift Package with four library products. Nothing exotic — no third-party SDKs, no CocoaPods, no entitlements file. PROJECT.YML — RELEVANT TARGET BLOCK PROJECT.YML targets: QuestionsWeCarry: type: application platform: iOS deploymentTarget: "17.0" sources: - path: App/Sources - path: App/Resources type: folder buildPhase: resources info: path: App/Info.plist properties: CFBundleDisplayName: "Questions We Carry" UILaunchScreen: {} ITSAppUsesNonExemptEncryption: false UIApplicationSceneManifest: UIApplicationSupportsMultipleScenes: false settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.brodywolfstudio.questionswecarry MARKETING_VERSION: "1.0.0" CURRENT_PROJECT_VERSION: "1" SWIFT_VERSION: "5.10" TARGETED_DEVICE_FAMILY: "1,2" CODE_SIGN_STYLE: Manual CODE_SIGN_IDENTITY: "-" CODE_SIGNING_REQUIRED: NO CODE_SIGNING_ALLOWED: YES dependencies: - package: QWCKit product: QWCCore - package: QWCKit product: QWCEngine - package: QWCKit product: QWCStore - package: QWCKit product: QWCUI BUILD COMMAND THAT SUCCEEDS SHELL xcodebuild -project QuestionsWeCarry.xcodeproj -scheme QuestionsWeCarry -configuration Debug -destination "platform=iOS Simulator,id=" -derivedDataPath DerivedData build Result: BUILD SUCCEEDED, produces DerivedData/Build/Products/Debug-iphonesimulator/QuestionsWeCarry.app. INFO.PLIST INSIDE THE BUILT .APP (VIA PLUTIL -P) INFO.PLIST { "BuildMachineOSBuild" => "25F84" "CFBundleDevelopmentRegion" => "en" "CFBundleDisplayName" => "Questions We Carry" "CFBundleExecutable" => "QuestionsWeCarry" "CFBundleIdentifier" => "com.brodywolfstudio.questionswecarry" "CFBundleInfoDictionaryVersion" => "6.0" "CFBundleName" => "QuestionsWeCarry" "CFBundlePackageType" => "APPL" "CFBundleShortVersionString" => "1.0" "CFBundleSupportedPlatforms" => [ 0 => "iPhoneSimulator" ] "CFBundleVersion" => "1" "DTCompiler" => "com.apple.compilers.llvm.clang.1_0" "DTPlatformBuild" => "23F81a" "DTPlatformName" => "iphonesimulator" "DTPlatformVersion" => "26.5" "DTSDKBuild" => "23F81a" "DTSDKName" => "iphonesimulator26.5" "DTXcode" => "2660" "DTXcodeBuild" => "17F113" "ITSAppUsesNonExemptEncryption" => false "MinimumOSVersion" => "17.0" "UIApplicationSceneManifest" => { "UIApplicationSupportsMultipleScenes" => false } "UIDeviceFamily" => [ 0 => 1 1 => 2 ] "UILaunchScreen" => { } } CFBundleIdentifier is present, correctly formed, and matches PRODUCT_BUNDLE_IDENTIFIER. file confirms this is a valid Apple binary property list, not corrupted. CODESIGN -DV ON THE BUILT APP CODESIGN -DV Executable=/QuestionsWeCarry.app/QuestionsWeCarry Identifier=QuestionsWeCarry-******* Format=bundle with Mach-O thin (arm64) CodeDirectory v=20400 size=338 flags=0x2(adhoc) hashes=3+3 location=embedded Signature=adhoc Info.plist=not bound TeamIdentifier=not set Sealed Resources version=2 rules=13 files=4 Internal requirements count=0 size=12 Note Info.plist=not bound — unclear whether this is expected for an ad-hoc-signed bundle app (as opposed to a framework), or is itself a symptom of the underlying problem. Reproduction Minimal, reproducible with the plain command-line tool — no Claude tooling involved in this step: SHELL xcrun simctl install "iPhone 17 Pro" "/DerivedData/Build/Products/Debug-iphonesimulator/QuestionsWeCarry.app" Result (100% reproducible, every attempt): STDERR An error was encountered processing the command (domain=IXErrorDomain, code=13): Simulator device failed to install the application. Missing bundle ID. Underlying error (domain=IXErrorDomain, code=13): Failed to get bundle ID from /QuestionsWeCarry.app Missing bundle ID. Also reproduced with xcrun simctl launch, which fails as a consequence: Isolation steps taken All of the following were tried, and none changed the outcome — the exact same "Missing bundle ID" error occurs every time: 01 Two signing configurations — unsigned/linker-signed (Sealed Resources=none) vs. proper ad-hoc sign (Sealed Resources version=2 rules=13 files=4), plus a manual codesign --force --deep --sign - re-sign pass. Same failure every time. 02 Two simulator destinations — generic/platform=iOS Simulator and a concrete device id for iPhone 17 Pro. 03 Two never-before-used simulator devices — iPhone 17 Pro and iPhone Air — ruling out per-device CoreSimulator state corruption. 04 Erase + cold boot — simctl shutdown, erase, boot immediately before a fresh install attempt. 05 Real Simulator.app GUI running — not just a headless simctl boot — ruled out a CoreSimulatorService/GUI dependency. 06 Path with no spaces — copied the .app out of a path containing "Application Support" — ruled out a path-quoting issue. The build itself is never in question — xcodebuild reports BUILD SUCCEEDED every time; only the subsequent simctl install step fails. What I'd like feedback on Is this a known issue with this specific Xcode 26.6 / iOS 26.5 Simulator runtime combination — both very recently installed, so possibly a fresh-install/first-boot bug? Is there a required build setting for this Xcode version not yet reflected in commonly-documented XcodeGen/xcodebuild recipes — e.g. an entitlements file now required even for simulator-only, no-team builds, or a different expected code-signing identity/format? Is Info.plist=not bound in the codesign -dv output actually abnormal for an app bundle (as opposed to a framework), and could that be the root cause simctl is choking on?
Replies
0
Boosts
0
Views
108
Activity
6d
WatchBlocks v1.5 is now available: a sandbox game built for Apple Watch
Hi everyone! After about 4-5 months of development, I released WatchBlocks v1.5 today. The project started as an experiment to answer a simple question: Could you build a real sandbox survival game that runs well on Apple Watch? It eventually grew into a cross-platform game supporting Apple Watch, iPhone, iPad, and Mac. Some of the technical challenges I enjoyed solving included: Optimizing rendering and gameplay for watchOS. Designing controls around the Digital Crown and the watch display. Building multiplayer across Apple platforms. Creating a content system that lets players make and share their own blocks, items, mobs, and biomes. The new update also transitions the game to a free-to-start model, making it easier for people to try it before deciding whether to unlock the full experience. I’d love to hear from other developers building for watchOS. It’s a platform that doesn’t get much attention for games, but I think there’s a lot of untapped potential. If anyone has questions about developing games for Apple Watch, I’m happy to answer them. App Store: https://apps.apple.com/us/app/watchblocks-craft-build/id6760209351
Replies
0
Boosts
0
Views
471
Activity
6d
What's the preferred way enable scroll behind tab bar in nested ScrollView in SwiftUI
I am having a root TabView with tabs. One of the tabs has a TabBar with page style as the root view and each Page has a ScrollView. Unfortunately the scroll view get's clipped by the parent TabView size. But I want to make the ScrollView content to go behind the root TabView's tab bar like it would work if I would have the ScrollView as direct child to the root TabBar I tried using ignoreSafeArea on the page style TabView and there are other weird bugs, it stops reacting to the Binding pageIndex I am having as a State. The custom page index view disappears Sample code: https://github.com/BProg/TabViewScrollViewBug.git
Replies
2
Boosts
0
Views
83
Activity
6d
SwiftUI's `scrollTo(id:anchor:)` doesn't work if the ScrollView is scrolling
Can somebody tell me if I'm doing something wrong or SwiftUI's scrollTo(id:anchor:) just doesn't work if the ScrollView is scrolling? I have a trivial example that demonstrates the issue: import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct Item: Identifiable { let id = UUID() let timestamp: Date let text: String } struct ContentView: View { @State private var items: [Item] = (0...10_000).map{ .init(timestamp: Date(), text: "Row \($0)") } @State private var scrollPosition = ScrollPosition(idType: Item.ID.self) @State private var newMessage: String = "" var body: some View { ScrollView { LazyVStack { ForEach(items) { item in ItemView(item: item) } }.scrollTargetLayout() } .defaultScrollAnchor(.bottom, for: .initialOffset) .scrollPosition($scrollPosition, anchor: .bottom) .safeAreaBar(edge: .bottom) { HStack { TextField("Type here", text: $newMessage, axis: .vertical) .textFieldStyle(.roundedBorder) Button("Send", action: { let trimmed = newMessage.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } newMessage = "" items.append(.init(timestamp: .now, text: trimmed)) withAnimation(.smooth) { scrollPosition.scrollTo(id: items.last!.id, anchor: .bottom) } }) }.padding() } } } struct ItemView: View { let item: Item var body: some View { VStack(alignment: .leading) { Text(item.text) Text(item.timestamp.formatted()) }.padding() .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))) } } #Preview { ContentView() }
Replies
2
Boosts
0
Views
125
Activity
6d
SwiftUI `List` incorrectly reuses stale `Equatable` objects when redrawing
Hi, We have found a nasty issue with SwiftUI List and Equatable reference types. In such scenarios List might resurface stale objects from some internal cache when inserting new equal instances, which can lead to outdated cells on screen. Detailed information can be found in our bug report (FB23923342). Since List is quite a widespread component we thought dropping a few lines here in addition to our report could be helpful, especially if you have been bitten by this issue in the past.
Replies
0
Boosts
0
Views
94
Activity
1w
Live Activity (ActivityKit) always defaults to dark colorScheme on iOS 27
Environment: iOS Version: iOS 27.0 Framework: ActivityKit Xcode Version: Xcode 26.1 Issue Description: In iOS 27, Live Activities fail to adapt to the system colorScheme. Regardless of whether the system theme is set to Light or Dark mode, @Environment(.colorScheme) inside the Live Activity view always returns .dark. This behavior worked as expected on iOS 26, where the Live Activity correctly responded to light/dark mode changes and rendered the appropriate theme. Expected Behavior: The Live Activity view should respect the system's current colorScheme (returning .light when the system is in Light Mode) on iOS 27, consistent with the behavior on iOS 26. Actual Behavior: The Live Activity view strictly defaults to .dark mode on iOS 27, even when the device is explicitly set to Light Mode. struct LockScreenView<T: BaseLiveActivityAttributes>: View { let context: ActivityViewContext<T> @Environment(\.colorScheme) var colorScheme var isLight: Bool { colorScheme == .light } var body: some View { Color(isLight ? .white : .black) .overlay(alignment: .topTrailing) { VStack(alignment: .trailing, spacing: 2) { Text("colorScheme: \(String(describing: colorScheme))") } .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.yellow) .padding(4) .background(Color.black.opacity(0.6)) .cornerRadius(4) .padding(.trailing, 8) .padding(.top, 4) } } } Any insights or workarounds would be greatly appreciated. Thanks!
Replies
0
Boosts
0
Views
157
Activity
1w
Vertical layout breaks after app switching from active keyboard context.
When switching to a SwiftUI app (built with Xcode 26.5) from an app with an active keyboard, the target app's tab bar incorrectly floats above the keyboard safe area. This layout issue occurs even though the target app does not display a keyboard and contains only a tab bar and scroll views.
Replies
2
Boosts
0
Views
136
Activity
1w
SwiftUI, macOS, PDFView, The "Remove Highlight" context menu does not work
I'm using PDFKitView: NSViewRepresentable to present the pdf page in SwiftUI. Seems we already have some useful built-in functions in the context menu. However, the highlight manipulation functions are not functional - I can neither delete the highlight annotation nor change the color/type of the current pointed highlight annotation. The "Add Note" and other page display changing functions work well.
Replies
2
Boosts
1
Views
1k
Activity
1w
Introducing My Independent App Portfolio — Games, Education and Utilities
Hello Apple Developer Community, My name is Chris, and I’m an independent developer building games, educational tools, and utility apps for Apple platforms. I’d like to share some of the applications I have released so far: ADVENT Text Game for Mac A retro-inspired text adventure designed specifically for macOS. View on the App Store ADVENT Text Game for iPhone and iPad Explore mysterious caves, discover hidden passages, collect treasures, and solve puzzles in a classic-inspired text adventure. View on the App Store iFrappe View on the App Store China Driving Exam Trainer A study and practice application for learners preparing for the Chinese driving licence theory examination. View on the App Store Ur: The Royal Game A digital interpretation of the ancient Royal Game of Ur. View on the App Store I’m also currently developing Steel Maze, a retro maze-based tank battle game for iPhone, iPad, and Mac. Each project has helped me explore different parts of Apple development, including SwiftUI, SpriteKit, Mac Catalyst, responsive layouts, Game Center, gameplay design, and App Store distribution. I would be happy to receive feedback from other developers and connect with people working on similar independent projects. You can find my current app portfolio here: CK My Apps Thank you for taking a look!
Replies
1
Boosts
0
Views
178
Activity
1w
iOS 27 beta 1: .scrollEdgeEffectStyle(.soft) renders fully transparent above safeAreaBar
Feedback ID: FB23086400 On iOS 27 beta 1, .scrollEdgeEffectStyle(.soft, for: .top) on a List underneath a custom .safeAreaBar(edge: .top) no longer renders the progressive fade-blur. The top edge is fully transparent — scrolled rows pass under the bar with no visual treatment at all, as if scrollEdgeEffectDisabled() had been applied. What I've verified so far: .hard renders correctly in the exact same hierarchy; only .soft is affected. The same binary works correctly on iOS 26.x Xcode preview. I'm building with Xcode 26.3 (iOS 26 SDK). Minimal reproduction: import SwiftUI struct EdgeEffectRepro: View { enum Style: String, CaseIterable, Identifiable { case automatic, soft, hard var id: Self { self } var value: ScrollEdgeEffectStyle { switch self { case .automatic: .automatic case .soft: .soft case .hard: .hard } } } @State private var style: Style = .soft @State private var useSystemBarOnly = false var body: some View { NavigationStack { List(0..<60, id: \.self) { i in Text("Row \(i)") .frame(maxWidth: .infinity, alignment: .leading) .listRowBackground( i.isMultiple(of: 2) ? Color.orange.opacity(0.45) : Color.teal.opacity(0.45) ) } .scrollIndicators(.hidden) .scrollEdgeEffectStyle(style.value, for: .top) .safeAreaBar(edge: .top) { if !useSystemBarOnly { VStack(spacing: 8) { HStack { Text("Custom Top Bar") .font(.system(size: 28, weight: .bold)) Spacer() } HStack { Text("Second row (e.g. date range picker)") .font(.caption) .foregroundStyle(.secondary) Spacer() } } .padding(.horizontal) } } .safeAreaInset(edge: .bottom) { VStack(spacing: 8) { Picker("Edge effect style", selection: $style) { ForEach(Style.allCases) { Text($0.rawValue).tag($0) } } .pickerStyle(.segmented) Toggle("System bar only (control group)", isOn: $useSystemBarOnly) .font(.caption) } .padding() .background(.regularMaterial) } .navigationTitle("EdgeEffect Repro") .navigationBarTitleDisplayMode(.inline) } } } Steps: run on iOS 27 beta 1, set the picker to soft, scroll rows under the bar. Expected: fade-blur as on iOS 26. Actual: fully transparent. Switch to hard: renders fine.
Replies
4
Boosts
7
Views
666
Activity
1w
UIDesignRequiresCompatibility support clarification.
Hello, Could someone from Apple clarify the support and behavior of the UIDesignRequiresCompatibility property? The UIDesignRequiresCompatibility documentation states that this property will be ignored for builds targeting iOS 27 or later. I have a couple of questions: Does "builds targeting iOS 27 or later" refer to an app that was built using Xcode 27 or later? iOS 27 is expected to be released in Fall 2026. Suppose that after iOS 27 is released, I create a new build using Xcode 26, with UIDesignRequiresCompatibility set to true, and install that build on an iOS 27 device. Will UIDesignRequiresCompatibility still be honored in this scenario, or will it be ignored and the app will use the Liquid Glass UI? Thanks!
Replies
1
Boosts
0
Views
155
Activity
1w