Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

Embedded Collection View in SwiftUI offset issue
I have a collection view that covers all the screen and it is scrolling behavior is paging. This collection view is embedded in a UIViewRepresentable and used in a SwiftUI app. The issue is that when users rotate the devices, sometimes the CollectionView.contentOffset get miscalculated and shows 2 pages. This is the code that I'm using for the collectionView and collectionViewLayout: class PageFlowLayout: UICollectionViewFlowLayout { override class var layoutAttributesClass: AnyClass { UICollectionViewLayoutAttributes.self } private var calculatedAttributes: [UICollectionViewLayoutAttributes] = [] private var calculatedContentWidth: CGFloat = 0 private var calculatedContentHeight: CGFloat = 0 public weak var delegate: PageFlowLayoutDelegate? override var collectionViewContentSize: CGSize { return CGSize(width: self.calculatedContentWidth, height: self.calculatedContentHeight) } override init() { super.init() self.estimatedItemSize = .zero self.scrollDirection = .horizontal self.minimumLineSpacing = 0 self.minimumInteritemSpacing = 0 self.sectionInset = .zero } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func prepare() { guard let collectionView = collectionView, collectionView.numberOfSections > 0, calculatedAttributes.isEmpty else { return } estimatedItemSize = collectionView.bounds.size for item in 0..<collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item, section: 0) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) let itemOrigin = CGPoint(x: CGFloat(item) * collectionView.frame.width, y: 0) attributes.frame = .init(origin: itemOrigin, size: collectionView.frame.size) calculatedAttributes.append(attributes) } calculatedContentWidth = collectionView.bounds.width * CGFloat(calculatedAttributes.count) calculatedContentHeight = collectionView.bounds.size.height } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return calculatedAttributes.compactMap { return $0.frame.intersects(rect) ? $0 : nil } } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return calculatedAttributes[indexPath.item] } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { guard let collectionView else { return false } if newBounds.size != collectionView.bounds.size { return true } if newBounds.size.width > 0 { let pages = calculatedContentWidth / newBounds.size.width // If the contentWidth matches the number of pages, // if not it requires to layout the cells let arePagesExact = pages.truncatingRemainder(dividingBy: 1) == 0 return !arePagesExact } return false } override func invalidateLayout() { calculatedAttributes = [] super.invalidateLayout() } override func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool { guard let collectionView, #available(iOS 18.0, *) else { return false } return preferredAttributes.size != collectionView.bounds.size } override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { guard let customContext = context as? UICollectionViewFlowLayoutInvalidationContext else { return } if let collectionView, let currentPage = delegate?.currentPage() { let delta = (CGFloat(currentPage) * collectionView.bounds.width) - collectionView.contentOffset.x customContext.contentOffsetAdjustment.x += delta } calculatedAttributes = [] super.invalidateLayout(with: customContext) } override func prepare(forAnimatedBoundsChange oldBounds: CGRect) { super.prepare(forAnimatedBoundsChange: oldBounds) guard let collectionView else { return } if oldBounds.width != collectionView.bounds.width { invalidateLayout() } } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { guard let collectionView, let currentPage = delegate?.currentPage() else { return .zero } let targetContentOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset) let targetPage = targetContentOffset.x / collectionView.frame.width if targetPage != CGFloat(currentPage) { let xPosition = CGFloat(currentPage) * collectionView.frame.width return CGPoint(x: xPosition, y: 0) } return targetContentOffset } // This function updates the contentOffset in case is wrong override func finalizeCollectionViewUpdates() { guard let collectionView, let currentPage = delegate?.currentPage() else { return } let xPosition = CGFloat(currentPage) * collectionView.bounds.width if xPosition != collectionView.contentOffset.x { let offset = CGPoint(x: xPosition, y: 0) collectionView.setContentOffset(offset, animated: false) } } } The full implementation is attached in the .txt file: RotationTestView.txt
6
0
216
Apr ’26
EXC_BAD_ACCESS in drawHierarchy(in:afterScreenUpdates:) on iOS 26.3.1+ — IOSurface CIF10 decompression crash
We're experiencing an EXC_BAD_ACCESS (SIGSEGV) crash in UIView.drawHierarchy(in:afterScreenUpdates: false) that occurs only on iOS 26.3.1 and later. It does not reproduce on iOS 26.3.0 or earlier. Crash Stack Thread 0 (Main Thread) — EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0 libvDSP.dylib vConvert_XRGB2101010ToARGB8888_vec 1 ImageIO IIOIOSurfaceWrapper_CIF10::CopyImageBlockSetWithOptions 2 ImageIO IIOImageProviderInfo::CopyImageBlockSetWithOptions 3 ImageIO CGImageReadGetBytesAtOffset 4 CoreGraphics CGAccessSessionGetBytes 5 CoreGraphics img_data_lock 6 CoreGraphics CGSImageDataLock 7 CoreGraphics ripc_AcquireImage 8 CoreGraphics ripc_DrawImage 9 CoreGraphics CGContextDrawImage 10 UIKitCore -[UIView(Rendering) drawHierarchy:afterScreenUpdates:] The crash occurs during 10-bit CIF10 → 8-bit ARGB8888 pixel conversion when the IOSurface backing a UIImageView in the view hierarchy is deallocated mid-render. How to Reproduce Display a scrollable list with multiple UIImageViews loaded via an async image library Call drawHierarchy(in: bounds, afterScreenUpdates: false) on visible cells periodically Scroll to trigger image recycling Crash occurs sporadically — more likely under memory pressure or rapid image recycling What We've Tried Both UIKit off-screen rendering approaches crash on iOS 26.3.1: Approach Result drawHierarchy(afterScreenUpdates: false) EXC_BAD_ACCESS in CIF10 IOSurface decompression view.layer.render(in:) EXC_BAD_ACCESS in Metal (agxaAssertBufferIsValid) iOS Version Correlation iOS 26.3.0 and earlier: No crash iOS 26.3.1 (23D8133)+: Crash occurs (~5 events per 7 days) We suspect the ImageIO security patches in iOS 26.3 (CVE-2026-20675, CVE-2026-20634) may have changed IOSurface lifecycle timing, exposing a race condition between drawHierarchy's composited buffer read and asynchronous IOSurface reclamation by the OS. Crash Data We sampled 3 crash events: Event 1 (iOS 26.3.1): 71 MB free memory — memory pressure Event 2 (iOS 26.3.1): 88 MB free memory — memory pressure Event 3 (iOS 26.3.2): 768 MB free memory — NOT memory pressure Event 3 shows this isn't purely a low-memory issue. The IOSurface can be reclaimed even with ample free memory, likely due to async image recycling. Question Is this a known regression in iOS 26.3.1? Is there a safe way to snapshot a view hierarchy containing IOSurface-backed images without risking EXC_BAD_ACCESS? Should drawHierarchy gracefully handle the case where an IOSurface backing store is reclaimed during the render? Any guidance or workarounds would be appreciated. We've also filed this as Feedback (will update with FB number after submission).
2
0
360
Apr ’26
AppKit - Legal to Change a View's Frame in -viewDidLayout?
I have (had) a view controller that does a bit of manual layout in a -viewDidLayout override. This was pretty easy to manage - however since introducing NSGlassEffectView into the view hierarchy I sometimes am getting hit with "Unable to simultaneously satisfy constraints" and Appkit would break a constraint to 'recover.' It appears translatesAutoresizingMaskIntoConstraints is creating some really weird fixed width and height constraints. Here I wasn't doing any autolayout - just add the glass view and set its frame in -viewDidLayout. At runtime since I do manual layout in -viewDidLayout the frames are fixed and there is no real "error" in my app in practice though I wanted to get rid of the constraint breaking warning being logged because I know Autolayout can be aggressive about 'correctness' who knows if they decide to throw and not catch in the future. In my perfect world I would probably just prefer a view.doesManualLayout = YES here - the subviews are big containers no labels so localization is not an issue for me. Rather than playing with autoresizing masks to get better translated constraints I decided to set translatesAutoresizingMaskIntoConstraints to NO and make the constraints myself. Now I get hit with the following exception: "The window has been marked as needing another Layout Window pass, but it has already had more Layout Window passes than there are views in the window" So this happens because the view which now has constraints -- I adjusted the frame of it one point in -viewDidLayout. My question is - is not legal to make changes in -viewDidLayout - which seems like the AppKit version of -viewDidLayoutSubviews. In UIKit I always thought it was fine to make changes in -viewDidLayoutSubviews to frames - even if constraints were used - this is a place where you could override things in complex layouts that cannot be easily described in constraints. But in AppKit if you touch certain frames in -viewDidLayout it can now cause this exception (also related: https://developer.apple.com/forums/thread/806471) I will change the constant of one of the constraints to account for the 1 point adjustment but my question still stands - is it not legal to touch frames in -viewDidLayout when autolayout constraints are used on that subview? It is (or at least was if I remember correctly) permitted to change the layout in -viewDidLayoutSubviews in UIKit but AppKit seems to be more aggressive in its checking for layout correctness). What about calling -sizeToFit on a control in viewDidLayout or some method that has side effect of invalidating layout in a non obvious way, is doing things like this now 'dangerous?' Shouldn't AppKit just block the layout from being invalidated from within -viewDidLayout - and leave whatever the layout is as is when viewDidLayout returns (thus making -viewDidLayout a useful place to override layout in the rare cases where you need a sledgehammer?)
4
0
603
Apr ’26
Keyboard greyed issue
I am facing weird keyboard issue when building the app with Xcode 26 recently. Actual behaviour I need is: But one below is the issue as the keyboard keys are greyed out: Please tell how to resolve this issue
4
0
300
Apr ’26
Technical risks of swapping between UITableViewDiffableDataSource and UITableViewDataSource on UITableView
I am currently migrating an app from the classic UITableViewDataSource to UITableViewDiffableDataSource. In certain complex cases, I find myself needing to toggle between the UITableViewDataSource and UITableViewDiffableDataSource on a single UITableView instance. Apple's official documentation for UITableViewDiffableDataSource contains a strict warning: "Do not change the dataSource on the table view after you configure it with a diffable data source. If the table view needs a new data source after you configure it initially, create and configure a new table view and diffable data source." I’m seeking clarification on: Internal State: What specific UIKit caching or internal state is corrupted if we nil out the diffable source and re-assign a classic one? Background Processes: Does the background diffing engine pose a risk (race conditions/crashes) if the source is swapped while a diff is calculating? The "Safe" Reset: If swapping is truly necessary, is there a verified cleanup sequence (e.g., clearing snapshots first) that avoids the need to recreate the UITableView entirely?
0
0
128
Apr ’26
TabView's Tab Label Image symbolEffect not allowed?
Hi, I'm using a TabView and for a given case I wish to have the icon of the Tab animated by symbolEffect to signify a state. The symbolEffect however doesn't seem to have an effect when used on a tab's label image. Is it really not possible? Tab(value: .hello) { EmptyView() } label: { Image(systemName: "hand.wave.fill") .symbolEffect(.wiggle, options: .repeating) } I still wish to use the TabView because it's amazing.
2
0
112
Apr ’26
macOS 26: NSTokenField crashes due to NSGenericException caused by too many Update Constraints
This example application crashes when entering any text to the token field with FAULT: NSGenericException: The window has been marked as needing another Update Constraints in Window pass, but it has already had more Update Constraints in Window passes than there are views in the window. The app uses controlTextDidChange to update a live preview where it accesses the objectValue of the token field. If one character is entered, it also looks like the NSTokenFieldDelegate methods tokenField(_:styleForRepresentedObject:) tokenField(_:editingStringForRepresentedObject:) tokenField(_:representedObjectForEditing:) are called more than 10000 times until the example app crashes on macOS Tahoe 26 beta 6. I've reported this issue with beta 1 as FB18088608, but haven't heard back so far. I have multiple occurrences of this issue in my app, which is working fine on previous versions of macOS. I haven't found a workaround yet, and I’m getting anxious of this issue persisting into the official release.
5
1
518
Apr ’26
Keyboard Toolbar Padding iOS26
When I create a SwiftUI toolbar item with placement of .keyboard on iOS 26, the item appears directly on top of and in contact with the keyboard. This does not look good visually nor does it match the behavior seen in Apple's apps, such as Reminders. Adding padding to the contents of the toolbar item only expands the size of the item but does not separate the capsule background of the item from the keyboard. How can I add vertical padding or spacing to separate the toolbar item capsule from the keyboard?
Topic: UI Frameworks SubTopic: SwiftUI
10
8
1.2k
Apr ’26
iOS 26 UITabBar Layout Glitch: Custom Appearance vs. Liquid Glass Effects during Rotation
Hello, I am encountering a UI layout issue on iOS 26 where UITabBar items become squashed or overlapping during device rotation (from Portrait to Landscape). This glitch occurs specifically when a custom UITabBarAppearance is applied. 1. "Liquid Glass" and UITabBar Customization According to TN3106, Apple states: "Starting in iOS 26, reduce your use of custom backgrounds in navigation elements and controls. While the techniques in this document remain valid for iOS 18 and earlier, prefer to remove custom effects and let the system determine the navigation bar background appearance. Any custom backgrounds and appearances you use in the navigation bar might overlay or interfere with Liquid Glass or other effects that the system provides, such as the scroll edge effect." Does this guidance also apply to UITabBar? Specifically, could setting a custom background color via UITabBarAppearance interfere with internal layout constraints required for the Liquid Glass effect to adapt correctly during orientation changes? It appears that the internal UIStackView may fail to recalculate width in time when these system effects are active. 2. Validation of the Layout Workaround To maintain our app's visual identity while resolving this squashing issue, I implemented the following fix within the transition coordinator of my UITabBarController: Code Implementation (Objective-C) [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { // Forcing a layout refresh to synchronize with the rotation animation [weakSelf.tabBar invalidateIntrinsicContentSize]; [weakSelf.tabBar setNeedsLayout]; [weakSelf.tabBar layoutIfNeeded]; } completion:nil]; Is manually invalidating the intrinsic content size an acceptable practice for iOS 26? Or is there a more "system-native" approach to ensure UITabBar layout remains stable and compatible with Liquid Glass, especially when custom appearances are necessary?
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
342
Apr ’26
MIDI Drag-and-drop to Logic Pro via NSItemProvider
Logic Pro recently changed the way it accepts drag and drop. If the ItemProvider contains UTType.midi, then Logic Pro shows visual feedback for the drop operation, but when the item is dropped, nothing happens. In the past, drag-and-drop used to work. With today's version (Logic Pro 11.2), the only way I was able to successfully drop MIDI was to provide UTType.fileURL and no other data types. But that's not a viable solution; I need other data types to be included too. As a side note, I tested with Ableton Live 12 and it works with no issue. Is this a bug in Logic Pro? What ItemProvider structure does Logic Pro expect to correctly receive the MIDI data?
5
0
403
Apr ’26
iOS 26 WKWebView STScreenTimeConfigurationObserver KVO Crash
Fatal Exception: NSInternalInconsistencyException Cannot remove an observer <WKWebView 0x135137800> for the key path "configuration.enforcesChildRestrictions" from <STScreenTimeConfigurationObserver 0x13c6d7460>, most likely because the value for the key "configuration" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the STScreenTimeConfigurationObserver [class.] I noticed that on iOS 26, WKWebView registers STScreenTimeConfigurationObserver, Is this an iOS 26 system issue? What should I do?
Topic: UI Frameworks SubTopic: UIKit Tags:
18
17
2.4k
Apr ’26
CarPlay CPListImageRowItem causes Inverted Scrolling and Side Button malfunction
In my CarPlaySceneDelegate.swift, I have two tabs: The first tab uses a CPListImageRowItem with a CPListImageRowItemRowElement. The scroll direction is inverted, and the side button does not function correctly. The second tab uses multiple CPListItem objects. There are no issues: scrolling works in the correct direction, and the side button behaves as expected. Steps To Reproduce Launch the app. Connect to CarPlay. In the first tab, scroll up and down, then use the side button to navigate. In the second tab, scroll up and down, then use the side button to navigate. As observed, the scrolling behavior is different between the two tabs. Code Example: import CarPlay import UIKit class CarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate { var interfaceController: CPInterfaceController? func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController ) { self.interfaceController = interfaceController downloadImageAndSetupTemplates() } func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController ) { self.interfaceController = nil } private func downloadImageAndSetupTemplates() { let urlString = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRcYUjd1FYkF04-8Vb7PKI1mGoF2quLPHKjvnR7V4ReZR8UjW-0NJ_kC7q13eISZGoTCLHaDPVbOthhH9QNq-YA0uuSUjfAoB3PPs1aXQ&s=10" guard let url = URL(string: urlString) else { setupTemplates(with: UIImage(systemName: "photo")!) return } URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in let image: UIImage if let data = data, let downloaded = UIImage(data: data) { image = downloaded } else { image = UIImage(systemName: "photo")! } DispatchQueue.main.async { self?.setupTemplates(with: image) } }.resume() } private func setupTemplates(with image: UIImage) { // Tab 1 : un seul CPListImageRowItem avec 12 CPListImageRowItemRowElement let elements: [CPListImageRowItemRowElement] = (1...12).map { index in CPListImageRowItemRowElement(image: image, title: "test \(index)", subtitle: nil) } let rowItem = CPListImageRowItem(text: "Images", elements: elements, allowsMultipleLines: true) rowItem.listImageRowHandler = { item, elementIndex, completion in print("tapped element \(elementIndex)") completion() } let tab1Section = CPListSection(items: [rowItem]) let tab1Template = CPListTemplate(title: "CPListImageRowItemRowElement", sections: [tab1Section]) // Tab 2 : 12 CPListItem simples let tab2Items: [CPListItem] = (1...12).map { index in let item = CPListItem(text: "Item \(index)", detailText: "Detail \(index)") item.handler = { _, completion in print("handler Tab 2") completion() } return item } let tab2Section = CPListSection(items: tab2Items) let tab2Template = CPListTemplate(title: "CPListItem", sections: [tab2Section]) // CPTabBarTemplate avec les deux tabs let tabBar = CPTabBarTemplate(templates: [tab1Template, tab2Template]) interfaceController?.setRootTemplate(tabBar, animated: true) } } Here is a quick video:
7
0
597
Apr ’26
iOS 26: Interactive sheet dismissal causes layout hitch in underlying SwiftUI view
I’ve been investigating a noticeable animation hitch when interactively dismissing a sheet over a SwiftUI screen with moderate complexity. This was not the case on iOS 18, so I’m curious if others are seeing the same on iOS 26 or have found any mitigations. When dismissing a sheet via the swipe gesture, there’s a visible hitch right after lift-off. The hitch comes from layout work in the underlying view (behind the sheet) The duration scales with the complexity of that view (e.g. number of TextFields/layout nodes) The animation for programmatic dismiss (e.g. tapping a “Done” button) is smooth, although it hangs for a similar amount of time before dismissing, so it appears that the underlying work still happens. SwiftUI is not reevaluating the body during this (validated with Self._printChanges()), so that is not the cause. Using Instruments, the hitch shows up as a layout spike on the main thread: 54ms UIView layoutSublayersOfLayer 54ms └─ _UIHostingView.layoutSubviews 38ms └─ SwiftUI.ViewGraph.updateOutputs 11ms ├─ partial apply for implicit closure #1 in closure #1 │ in closure #1 in Attribute.init<A>(_:) 4ms └─ -[UIView For the same hierarchy with varying complexity: ~3 TextFields in a List: ~25ms (not noticeable) ~20+ TextFields: ~60ms (clearly visible hitch) The same view hierarchy on iOS 18 did not exhibit a visible hitch. I’ve tested this on an iOS 26.4 device and simulator. I’ve also included a minimum reproducible example that illustrates this: struct ContentView: View { @State var showSheet = false var body: some View { NavigationStack { ScrollView { ForEach(0..<120) { _ in RowView() } } .navigationTitle("Repro") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Present") { showSheet = true } } } .sheet(isPresented: $showSheet) { PresentedSheet() } } } } struct RowView: View { @State var first = "" @State var second = "" var body: some View { VStack(alignment: .leading, spacing: 12) { Text("Row") .font(.headline) HStack(spacing: 12) { TextField("First", text: $first) .textFieldStyle(.roundedBorder) TextField("Second", text: $second) .textFieldStyle(.roundedBorder) } HStack(spacing: 12) { Text("Third") Text("Fourth") Image(systemName: "chevron.right") } } } } struct PresentedSheet: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { List {} .navigationTitle("Swipe To Dismiss Me") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Done") { dismiss() } } } } } } Is anyone else experiencing this and have any mitigations been found beyond reducing view complexity? I’ve filed a feedback report under FB22501630.
1
0
253
Apr ’26
UITextField and UITextView abnormally popped up the network permission application interface
in iOS26.4, after installing the app for the first time, opening the app and clicking on the UITextField input box will trigger the system to pop up the network permission application interface. This issue did not exist before iOS 26.3, only in iOS 26.4. This is a fatal bug where the network permission request box should not pop up when the developer has not called the network related API.
4
0
443
Apr ’26
CallKit automatically shows a system top toast after iOS 26, how to dismiss it?
I’m developing an iOS app that integrates with CallKit. Starting from iOS 26, I’ve noticed that the system automatically presents a top banner / toast-style UI when a CallKit call becomes active (see attached screenshot). This UI appears to be fully managed by the system. On iOS versions prior to iOS 26, this UI did not appear under the same CallKit configuration. What I’ve observed The banner is displayed automatically by the system It appears at the top of the screen, similar to a toast or call status banner It is not a view created by my app I could not find any public API or CallKit configuration related to dismissing or controlling it My questions: Is this top banner an intended system behavior change in newer iOS versions? Is there any public API to dismiss, hide, or customize this UI? If not, is this UI considered non-dismissible by design? Any clarification on the expected behavior or recommended approach would be greatly appreciated.
Topic: UI Frameworks SubTopic: UIKit Tags:
4
0
419
Apr ’26
How to achieve liquid glass button morph transition
Hi guys, I’m new on SwiftUI world. I wanted to ask how to achieve this kind of morph transition with ToolbarItem button just like the picture attached below. I have tried using Menu & confirmationDialog API but i didn’t achieve the same kind of looks here. Is there some kind of native API for this kind of transition? Thanks in advance guys 😁👍
Topic: UI Frameworks SubTopic: SwiftUI
1
0
90
Apr ’26
Text alignment issue in iOS 26.4
There appears to be a serious issue in iOS 26.4 regarding text alignment. All text strings are rendered right-aligned instead of left-aligned, even when explicitly setting the paragraph style to NSTextAlignmentLeft. This behavior is unexpected and seems to indicate a regression in text rendering. Could you please confirm whether this is a known issue in iOS 26.4? I am using the following code in a central function that has been working reliably for years across all my apps. Best regards, Rolf Code: NSMutableParagraphStyle* paragraphLeft = [[NSMutableParagraphStyle alloc] init]; if (paragraphLeft != nil) { paragraphLeft.alignment = NSTextAlignmentLeft; NSDictionary *settings = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : fontclr, NSParagraphStyleAttributeName : paragraphLeft }; [theString drawAtPoint:CGPointMake(x, y - font.ascender) withAttributes:settings]; [paragraphLeft release]; }
Topic: UI Frameworks SubTopic: UIKit
4
0
350
Apr ’26
NSView uses NSLayoutConstraint, and the transform set on the layer gets reset when the window size changes.
import Cocoa class RedRotatedView: NSView { override func viewDidMoveToSuperview() { super.viewDidMoveToSuperview() DispatchQueue.main.async { self.applyRotation() } } private func applyRotation() { wantsLayer = true layer?.backgroundColor = NSColor.red.cgColor let radians = CGFloat(30 * Double.pi / 180.0) self.layer?.transform = CATransform3DMakeRotation(radians, 0, 0, 1) } override func layout() { super.layout() } } class MainView: NSView { let redView: RedRotatedView override init(frame frameRect: NSRect) { self.redView = RedRotatedView() super.init(frame: frameRect) setupRedView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupRedView() { redView.wantsLayer = true redView.layer?.backgroundColor = NSColor.red.cgColor addSubview(redView) redView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ redView.centerXAnchor.constraint(equalTo: centerXAnchor), redView.centerYAnchor.constraint(equalTo: centerYAnchor), redView.widthAnchor.constraint(equalToConstant: 200), redView.heightAnchor.constraint(equalToConstant: 200) ]) // redView.frame = NSRect(x:100,y:100,width: 200,height: 200) } } @main struct AppKitRotationTestApp { static func main() { let app = NSApplication.shared let delegate = AppDelegate() app.delegate = delegate app.run() } } class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow! func applicationDidFinishLaunching(_ aNotification: Notification) { let mainView = MainView(frame: NSRect(x: 0, y: 0, width: 800, height: 600)) window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 800, height: 600), styleMask: [.titled, .closable, .resizable, .miniaturizable], backing: .buffered, defer: false ) window.center() window.title = "AppKit Rotation Test" window.contentView = mainView window.makeKeyAndOrderFront(nil) } func applicationWillTerminate(_ aNotification: Notification) { } func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } } If NSLayoutConstraint is not used directly and the NSView's frame is set directly, this situation does not occur. How can I avoid the transform being reset when using NSLayoutConstraint for layout?
Topic: UI Frameworks SubTopic: AppKit
0
0
119
Apr ’26
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp
1
0
199
Apr ’26
Embedded Collection View in SwiftUI offset issue
I have a collection view that covers all the screen and it is scrolling behavior is paging. This collection view is embedded in a UIViewRepresentable and used in a SwiftUI app. The issue is that when users rotate the devices, sometimes the CollectionView.contentOffset get miscalculated and shows 2 pages. This is the code that I'm using for the collectionView and collectionViewLayout: class PageFlowLayout: UICollectionViewFlowLayout { override class var layoutAttributesClass: AnyClass { UICollectionViewLayoutAttributes.self } private var calculatedAttributes: [UICollectionViewLayoutAttributes] = [] private var calculatedContentWidth: CGFloat = 0 private var calculatedContentHeight: CGFloat = 0 public weak var delegate: PageFlowLayoutDelegate? override var collectionViewContentSize: CGSize { return CGSize(width: self.calculatedContentWidth, height: self.calculatedContentHeight) } override init() { super.init() self.estimatedItemSize = .zero self.scrollDirection = .horizontal self.minimumLineSpacing = 0 self.minimumInteritemSpacing = 0 self.sectionInset = .zero } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func prepare() { guard let collectionView = collectionView, collectionView.numberOfSections > 0, calculatedAttributes.isEmpty else { return } estimatedItemSize = collectionView.bounds.size for item in 0..<collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item, section: 0) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) let itemOrigin = CGPoint(x: CGFloat(item) * collectionView.frame.width, y: 0) attributes.frame = .init(origin: itemOrigin, size: collectionView.frame.size) calculatedAttributes.append(attributes) } calculatedContentWidth = collectionView.bounds.width * CGFloat(calculatedAttributes.count) calculatedContentHeight = collectionView.bounds.size.height } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return calculatedAttributes.compactMap { return $0.frame.intersects(rect) ? $0 : nil } } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return calculatedAttributes[indexPath.item] } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { guard let collectionView else { return false } if newBounds.size != collectionView.bounds.size { return true } if newBounds.size.width > 0 { let pages = calculatedContentWidth / newBounds.size.width // If the contentWidth matches the number of pages, // if not it requires to layout the cells let arePagesExact = pages.truncatingRemainder(dividingBy: 1) == 0 return !arePagesExact } return false } override func invalidateLayout() { calculatedAttributes = [] super.invalidateLayout() } override func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool { guard let collectionView, #available(iOS 18.0, *) else { return false } return preferredAttributes.size != collectionView.bounds.size } override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { guard let customContext = context as? UICollectionViewFlowLayoutInvalidationContext else { return } if let collectionView, let currentPage = delegate?.currentPage() { let delta = (CGFloat(currentPage) * collectionView.bounds.width) - collectionView.contentOffset.x customContext.contentOffsetAdjustment.x += delta } calculatedAttributes = [] super.invalidateLayout(with: customContext) } override func prepare(forAnimatedBoundsChange oldBounds: CGRect) { super.prepare(forAnimatedBoundsChange: oldBounds) guard let collectionView else { return } if oldBounds.width != collectionView.bounds.width { invalidateLayout() } } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { guard let collectionView, let currentPage = delegate?.currentPage() else { return .zero } let targetContentOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset) let targetPage = targetContentOffset.x / collectionView.frame.width if targetPage != CGFloat(currentPage) { let xPosition = CGFloat(currentPage) * collectionView.frame.width return CGPoint(x: xPosition, y: 0) } return targetContentOffset } // This function updates the contentOffset in case is wrong override func finalizeCollectionViewUpdates() { guard let collectionView, let currentPage = delegate?.currentPage() else { return } let xPosition = CGFloat(currentPage) * collectionView.bounds.width if xPosition != collectionView.contentOffset.x { let offset = CGPoint(x: xPosition, y: 0) collectionView.setContentOffset(offset, animated: false) } } } The full implementation is attached in the .txt file: RotationTestView.txt
Replies
6
Boosts
0
Views
216
Activity
Apr ’26
EXC_BAD_ACCESS in drawHierarchy(in:afterScreenUpdates:) on iOS 26.3.1+ — IOSurface CIF10 decompression crash
We're experiencing an EXC_BAD_ACCESS (SIGSEGV) crash in UIView.drawHierarchy(in:afterScreenUpdates: false) that occurs only on iOS 26.3.1 and later. It does not reproduce on iOS 26.3.0 or earlier. Crash Stack Thread 0 (Main Thread) — EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0 libvDSP.dylib vConvert_XRGB2101010ToARGB8888_vec 1 ImageIO IIOIOSurfaceWrapper_CIF10::CopyImageBlockSetWithOptions 2 ImageIO IIOImageProviderInfo::CopyImageBlockSetWithOptions 3 ImageIO CGImageReadGetBytesAtOffset 4 CoreGraphics CGAccessSessionGetBytes 5 CoreGraphics img_data_lock 6 CoreGraphics CGSImageDataLock 7 CoreGraphics ripc_AcquireImage 8 CoreGraphics ripc_DrawImage 9 CoreGraphics CGContextDrawImage 10 UIKitCore -[UIView(Rendering) drawHierarchy:afterScreenUpdates:] The crash occurs during 10-bit CIF10 → 8-bit ARGB8888 pixel conversion when the IOSurface backing a UIImageView in the view hierarchy is deallocated mid-render. How to Reproduce Display a scrollable list with multiple UIImageViews loaded via an async image library Call drawHierarchy(in: bounds, afterScreenUpdates: false) on visible cells periodically Scroll to trigger image recycling Crash occurs sporadically — more likely under memory pressure or rapid image recycling What We've Tried Both UIKit off-screen rendering approaches crash on iOS 26.3.1: Approach Result drawHierarchy(afterScreenUpdates: false) EXC_BAD_ACCESS in CIF10 IOSurface decompression view.layer.render(in:) EXC_BAD_ACCESS in Metal (agxaAssertBufferIsValid) iOS Version Correlation iOS 26.3.0 and earlier: No crash iOS 26.3.1 (23D8133)+: Crash occurs (~5 events per 7 days) We suspect the ImageIO security patches in iOS 26.3 (CVE-2026-20675, CVE-2026-20634) may have changed IOSurface lifecycle timing, exposing a race condition between drawHierarchy's composited buffer read and asynchronous IOSurface reclamation by the OS. Crash Data We sampled 3 crash events: Event 1 (iOS 26.3.1): 71 MB free memory — memory pressure Event 2 (iOS 26.3.1): 88 MB free memory — memory pressure Event 3 (iOS 26.3.2): 768 MB free memory — NOT memory pressure Event 3 shows this isn't purely a low-memory issue. The IOSurface can be reclaimed even with ample free memory, likely due to async image recycling. Question Is this a known regression in iOS 26.3.1? Is there a safe way to snapshot a view hierarchy containing IOSurface-backed images without risking EXC_BAD_ACCESS? Should drawHierarchy gracefully handle the case where an IOSurface backing store is reclaimed during the render? Any guidance or workarounds would be appreciated. We've also filed this as Feedback (will update with FB number after submission).
Replies
2
Boosts
0
Views
360
Activity
Apr ’26
AppKit - Legal to Change a View's Frame in -viewDidLayout?
I have (had) a view controller that does a bit of manual layout in a -viewDidLayout override. This was pretty easy to manage - however since introducing NSGlassEffectView into the view hierarchy I sometimes am getting hit with "Unable to simultaneously satisfy constraints" and Appkit would break a constraint to 'recover.' It appears translatesAutoresizingMaskIntoConstraints is creating some really weird fixed width and height constraints. Here I wasn't doing any autolayout - just add the glass view and set its frame in -viewDidLayout. At runtime since I do manual layout in -viewDidLayout the frames are fixed and there is no real "error" in my app in practice though I wanted to get rid of the constraint breaking warning being logged because I know Autolayout can be aggressive about 'correctness' who knows if they decide to throw and not catch in the future. In my perfect world I would probably just prefer a view.doesManualLayout = YES here - the subviews are big containers no labels so localization is not an issue for me. Rather than playing with autoresizing masks to get better translated constraints I decided to set translatesAutoresizingMaskIntoConstraints to NO and make the constraints myself. Now I get hit with the following exception: "The window has been marked as needing another Layout Window pass, but it has already had more Layout Window passes than there are views in the window" So this happens because the view which now has constraints -- I adjusted the frame of it one point in -viewDidLayout. My question is - is not legal to make changes in -viewDidLayout - which seems like the AppKit version of -viewDidLayoutSubviews. In UIKit I always thought it was fine to make changes in -viewDidLayoutSubviews to frames - even if constraints were used - this is a place where you could override things in complex layouts that cannot be easily described in constraints. But in AppKit if you touch certain frames in -viewDidLayout it can now cause this exception (also related: https://developer.apple.com/forums/thread/806471) I will change the constant of one of the constraints to account for the 1 point adjustment but my question still stands - is it not legal to touch frames in -viewDidLayout when autolayout constraints are used on that subview? It is (or at least was if I remember correctly) permitted to change the layout in -viewDidLayoutSubviews in UIKit but AppKit seems to be more aggressive in its checking for layout correctness). What about calling -sizeToFit on a control in viewDidLayout or some method that has side effect of invalidating layout in a non obvious way, is doing things like this now 'dangerous?' Shouldn't AppKit just block the layout from being invalidated from within -viewDidLayout - and leave whatever the layout is as is when viewDidLayout returns (thus making -viewDidLayout a useful place to override layout in the rare cases where you need a sledgehammer?)
Replies
4
Boosts
0
Views
603
Activity
Apr ’26
Keyboard greyed issue
I am facing weird keyboard issue when building the app with Xcode 26 recently. Actual behaviour I need is: But one below is the issue as the keyboard keys are greyed out: Please tell how to resolve this issue
Replies
4
Boosts
0
Views
300
Activity
Apr ’26
Technical risks of swapping between UITableViewDiffableDataSource and UITableViewDataSource on UITableView
I am currently migrating an app from the classic UITableViewDataSource to UITableViewDiffableDataSource. In certain complex cases, I find myself needing to toggle between the UITableViewDataSource and UITableViewDiffableDataSource on a single UITableView instance. Apple's official documentation for UITableViewDiffableDataSource contains a strict warning: "Do not change the dataSource on the table view after you configure it with a diffable data source. If the table view needs a new data source after you configure it initially, create and configure a new table view and diffable data source." I’m seeking clarification on: Internal State: What specific UIKit caching or internal state is corrupted if we nil out the diffable source and re-assign a classic one? Background Processes: Does the background diffing engine pose a risk (race conditions/crashes) if the source is swapped while a diff is calculating? The "Safe" Reset: If swapping is truly necessary, is there a verified cleanup sequence (e.g., clearing snapshots first) that avoids the need to recreate the UITableView entirely?
Replies
0
Boosts
0
Views
128
Activity
Apr ’26
TabView's Tab Label Image symbolEffect not allowed?
Hi, I'm using a TabView and for a given case I wish to have the icon of the Tab animated by symbolEffect to signify a state. The symbolEffect however doesn't seem to have an effect when used on a tab's label image. Is it really not possible? Tab(value: .hello) { EmptyView() } label: { Image(systemName: "hand.wave.fill") .symbolEffect(.wiggle, options: .repeating) } I still wish to use the TabView because it's amazing.
Replies
2
Boosts
0
Views
112
Activity
Apr ’26
macOS 26: NSTokenField crashes due to NSGenericException caused by too many Update Constraints
This example application crashes when entering any text to the token field with FAULT: NSGenericException: The window has been marked as needing another Update Constraints in Window pass, but it has already had more Update Constraints in Window passes than there are views in the window. The app uses controlTextDidChange to update a live preview where it accesses the objectValue of the token field. If one character is entered, it also looks like the NSTokenFieldDelegate methods tokenField(_:styleForRepresentedObject:) tokenField(_:editingStringForRepresentedObject:) tokenField(_:representedObjectForEditing:) are called more than 10000 times until the example app crashes on macOS Tahoe 26 beta 6. I've reported this issue with beta 1 as FB18088608, but haven't heard back so far. I have multiple occurrences of this issue in my app, which is working fine on previous versions of macOS. I haven't found a workaround yet, and I’m getting anxious of this issue persisting into the official release.
Replies
5
Boosts
1
Views
518
Activity
Apr ’26
Keyboard Toolbar Padding iOS26
When I create a SwiftUI toolbar item with placement of .keyboard on iOS 26, the item appears directly on top of and in contact with the keyboard. This does not look good visually nor does it match the behavior seen in Apple's apps, such as Reminders. Adding padding to the contents of the toolbar item only expands the size of the item but does not separate the capsule background of the item from the keyboard. How can I add vertical padding or spacing to separate the toolbar item capsule from the keyboard?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
10
Boosts
8
Views
1.2k
Activity
Apr ’26
iOS 26 UITabBar Layout Glitch: Custom Appearance vs. Liquid Glass Effects during Rotation
Hello, I am encountering a UI layout issue on iOS 26 where UITabBar items become squashed or overlapping during device rotation (from Portrait to Landscape). This glitch occurs specifically when a custom UITabBarAppearance is applied. 1. "Liquid Glass" and UITabBar Customization According to TN3106, Apple states: "Starting in iOS 26, reduce your use of custom backgrounds in navigation elements and controls. While the techniques in this document remain valid for iOS 18 and earlier, prefer to remove custom effects and let the system determine the navigation bar background appearance. Any custom backgrounds and appearances you use in the navigation bar might overlay or interfere with Liquid Glass or other effects that the system provides, such as the scroll edge effect." Does this guidance also apply to UITabBar? Specifically, could setting a custom background color via UITabBarAppearance interfere with internal layout constraints required for the Liquid Glass effect to adapt correctly during orientation changes? It appears that the internal UIStackView may fail to recalculate width in time when these system effects are active. 2. Validation of the Layout Workaround To maintain our app's visual identity while resolving this squashing issue, I implemented the following fix within the transition coordinator of my UITabBarController: Code Implementation (Objective-C) [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { // Forcing a layout refresh to synchronize with the rotation animation [weakSelf.tabBar invalidateIntrinsicContentSize]; [weakSelf.tabBar setNeedsLayout]; [weakSelf.tabBar layoutIfNeeded]; } completion:nil]; Is manually invalidating the intrinsic content size an acceptable practice for iOS 26? Or is there a more "system-native" approach to ensure UITabBar layout remains stable and compatible with Liquid Glass, especially when custom appearances are necessary?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
0
Views
342
Activity
Apr ’26
Logic Pro 11.2.2 drag audio into plugin Broken
I am an audio plugin developer. 11.2.1 we were able to drag audio from the arrange page into the plugin. 11.2.2. that is now broken. I saw someone have a similar post, but MIDI. Any help would be greatly appreciated.
Replies
1
Boosts
0
Views
157
Activity
Apr ’26
MIDI Drag-and-drop to Logic Pro via NSItemProvider
Logic Pro recently changed the way it accepts drag and drop. If the ItemProvider contains UTType.midi, then Logic Pro shows visual feedback for the drop operation, but when the item is dropped, nothing happens. In the past, drag-and-drop used to work. With today's version (Logic Pro 11.2), the only way I was able to successfully drop MIDI was to provide UTType.fileURL and no other data types. But that's not a viable solution; I need other data types to be included too. As a side note, I tested with Ableton Live 12 and it works with no issue. Is this a bug in Logic Pro? What ItemProvider structure does Logic Pro expect to correctly receive the MIDI data?
Replies
5
Boosts
0
Views
403
Activity
Apr ’26
iOS 26 WKWebView STScreenTimeConfigurationObserver KVO Crash
Fatal Exception: NSInternalInconsistencyException Cannot remove an observer <WKWebView 0x135137800> for the key path "configuration.enforcesChildRestrictions" from <STScreenTimeConfigurationObserver 0x13c6d7460>, most likely because the value for the key "configuration" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the STScreenTimeConfigurationObserver [class.] I noticed that on iOS 26, WKWebView registers STScreenTimeConfigurationObserver, Is this an iOS 26 system issue? What should I do?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
18
Boosts
17
Views
2.4k
Activity
Apr ’26
CarPlay CPListImageRowItem causes Inverted Scrolling and Side Button malfunction
In my CarPlaySceneDelegate.swift, I have two tabs: The first tab uses a CPListImageRowItem with a CPListImageRowItemRowElement. The scroll direction is inverted, and the side button does not function correctly. The second tab uses multiple CPListItem objects. There are no issues: scrolling works in the correct direction, and the side button behaves as expected. Steps To Reproduce Launch the app. Connect to CarPlay. In the first tab, scroll up and down, then use the side button to navigate. In the second tab, scroll up and down, then use the side button to navigate. As observed, the scrolling behavior is different between the two tabs. Code Example: import CarPlay import UIKit class CarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate { var interfaceController: CPInterfaceController? func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController ) { self.interfaceController = interfaceController downloadImageAndSetupTemplates() } func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController ) { self.interfaceController = nil } private func downloadImageAndSetupTemplates() { let urlString = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRcYUjd1FYkF04-8Vb7PKI1mGoF2quLPHKjvnR7V4ReZR8UjW-0NJ_kC7q13eISZGoTCLHaDPVbOthhH9QNq-YA0uuSUjfAoB3PPs1aXQ&s=10" guard let url = URL(string: urlString) else { setupTemplates(with: UIImage(systemName: "photo")!) return } URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in let image: UIImage if let data = data, let downloaded = UIImage(data: data) { image = downloaded } else { image = UIImage(systemName: "photo")! } DispatchQueue.main.async { self?.setupTemplates(with: image) } }.resume() } private func setupTemplates(with image: UIImage) { // Tab 1 : un seul CPListImageRowItem avec 12 CPListImageRowItemRowElement let elements: [CPListImageRowItemRowElement] = (1...12).map { index in CPListImageRowItemRowElement(image: image, title: "test \(index)", subtitle: nil) } let rowItem = CPListImageRowItem(text: "Images", elements: elements, allowsMultipleLines: true) rowItem.listImageRowHandler = { item, elementIndex, completion in print("tapped element \(elementIndex)") completion() } let tab1Section = CPListSection(items: [rowItem]) let tab1Template = CPListTemplate(title: "CPListImageRowItemRowElement", sections: [tab1Section]) // Tab 2 : 12 CPListItem simples let tab2Items: [CPListItem] = (1...12).map { index in let item = CPListItem(text: "Item \(index)", detailText: "Detail \(index)") item.handler = { _, completion in print("handler Tab 2") completion() } return item } let tab2Section = CPListSection(items: tab2Items) let tab2Template = CPListTemplate(title: "CPListItem", sections: [tab2Section]) // CPTabBarTemplate avec les deux tabs let tabBar = CPTabBarTemplate(templates: [tab1Template, tab2Template]) interfaceController?.setRootTemplate(tabBar, animated: true) } } Here is a quick video:
Replies
7
Boosts
0
Views
597
Activity
Apr ’26
iOS 26: Interactive sheet dismissal causes layout hitch in underlying SwiftUI view
I’ve been investigating a noticeable animation hitch when interactively dismissing a sheet over a SwiftUI screen with moderate complexity. This was not the case on iOS 18, so I’m curious if others are seeing the same on iOS 26 or have found any mitigations. When dismissing a sheet via the swipe gesture, there’s a visible hitch right after lift-off. The hitch comes from layout work in the underlying view (behind the sheet) The duration scales with the complexity of that view (e.g. number of TextFields/layout nodes) The animation for programmatic dismiss (e.g. tapping a “Done” button) is smooth, although it hangs for a similar amount of time before dismissing, so it appears that the underlying work still happens. SwiftUI is not reevaluating the body during this (validated with Self._printChanges()), so that is not the cause. Using Instruments, the hitch shows up as a layout spike on the main thread: 54ms UIView layoutSublayersOfLayer 54ms └─ _UIHostingView.layoutSubviews 38ms └─ SwiftUI.ViewGraph.updateOutputs 11ms ├─ partial apply for implicit closure #1 in closure #1 │ in closure #1 in Attribute.init<A>(_:) 4ms └─ -[UIView For the same hierarchy with varying complexity: ~3 TextFields in a List: ~25ms (not noticeable) ~20+ TextFields: ~60ms (clearly visible hitch) The same view hierarchy on iOS 18 did not exhibit a visible hitch. I’ve tested this on an iOS 26.4 device and simulator. I’ve also included a minimum reproducible example that illustrates this: struct ContentView: View { @State var showSheet = false var body: some View { NavigationStack { ScrollView { ForEach(0..<120) { _ in RowView() } } .navigationTitle("Repro") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Present") { showSheet = true } } } .sheet(isPresented: $showSheet) { PresentedSheet() } } } } struct RowView: View { @State var first = "" @State var second = "" var body: some View { VStack(alignment: .leading, spacing: 12) { Text("Row") .font(.headline) HStack(spacing: 12) { TextField("First", text: $first) .textFieldStyle(.roundedBorder) TextField("Second", text: $second) .textFieldStyle(.roundedBorder) } HStack(spacing: 12) { Text("Third") Text("Fourth") Image(systemName: "chevron.right") } } } } struct PresentedSheet: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { List {} .navigationTitle("Swipe To Dismiss Me") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Done") { dismiss() } } } } } } Is anyone else experiencing this and have any mitigations been found beyond reducing view complexity? I’ve filed a feedback report under FB22501630.
Replies
1
Boosts
0
Views
253
Activity
Apr ’26
UITextField and UITextView abnormally popped up the network permission application interface
in iOS26.4, after installing the app for the first time, opening the app and clicking on the UITextField input box will trigger the system to pop up the network permission application interface. This issue did not exist before iOS 26.3, only in iOS 26.4. This is a fatal bug where the network permission request box should not pop up when the developer has not called the network related API.
Replies
4
Boosts
0
Views
443
Activity
Apr ’26
CallKit automatically shows a system top toast after iOS 26, how to dismiss it?
I’m developing an iOS app that integrates with CallKit. Starting from iOS 26, I’ve noticed that the system automatically presents a top banner / toast-style UI when a CallKit call becomes active (see attached screenshot). This UI appears to be fully managed by the system. On iOS versions prior to iOS 26, this UI did not appear under the same CallKit configuration. What I’ve observed The banner is displayed automatically by the system It appears at the top of the screen, similar to a toast or call status banner It is not a view created by my app I could not find any public API or CallKit configuration related to dismissing or controlling it My questions: Is this top banner an intended system behavior change in newer iOS versions? Is there any public API to dismiss, hide, or customize this UI? If not, is this UI considered non-dismissible by design? Any clarification on the expected behavior or recommended approach would be greatly appreciated.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
4
Boosts
0
Views
419
Activity
Apr ’26
How to achieve liquid glass button morph transition
Hi guys, I’m new on SwiftUI world. I wanted to ask how to achieve this kind of morph transition with ToolbarItem button just like the picture attached below. I have tried using Menu & confirmationDialog API but i didn’t achieve the same kind of looks here. Is there some kind of native API for this kind of transition? Thanks in advance guys 😁👍
Topic: UI Frameworks SubTopic: SwiftUI
Replies
1
Boosts
0
Views
90
Activity
Apr ’26
Text alignment issue in iOS 26.4
There appears to be a serious issue in iOS 26.4 regarding text alignment. All text strings are rendered right-aligned instead of left-aligned, even when explicitly setting the paragraph style to NSTextAlignmentLeft. This behavior is unexpected and seems to indicate a regression in text rendering. Could you please confirm whether this is a known issue in iOS 26.4? I am using the following code in a central function that has been working reliably for years across all my apps. Best regards, Rolf Code: NSMutableParagraphStyle* paragraphLeft = [[NSMutableParagraphStyle alloc] init]; if (paragraphLeft != nil) { paragraphLeft.alignment = NSTextAlignmentLeft; NSDictionary *settings = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : fontclr, NSParagraphStyleAttributeName : paragraphLeft }; [theString drawAtPoint:CGPointMake(x, y - font.ascender) withAttributes:settings]; [paragraphLeft release]; }
Topic: UI Frameworks SubTopic: UIKit
Replies
4
Boosts
0
Views
350
Activity
Apr ’26
NSView uses NSLayoutConstraint, and the transform set on the layer gets reset when the window size changes.
import Cocoa class RedRotatedView: NSView { override func viewDidMoveToSuperview() { super.viewDidMoveToSuperview() DispatchQueue.main.async { self.applyRotation() } } private func applyRotation() { wantsLayer = true layer?.backgroundColor = NSColor.red.cgColor let radians = CGFloat(30 * Double.pi / 180.0) self.layer?.transform = CATransform3DMakeRotation(radians, 0, 0, 1) } override func layout() { super.layout() } } class MainView: NSView { let redView: RedRotatedView override init(frame frameRect: NSRect) { self.redView = RedRotatedView() super.init(frame: frameRect) setupRedView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupRedView() { redView.wantsLayer = true redView.layer?.backgroundColor = NSColor.red.cgColor addSubview(redView) redView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ redView.centerXAnchor.constraint(equalTo: centerXAnchor), redView.centerYAnchor.constraint(equalTo: centerYAnchor), redView.widthAnchor.constraint(equalToConstant: 200), redView.heightAnchor.constraint(equalToConstant: 200) ]) // redView.frame = NSRect(x:100,y:100,width: 200,height: 200) } } @main struct AppKitRotationTestApp { static func main() { let app = NSApplication.shared let delegate = AppDelegate() app.delegate = delegate app.run() } } class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow! func applicationDidFinishLaunching(_ aNotification: Notification) { let mainView = MainView(frame: NSRect(x: 0, y: 0, width: 800, height: 600)) window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 800, height: 600), styleMask: [.titled, .closable, .resizable, .miniaturizable], backing: .buffered, defer: false ) window.center() window.title = "AppKit Rotation Test" window.contentView = mainView window.makeKeyAndOrderFront(nil) } func applicationWillTerminate(_ aNotification: Notification) { } func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } } If NSLayoutConstraint is not used directly and the NSView's frame is set directly, this situation does not occur. How can I avoid the transform being reset when using NSLayoutConstraint for layout?
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
119
Activity
Apr ’26
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp
Replies
1
Boosts
0
Views
199
Activity
Apr ’26