Core Animation

RSS for tag

Render, compose, and animate visual elements using Core Animation.

Posts under Core Animation tag

175 Posts

Post

Replies

Boosts

Views

Activity

macOS 27 beta: ProMotion refresh cadence is unstable, causing constant scroll judder
FB24091347 On macOS 27.0 beta (26A5388g), MacBook Pro M4 Pro, the built-in ProMotion display never settles on a stable refresh cadence. Scrolling in SwiftUI judders constantly. The same app binary was smooth on macOS 26, and is smooth on a 120 Hz ProMotion iPad. I captured two 60-second Instruments traces — same app, same scene, same scrolling, no external display — changing only the display's refresh-rate setting. On ProMotion the vsync interval standard deviation is 4.093 ms across six different cadences, mostly flip-flopping between 120 Hz and 60 Hz. Forced to a fixed 60 Hz it drops to 0.391 ms with a single cadence. The app presented an identical 59 fps median in both runs — frame production is perfectly steady, the display just holds each frame for an unpredictable length of time. That's what makes this nasty: it's invisible to every frame-rate metric, so it looks like the app got slow when nothing about the app changed. I spent most of a day profiling my own code before realising the app was never the problem. Workaround: force the built-in display to 60 Hz. Worth noting, because it complicates the picture: attaching a 60 Hz Studio Display makes the built-in smooth, but the Studio itself then judders — despite its own vsync cadence measuring perfectly stable. So refresh rate alone isn't the whole story, and there may be a second mechanism. The clean, reproducible, single-variable result is the ProMotion vs forced-60 Hz comparison on the built-in panel. If you can reproduce this on an M-series MacBook Pro on 27 beta, please file a duplicate referencing FB24091347.
6
2
2.5k
2w
Core Animation Background Thread CATransaction
Hey everyone 👋 I'm trying to initialize a part of a CALayer hierarchy on a background thread and then attach the root of that hierarchy to a CALayer that backs a UIView. The motivation is to keep the main thread responsive when constructing a complex layer hierarchy. This isn't a case where I'm creating two or three layers and then switching back to the main thread. The hierarchy can potentially contain a large number of layers, with animations being created/configured for those layers as well. My first approach was to create and configure the layers entirely on a background thread. While the output might be the expected one (not always), CoreAnimation emits an assertion along the lines of: "Modifications to the layer tree from a background thread may not be committed" (or something like this). This makes sense to me if implicit CATransaction is thread-local. In that case, the implicit transaction opened by the layer modification on the background thread would not be part of the transaction that is already open on the main thread. Therefore, committing the main-thread transaction would not commit the changes made on the background thread. My second approach was to explicitly create and commit a CATransaction on the background thread. This appears to be accepted by Core Animation's threading model, but I'm seeing unreliable results. Sometimes parts of the hierarchy are missing, and in other cases the hierarchy is present but the animations don't appear to run at all. I do understand that this is private behavior of the framework, but I wanted to know if what I am trying to achieve is possible and, if so, what the solution would be (obviously if you can share this information). Besides this, I would also like to know what behavior CATransactions have when they are created on different threads. What I mean by this is that the transactions work as a stack, and the changes are committed when the stack is empty. Does this behavior still apply when having transactions on different threads? Any weird behaviours that might appear between transactions operated on main vs background threads? Thank you! Vlad.
7
0
1.1k
Sep ’26
window:willUseFullScreenPresentationOptions: with NSApplicationPresentationHideDock causes other windows to be unminimizable
In the below code, I create two windows, and use a window delegate to make sure that whenever the first is fullscreened, its menubar and dock are hidden properly. However, when I fullscreen the first window and go back to the desktop to see my second window, the second window's minimize button is grayed out and using miniaturize on it will not work either. I've tried various things; it seems like if I fullscreen the second window and the unfullscreen it, it then becomes minimizable without additional side effects. Is there any reason why this is happening? This seems like a bug in AppKit... so how do I work around it programmatically? #import <Cocoa/Cocoa.h> @interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> @property (strong) NSWindow *mainWindow; @property (strong) NSWindow *secondaryWindow; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSRect mainRect = NSMakeRect(100, 300, 400, 300); self.mainWindow = [[NSWindow alloc] initWithContentRect:mainRect styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable) backing:NSBackingStoreBuffered defer:NO]; [self.mainWindow setTitle:@"Main Window (Go Fullscreen Here)"]; [self.mainWindow setDelegate:self]; NSTextField *mainLabel = [NSTextField labelWithString:@"1. Click the green zoom/fullscreen button on THIS window.\n\n2. Look at the other window's yellow minimize button."]; [mainLabel setFrame:NSMakeRect(20, 100, 360, 100)]; [[self.mainWindow contentView] addSubview:mainLabel]; [self.mainWindow makeKeyAndOrderFront:nil]; NSRect secondaryRect = NSMakeRect(550, 300, 400, 300); self.secondaryWindow = [[NSWindow alloc] initWithContentRect:secondaryRect styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable) backing:NSBackingStoreBuffered defer:NO]; [self.secondaryWindow setTitle:@"Secondary Window (The Victim)"]; NSButton *testButton = [NSButton buttonWithTitle:@"Try code [window miniaturize:]" target:self action:@selector(attemptProgrammaticMinimize:)]; [testButton setFrame:NSMakeRect(80, 130, 240, 40)]; [[self.secondaryWindow contentView] addSubview:testButton]; [self.secondaryWindow makeKeyAndOrderFront:nil]; } - (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { return NSApplicationPresentationFullScreen | NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock; } - (void)attemptProgrammaticMinimize:(id)sender { [self.secondaryWindow miniaturize:nil]; NSLog(@"[Repro] Minimize attempted"); } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { return YES; } @end int main(int argc, const char * argv[]) { @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; [app setActivationPolicy:NSApplicationActivationPolicyRegular]; AppDelegate *delegate = [[AppDelegate alloc] init]; [app setDelegate:delegate]; [app activateIgnoringOtherApps:YES]; [app run]; } return 0; }
3
0
985
Aug ’26
How Did Apple Create the Fitness App Awards Animation?
Open your Apple Fitness app, I am facinated by the animation of the Awards screen, it is so smooth. Any idea how this was transiton created from a Grid/CollectionView to a RealityView? I assume the interative badge is a RealityView with a 3D model in there, but how the hell the transition was so smooth from the parent list screen to the detail screen.
0
0
555
Jul ’26
CATiledLayer flashes and re-draws entirely when re-drawing a single tile
I have filed a bug report for this (FB17734946), but I'm posting it here verbatim in case others have the same issue and in hopes of getting attention from an Apple engineer sooner. When calling setNeedsDisplayInRect on a CATiledLayer - or a UIView whose backing layer is CATiledLayer - one would expect to re-draw only a region identified by the rect passed to the method. This is even written in the documentation for the class: "Regions of the layer may be invalidated using the setNeedsDisplayInRect: method however the update will be asynchronous. While the next display update will most likely not contain the updated content, a future update will." However, upon calling this method, CATiledLayer redraws whole contents instead of just the tile at the specified rect, and it flashes when doing so. It behaves exactly the same as if one had called setNeedsDisplay without passing any rect; all contents are cleared and re-drawn again. I'm 100% sure I've passed in the correct rect of the exact tile that I need to redraw. I have even tried passing much smaller rects, but still the same. (And yes, the rect I've passed accounts for the current level of detail.) I have found this GitHub repo https://github.com/frankus/NetPhotoScroller, which based on discussion from here https://forums.macrumors.com/threads/catiledlayer-blanks-out-tiles-when-redrawing.1333948/ aims at solving these issues by using two private methods on CATiledLayer class: (void)setNeedsDisplayInRect:(CGRect)r levelOfDetail:(int)level; (BOOL)canDrawRect:(CGRect)rect levelOfDetail:(int)level; I have explored the repo in detail, however I wasn't able to test exactly this code from the GitHub repo. I have tried using those two private methods myself (through an Objective-C class that defines the methods in the header file and then a swift class which inherits it), but I couldn't solve the issue; the flashing and the full re-draw is still there. After doing a lot of research, the conclusion seems to be that one cannot use CATiledLayer with contents that are downloaded remotely, on demand, as tiles are being requested. I have, however, found one interesting thing which seems to work so far: before calling setNeedsDisplayInRect (or just setNeedsDisplay, as they behave the same for CATiledLayer in my testing), cache the current layer's contents, and after calling setNeedsDisplay (or setNeedsDisplayInRect), restore the contents back to the layer. This prevents flashing and preserves any tiles that were drawn at the time of the re-draw. let c = tiledLayer.contents tiledLayer.setNeedsDisplay(tileRect) tiledLayer.contents = c However! Docs clearly state the warning: Do not attempt to directly modify the contents property of a CATiledLayer object. Doing so disables the ability of a tiled layer to asynchronously provide tiled content, effectively turning the layer into a regular CALayer object. I believe this message implies modifying the contents property with some raw content, like image data, and that it may be safe to re-apply the existing contents (which are in my testing of type CAImageProvider) -- but I can't rely on an implementation detail in my production app. I have tested this and confirmed that the bug appears on: iPhone 14 Pro, iOS 18.5 iPhone 13 Pro, iOS 17.5.1 iPhone 5s, iOS 15.8.3 iPad Pro 1st gen, iPadOS 18.4.1 a couple simulator versions I can also confirm that the fix (to re-apply contents property) is also working properly on all these versions. Is this expected behavior, that tiled layer redraws itself entirely instead of redrawing specific tiles? Is it safe to modify contents of a CATiledLayer by re-applying the existing contents? If not, is there an alternative to avoid flashing?
4
1
1.1k
Jul ’26
HVF FlatPartCache Inefficiency Causing Chinese Text Rendering Regression on iOS 18+
Summary On iOS 18 and later, Chinese text rendering shows a noticeable performance regression related to the HVF (Hierarchical Variable Font) pipeline. Environment iOS Version: iOS 18+ Framework: libhvf.dylib (Hierarchical Variable Font) Affected Font: PingFangUI.ttc (private system font, automatically used for Chinese text) Related Frameworks: CoreText, CoreGraphics, FontParser Devices: All iOS devices (more noticeable on older hardware) Background iOS 18 Change: PingFang.ttc was removed from /System/Library/Fonts/ Private PingFangUI.ttc was added (inaccessible via normal font APIs) System automatically uses PingFangUI.ttc for all Chinese text rendering PingFangUI.ttc contains HVF tables → utilizes libhvf.dylib HVF Architecture: HVF (Hierarchical Variable Font) organizes glyphs as tree structures Each glyph = Composite → multiple Parts → nested hierarchy Rendering a single character requires traversing this tree Key Observation A single Chinese glyph typically triggers ~20 calls to HVF::LoaderHVGL::loadPartAtIndex. Cache invalidation is triggered via IncrementRenderCount after every 18 glyphs: __ZNK27THierVariationsDataForkFont20IncrementRenderCountEv: ldr w8, [x0, #0x12c] add w8, w8, #0x1 str w8, [x0, #0x12c] cmp w8, #0x12 b.lo return ldr x0, [x0, #0x120] bl HVF_clear_part_cache str wzr, [x19, #0x12c] return: ret This causes the cache to be cleared before a typical sentence finishes rendering. Complete Call Stack (Rendering Hot Path) #0-1 HVF::LoaderHVGL::loadPartAtIndex #2 HVF::FlatPartCache::partAtIndex #3 HVF::PartTransformRenderer::renderComposite #4 HVF::PartTransformRenderer::render #5 HVF::PartTransformRenderer::renderToContext #6 _HVF_render_current_part #7 THierVariationsFontHandler::GetOutlinePath #8 TFontHandler::CopyGlyphPath #9 THierVariationsFontHandler::CopyGlyphPath #10 TFPFont::CopyGlyphPath #11-12 TFPFont::CopyGlyphPath / _FPFontCopyGlyphPath #13 _CGFontCreateGlyphPath #14 _CGGlyphBuilderLockBitmaps #15 _render_glyphs #16 _draw_glyph_bitmaps #17 _ripc_DrawGlyphs #18 CG::DisplayList::executeEntries #19 _CGDisplayListDrawInContextDelegate #20 _CABackingStoreUpdate_ #21-22 CALayer display/layout #23-24 CA::Transaction::commit #25-30 UIApplicationMain / RunLoop HVF::LoaderHVGL::loadPartAtIndex is consistently observed as a hot function in Instruments and in production. Cache Clear Call Stack #0 HVF::FlatPartCache::clear #1 HVF_clear_part_cache #2 THierVariationsDataForkFont::IncrementRenderCount #3 THierVariationsFontHandler::GetOutlinePath #4 TFontHandler::CopyGlyphPath #5 FPFontCopyGlyphPath #6 CGFontCreateGlyphPath #7 _render_glyphs #8 _draw_glyph_bitmaps #9 _ripc_DrawGlyphs This shows that cache clearing occurs within the glyph rendering path. Impact For a typical Chinese sentence (~20 characters): Each glyph requires multiple part loads (~20 per glyph) Cache is cleared before rendering completes Previously loaded parts cannot be reused Observed effects: Increased loadPartAtIndex invocation count Low cache hit rate Increased CPU usage in glyph rendering Main-thread blocking during Core Animation commit Regression iOS 17 and earlier: Rendering is smooth under similar workloads. iOS 18+: Increased rendering cost and visible frame drops. The issue is more pronounced on older devices such as iPhone XS and iPhone 11. Reproduction Render a Chinese text string longer than 18 characters, for example: 刷新测试中文文本用于验证渲染性能问题需要超过十八个字 Observe: Repeated loadPartAtIndex calls Frequent cache clearing Request It would be helpful to review the cache eviction strategy for HVF, particularly for complex scripts such as Chinese. Potential considerations: Adjusting or scaling the cache threshold Avoiding full cache clears during continuous rendering Improving reuse of parts across glyphs within the same rendering batch
1
0
1k
May ’26
[iOS18]The transition animation stops and cannot be interacted with
The app becomes unresponsive when pushing a new page. The screen is covered by the _UIParallaxOverlayView class, blocking all gestures. Are there any scenarios where the transition animation might suddenly stop mid-process? Or could you provide more information to help me troubleshoot this issue? I noticed: When the issue occurs, the FromViewController is displayed on the screen. The ToViewController also exists in the view tree, but it's not visible on the screen. _UIParallaxOverlayView only appears on iOS 18 and above. The animation appears to be controlled by +[UIView _fluidParallaxTransitionsEnabledWithTraitCollection:], which is _os_feature_enabled_impl("UIKit", "fluid_parallax_transitions"). Reference
2
0
931
May ’26
SwiftUI Canvas ring animation briefly rotates backward after app returns from background
Hi, I have a SwiftUI "work time" screen with a rotating ring (60 tick marks, Canvas-based). While the app stays in foreground, rotation is fine. After the app is in background for a while and comes back to foreground, I consistently see one visual glitch: the ring makes one very short step in the opposite direction once then continues rotating clockwise normally So this is not a crash, only a visual reverse tick on resume. What I expect: no direction change after foreground resume continuous clockwise motion What I already tried: withAnimation(.linear(...).repeatForever(...)) + restart on scenePhase TimelineView (.animation and .periodic) with time-based angle angle with and without modulo wrapping wall-clock and monotonic time sources rotation via rotationEffect and also via Canvas geometry warmup delays after resume restoring original ring visuals (long/short tick marks) The effect is still reproducible. Question: What is the correct SwiftUI approach to implement a continuously rotating ring that stays direction-stable across background/foreground transitions, with no one-frame reverse step on resume? Any pattern that is robust on current iOS versions and avoids visual artifacts on scene phase changes would be appreciated. Minimal repro: import SwiftUI struct ReproClockView: View { @Environment(\.scenePhase) private var scenePhase private let tickCount = 60 private let rotationDuration: Double = 120 @State private var rotationDegrees: Double = 0 @State private var hasAppeared = false var body: some View { ZStack { Canvas { context, size in let center = CGPoint(x: size.width / 2, y: size.height / 2) let radius = min(size.width, size.height) / 2 - 8 for index in 0..<tickCount { let angle = Double(index) * (360.0 / Double(tickCount)) - 90 let radians = angle * .pi / 180 let isLongTick = index % 5 == 0 let length: CGFloat = isLongTick ? 22 : 14 let outerRadius = radius let innerRadius = radius - length let startPoint = CGPoint( x: center.x + cos(radians) * outerRadius, y: center.y + sin(radians) * outerRadius ) let endPoint = CGPoint( x: center.x + cos(radians) * innerRadius, y: center.y + sin(radians) * innerRadius ) var path = Path() path.move(to: startPoint) path.addLine(to: endPoint) context.stroke( path, with: .color(.red), style: StrokeStyle(lineWidth: 2.5, lineCap: .round) ) } } .rotationEffect(.degrees(rotationDegrees)) .drawingGroup() } .frame(width: 340, height: 340) .onAppear { guard !hasAppeared else { return } hasAppeared = true startRotation() } .onChange(of: scenePhase) { oldPhase, newPhase in if oldPhase == .background && newPhase == .active { withAnimation(.linear(duration: 0)) { rotationDegrees = 0 } DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { startRotation() } } } } private func startRotation() { rotationDegrees = 0 withAnimation(.linear(duration: rotationDuration).repeatForever(autoreverses: false)) { rotationDegrees = 360 } } }
0
0
315
May ’26
navigationTransition Rendering Glitch for Stroke Borders
If you use .navigationTransition(.zoom(sourceID: zoomID, in: namespace)) with a carousel or a card view, which uses : .stroke(Color.secondary.opacity(0.5), lineWidth: 5) It causes the border stroke to render incorrectly, and even in some cases, the card glitches out and disappears from the screen. The card is clickable but there is no entity in the placeholder of that place.
0
0
198
Apr ’26
My app doesn't respond on iPhone Air iOS 26.1.
My app doesn't respond on iPhone Air iOS 26.1. After startup, my app shows the main view with a tab bar controller containing 4 navigation controllers. However, when a second-level view controller is pushed onto any navigation controller, the UI freezes and becomes unresponsive. The iPhone simulator running iOS 26.1 exhibits the same problem. The debug profile shows CPU usage at 100%. However, other devices and simulators do not have this problem.
7
3
1.6k
Mar ’26
Smooth appearance switching
Hello every developers. I need your help. Do you know how to attach animation to appearance, like a smooth transition from dark to light and vise versa. My code here: @main struct The_Library_of_BabelonApp: App { @AppStorage("selectedAppearance") private var selectedAppearance = 0 @StateObject private var router = AppRouter() var scheme: ColorScheme? { if selectedAppearance == 1 { return .light } if selectedAppearance == 2 { return .dark } return nil } var body: some Scene { WindowGroup { RootView() .preferredColorScheme(scheme) .environmentObject(router) // this is doesn't work correctly .animation(.smooth(duration: 2), value: selectedAppearance) } } } And my appearance switching looks: struct SettingsView: View { @AppStorage("selectedAppearance") private var selectedAppearance = 0 var body: some View { List { Section(header: Text("Appearance")) { HStack(spacing: 20) { ThemePreview(title: "Light", imageName: "lightTheme", tag: 1, selection: $selectedAppearance) ThemePreview(title: "Dark", imageName: "darkTheme", tag: 2, selection: $selectedAppearance) ThemePreview(title: "System", imageName: "systemMode", tag: 0, selection: $selectedAppearance) } .padding(.vertical, 10) .frame(maxWidth: .infinity) } } } } struct ThemePreview: View { let title: String let imageName: String let tag: Int @Binding var selection: Int var body: some View { Button { selection = tag } label: { VStack { Image(imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 120, height: 80) .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(selection == tag ? Color.blue : Color.clear, lineWidth: 3) ) Text(title) .font(.caption) .foregroundColor(selection == tag ? .blue : .primary) } } .buttonStyle(.plain) } } I guess my code works but animation working another way, its turn my Section, I don't know.... Thank you in advance
1
0
419
Feb ’26
Core Text incremental redraw glitch: overlapping glyphs during editing
During editing in Pages (or Word) I am getting these glitches (see attachment). Started after the last update to Mac OS 26.3 (beta) Also removed 2 recent instalments (Blackhole audio driver and kDrive/Infomaniak, but trouble is still there. 27" iMac 2020 (Intel) i7 3,8 Ghz AMD Radeon Pro 5500 XT 8 GB 24 GB RAM macOS Tahoe 26.3 (=beta) Tried restart in safe mode, checked fonts. Talked to aissistent to get a solution, but no ...) Thx for any advice, Pieter (not a developer so please kee pit simple 🙏🏻)
3
0
1.7k
Feb ’26
Animation Help
Hello, I am trying to use matchedGeometryEffect to animate between an item in a list view and the item's detail view. Right now, I am getting an unwanted cross-fade animation as the view transitions. So the list item moves into place as it should with the modifier, but it fades out as its detail version fades in, which I do not want. I do not want any fading at all, just the movement from one component to the other. How do I stop this? Thanks.
2
0
136
Jan ’26
Animation Ghosting with animation-timeline on 120HZ ProMotion Devices
On iOS Devices with ProMotion (120HZ) if you animate Elements on your Page with animation-timeline you get Ghosting Effects. You can not see the Ghosting with a Simulator or on Screenshots, only on real Devices. To Reproduce I made a Minimal Example: https://codesandbox.io/p/sandbox/120hztest-xrwgtc When you scroll quickly on the Page with an iOS 120HZ Device (https://en.wikipedia.org/wiki/List_of_smartphones_with_a_high_refresh_rate_display) you will see ghosting on the Top of the right Element (animation-timeline) and no ghosting on the other animated Element. (I edited the Screenshot, to Illustrate how the Effect looks like, since it is only visible on the real Display)
2
0
525
Jan ’26
Keyframe animation crashes with +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class on iOS 26
We have an UIViewController called InfoPlayerViewController. Its main subview is from a child view controller backed by SwiftUI via UIHostingController. The InfoPlayerViewController conforms to UIViewControllerTransitioningDelegate. The animation controller for dismissing is DismissPlayerAnimationController. It runs UIKit keyframe animations via UIViewPropertyAnimator. When the keyframe animation is executed there’s an occasional crash for end users in production. It only happens on iOS 26. FB Radar: FB20871547 An example crash is below. Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Reason: +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class 0x20c95da08 Termination Reason: SIGNAL 6 Abort trap: 6 Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x1a23828c8 __exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x19f2f97c4 objc_exception_throw + 88 (objc-exception.mm:356) 2 CoreFoundation 0x1a241e6cc +[NSObject(NSObject) doesNotRecognizeSelector:] + 364 (NSObject.m:158) 3 CoreFoundation 0x1a22ff4f8 ___forwarding___ + 1472 (NSForwarding.m:3616) 4 CoreFoundation 0x1a23073a0 _CF_forwarding_prep_0 + 96 (:-1) 5 UIKitCore 0x1a948e880 __35-[UIViewKeyframeAnimationState pop]_block_invoke + 300 (UIView.m:2973) 6 CoreFoundation 0x1a22cb170 __NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__ + 24 (NSDictionaryHelpers.m:10) 7 CoreFoundation 0x1a245d7cc -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 288 (NSDictionaryM.m:271) 8 UIKitCore 0x1a948e6bc -[UIViewKeyframeAnimationState pop] + 376 (UIView.m:2955) 9 UIKitCore 0x1a7bc40e8 +[UIViewAnimationState popAnimationState] + 60 (UIView.m:1250) 10 UIKitCore 0x1a94acc44 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 684 (UIView.m:17669) 11 UIKitCore 0x1a94ae334 +[UIView(UIViewKeyframeAnimations) animateKeyframesWithDuration:delay:options:animations:completion:] + 224 (UIView.m:17945) 12 MyApp 0x102c78dec static UIView.animateNestedKeyframe(withRelativeStartTime:relativeDuration:animations:) + 208 (UIView+AnimateNestedKeyframe.swift:10) 13 MyApp 0x102aef3c0 closure #1 in DismissPlayerAnimationController.slideDownBelowTabBarTransitionAnimator(using:) + 156 (DismissPlayerAnimationController.swift:229) 14 MyApp 0x102a2d3d4 <deduplicated_symbol> + 28 15 UIKitCore 0x1a7d5ae5c -[UIViewPropertyAnimator _runAnimations] + 172 (UIViewPropertyAnimator.m:2123) 16 UIKitCore 0x1a83e1594 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_3 + 92 (UIViewPropertyAnimator.m:3557) 17 UIKitCore 0x1a83e1464 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke + 96 (UIViewPropertyAnimator.m:3547) 18 UIKitCore 0x1a83e1518 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_2 + 144 (UIViewPropertyAnimator.m:3553) 19 UIKitCore 0x1a83e0e64 -[UIViewPropertyAnimator _setupAnimationTracking:] + 100 (UIViewPropertyAnimator.m:3510) 20 UIKitCore 0x1a83e1264 -[UIViewPropertyAnimator startAnimationAsPaused:] + 728 (UIViewPropertyAnimator.m:3610) 21 UIKitCore 0x1a83de42c -[UIViewPropertyAnimator pauseAnimation] + 68 (UIViewPropertyAnimator.m:2753) 22 UIKitCore 0x1a87d5328 -[UIPercentDrivenInteractiveTransition _startInterruptibleTransition:] + 244 (UIViewControllerTransitioning.m:982) 23 UIKitCore 0x1a87d5514 -[UIPercentDrivenInteractiveTransition startInteractiveTransition:] + 184 (UIViewControllerTransitioning.m:1012) 24 UIKitCore 0x1a7c7931c ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_3 + 152 (UIViewControllerTransitioning.m:1579) 25 UIKitCore 0x1a892aefc +[UIKeyboardSceneDelegate _pinInputViewsForKeyboardSceneDelegate:onBehalfOfResponder:duringBlock:] + 96 (UIKeyboardSceneDelegate.m:3518) 26 UIKitCore 0x1a7c79238 ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_2 + 236 (UIViewControllerTransitioning.m:1571) 27 UIKitCore 0x1a94ab4b8 +[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:animated:] + 188 (UIView.m:17089) 28 UIKitCore 0x1a7c79070 _UIViewControllerTransitioningRunCustomTransitionWithRequest + 556 (UIViewControllerTransitioning.m:1560) 29 UIKitCore 0x1a86cb7cc __77-[UIPresentationController runTransitionForCurrentStateAnimated:handoffData:]_block_invoke_3 + 1784 (UIPresentationController.m:1504) 30 UIKitCore 0x1a7c43888 -[_UIAfterCACommitBlock run] + 72 (_UIAfterCACommitQueue.m:137) 31 UIKitCore 0x1a7c437c0 -[_UIAfterCACommitQueue flush] + 168 (_UIAfterCACommitQueue.m:228) 32 UIKitCore 0x1a7c436d0 _runAfterCACommitDeferredBlocks + 260 (UIApplication.m:3297) 33 UIKitCore 0x1a7c43c34 _cleanUpAfterCAFlushAndRunDeferredBlocks + 80 (UIApplication.m:3275) 34 UIKitCore 0x1a7c1f104 _UIApplicationFlushCATransaction + 72 (UIApplication.m:3338) 35 UIKitCore 0x1a7c1f024 __setupUpdateSequence_block_invoke_2 + 352 (_UIUpdateScheduler.m:1634) 36 UIKitCore 0x1a7c2cee8 _UIUpdateSequenceRunNext + 128 (_UIUpdateSequence.mm:189) 37 UIKitCore 0x1a7c2c378 schedulerStepScheduledMainSectionContinue + 60 (_UIUpdateScheduler.m:1185) 38 UpdateCycle 0x28c58f5f8 UC::DriverCore::continueProcessing() + 84 (UCDriver.cc:288) 39 CoreFoundation 0x1a2323230 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:2021) 40 CoreFoundation 0x1a23231a4 __CFRunLoopDoSource0 + 172 (CFRunLoop.c:2065) 41 CoreFoundation 0x1a2300c6c __CFRunLoopDoSources0 + 232 (CFRunLoop.c:2102) 42 CoreFoundation 0x1a22d68b0 __CFRunLoopRun + 820 (CFRunLoop.c:2983) 43 CoreFoundation 0x1a22d5c44 _CFRunLoopRunSpecificWithOptions + 532 (CFRunLoop.c:3462) 44 GraphicsServices 0x2416a2498 GSEventRunModal + 120 (GSEvent.c:2049) 45 UIKitCore 0x1a7c50ddc -[UIApplication _run] + 792 (UIApplication.m:3899) 46 UIKitCore 0x1a7bf5b0c UIApplicationMain + 336 (UIApplication.m:5574) // ...
4
1
781
Jan ’26
Race conditions when changing CAMetalLayer.drawableSize?
Is the pseudocode below thread-safe? Imagine that the Main thread sets the CAMetalLayer's drawableSize to a new size meanwhile the rendering thread is in the middle of rendering into an existing MTLDrawable which does still have the old size. Is the change of metalLayer.drawableSize thread-safe in the sense that I can present an old MTLDrawable which has a different resolution than the current value of metalLayer.drawableSize? I assume that setting the drawableSize property informs Metal that the next MTLDrawable offered by the CAMetalLayer should have the new size, right? Is it valid to assume that "metalLayer.drawableSize = newSize" and "metalLayer.nextDrawable()" are internally synchronized, so it cannot happen that metalLayer.nextDrawable() would produce e.g. a MTLDrawable with the old width but with the new height (or a completely invalid resolution due to potential race conditions)? func onWindowResized(newSize: CGSize) { // Called on the Main thread metalLayer.drawableSize = newSize } func onVsync(drawable: MTLDrawable) { // Called on a background rendering thread renderer.renderInto(drawable: drawable) }
1
1
840
Dec ’25
Liquid Glass TabBar animations causes Hangs, bug with UIKitCore?
With iOS 26.1 we started seeing a bug that only appears on iPhone Air. This bug is visible with simulators too. I have tried so many different ways to fix the issue, but Instruments Profiler is pointing at UIKitCore. We load a tab bar, when the user attempts to switch a tab, the app hangs and never recovers. It happens right as the animation of the Glass bubble is in progress. I have tried a UIKit Tab bar, a SwiftUI Tab bar. I tore out AppDelegate and did a direct @main SwiftUI entry for my application. This issue appears with every tab bar instance I try. I attempted to disable LiquidGlass by utilizing this flag UIDesignRequiresCompatibility in my plist, but the flag seems to be ignored by the system. I am not sure what else to try. I have a trace file if that is helpful. What else can I upload? Here is what the code looks like. struct ContentView: View { @State private var selectedTab = 2 var body: some View { TabView(selection: $selectedTab) { Text("Profile") .tabItem { Label("Me", systemImage: "person") } .tag(0) Text("Training") .tabItem { Label("Training", systemImage: "calendar") } .tag(1) Text("Home") .tabItem { Label("Home", systemImage: "house") } .tag(2) Text("Goals") .tabItem { Label("Goals", systemImage: "target") } .tag(3) Text("Coach") .tabItem { Label("Coach", systemImage: "person.2") } .tag(4) } } } #Preview { ContentView() } and AppView entry point import SwiftUI @main struct RunCoachApp: App { var body: some Scene { WindowGroup { ContentView() } } }
6
1
1.2k
Dec ’25
Unable to Display NSProgressIndicator on macOS Unlock (First Lock) Screen
I'm Trying to add an NSProgressIndicator on the unlock (first lock screen ) in macOS ( the screen with the lock icon ) I already added a label and it works fine and after entering the password on the second (authentication) page I can able to add ProgressIndicator but not on first screen. But Whenever I try to add a Progress indicator, the entire screen turns Black and nothing is displayed Is NSProgressIndicator supported on the first unlock Screen ? Or does macOS block animated UI on this screen Any Guidance would be helpful Thanks
1
0
585
Nov ’25
macOS 27 beta: ProMotion refresh cadence is unstable, causing constant scroll judder
FB24091347 On macOS 27.0 beta (26A5388g), MacBook Pro M4 Pro, the built-in ProMotion display never settles on a stable refresh cadence. Scrolling in SwiftUI judders constantly. The same app binary was smooth on macOS 26, and is smooth on a 120 Hz ProMotion iPad. I captured two 60-second Instruments traces — same app, same scene, same scrolling, no external display — changing only the display's refresh-rate setting. On ProMotion the vsync interval standard deviation is 4.093 ms across six different cadences, mostly flip-flopping between 120 Hz and 60 Hz. Forced to a fixed 60 Hz it drops to 0.391 ms with a single cadence. The app presented an identical 59 fps median in both runs — frame production is perfectly steady, the display just holds each frame for an unpredictable length of time. That's what makes this nasty: it's invisible to every frame-rate metric, so it looks like the app got slow when nothing about the app changed. I spent most of a day profiling my own code before realising the app was never the problem. Workaround: force the built-in display to 60 Hz. Worth noting, because it complicates the picture: attaching a 60 Hz Studio Display makes the built-in smooth, but the Studio itself then judders — despite its own vsync cadence measuring perfectly stable. So refresh rate alone isn't the whole story, and there may be a second mechanism. The clean, reproducible, single-variable result is the ProMotion vs forced-60 Hz comparison on the built-in panel. If you can reproduce this on an M-series MacBook Pro on 27 beta, please file a duplicate referencing FB24091347.
Replies
6
Boosts
2
Views
2.5k
Activity
2w
Core Animation Background Thread CATransaction
Hey everyone 👋 I'm trying to initialize a part of a CALayer hierarchy on a background thread and then attach the root of that hierarchy to a CALayer that backs a UIView. The motivation is to keep the main thread responsive when constructing a complex layer hierarchy. This isn't a case where I'm creating two or three layers and then switching back to the main thread. The hierarchy can potentially contain a large number of layers, with animations being created/configured for those layers as well. My first approach was to create and configure the layers entirely on a background thread. While the output might be the expected one (not always), CoreAnimation emits an assertion along the lines of: "Modifications to the layer tree from a background thread may not be committed" (or something like this). This makes sense to me if implicit CATransaction is thread-local. In that case, the implicit transaction opened by the layer modification on the background thread would not be part of the transaction that is already open on the main thread. Therefore, committing the main-thread transaction would not commit the changes made on the background thread. My second approach was to explicitly create and commit a CATransaction on the background thread. This appears to be accepted by Core Animation's threading model, but I'm seeing unreliable results. Sometimes parts of the hierarchy are missing, and in other cases the hierarchy is present but the animations don't appear to run at all. I do understand that this is private behavior of the framework, but I wanted to know if what I am trying to achieve is possible and, if so, what the solution would be (obviously if you can share this information). Besides this, I would also like to know what behavior CATransactions have when they are created on different threads. What I mean by this is that the transactions work as a stack, and the changes are committed when the stack is empty. Does this behavior still apply when having transactions on different threads? Any weird behaviours that might appear between transactions operated on main vs background threads? Thank you! Vlad.
Replies
7
Boosts
0
Views
1.1k
Activity
Sep ’26
window:willUseFullScreenPresentationOptions: with NSApplicationPresentationHideDock causes other windows to be unminimizable
In the below code, I create two windows, and use a window delegate to make sure that whenever the first is fullscreened, its menubar and dock are hidden properly. However, when I fullscreen the first window and go back to the desktop to see my second window, the second window's minimize button is grayed out and using miniaturize on it will not work either. I've tried various things; it seems like if I fullscreen the second window and the unfullscreen it, it then becomes minimizable without additional side effects. Is there any reason why this is happening? This seems like a bug in AppKit... so how do I work around it programmatically? #import <Cocoa/Cocoa.h> @interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> @property (strong) NSWindow *mainWindow; @property (strong) NSWindow *secondaryWindow; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSRect mainRect = NSMakeRect(100, 300, 400, 300); self.mainWindow = [[NSWindow alloc] initWithContentRect:mainRect styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable) backing:NSBackingStoreBuffered defer:NO]; [self.mainWindow setTitle:@"Main Window (Go Fullscreen Here)"]; [self.mainWindow setDelegate:self]; NSTextField *mainLabel = [NSTextField labelWithString:@"1. Click the green zoom/fullscreen button on THIS window.\n\n2. Look at the other window's yellow minimize button."]; [mainLabel setFrame:NSMakeRect(20, 100, 360, 100)]; [[self.mainWindow contentView] addSubview:mainLabel]; [self.mainWindow makeKeyAndOrderFront:nil]; NSRect secondaryRect = NSMakeRect(550, 300, 400, 300); self.secondaryWindow = [[NSWindow alloc] initWithContentRect:secondaryRect styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable) backing:NSBackingStoreBuffered defer:NO]; [self.secondaryWindow setTitle:@"Secondary Window (The Victim)"]; NSButton *testButton = [NSButton buttonWithTitle:@"Try code [window miniaturize:]" target:self action:@selector(attemptProgrammaticMinimize:)]; [testButton setFrame:NSMakeRect(80, 130, 240, 40)]; [[self.secondaryWindow contentView] addSubview:testButton]; [self.secondaryWindow makeKeyAndOrderFront:nil]; } - (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { return NSApplicationPresentationFullScreen | NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock; } - (void)attemptProgrammaticMinimize:(id)sender { [self.secondaryWindow miniaturize:nil]; NSLog(@"[Repro] Minimize attempted"); } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { return YES; } @end int main(int argc, const char * argv[]) { @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; [app setActivationPolicy:NSApplicationActivationPolicyRegular]; AppDelegate *delegate = [[AppDelegate alloc] init]; [app setDelegate:delegate]; [app activateIgnoringOtherApps:YES]; [app run]; } return 0; }
Replies
3
Boosts
0
Views
985
Activity
Aug ’26
How Did Apple Create the Fitness App Awards Animation?
Open your Apple Fitness app, I am facinated by the animation of the Awards screen, it is so smooth. Any idea how this was transiton created from a Grid/CollectionView to a RealityView? I assume the interative badge is a RealityView with a 3D model in there, but how the hell the transition was so smooth from the parent list screen to the detail screen.
Replies
0
Boosts
0
Views
555
Activity
Jul ’26
CATiledLayer flashes and re-draws entirely when re-drawing a single tile
I have filed a bug report for this (FB17734946), but I'm posting it here verbatim in case others have the same issue and in hopes of getting attention from an Apple engineer sooner. When calling setNeedsDisplayInRect on a CATiledLayer - or a UIView whose backing layer is CATiledLayer - one would expect to re-draw only a region identified by the rect passed to the method. This is even written in the documentation for the class: "Regions of the layer may be invalidated using the setNeedsDisplayInRect: method however the update will be asynchronous. While the next display update will most likely not contain the updated content, a future update will." However, upon calling this method, CATiledLayer redraws whole contents instead of just the tile at the specified rect, and it flashes when doing so. It behaves exactly the same as if one had called setNeedsDisplay without passing any rect; all contents are cleared and re-drawn again. I'm 100% sure I've passed in the correct rect of the exact tile that I need to redraw. I have even tried passing much smaller rects, but still the same. (And yes, the rect I've passed accounts for the current level of detail.) I have found this GitHub repo https://github.com/frankus/NetPhotoScroller, which based on discussion from here https://forums.macrumors.com/threads/catiledlayer-blanks-out-tiles-when-redrawing.1333948/ aims at solving these issues by using two private methods on CATiledLayer class: (void)setNeedsDisplayInRect:(CGRect)r levelOfDetail:(int)level; (BOOL)canDrawRect:(CGRect)rect levelOfDetail:(int)level; I have explored the repo in detail, however I wasn't able to test exactly this code from the GitHub repo. I have tried using those two private methods myself (through an Objective-C class that defines the methods in the header file and then a swift class which inherits it), but I couldn't solve the issue; the flashing and the full re-draw is still there. After doing a lot of research, the conclusion seems to be that one cannot use CATiledLayer with contents that are downloaded remotely, on demand, as tiles are being requested. I have, however, found one interesting thing which seems to work so far: before calling setNeedsDisplayInRect (or just setNeedsDisplay, as they behave the same for CATiledLayer in my testing), cache the current layer's contents, and after calling setNeedsDisplay (or setNeedsDisplayInRect), restore the contents back to the layer. This prevents flashing and preserves any tiles that were drawn at the time of the re-draw. let c = tiledLayer.contents tiledLayer.setNeedsDisplay(tileRect) tiledLayer.contents = c However! Docs clearly state the warning: Do not attempt to directly modify the contents property of a CATiledLayer object. Doing so disables the ability of a tiled layer to asynchronously provide tiled content, effectively turning the layer into a regular CALayer object. I believe this message implies modifying the contents property with some raw content, like image data, and that it may be safe to re-apply the existing contents (which are in my testing of type CAImageProvider) -- but I can't rely on an implementation detail in my production app. I have tested this and confirmed that the bug appears on: iPhone 14 Pro, iOS 18.5 iPhone 13 Pro, iOS 17.5.1 iPhone 5s, iOS 15.8.3 iPad Pro 1st gen, iPadOS 18.4.1 a couple simulator versions I can also confirm that the fix (to re-apply contents property) is also working properly on all these versions. Is this expected behavior, that tiled layer redraws itself entirely instead of redrawing specific tiles? Is it safe to modify contents of a CATiledLayer by re-applying the existing contents? If not, is there an alternative to avoid flashing?
Replies
4
Boosts
1
Views
1.1k
Activity
Jul ’26
HVF FlatPartCache Inefficiency Causing Chinese Text Rendering Regression on iOS 18+
Summary On iOS 18 and later, Chinese text rendering shows a noticeable performance regression related to the HVF (Hierarchical Variable Font) pipeline. Environment iOS Version: iOS 18+ Framework: libhvf.dylib (Hierarchical Variable Font) Affected Font: PingFangUI.ttc (private system font, automatically used for Chinese text) Related Frameworks: CoreText, CoreGraphics, FontParser Devices: All iOS devices (more noticeable on older hardware) Background iOS 18 Change: PingFang.ttc was removed from /System/Library/Fonts/ Private PingFangUI.ttc was added (inaccessible via normal font APIs) System automatically uses PingFangUI.ttc for all Chinese text rendering PingFangUI.ttc contains HVF tables → utilizes libhvf.dylib HVF Architecture: HVF (Hierarchical Variable Font) organizes glyphs as tree structures Each glyph = Composite → multiple Parts → nested hierarchy Rendering a single character requires traversing this tree Key Observation A single Chinese glyph typically triggers ~20 calls to HVF::LoaderHVGL::loadPartAtIndex. Cache invalidation is triggered via IncrementRenderCount after every 18 glyphs: __ZNK27THierVariationsDataForkFont20IncrementRenderCountEv: ldr w8, [x0, #0x12c] add w8, w8, #0x1 str w8, [x0, #0x12c] cmp w8, #0x12 b.lo return ldr x0, [x0, #0x120] bl HVF_clear_part_cache str wzr, [x19, #0x12c] return: ret This causes the cache to be cleared before a typical sentence finishes rendering. Complete Call Stack (Rendering Hot Path) #0-1 HVF::LoaderHVGL::loadPartAtIndex #2 HVF::FlatPartCache::partAtIndex #3 HVF::PartTransformRenderer::renderComposite #4 HVF::PartTransformRenderer::render #5 HVF::PartTransformRenderer::renderToContext #6 _HVF_render_current_part #7 THierVariationsFontHandler::GetOutlinePath #8 TFontHandler::CopyGlyphPath #9 THierVariationsFontHandler::CopyGlyphPath #10 TFPFont::CopyGlyphPath #11-12 TFPFont::CopyGlyphPath / _FPFontCopyGlyphPath #13 _CGFontCreateGlyphPath #14 _CGGlyphBuilderLockBitmaps #15 _render_glyphs #16 _draw_glyph_bitmaps #17 _ripc_DrawGlyphs #18 CG::DisplayList::executeEntries #19 _CGDisplayListDrawInContextDelegate #20 _CABackingStoreUpdate_ #21-22 CALayer display/layout #23-24 CA::Transaction::commit #25-30 UIApplicationMain / RunLoop HVF::LoaderHVGL::loadPartAtIndex is consistently observed as a hot function in Instruments and in production. Cache Clear Call Stack #0 HVF::FlatPartCache::clear #1 HVF_clear_part_cache #2 THierVariationsDataForkFont::IncrementRenderCount #3 THierVariationsFontHandler::GetOutlinePath #4 TFontHandler::CopyGlyphPath #5 FPFontCopyGlyphPath #6 CGFontCreateGlyphPath #7 _render_glyphs #8 _draw_glyph_bitmaps #9 _ripc_DrawGlyphs This shows that cache clearing occurs within the glyph rendering path. Impact For a typical Chinese sentence (~20 characters): Each glyph requires multiple part loads (~20 per glyph) Cache is cleared before rendering completes Previously loaded parts cannot be reused Observed effects: Increased loadPartAtIndex invocation count Low cache hit rate Increased CPU usage in glyph rendering Main-thread blocking during Core Animation commit Regression iOS 17 and earlier: Rendering is smooth under similar workloads. iOS 18+: Increased rendering cost and visible frame drops. The issue is more pronounced on older devices such as iPhone XS and iPhone 11. Reproduction Render a Chinese text string longer than 18 characters, for example: 刷新测试中文文本用于验证渲染性能问题需要超过十八个字 Observe: Repeated loadPartAtIndex calls Frequent cache clearing Request It would be helpful to review the cache eviction strategy for HVF, particularly for complex scripts such as Chinese. Potential considerations: Adjusting or scaling the cache threshold Avoiding full cache clears during continuous rendering Improving reuse of parts across glyphs within the same rendering batch
Replies
1
Boosts
0
Views
1k
Activity
May ’26
[iOS18]The transition animation stops and cannot be interacted with
The app becomes unresponsive when pushing a new page. The screen is covered by the _UIParallaxOverlayView class, blocking all gestures. Are there any scenarios where the transition animation might suddenly stop mid-process? Or could you provide more information to help me troubleshoot this issue? I noticed: When the issue occurs, the FromViewController is displayed on the screen. The ToViewController also exists in the view tree, but it's not visible on the screen. _UIParallaxOverlayView only appears on iOS 18 and above. The animation appears to be controlled by +[UIView _fluidParallaxTransitionsEnabledWithTraitCollection:], which is _os_feature_enabled_impl("UIKit", "fluid_parallax_transitions"). Reference
Replies
2
Boosts
0
Views
931
Activity
May ’26
SwiftUI Canvas ring animation briefly rotates backward after app returns from background
Hi, I have a SwiftUI "work time" screen with a rotating ring (60 tick marks, Canvas-based). While the app stays in foreground, rotation is fine. After the app is in background for a while and comes back to foreground, I consistently see one visual glitch: the ring makes one very short step in the opposite direction once then continues rotating clockwise normally So this is not a crash, only a visual reverse tick on resume. What I expect: no direction change after foreground resume continuous clockwise motion What I already tried: withAnimation(.linear(...).repeatForever(...)) + restart on scenePhase TimelineView (.animation and .periodic) with time-based angle angle with and without modulo wrapping wall-clock and monotonic time sources rotation via rotationEffect and also via Canvas geometry warmup delays after resume restoring original ring visuals (long/short tick marks) The effect is still reproducible. Question: What is the correct SwiftUI approach to implement a continuously rotating ring that stays direction-stable across background/foreground transitions, with no one-frame reverse step on resume? Any pattern that is robust on current iOS versions and avoids visual artifacts on scene phase changes would be appreciated. Minimal repro: import SwiftUI struct ReproClockView: View { @Environment(\.scenePhase) private var scenePhase private let tickCount = 60 private let rotationDuration: Double = 120 @State private var rotationDegrees: Double = 0 @State private var hasAppeared = false var body: some View { ZStack { Canvas { context, size in let center = CGPoint(x: size.width / 2, y: size.height / 2) let radius = min(size.width, size.height) / 2 - 8 for index in 0..<tickCount { let angle = Double(index) * (360.0 / Double(tickCount)) - 90 let radians = angle * .pi / 180 let isLongTick = index % 5 == 0 let length: CGFloat = isLongTick ? 22 : 14 let outerRadius = radius let innerRadius = radius - length let startPoint = CGPoint( x: center.x + cos(radians) * outerRadius, y: center.y + sin(radians) * outerRadius ) let endPoint = CGPoint( x: center.x + cos(radians) * innerRadius, y: center.y + sin(radians) * innerRadius ) var path = Path() path.move(to: startPoint) path.addLine(to: endPoint) context.stroke( path, with: .color(.red), style: StrokeStyle(lineWidth: 2.5, lineCap: .round) ) } } .rotationEffect(.degrees(rotationDegrees)) .drawingGroup() } .frame(width: 340, height: 340) .onAppear { guard !hasAppeared else { return } hasAppeared = true startRotation() } .onChange(of: scenePhase) { oldPhase, newPhase in if oldPhase == .background && newPhase == .active { withAnimation(.linear(duration: 0)) { rotationDegrees = 0 } DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { startRotation() } } } } private func startRotation() { rotationDegrees = 0 withAnimation(.linear(duration: rotationDuration).repeatForever(autoreverses: false)) { rotationDegrees = 360 } } }
Replies
0
Boosts
0
Views
315
Activity
May ’26
navigationTransition Rendering Glitch for Stroke Borders
If you use .navigationTransition(.zoom(sourceID: zoomID, in: namespace)) with a carousel or a card view, which uses : .stroke(Color.secondary.opacity(0.5), lineWidth: 5) It causes the border stroke to render incorrectly, and even in some cases, the card glitches out and disappears from the screen. The card is clickable but there is no entity in the placeholder of that place.
Replies
0
Boosts
0
Views
198
Activity
Apr ’26
My app doesn't respond on iPhone Air iOS 26.1.
My app doesn't respond on iPhone Air iOS 26.1. After startup, my app shows the main view with a tab bar controller containing 4 navigation controllers. However, when a second-level view controller is pushed onto any navigation controller, the UI freezes and becomes unresponsive. The iPhone simulator running iOS 26.1 exhibits the same problem. The debug profile shows CPU usage at 100%. However, other devices and simulators do not have this problem.
Replies
7
Boosts
3
Views
1.6k
Activity
Mar ’26
Smooth appearance switching
Hello every developers. I need your help. Do you know how to attach animation to appearance, like a smooth transition from dark to light and vise versa. My code here: @main struct The_Library_of_BabelonApp: App { @AppStorage("selectedAppearance") private var selectedAppearance = 0 @StateObject private var router = AppRouter() var scheme: ColorScheme? { if selectedAppearance == 1 { return .light } if selectedAppearance == 2 { return .dark } return nil } var body: some Scene { WindowGroup { RootView() .preferredColorScheme(scheme) .environmentObject(router) // this is doesn't work correctly .animation(.smooth(duration: 2), value: selectedAppearance) } } } And my appearance switching looks: struct SettingsView: View { @AppStorage("selectedAppearance") private var selectedAppearance = 0 var body: some View { List { Section(header: Text("Appearance")) { HStack(spacing: 20) { ThemePreview(title: "Light", imageName: "lightTheme", tag: 1, selection: $selectedAppearance) ThemePreview(title: "Dark", imageName: "darkTheme", tag: 2, selection: $selectedAppearance) ThemePreview(title: "System", imageName: "systemMode", tag: 0, selection: $selectedAppearance) } .padding(.vertical, 10) .frame(maxWidth: .infinity) } } } } struct ThemePreview: View { let title: String let imageName: String let tag: Int @Binding var selection: Int var body: some View { Button { selection = tag } label: { VStack { Image(imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 120, height: 80) .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(selection == tag ? Color.blue : Color.clear, lineWidth: 3) ) Text(title) .font(.caption) .foregroundColor(selection == tag ? .blue : .primary) } } .buttonStyle(.plain) } } I guess my code works but animation working another way, its turn my Section, I don't know.... Thank you in advance
Replies
1
Boosts
0
Views
419
Activity
Feb ’26
Core Text incremental redraw glitch: overlapping glyphs during editing
During editing in Pages (or Word) I am getting these glitches (see attachment). Started after the last update to Mac OS 26.3 (beta) Also removed 2 recent instalments (Blackhole audio driver and kDrive/Infomaniak, but trouble is still there. 27" iMac 2020 (Intel) i7 3,8 Ghz AMD Radeon Pro 5500 XT 8 GB 24 GB RAM macOS Tahoe 26.3 (=beta) Tried restart in safe mode, checked fonts. Talked to aissistent to get a solution, but no ...) Thx for any advice, Pieter (not a developer so please kee pit simple 🙏🏻)
Replies
3
Boosts
0
Views
1.7k
Activity
Feb ’26
Animation Help
Hello, I am trying to use matchedGeometryEffect to animate between an item in a list view and the item's detail view. Right now, I am getting an unwanted cross-fade animation as the view transitions. So the list item moves into place as it should with the modifier, but it fades out as its detail version fades in, which I do not want. I do not want any fading at all, just the movement from one component to the other. How do I stop this? Thanks.
Replies
2
Boosts
0
Views
136
Activity
Jan ’26
Animation Ghosting with animation-timeline on 120HZ ProMotion Devices
On iOS Devices with ProMotion (120HZ) if you animate Elements on your Page with animation-timeline you get Ghosting Effects. You can not see the Ghosting with a Simulator or on Screenshots, only on real Devices. To Reproduce I made a Minimal Example: https://codesandbox.io/p/sandbox/120hztest-xrwgtc When you scroll quickly on the Page with an iOS 120HZ Device (https://en.wikipedia.org/wiki/List_of_smartphones_with_a_high_refresh_rate_display) you will see ghosting on the Top of the right Element (animation-timeline) and no ghosting on the other animated Element. (I edited the Screenshot, to Illustrate how the Effect looks like, since it is only visible on the real Display)
Replies
2
Boosts
0
Views
525
Activity
Jan ’26
Keyframe animation crashes with +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class on iOS 26
We have an UIViewController called InfoPlayerViewController. Its main subview is from a child view controller backed by SwiftUI via UIHostingController. The InfoPlayerViewController conforms to UIViewControllerTransitioningDelegate. The animation controller for dismissing is DismissPlayerAnimationController. It runs UIKit keyframe animations via UIViewPropertyAnimator. When the keyframe animation is executed there’s an occasional crash for end users in production. It only happens on iOS 26. FB Radar: FB20871547 An example crash is below. Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Reason: +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class 0x20c95da08 Termination Reason: SIGNAL 6 Abort trap: 6 Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x1a23828c8 __exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x19f2f97c4 objc_exception_throw + 88 (objc-exception.mm:356) 2 CoreFoundation 0x1a241e6cc +[NSObject(NSObject) doesNotRecognizeSelector:] + 364 (NSObject.m:158) 3 CoreFoundation 0x1a22ff4f8 ___forwarding___ + 1472 (NSForwarding.m:3616) 4 CoreFoundation 0x1a23073a0 _CF_forwarding_prep_0 + 96 (:-1) 5 UIKitCore 0x1a948e880 __35-[UIViewKeyframeAnimationState pop]_block_invoke + 300 (UIView.m:2973) 6 CoreFoundation 0x1a22cb170 __NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__ + 24 (NSDictionaryHelpers.m:10) 7 CoreFoundation 0x1a245d7cc -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 288 (NSDictionaryM.m:271) 8 UIKitCore 0x1a948e6bc -[UIViewKeyframeAnimationState pop] + 376 (UIView.m:2955) 9 UIKitCore 0x1a7bc40e8 +[UIViewAnimationState popAnimationState] + 60 (UIView.m:1250) 10 UIKitCore 0x1a94acc44 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 684 (UIView.m:17669) 11 UIKitCore 0x1a94ae334 +[UIView(UIViewKeyframeAnimations) animateKeyframesWithDuration:delay:options:animations:completion:] + 224 (UIView.m:17945) 12 MyApp 0x102c78dec static UIView.animateNestedKeyframe(withRelativeStartTime:relativeDuration:animations:) + 208 (UIView+AnimateNestedKeyframe.swift:10) 13 MyApp 0x102aef3c0 closure #1 in DismissPlayerAnimationController.slideDownBelowTabBarTransitionAnimator(using:) + 156 (DismissPlayerAnimationController.swift:229) 14 MyApp 0x102a2d3d4 <deduplicated_symbol> + 28 15 UIKitCore 0x1a7d5ae5c -[UIViewPropertyAnimator _runAnimations] + 172 (UIViewPropertyAnimator.m:2123) 16 UIKitCore 0x1a83e1594 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_3 + 92 (UIViewPropertyAnimator.m:3557) 17 UIKitCore 0x1a83e1464 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke + 96 (UIViewPropertyAnimator.m:3547) 18 UIKitCore 0x1a83e1518 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_2 + 144 (UIViewPropertyAnimator.m:3553) 19 UIKitCore 0x1a83e0e64 -[UIViewPropertyAnimator _setupAnimationTracking:] + 100 (UIViewPropertyAnimator.m:3510) 20 UIKitCore 0x1a83e1264 -[UIViewPropertyAnimator startAnimationAsPaused:] + 728 (UIViewPropertyAnimator.m:3610) 21 UIKitCore 0x1a83de42c -[UIViewPropertyAnimator pauseAnimation] + 68 (UIViewPropertyAnimator.m:2753) 22 UIKitCore 0x1a87d5328 -[UIPercentDrivenInteractiveTransition _startInterruptibleTransition:] + 244 (UIViewControllerTransitioning.m:982) 23 UIKitCore 0x1a87d5514 -[UIPercentDrivenInteractiveTransition startInteractiveTransition:] + 184 (UIViewControllerTransitioning.m:1012) 24 UIKitCore 0x1a7c7931c ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_3 + 152 (UIViewControllerTransitioning.m:1579) 25 UIKitCore 0x1a892aefc +[UIKeyboardSceneDelegate _pinInputViewsForKeyboardSceneDelegate:onBehalfOfResponder:duringBlock:] + 96 (UIKeyboardSceneDelegate.m:3518) 26 UIKitCore 0x1a7c79238 ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_2 + 236 (UIViewControllerTransitioning.m:1571) 27 UIKitCore 0x1a94ab4b8 +[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:animated:] + 188 (UIView.m:17089) 28 UIKitCore 0x1a7c79070 _UIViewControllerTransitioningRunCustomTransitionWithRequest + 556 (UIViewControllerTransitioning.m:1560) 29 UIKitCore 0x1a86cb7cc __77-[UIPresentationController runTransitionForCurrentStateAnimated:handoffData:]_block_invoke_3 + 1784 (UIPresentationController.m:1504) 30 UIKitCore 0x1a7c43888 -[_UIAfterCACommitBlock run] + 72 (_UIAfterCACommitQueue.m:137) 31 UIKitCore 0x1a7c437c0 -[_UIAfterCACommitQueue flush] + 168 (_UIAfterCACommitQueue.m:228) 32 UIKitCore 0x1a7c436d0 _runAfterCACommitDeferredBlocks + 260 (UIApplication.m:3297) 33 UIKitCore 0x1a7c43c34 _cleanUpAfterCAFlushAndRunDeferredBlocks + 80 (UIApplication.m:3275) 34 UIKitCore 0x1a7c1f104 _UIApplicationFlushCATransaction + 72 (UIApplication.m:3338) 35 UIKitCore 0x1a7c1f024 __setupUpdateSequence_block_invoke_2 + 352 (_UIUpdateScheduler.m:1634) 36 UIKitCore 0x1a7c2cee8 _UIUpdateSequenceRunNext + 128 (_UIUpdateSequence.mm:189) 37 UIKitCore 0x1a7c2c378 schedulerStepScheduledMainSectionContinue + 60 (_UIUpdateScheduler.m:1185) 38 UpdateCycle 0x28c58f5f8 UC::DriverCore::continueProcessing() + 84 (UCDriver.cc:288) 39 CoreFoundation 0x1a2323230 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:2021) 40 CoreFoundation 0x1a23231a4 __CFRunLoopDoSource0 + 172 (CFRunLoop.c:2065) 41 CoreFoundation 0x1a2300c6c __CFRunLoopDoSources0 + 232 (CFRunLoop.c:2102) 42 CoreFoundation 0x1a22d68b0 __CFRunLoopRun + 820 (CFRunLoop.c:2983) 43 CoreFoundation 0x1a22d5c44 _CFRunLoopRunSpecificWithOptions + 532 (CFRunLoop.c:3462) 44 GraphicsServices 0x2416a2498 GSEventRunModal + 120 (GSEvent.c:2049) 45 UIKitCore 0x1a7c50ddc -[UIApplication _run] + 792 (UIApplication.m:3899) 46 UIKitCore 0x1a7bf5b0c UIApplicationMain + 336 (UIApplication.m:5574) // ...
Replies
4
Boosts
1
Views
781
Activity
Jan ’26
Race conditions when changing CAMetalLayer.drawableSize?
Is the pseudocode below thread-safe? Imagine that the Main thread sets the CAMetalLayer's drawableSize to a new size meanwhile the rendering thread is in the middle of rendering into an existing MTLDrawable which does still have the old size. Is the change of metalLayer.drawableSize thread-safe in the sense that I can present an old MTLDrawable which has a different resolution than the current value of metalLayer.drawableSize? I assume that setting the drawableSize property informs Metal that the next MTLDrawable offered by the CAMetalLayer should have the new size, right? Is it valid to assume that "metalLayer.drawableSize = newSize" and "metalLayer.nextDrawable()" are internally synchronized, so it cannot happen that metalLayer.nextDrawable() would produce e.g. a MTLDrawable with the old width but with the new height (or a completely invalid resolution due to potential race conditions)? func onWindowResized(newSize: CGSize) { // Called on the Main thread metalLayer.drawableSize = newSize } func onVsync(drawable: MTLDrawable) { // Called on a background rendering thread renderer.renderInto(drawable: drawable) }
Replies
1
Boosts
1
Views
840
Activity
Dec ’25
Liquid Glass TabBar animations causes Hangs, bug with UIKitCore?
With iOS 26.1 we started seeing a bug that only appears on iPhone Air. This bug is visible with simulators too. I have tried so many different ways to fix the issue, but Instruments Profiler is pointing at UIKitCore. We load a tab bar, when the user attempts to switch a tab, the app hangs and never recovers. It happens right as the animation of the Glass bubble is in progress. I have tried a UIKit Tab bar, a SwiftUI Tab bar. I tore out AppDelegate and did a direct @main SwiftUI entry for my application. This issue appears with every tab bar instance I try. I attempted to disable LiquidGlass by utilizing this flag UIDesignRequiresCompatibility in my plist, but the flag seems to be ignored by the system. I am not sure what else to try. I have a trace file if that is helpful. What else can I upload? Here is what the code looks like. struct ContentView: View { @State private var selectedTab = 2 var body: some View { TabView(selection: $selectedTab) { Text("Profile") .tabItem { Label("Me", systemImage: "person") } .tag(0) Text("Training") .tabItem { Label("Training", systemImage: "calendar") } .tag(1) Text("Home") .tabItem { Label("Home", systemImage: "house") } .tag(2) Text("Goals") .tabItem { Label("Goals", systemImage: "target") } .tag(3) Text("Coach") .tabItem { Label("Coach", systemImage: "person.2") } .tag(4) } } } #Preview { ContentView() } and AppView entry point import SwiftUI @main struct RunCoachApp: App { var body: some Scene { WindowGroup { ContentView() } } }
Replies
6
Boosts
1
Views
1.2k
Activity
Dec ’25
Incorrect transitionFlipFromRight animations on iOS 26.1
On devices and simulators with iOS 26.1, the animation does not work correctly (the initial and final screens are distorted). I use open class func transition(with view: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil) with options: .transitionFlipFromRight
Replies
6
Boosts
3
Views
485
Activity
Nov ’25
Unable to Display NSProgressIndicator on macOS Unlock (First Lock) Screen
I'm Trying to add an NSProgressIndicator on the unlock (first lock screen ) in macOS ( the screen with the lock icon ) I already added a label and it works fine and after entering the password on the second (authentication) page I can able to add ProgressIndicator but not on first screen. But Whenever I try to add a Progress indicator, the entire screen turns Black and nothing is displayed Is NSProgressIndicator supported on the first unlock Screen ? Or does macOS block animated UI on this screen Any Guidance would be helpful Thanks
Replies
1
Boosts
0
Views
585
Activity
Nov ’25
ios 26, CAShapeLayer with pattern image not work
please fix!
Replies
4
Boosts
2
Views
516
Activity
Oct ’25