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.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

SwiftData in-memory ModelContainer causes DefaultStore validation errors on consecutive xcodebuild test runs
When running parallel Swift Testing tests that each create their own in-memory ModelContainer, the first xcodebuild test run succeeds but all subsequent runs fail with DefaultStore save failed validation errors — unless DerivedData is deleted between runs. Setup Each test suite creates an isolated in-memory container with a unique name: ModelConfiguration(UUID().uuidString, schema: schema, isStoredInMemoryOnly: true) The @Model class has non-optional properties (e.g. var v: String, var entityDicMoveNr: Int) that are always set in init. Symptoms on second run SwiftData.DefaultStore save failed with error: Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred." NSValidationErrorKey=v, NSValidationErrorValue=null NSValidationErrorKey=entityDicMoveNr, NSValidationErrorValue=null NSValidationErrorKey=historyBackup, NSValidationErrorValue=null The errors appear before test code executes — during SwiftData's internal DefaultStore auto-save. Properties that are always initialized in Swift show as nil in the Core Data layer. What we verified Each run uses a fresh xctest process (different PIDs) Container creation succeeds (no errors in our ModelContainer init) The @Model init always sets all fields — confirmed with debug prints Deleting DerivedData before each run fixes it (but forces a full rebuild) What didn't help Using ModelContext(container) instead of container.mainContext Setting autosaveEnabled = false on both mainContext and custom contexts Using /dev/null URL instead of isStoredInMemoryOnly: true build-for-testing + test-without-building Clearing only Logs/Test or TestResults subdirectories Why not run via swift test? We can't fall back to swift test because our project uses RealityKit custom components, which silently fail to decode in CLI swift test. So xcodebuild test is our only option, making the DerivedData workaround especially costly. Workaround Delete DerivedData before each xcodebuild test invocation. Environment macOS 15.5, Xcode 16.4, Swift Testing with @Suite @MainActor parallel test suites. Question Is there a way to fully isolate in-memory ModelContainer instances so that no metadata leaks between xcodebuild test runs without requiring a full DerivedData clean?
4
0
156
1d
SF Symbols Variable Color — "Draw" symbols show no effect in Default mode
I've noticed an inconsistency between how the SF Symbols app and SwiftUI code handle variable color for symbols that use the "Draw" animation mode. Background SF Symbols that support variable color fall into two categories based on their animation preference: Symbols suited for .symbolVariableValueMode(.color) — layers are highlighted/dimmed by color opacity Symbols suited for .symbolVariableValueMode(.draw) — layers are progressively drawn/erased When .symbolVariableValueMode is not set (i.e., the default mode), I expected the system to automatically choose the appropriate mode for each symbol. What SF Symbols app shows In the SF Symbols app, selecting thermometer.high, enabling variable color, and setting the value to 0.5 with "Default" mode selected produces a correct and expected result — the symbol renders identically to the explicit "Draw" mode. What SwiftUI code does In code, when symbolVariableValueMode is not specified (default), symbols from the "Draw" category receive no visual effect — they appear static, as if variable value is ignored entirely. // This works correctly Image(systemName: "thermometer.high") .symbolVariableValue(0.5) .symbolVariableValueMode(.draw) // This shows NO effect — expected to fall back to .draw, but doesn't Image(systemName: "thermometer.high") .symbolVariableValue(0.5) // no .symbolVariableValueMode set Symbols in the "Color" category appear unaffected — they render correctly with or without an explicit mode. Question / Bug? Is this a known limitation, or is the default mode in code intentionally different from what the SF Symbols app previews? If so, is there a programmatic way to query which symbolVariableValueMode a given symbol prefers at runtime, so I can set it explicitly without hardcoding per-symbol logic?
0
0
92
2d
SwiftUI + AppKit context menu wedges window-level mouse events when the menu's anchor view is deleted by the menu's own action
I'm on macOS 26.4 (SwiftUI + SwiftData + AppKit bridging). I have a SwiftUI canvas where each child view (a card) carries a per-card AppKit context menu via an NSViewRepresentable overlay (a small NSView subclass that overrides menu(for:) and returns an NSMenu whose items invoke a Swift closure). The closure for the "Delete" item removes the underlying model object. SwiftData mutates → SwiftUI re-emits the canvas → the card containing the menu's anchor NSView unmounts → that anchor NSView is removed from the AppKit view hierarchy. After this happens, the entire window's SwiftUI gestures stop receiving mouse events: pan, zoom, taps on a separate background Color view all go silent. The window's first responder ends up at the NSWindow itself. The wedge persists across switching to a sibling SwiftUI view in the same window (different SwiftData root), so the bad state is at the window/event-routing level, not in any one SwiftUI subtree. The wedge is reliably cleared by another right-click that successfully shows + dismisses any menu — strongly suggesting AppKit's menu/event-tracking cleanup is left in a half-finished state because the anchor view went away during the cleanup window. I've already verified: Switching from explicit NSMenu.popUpContextMenu(_:with:for:) to overriding menu(for:) does not change the behavior. Deferring the model deletion via DispatchQueue.main.async, asyncAfter (30 ms), or RunLoop.main.perform(inModes: [.default]) either doesn't help or only avoids the wedge if the delay is long enough to be perceptible (seconds), implying the cleanup window is event-driven, not time-driven. Triggering the same deletion from a SwiftUI Button (no AppKit menu involved) never wedges. My current understanding is that the standard AppKit pattern (e.g., NSTableView, NSOutlineView) attaches the context menu to a stable parent view, never to the per-row view itself, precisely so the menu's anchor outlives any single row's deletion. Restructuring my code so a single canvas-level AppKitContextMenuRegion returns the appropriate menu via hit-testing in menu(for:) should avoid the issue, but I'd like to confirm: Is the assumption that an NSMenu's anchor view must outlive the menu's tracking-end cleanup documented anywhere, or is it implicit? Is there a supported way to safely use a per-row anchor view that gets deleted by the menu's own action, or is the canvas-level / parent-level menu attachment the only correct pattern? 3. Are there any post-tracking notifications or APIs that guarantee AppKit's cleanup is complete before the anchor view is allowed to be torn down (so a per-row anchor could be made safe with the right ordering)? Thanks!
0
0
271
3d
Crash in PDFView / PDFPageAnalyzerV2
Hello. Some users of my app experience crashes that mention PDFKit. I managed to find out what specific PDF file caused the crash and created a sample that demonstrates the issue and created a bug report in Feedback Assistant (FB22409977). Unfortunately I didn't get any answer for over a month, hence I'm writing it here so others can see that this is a known issue. The crash repro sample is very simple, it's just a PDFView that opens a bundled PDF file upon application lanunch. To cause the crash it is only needed to zoom-in and move around the page that has a table. The crash happens when the system tries to do some sort of OCR. The original crash report came from iPhone 11 user running iOS 26.3.1. Recently another user with iPhone 16 Pro Max running 26.5 experienced the same crash. Thread 12 Queue : PDFKWit.PDFDocument.formFillingQueue (serial) #0 0x000000018d320bd8 in PageLayout::GetBoundsForRangeWithinLine () #1 0x000000018d320c88 in PageLayout::GetBoundsForTextRange () #2 0x000000018d393028 in CGPDFTaggedNodeCreateCopyWithStringRange () #3 0x000000018d316630 in invocation function for block in TaggedParser::InsertLinkAnnotationsIntoStructureTree(CGPDFTaggedNode*, CGPDFPage*, PageLayout&) () #4 0x000000018d104f00 in CGPDFPageEnumerateAnnotations () #5 0x000000018d106968 in CGPDFPageCopyRootTaggedNode () #6 0x000000018d106710 in CGPDFPageInsertTableDescriptions () #7 0x00000001957a65b8 in +[PDFPageAnalyzerV2 addTablesFromVisionDocument:documentImage:toPage:withBox:] () #8 0x00000001957a3030 in +[PDFPageAnalyzerV2 analyzePage:withBox:requestTypes:] () #9 0x000000019584c018 in __31-[PDFView visiblePagesChanged:]_block_invoke () When CG_PDF_VERBOSE env variable is set, "New text range needs to be within the original node's text range." warning is printed to console several times before the crash happens.
0
0
103
5d
Navigation Title and UIAlertViewController actions truncated/cut on iPhone 13/14/15 Pro Max with iOS 26.4/5 using Cyrillic localisation
Since iOS 26.4, we are observing an issue on iPhone 13 Pro Max, iPhone 14 Pro Max, and iPhone 15 Pro Max where text is truncated on first presentation when using Bulgarian (Cyrillic) localization. The issue affects: UINavigationBar title (both inline and large titles) UIAlertController action titles Behavior: On first presentation, the text is truncated/cut off. On subsequent presentations, the layout appears correct. Adding a zero-width space (\u{200B}) before the last character of the string prevents truncation. This appears to slightly increase the layout width calculation and avoids the issue. Has anyone else encountered this behavior or found a more appropriate workaround?
1
0
106
5d
CarPlay voice-based-conversational app crashes when CarPlay scene activates before phone scene (React Native + Expo)
Hi all, I'm building a CarPlay app for the voice-based-conversational category (entitlement approved March 2026), and I've hit a crash I can't resolve through public documentation. Hoping someone here has seen this. Setup App: React Native via Expo SDK 54 (RN 0.81) CarPlay library: react-native-carplay@2.4.1-beta.0 iOS: 26.4.2 Entitlement: com.apple.developer.carplay-voice-based-conversation Architecture: ExpoAppDelegate subclass with two scene delegates declared in UIApplicationSceneManifest: PhoneSceneDelegate (UIWindowSceneDelegate) CarSceneDelegate (CPTemplateApplicationSceneDelegate) What works iPhone app launched first, CarPlay connects after: no crash. Placeholder CPListTemplate titled "Enough" displays. templateApplicationScene(_:didConnect:) is called. However the React Native side never receives the didConnect event from RNCarPlay — the placeholder is the only thing that ever shows. JS never gets a chance to call setRootTemplate(VoiceControlTemplate). What fails When CarPlay is the first scene to activate (iPhone app not running, user opens the app icon directly on the head unit), the app crashes immediately: Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x0000000190932800 Termination Reason: SIGNAL 5 Trace/BPT trap: 5 Triggered by Thread: 0 Thread 0 Crashed: 0 libswiftCore.dylib _assertionFailure(...) AssertCommon.swift:171 1-5 Enough (our Swift code, in CarSceneDelegate path) 6 libdispatch.dylib _dispatch_call_block_and_release Thread 11 (in parallel): hermes evaluatePreparedJavaScript React ReactInstance::loadScript React RCTJSThreadManager runRunLoop So React Native is bootstrapping on Thread 11 (Hermes loading the bundle), but Thread 0 fires a Swift assertion in our code path immediately after factory.startReactNative(...). What we've tried ~16 builds with iterative hypotheses. Two key ones: Passing UIWindow(frame: UIScreen.main.bounds) to factory.startReactNative(in:): crashes because iOS 13+ requires every UIWindow to belong to a UIWindowScene, and we were creating one without scene association. Passing nil to factory.startReactNative(in:): the header RCTReactNativeFactory.h declares inWindow:(UIWindow *_Nullable)window, so nil should be valid. But the crash signature is identical — Swift assertion failure inside ExpoReactNativeFactory or RCTReactNativeFactory. Looks like an internal precondition that requires window != nil despite the header. Other hypotheses ruled out: linker stripping of scene delegate classes (verified with nm), wrong protocol method signature (we use didConnect: for voice-based-conversational, not didConnect:to: which is for navigation apps), AppDelegate vs SceneDelegate bootstrap conflict. One hypothesis we haven't tested: bootstrapping React Native fully in application:didFinishLaunchingWithOptions: before any scene activates, exposing the bridge via singleton. This is the pattern documented in RN issue #41777 and the Adapptor blog (2022). We haven't tried because ExpoReactNativeFactory is more opaque than the older RCTAppDelegate and we're unsure which internal initialization steps are safe to extract. Specific questions Is RCTReactNativeFactory.startReactNative(withModuleName:in:launchOptions:) actually supported with nil window? The _Nullable annotation suggests yes, but runtime says no. Is the annotation aspirational or am I missing a setup step? For React Native apps using voice-based-conversational, is there a recommended pattern to handle CarPlay-first launch? All public documentation I've found is either for legacy CPApplicationDelegate or for navigation apps with MapTemplate. Can VoiceControlTemplate be presented from native Swift without involving the JS bridge for the initial template? This would let us avoid the bridge bootstrap problem on the CarPlay scene path. Any insights, war stories, or pointers to documentation I might have missed would be hugely appreciated. Multi-week investigation here and I'd love to find the right pattern or confirm an upstream issue worth filing as feedback. Thanks!
1
0
125
1w
Digital Wallet Verification Options
Good Morning all! I was wondering what the customization is in regard to Digital Wallet Verification. Currently we have Verify with Phone Call as the default option selected, then Verify within App as the second option. Is there a way or any documentation that can be looked at to see how we can have Verify within App be the defaulted option?
0
0
40
1w
MEMessageActionHandler — Mail shows "Uninstall only", no enable toggle, consent dialog never fires
I'm implementing a MEMessageActionHandler Mail extension on macOS 26.4.1 (Xcode 26.4). The extension is discovered by Mail and appears in Mail > Settings > Extensions, but Mail shows only an "Uninstall" button — no enable toggle. The MailKit consent dialog asking permission to process messages in the background has never appeared. Console logs show optedIn: NO / userEnabled: Not Enabled. Extension Info.plist (key parts): NSExtensionPointIdentifier com.apple.email.extension NSExtensionPrincipalClass CheckThisMailExtension.MailExtension MEExtensionCapabilities MEMessageActionHandler Principal class: class MailExtension: NSObject, MEExtension { func handlerForMessageActions() -> any MEMessageActionHandler { return MessageActionHandler() } } Entitlements: app-sandbox: true, application-groups: [group.com.xxx]. App is Developer ID signed and notarized. Has anyone successfully gotten the consent dialog to appear for MEMessageActionHandler on macOS 15/26? Is there something beyond the standard template configuration that enables it? Any entitlement that needs to be provisioned separately?
1
0
210
1w
How can I reliably get the final restored window size on macOS when onAppear / viewDidAppear fires too early?
I’m running into a macOS window restoration behavior issue where viewDidAppear (AppKit) or onAppear (SwiftUI) fires before the window’s final restored size is applied. AppKit example class MyViewController: NSViewController { override func viewDidLayout() { print("viewDidLayout: \(view.bounds.size)") } override func viewDidAppear() { print("viewDidAppear: \(view.bounds.size)") } } Logs on launch: viewDidAppear: (480.0, 270.0) viewDidLayout: (480.0, 270.0) viewDidLayout: (556.0, 476.0) viewDidLayout: (556.0, 476.0) The correct restored size is (556.0, 476.0), but viewDidAppear initially reports the old default size (480.0, 270.0). SwiftUI equivalent struct MyView: View { var body: some View { GeometryReader { geo in VStack {} .onAppear { print("onAppear: \(geo.size)") } .onChange(of: geo.size) { print("onChange: \(geo.size)") } } } } Logs on launch: onAppear: (900.0, 450.0) onChange: (680.0, 658.0) Problem I need to run some setup code: Only once After the view/window has its correct restored size Without rerunning on every layout or geometry change Question What is the proper macOS-native way to perform one-time startup logic only after the final restored window size is available? Is there a recommended lifecycle hook or pattern for this? Also, is it expected behavior that onAppear / viewDidAppear reports the pre-restoration size, or is it a bug?
3
0
192
1w
Custom keyboard.
I have created a keyboard extension but I do not feel the responsiveness like the default keyboard. I feel I have to mash down the keys and I feel when typing quickly the touch will skip a letter or two till the UI catches back up. My process - I have an xib that the visual is made. I have created my view then I added a view inside that and then 4 rows(views) inside that. In the rows I place the buttons. I had the touch down event for the buttons but that seemed it wouldn't register some times so I moved to the touch up and outside and inside but then I felt the edges when clicked wouldnt register. I know moved to every button in the key board has a tap gesture. This seems to be alot better but still missing the fluidness of the default keyboard. I am not expecting it to be perfect but something like swiftkey. Please ask if you want to see anything or if anything didnt make sense.Thank you!
3
0
669
1w
Custom keyboard extension left edge detecting touch after a second.
I'm creating a custom keyboard extension. So as a result, there are buttons which are pinned to the left edge of the keyboard. (Think of q key as an example). The logic of the key presses go something like this: Button detects a touchDown event and shows the magnified text which you normally see in system keyboard when tapping a key. Button detects a touchUpInside/touchDragOutside event and the magnified text disappears, again very similar to the system keyboard. This logic worked for all the buttons which were not pinned to the left edge of the keyboard. But for the buttons that were pinned to the left edge, the touchDown events were being detected after a second. So you can see this is obviously bad because I want to see the magnified text right after I place my finger on the button. WHAT I TRIED AS AN ALTERNATIVE: I removed all the touchDown, touchUpInside and touchDragOutside events from the button and disabled all their user interaction. Then I implemented to touches functions(touchesBegan, touchesEnded, etc.) and observed the touch locations on the background view. Surprisingly, even in this case, the touchesBegan function was called after a second after I placed my finger on the left edge of the screen and as usual, the touchesBegan function called just fine in the rest of the screen. Here's the code for the touches function: override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 		guard let touch = event?.allTouches?.first else { return } 		let location = touch.location(in: self.touchView) 				 		print(location) } What exactly is happening here? And what can I do to avoid this problem? NOTE: It works fine in simulator for some reason but has a problem with real devices.
1
2
631
1w
Switch view that digital crown controls
I wonder if there is way to switch the view that the digital crown controls. Like if have a list and a vertical tab view, when the tab displays, I want the crown control the scrolling in the tab. I dont want to use sheet, cause I have some special UX design, and also dont want to use if else to toggle between the two views. I have tried with resetFocus and other focus related functions, not working
0
0
46
2w
Under what conditions can a LocalizedStringResource be serialised?
I had a need to store a localised string in a shared file used by other applications, and noticed that LocalizedStringResource conforms to Codable -- and indeed, if I encode a string from App A, then switch to App B, B is able to read the value and load different localisations of that string out of App A's bundle. Very cool. This isn't clearly documented (the documentation for LocalizedStringResource just mentions cross-process use, not generally longer-term storage), so I wondered if there are any caveats to be aware of when using this approach? I am aware that LocalizedStringResource is just a reference, so obviously if App A is deleted, it becomes a kind of dangling reference and will presumably fall back to its default value (which is included in the encoded representation). But I also noticed that the encoded LSR includes a sandbox extension token. Is there anything in particular to be aware of with that? Is it time-limited? One thing I did notice, that is quite annoying (potentially a bug) is that if I serialise and deserialise a record containing a LSR, it no longer compares as == to its previous self. That is because the original LSR did not contain a sandbox extension token, but as part of encoding it, that field seems to get populated. I'm not sure if there is a good workaround there; perhaps the extension token could be ignored from ==? That would result in extension tokens being dropped (e.g. if you had two LSRs in a Dictionary, differing only by the sandbox token, they would still be considered substitutable and already "in" the dictionary), but perhaps that's fine.
1
0
85
2w
Creating UTImportedTypeDeclarations entries yields duplicate Open menu entry
My iPadOS app can open .xml files. In my XMLApp.swift, I hooked up a: var body: some Scene { WindowGroup(id: "main") { .commands CommandGroup(replacing: .newItem) { ... Button(.openDot) { openXMLFile() } ... Next, I entered a new UTImportedTypeDeclarations / UTExportedTypeDeclarations in Project Settings -> Target -> Info -> Document Types, Exported Type Identifiers, Imported Type Identifiers, for the XML file-type: ... <key>UTImportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.data</string> <string>public.xml</string> <string>public.content</string> </array> ... As soon as I do that, Xcode creates an additional Open... menu entry all the way at the bottom of the File menu. I cannot get rid of this additional menu entry. Its state is disabled (grayed out). I have my own Open (per the code above), which also responds to ⌘ - O. My menu entry works fine, as long as I disable the same keyboard shortcut so they don't collide. The extra Open entry is also displayed on the matching iPadOS simulator. From the same codebase, the Open is not displayed on the Mac (targeting macOS, not Catalyst). On macOS, only my Open is in the File menu, as expected. Why is there a duplicate Open menu entry and how do I get rid of it?
0
0
182
3w
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
208
3w
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
384
4w
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
588
4w
SwiftData in-memory ModelContainer causes DefaultStore validation errors on consecutive xcodebuild test runs
When running parallel Swift Testing tests that each create their own in-memory ModelContainer, the first xcodebuild test run succeeds but all subsequent runs fail with DefaultStore save failed validation errors — unless DerivedData is deleted between runs. Setup Each test suite creates an isolated in-memory container with a unique name: ModelConfiguration(UUID().uuidString, schema: schema, isStoredInMemoryOnly: true) The @Model class has non-optional properties (e.g. var v: String, var entityDicMoveNr: Int) that are always set in init. Symptoms on second run SwiftData.DefaultStore save failed with error: Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred." NSValidationErrorKey=v, NSValidationErrorValue=null NSValidationErrorKey=entityDicMoveNr, NSValidationErrorValue=null NSValidationErrorKey=historyBackup, NSValidationErrorValue=null The errors appear before test code executes — during SwiftData's internal DefaultStore auto-save. Properties that are always initialized in Swift show as nil in the Core Data layer. What we verified Each run uses a fresh xctest process (different PIDs) Container creation succeeds (no errors in our ModelContainer init) The @Model init always sets all fields — confirmed with debug prints Deleting DerivedData before each run fixes it (but forces a full rebuild) What didn't help Using ModelContext(container) instead of container.mainContext Setting autosaveEnabled = false on both mainContext and custom contexts Using /dev/null URL instead of isStoredInMemoryOnly: true build-for-testing + test-without-building Clearing only Logs/Test or TestResults subdirectories Why not run via swift test? We can't fall back to swift test because our project uses RealityKit custom components, which silently fail to decode in CLI swift test. So xcodebuild test is our only option, making the DerivedData workaround especially costly. Workaround Delete DerivedData before each xcodebuild test invocation. Environment macOS 15.5, Xcode 16.4, Swift Testing with @Suite @MainActor parallel test suites. Question Is there a way to fully isolate in-memory ModelContainer instances so that no metadata leaks between xcodebuild test runs without requiring a full DerivedData clean?
Replies
4
Boosts
0
Views
156
Activity
1d
SF Symbols Variable Color — "Draw" symbols show no effect in Default mode
I've noticed an inconsistency between how the SF Symbols app and SwiftUI code handle variable color for symbols that use the "Draw" animation mode. Background SF Symbols that support variable color fall into two categories based on their animation preference: Symbols suited for .symbolVariableValueMode(.color) — layers are highlighted/dimmed by color opacity Symbols suited for .symbolVariableValueMode(.draw) — layers are progressively drawn/erased When .symbolVariableValueMode is not set (i.e., the default mode), I expected the system to automatically choose the appropriate mode for each symbol. What SF Symbols app shows In the SF Symbols app, selecting thermometer.high, enabling variable color, and setting the value to 0.5 with "Default" mode selected produces a correct and expected result — the symbol renders identically to the explicit "Draw" mode. What SwiftUI code does In code, when symbolVariableValueMode is not specified (default), symbols from the "Draw" category receive no visual effect — they appear static, as if variable value is ignored entirely. // This works correctly Image(systemName: "thermometer.high") .symbolVariableValue(0.5) .symbolVariableValueMode(.draw) // This shows NO effect — expected to fall back to .draw, but doesn't Image(systemName: "thermometer.high") .symbolVariableValue(0.5) // no .symbolVariableValueMode set Symbols in the "Color" category appear unaffected — they render correctly with or without an explicit mode. Question / Bug? Is this a known limitation, or is the default mode in code intentionally different from what the SF Symbols app previews? If so, is there a programmatic way to query which symbolVariableValueMode a given symbol prefers at runtime, so I can set it explicitly without hardcoding per-symbol logic?
Replies
0
Boosts
0
Views
92
Activity
2d
SwiftUI + AppKit context menu wedges window-level mouse events when the menu's anchor view is deleted by the menu's own action
I'm on macOS 26.4 (SwiftUI + SwiftData + AppKit bridging). I have a SwiftUI canvas where each child view (a card) carries a per-card AppKit context menu via an NSViewRepresentable overlay (a small NSView subclass that overrides menu(for:) and returns an NSMenu whose items invoke a Swift closure). The closure for the "Delete" item removes the underlying model object. SwiftData mutates → SwiftUI re-emits the canvas → the card containing the menu's anchor NSView unmounts → that anchor NSView is removed from the AppKit view hierarchy. After this happens, the entire window's SwiftUI gestures stop receiving mouse events: pan, zoom, taps on a separate background Color view all go silent. The window's first responder ends up at the NSWindow itself. The wedge persists across switching to a sibling SwiftUI view in the same window (different SwiftData root), so the bad state is at the window/event-routing level, not in any one SwiftUI subtree. The wedge is reliably cleared by another right-click that successfully shows + dismisses any menu — strongly suggesting AppKit's menu/event-tracking cleanup is left in a half-finished state because the anchor view went away during the cleanup window. I've already verified: Switching from explicit NSMenu.popUpContextMenu(_:with:for:) to overriding menu(for:) does not change the behavior. Deferring the model deletion via DispatchQueue.main.async, asyncAfter (30 ms), or RunLoop.main.perform(inModes: [.default]) either doesn't help or only avoids the wedge if the delay is long enough to be perceptible (seconds), implying the cleanup window is event-driven, not time-driven. Triggering the same deletion from a SwiftUI Button (no AppKit menu involved) never wedges. My current understanding is that the standard AppKit pattern (e.g., NSTableView, NSOutlineView) attaches the context menu to a stable parent view, never to the per-row view itself, precisely so the menu's anchor outlives any single row's deletion. Restructuring my code so a single canvas-level AppKitContextMenuRegion returns the appropriate menu via hit-testing in menu(for:) should avoid the issue, but I'd like to confirm: Is the assumption that an NSMenu's anchor view must outlive the menu's tracking-end cleanup documented anywhere, or is it implicit? Is there a supported way to safely use a per-row anchor view that gets deleted by the menu's own action, or is the canvas-level / parent-level menu attachment the only correct pattern? 3. Are there any post-tracking notifications or APIs that guarantee AppKit's cleanup is complete before the anchor view is allowed to be torn down (so a per-row anchor could be made safe with the right ordering)? Thanks!
Replies
0
Boosts
0
Views
271
Activity
3d
Crash in PDFView / PDFPageAnalyzerV2
Hello. Some users of my app experience crashes that mention PDFKit. I managed to find out what specific PDF file caused the crash and created a sample that demonstrates the issue and created a bug report in Feedback Assistant (FB22409977). Unfortunately I didn't get any answer for over a month, hence I'm writing it here so others can see that this is a known issue. The crash repro sample is very simple, it's just a PDFView that opens a bundled PDF file upon application lanunch. To cause the crash it is only needed to zoom-in and move around the page that has a table. The crash happens when the system tries to do some sort of OCR. The original crash report came from iPhone 11 user running iOS 26.3.1. Recently another user with iPhone 16 Pro Max running 26.5 experienced the same crash. Thread 12 Queue : PDFKWit.PDFDocument.formFillingQueue (serial) #0 0x000000018d320bd8 in PageLayout::GetBoundsForRangeWithinLine () #1 0x000000018d320c88 in PageLayout::GetBoundsForTextRange () #2 0x000000018d393028 in CGPDFTaggedNodeCreateCopyWithStringRange () #3 0x000000018d316630 in invocation function for block in TaggedParser::InsertLinkAnnotationsIntoStructureTree(CGPDFTaggedNode*, CGPDFPage*, PageLayout&) () #4 0x000000018d104f00 in CGPDFPageEnumerateAnnotations () #5 0x000000018d106968 in CGPDFPageCopyRootTaggedNode () #6 0x000000018d106710 in CGPDFPageInsertTableDescriptions () #7 0x00000001957a65b8 in +[PDFPageAnalyzerV2 addTablesFromVisionDocument:documentImage:toPage:withBox:] () #8 0x00000001957a3030 in +[PDFPageAnalyzerV2 analyzePage:withBox:requestTypes:] () #9 0x000000019584c018 in __31-[PDFView visiblePagesChanged:]_block_invoke () When CG_PDF_VERBOSE env variable is set, "New text range needs to be within the original node's text range." warning is printed to console several times before the crash happens.
Replies
0
Boosts
0
Views
103
Activity
5d
Navigation Title and UIAlertViewController actions truncated/cut on iPhone 13/14/15 Pro Max with iOS 26.4/5 using Cyrillic localisation
Since iOS 26.4, we are observing an issue on iPhone 13 Pro Max, iPhone 14 Pro Max, and iPhone 15 Pro Max where text is truncated on first presentation when using Bulgarian (Cyrillic) localization. The issue affects: UINavigationBar title (both inline and large titles) UIAlertController action titles Behavior: On first presentation, the text is truncated/cut off. On subsequent presentations, the layout appears correct. Adding a zero-width space (\u{200B}) before the last character of the string prevents truncation. This appears to slightly increase the layout width calculation and avoids the issue. Has anyone else encountered this behavior or found a more appropriate workaround?
Replies
1
Boosts
0
Views
106
Activity
5d
.icon files and "imageNamed:"
Composer icons can be loaded with NSImage's imageNamed: but I haven't figured out how to make it load any variation other than the light style. Is this even possible? Thank you!
Replies
1
Boosts
0
Views
133
Activity
6d
CarPlay voice-based-conversational app crashes when CarPlay scene activates before phone scene (React Native + Expo)
Hi all, I'm building a CarPlay app for the voice-based-conversational category (entitlement approved March 2026), and I've hit a crash I can't resolve through public documentation. Hoping someone here has seen this. Setup App: React Native via Expo SDK 54 (RN 0.81) CarPlay library: react-native-carplay@2.4.1-beta.0 iOS: 26.4.2 Entitlement: com.apple.developer.carplay-voice-based-conversation Architecture: ExpoAppDelegate subclass with two scene delegates declared in UIApplicationSceneManifest: PhoneSceneDelegate (UIWindowSceneDelegate) CarSceneDelegate (CPTemplateApplicationSceneDelegate) What works iPhone app launched first, CarPlay connects after: no crash. Placeholder CPListTemplate titled "Enough" displays. templateApplicationScene(_:didConnect:) is called. However the React Native side never receives the didConnect event from RNCarPlay — the placeholder is the only thing that ever shows. JS never gets a chance to call setRootTemplate(VoiceControlTemplate). What fails When CarPlay is the first scene to activate (iPhone app not running, user opens the app icon directly on the head unit), the app crashes immediately: Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x0000000190932800 Termination Reason: SIGNAL 5 Trace/BPT trap: 5 Triggered by Thread: 0 Thread 0 Crashed: 0 libswiftCore.dylib _assertionFailure(...) AssertCommon.swift:171 1-5 Enough (our Swift code, in CarSceneDelegate path) 6 libdispatch.dylib _dispatch_call_block_and_release Thread 11 (in parallel): hermes evaluatePreparedJavaScript React ReactInstance::loadScript React RCTJSThreadManager runRunLoop So React Native is bootstrapping on Thread 11 (Hermes loading the bundle), but Thread 0 fires a Swift assertion in our code path immediately after factory.startReactNative(...). What we've tried ~16 builds with iterative hypotheses. Two key ones: Passing UIWindow(frame: UIScreen.main.bounds) to factory.startReactNative(in:): crashes because iOS 13+ requires every UIWindow to belong to a UIWindowScene, and we were creating one without scene association. Passing nil to factory.startReactNative(in:): the header RCTReactNativeFactory.h declares inWindow:(UIWindow *_Nullable)window, so nil should be valid. But the crash signature is identical — Swift assertion failure inside ExpoReactNativeFactory or RCTReactNativeFactory. Looks like an internal precondition that requires window != nil despite the header. Other hypotheses ruled out: linker stripping of scene delegate classes (verified with nm), wrong protocol method signature (we use didConnect: for voice-based-conversational, not didConnect:to: which is for navigation apps), AppDelegate vs SceneDelegate bootstrap conflict. One hypothesis we haven't tested: bootstrapping React Native fully in application:didFinishLaunchingWithOptions: before any scene activates, exposing the bridge via singleton. This is the pattern documented in RN issue #41777 and the Adapptor blog (2022). We haven't tried because ExpoReactNativeFactory is more opaque than the older RCTAppDelegate and we're unsure which internal initialization steps are safe to extract. Specific questions Is RCTReactNativeFactory.startReactNative(withModuleName:in:launchOptions:) actually supported with nil window? The _Nullable annotation suggests yes, but runtime says no. Is the annotation aspirational or am I missing a setup step? For React Native apps using voice-based-conversational, is there a recommended pattern to handle CarPlay-first launch? All public documentation I've found is either for legacy CPApplicationDelegate or for navigation apps with MapTemplate. Can VoiceControlTemplate be presented from native Swift without involving the JS bridge for the initial template? This would let us avoid the bridge bootstrap problem on the CarPlay scene path. Any insights, war stories, or pointers to documentation I might have missed would be hugely appreciated. Multi-week investigation here and I'd love to find the right pattern or confirm an upstream issue worth filing as feedback. Thanks!
Replies
1
Boosts
0
Views
125
Activity
1w
Digital Wallet Verification Options
Good Morning all! I was wondering what the customization is in regard to Digital Wallet Verification. Currently we have Verify with Phone Call as the default option selected, then Verify within App as the second option. Is there a way or any documentation that can be looked at to see how we can have Verify within App be the defaulted option?
Replies
0
Boosts
0
Views
40
Activity
1w
MEMessageActionHandler — Mail shows "Uninstall only", no enable toggle, consent dialog never fires
I'm implementing a MEMessageActionHandler Mail extension on macOS 26.4.1 (Xcode 26.4). The extension is discovered by Mail and appears in Mail > Settings > Extensions, but Mail shows only an "Uninstall" button — no enable toggle. The MailKit consent dialog asking permission to process messages in the background has never appeared. Console logs show optedIn: NO / userEnabled: Not Enabled. Extension Info.plist (key parts): NSExtensionPointIdentifier com.apple.email.extension NSExtensionPrincipalClass CheckThisMailExtension.MailExtension MEExtensionCapabilities MEMessageActionHandler Principal class: class MailExtension: NSObject, MEExtension { func handlerForMessageActions() -> any MEMessageActionHandler { return MessageActionHandler() } } Entitlements: app-sandbox: true, application-groups: [group.com.xxx]. App is Developer ID signed and notarized. Has anyone successfully gotten the consent dialog to appear for MEMessageActionHandler on macOS 15/26? Is there something beyond the standard template configuration that enables it? Any entitlement that needs to be provisioned separately?
Replies
1
Boosts
0
Views
210
Activity
1w
How can I reliably get the final restored window size on macOS when onAppear / viewDidAppear fires too early?
I’m running into a macOS window restoration behavior issue where viewDidAppear (AppKit) or onAppear (SwiftUI) fires before the window’s final restored size is applied. AppKit example class MyViewController: NSViewController { override func viewDidLayout() { print("viewDidLayout: \(view.bounds.size)") } override func viewDidAppear() { print("viewDidAppear: \(view.bounds.size)") } } Logs on launch: viewDidAppear: (480.0, 270.0) viewDidLayout: (480.0, 270.0) viewDidLayout: (556.0, 476.0) viewDidLayout: (556.0, 476.0) The correct restored size is (556.0, 476.0), but viewDidAppear initially reports the old default size (480.0, 270.0). SwiftUI equivalent struct MyView: View { var body: some View { GeometryReader { geo in VStack {} .onAppear { print("onAppear: \(geo.size)") } .onChange(of: geo.size) { print("onChange: \(geo.size)") } } } } Logs on launch: onAppear: (900.0, 450.0) onChange: (680.0, 658.0) Problem I need to run some setup code: Only once After the view/window has its correct restored size Without rerunning on every layout or geometry change Question What is the proper macOS-native way to perform one-time startup logic only after the final restored window size is available? Is there a recommended lifecycle hook or pattern for this? Also, is it expected behavior that onAppear / viewDidAppear reports the pre-restoration size, or is it a bug?
Replies
3
Boosts
0
Views
192
Activity
1w
Custom keyboard.
I have created a keyboard extension but I do not feel the responsiveness like the default keyboard. I feel I have to mash down the keys and I feel when typing quickly the touch will skip a letter or two till the UI catches back up. My process - I have an xib that the visual is made. I have created my view then I added a view inside that and then 4 rows(views) inside that. In the rows I place the buttons. I had the touch down event for the buttons but that seemed it wouldn't register some times so I moved to the touch up and outside and inside but then I felt the edges when clicked wouldnt register. I know moved to every button in the key board has a tap gesture. This seems to be alot better but still missing the fluidness of the default keyboard. I am not expecting it to be perfect but something like swiftkey. Please ask if you want to see anything or if anything didnt make sense.Thank you!
Replies
3
Boosts
0
Views
669
Activity
1w
Custom keyboard extension left edge detecting touch after a second.
I'm creating a custom keyboard extension. So as a result, there are buttons which are pinned to the left edge of the keyboard. (Think of q key as an example). The logic of the key presses go something like this: Button detects a touchDown event and shows the magnified text which you normally see in system keyboard when tapping a key. Button detects a touchUpInside/touchDragOutside event and the magnified text disappears, again very similar to the system keyboard. This logic worked for all the buttons which were not pinned to the left edge of the keyboard. But for the buttons that were pinned to the left edge, the touchDown events were being detected after a second. So you can see this is obviously bad because I want to see the magnified text right after I place my finger on the button. WHAT I TRIED AS AN ALTERNATIVE: I removed all the touchDown, touchUpInside and touchDragOutside events from the button and disabled all their user interaction. Then I implemented to touches functions(touchesBegan, touchesEnded, etc.) and observed the touch locations on the background view. Surprisingly, even in this case, the touchesBegan function was called after a second after I placed my finger on the left edge of the screen and as usual, the touchesBegan function called just fine in the rest of the screen. Here's the code for the touches function: override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) { &#9;&#9;guard let touch = event?.allTouches?.first else { return } &#9;&#9;let location = touch.location(in: self.touchView) &#9;&#9;&#9;&#9; &#9;&#9;print(location) } What exactly is happening here? And what can I do to avoid this problem? NOTE: It works fine in simulator for some reason but has a problem with real devices.
Replies
1
Boosts
2
Views
631
Activity
1w
Switch view that digital crown controls
I wonder if there is way to switch the view that the digital crown controls. Like if have a list and a vertical tab view, when the tab displays, I want the crown control the scrolling in the tab. I dont want to use sheet, cause I have some special UX design, and also dont want to use if else to toggle between the two views. I have tried with resetFocus and other focus related functions, not working
Replies
0
Boosts
0
Views
46
Activity
2w
Under what conditions can a LocalizedStringResource be serialised?
I had a need to store a localised string in a shared file used by other applications, and noticed that LocalizedStringResource conforms to Codable -- and indeed, if I encode a string from App A, then switch to App B, B is able to read the value and load different localisations of that string out of App A's bundle. Very cool. This isn't clearly documented (the documentation for LocalizedStringResource just mentions cross-process use, not generally longer-term storage), so I wondered if there are any caveats to be aware of when using this approach? I am aware that LocalizedStringResource is just a reference, so obviously if App A is deleted, it becomes a kind of dangling reference and will presumably fall back to its default value (which is included in the encoded representation). But I also noticed that the encoded LSR includes a sandbox extension token. Is there anything in particular to be aware of with that? Is it time-limited? One thing I did notice, that is quite annoying (potentially a bug) is that if I serialise and deserialise a record containing a LSR, it no longer compares as == to its previous self. That is because the original LSR did not contain a sandbox extension token, but as part of encoding it, that field seems to get populated. I'm not sure if there is a good workaround there; perhaps the extension token could be ignored from ==? That would result in extension tokens being dropped (e.g. if you had two LSRs in a Dictionary, differing only by the sandbox token, they would still be considered substitutable and already "in" the dictionary), but perhaps that's fine.
Replies
1
Boosts
0
Views
85
Activity
2w
Creating UTImportedTypeDeclarations entries yields duplicate Open menu entry
My iPadOS app can open .xml files. In my XMLApp.swift, I hooked up a: var body: some Scene { WindowGroup(id: "main") { .commands CommandGroup(replacing: .newItem) { ... Button(.openDot) { openXMLFile() } ... Next, I entered a new UTImportedTypeDeclarations / UTExportedTypeDeclarations in Project Settings -> Target -> Info -> Document Types, Exported Type Identifiers, Imported Type Identifiers, for the XML file-type: ... <key>UTImportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.data</string> <string>public.xml</string> <string>public.content</string> </array> ... As soon as I do that, Xcode creates an additional Open... menu entry all the way at the bottom of the File menu. I cannot get rid of this additional menu entry. Its state is disabled (grayed out). I have my own Open (per the code above), which also responds to ⌘ - O. My menu entry works fine, as long as I disable the same keyboard shortcut so they don't collide. The extra Open entry is also displayed on the matching iPadOS simulator. From the same codebase, the Open is not displayed on the Mac (targeting macOS, not Catalyst). On macOS, only my Open is in the File menu, as expected. Why is there a duplicate Open menu entry and how do I get rid of it?
Replies
0
Boosts
0
Views
182
Activity
3w
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
208
Activity
3w
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
137
Activity
3w
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
384
Activity
4w
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
588
Activity
4w
How to disable automatic hyphenation on iPhone?
Does anyone know how to remove that automatic hyphen at the end of a sentence when the word doesn't fit on the line? It's so annoying and incredibly disruptive. I tried sending an HTML file on WhatsApp, and I couldn't get it to work without that darn hyphen. Iphone 17, ios 26.5 beta
Replies
3
Boosts
0
Views
192
Activity
Apr ’26