I'm trying to understand the behavior I'm seeing here. In the following example, I have a custom @Observable class that adopts RandomAccessCollection and am attempting to populate a List with it.
If I use an inner collection property of the instance (even computed as this shows), the top view identifies additions to the list.
However, if I just use the list as a collection in its own right, it detects when a change is made, but not that the change increased the length of the list. If you add text that has capital letters you'll see them get sorted correctly, but the lower list retains its prior count. The choice of a List initializer with the model versus an inner ForEach doesn't change the outcome, btw.
If I cast that type as an Array(), effectively copying its contents, it works fine which leads me to believe there is some additional Array protocol conformance that I'm missing, but that would be unfortunate since I'm not sure how I would have known that. Any ideas what's going on here? The new type can be used with for-in scenarios fine and compiles great with List/ForEach, but has this issue. I'd like the type to not require extra nonsense to be used like an array here.
import SwiftUI
fileprivate struct _VExpObservable6: View {
@Binding var model: ExpModel
@State private var text: String = ""
var body: some View {
NavigationStack {
VStack(spacing: 20) {
Spacer()
.frame(height: 40)
HStack {
TextField("Item", text: $text)
.textFieldStyle(.roundedBorder)
.textContentType(.none)
.textCase(.none)
Button("Add Item") {
guard !text.isEmpty else { return }
model.addItem(text)
text = ""
print("updated model #2 using \(Array(model.indices)):")
for s in model {
print("- \(s)")
}
}
}
InnerView(model: model)
OuterView(model: model)
}
.listStyle(.plain)
.padding()
}
}
}
// - displays the model data using an inner property expressed as
// a collection.
fileprivate struct InnerView: View {
let model: ExpModel
var body: some View {
VStack {
Text("Model Inner Collection:")
.font(.title3)
List {
ForEach(model.sorted, id: \.self) { item in
Text("- \(item)")
}
}
.border(.darkGray)
}
}
}
// - displays the model using the model _as the collection_
fileprivate struct OuterView: View {
let model: ExpModel
var body: some View {
VStack {
Text("Model as Collection:")
.font(.title3)
// - the List/ForEach collections do not appear to work
// by default using the @Observable model (RandomAccessCollection)
// itself, unless it is cast as an Array here.
List {
// ForEach(Array(model), id: \.self) { item in
ForEach(model, id: \.self) { item in
Text("- \(item)")
}
}
.border(.darkGray)
}
}
}
#Preview {
@Previewable @State var model = ExpModel()
_VExpObservable6(model: $model)
}
@Observable
fileprivate final class ExpModel: RandomAccessCollection {
typealias Element = String
var startIndex: Int { 0 }
var endIndex: Int { sorted.count }
init() {
_listData = ["apple", "yellow", "about"]
}
subscript(_ position: Int) -> String {
sortedData()[position]
}
var sorted: [String] {
sortedData()
}
func addItem(_ item: String) {
_listData.append(item)
_sorted = nil
}
private var _listData: [String]
private var _sorted: [String]?
private func sortedData() -> [String] {
if let ret = _sorted { return ret }
let ret = _listData.sorted()
_sorted = ret
return ret
}
}
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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I encountered a bug with drag-and-drop sorting in ios 26.
I created a UITableView for dragging and dropping to adjust the order of the list. However, when I set the height of the cells to a custom height, some cells were not displayed during the dragging process.
The tools I use are the official version of Xcode16.1 and the ios 26 emulator
And I can also reproduce the same problem on the real device.
class ViewController: UIViewController {
private let tableView: UITableView = {
let tableView = UITableView.init(frame: .zero, style: .grouped)
tableView.backgroundColor = .clear
tableView.estimatedSectionHeaderHeight = 50
tableView.isEditing = true
tableView.showsVerticalScrollIndicator = false
tableView.allowsSelectionDuringEditing = true
return tableView
}()
var content: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(FTWatchGroupPageCell.self, forCellReuseIdentifier: "FTWatchGroupPageCell")
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
for i in 1...100 {
content.append(i)
}
tableView.reloadData()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var frame = view.bounds
frame.origin.y = 200
frame.size.height = frame.size.height - 200
tableView.frame = frame
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return content.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FTWatchGroupPageCell", for: indexPath) as! FTWatchGroupPageCell
cell.label.text = "\(content[indexPath.row])"
cell.label.sizeToFit()
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 52.66
}
public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.01
}
public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.01
}
public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
public func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
public func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
public func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = content.remove(at: sourceIndexPath.row)
content.insert(item, at: destinationIndexPath.row)
tableView.reloadData()
}
}
class FTWatchGroupPageCell: UITableViewCell {
private let contentBackView = UIView()
let label = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.isHidden = true
addSubview(contentBackView)
contentBackView.backgroundColor = .red
contentBackView.addSubview(label)
label.textColor = .black
label.font = .systemFont(ofSize: 14)
contentBackView.frame = .init(x: 0, y: 0, width: 200, height: 30)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
guard let reorderControlClass = NSClassFromString("UITableViewCellReorderControl"),
let reorderControl = subviews.first(where: { $0.isKind(of: reorderControlClass) }) else {
return
}
reorderControl.alpha = 0.02
reorderControl.subviews.forEach({ subView in
if let imageView = subView as? UIImageView {
imageView.image = UIImage()
imageView.contentMode = .scaleAspectFit
imageView.frame.size = CGSize(width: 20, height: 20)
}
})
}
}
Hey there,
Is there a way to launch another view by tapping on the preview of a context menu? Something like the behavior of the Photos app where tapping on the preview navigates to the details view.
Tap gesture handlers on the preview don't seem to get called, even as high priority gestures.
Thanks for the help!
Gab
Question: How to prevent Flutter app crash on iOS 18 during cold start when iOS traverses view hierarchy before Flutter engine is fully initialized?
Help needed: Looking for a way to either delay iOS view hierarchy traversal or ensure Flutter is fully initialized before iOS lifecycle callbacks fire.
Problem Summary
Our Flutter app crashes on cold start for approximately 1-2% of iOS users. The crash occurs specifically on iOS and only under these exact conditions:
When crash happens:
User opens app and uses it normally ✅
User minimizes app (goes to background) ✅
User returns to app from background ✅ (works fine)
User kills app from app switcher (swipe up to close)
User taps app icon to launch again → CRASH ❌
Key observations:
Crash is intermittent - app may open on 2nd, 3rd, or 5th attempt
100% reproducible on affected devices by repeating kill→launch cycle
~98% of users have no issues
Environment
Flutter: 3.38.3
Crash Logs (from Sentry)
Crash Type 1: Stack Overflow (most common)
OS Version: iOS 18.7.2 (22H124)
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: BUS_NOOP at 0x000000016ad5be90
Application Specific Information:
compare:options:range:locale: >
Stack overflow in (null)
Thread 0 Crashed:
0 CoreFoundation CFStringGetLength
1 CoreFoundation CFStringCompareWithOptionsAndLocale
2 CoreFoundation
3 libsystem_c bsearch
4 CoreFoundation
5 UIKitCore
...
15-99: UIKitCore 0x30e177148 [inlined] // 85+ recursive calls
Crash Type 2: Use-After-Free
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: SEGV_NOOP at 0x0500007f14000000
KERN_INVALID_ADDRESS at 0x500007f14000000
Thread 0 Crashed:
0 libobjc.A.dylib objc_retainAutoreleaseReturnValue
1 UIKitCore
...
6 libobjc.A.dylib objcrootDealloc
7 QuartzCore // CALayer operations
What We Tried (nothing solved cold start crash)
Attempt
Result
Increased stack size to 64MB (-Wl,-stack_size,0x4000000)
❌ No effect
Disabled iOS State Restoration
❌ No effect
Added isViewLoaded checks in AppDelegate
❌ No effect
Added try-catch around GetStorage/SecureStorage init
❌ No effect
Added isAppActive flag to track app state
❌ No effect
Snapshot overlay in applicationWillResignActive
✅ Fixed background→foreground crash, ❌ but NOT cold start
Current AppDelegate.swift
import UIKit
import Flutter
@main
@objc
class AppDelegate: FlutterAppDelegate {
private var snapshotView: UIView?
private var isAppActive = false
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
window?.overrideUserInterfaceStyle = .light
isAppActive = true
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, shouldSaveSecureApplicationState coder: NSCoder) -> Bool {
return false
}
override func application(_ application: UIApplication, shouldRestoreSecureApplicationState coder: NSCoder) -> Bool {
return false
}
override func applicationWillResignActive(_ application: UIApplication) {
guard isAppActive,
let window = self.window,
let rootVC = window.rootViewController,
rootVC.isViewLoaded,
snapshotView == nil
else { return }
let snapshot = UIView(frame: window.bounds)
snapshot.backgroundColor = .white
snapshot.tag = 999
window.addSubview(snapshot)
snapshotView = snapshot
}
override func applicationDidBecomeActive(_ application: UIApplication) {
guard snapshotView != nil else {
isAppActive = true
return
}
snapshotView?.removeFromSuperview()
snapshotView = nil
}
}
Topic:
UI Frameworks
SubTopic:
UIKit
Running print operation on WKWebView I hit EXC_BREAKPOINT and there is all kinds of console spew that looks concerning:
ERROR: The NSPrintOperation view's frame was not initialized properly before knowsPageRange: returned. (WKPrintingView)
** CGContextClipToRect: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.**
WebContent[7743] networkd_settings_read_from_file Sandbox is preventing this process from reading networkd settings file at "/Library/Preferences/com.apple.networkd.plist", please add an exception.
CRASHSTRING: XPC_ERROR_CONNECTION_INVALID from launchservicesd
CRASHSTRING: rdar://problem/28724618 Process unable to create connection because the sandbox denied the right to lookup com.apple.coreservices.launchservicesd and so this process cannot talk to launchservicesd.
WebContent[7921] The sandbox in this process does not allow access to RunningBoard.
Safe to ignore all this?
I’m hoping to get some insight from Apple engineers or developers who have seen similar behavior.
Background
We previously had a React Native / Expo iOS app in production for several years.
Recently, we rebuilt the app completely from scratch as a native SwiftUI app using WKWebView (no shared code, no RN runtime).
The new app architecture is:
Native SwiftUI container
WKWebView loading a remote web app
Firebase Analytics & Crashlytics
Push notifications (APNs + FCM)
No local database, no persistent native state
Migration scenario
Users update the app via the App Store:
Old app: React Native / Expo
New app: native SwiftUI + WKWebView
For most users, the migration works fine.
However, for a about 10% of users, the following happens:
The issue
After updating from the old React Native app to the new SwiftUI app:
The app opens
The native landing screen appears (solid black OR blue background, depending on which most recent version if being installed)
The app never transitions to the WKWebView
No crash
Force-quitting does not help
Deleting the app completely and reinstalling does fix it 9/10 times, but NOT ALWAYS.
From the user’s perspective:
“The app is stuck on a black OR blue screen forever.”
Important detail
Most of the times, a full uninstall + reinstall FIXES the issue, but funny enough, NOT always.. In some cases, the issue persists:
What we’ve already tried
Over the last weeks, multiple iOS developers have investigated this.
We have implemented and/or tested:
Full rebuild in SwiftUI (no RN remnants)
Aggressive cleanup on first launch after update:
-- UserDefaults cleanup
-- WKWebsiteDataStore cleanup
-- URLCache / cookies cleanup
Timeouts and fallbacks so the UI never blocks indefinitely
Explicit logging of:
-- app_open
-- session_start
-- webview_init
-- webview_load_start / finish
-- blank screen detection
Handling:
-- WKWebView content process terminated
-- network / TLS / DNS errors
Added a native SwiftUI landing screen (in the latest version) so users no longer see a black screen, but now they see a BLUE screen when the transition fails
Observations from Analytics & Crashlytics
No native crashes
Very high user engagement (~99%)
Very low blank-screen detection (~1–2%)
The issue does not appear to be mass-scale
But support still receives complaints daily from affected users
This suggests a device / iOS / network-specific edge case, not a general migration failure.
Hypotheses (not confirmed)
We suspect one of the following, but haven’t been able to prove it:
WKWebView failing to initialize under specific conditions after App Store updates
TLS / ATS / CDN edge behavior affecting first WKWebView load
iOS lifecycle timing issue when transitioning from SwiftUI landing view to WKWebView
OS-specific WebKit state that survives reinstall (keychain? system WebKit state?)
ISP / DNS / IPv6-related issues on first launch
What we’re looking for
We would really appreciate insight on:
Are there known cases where WKWebView fails silently after an App Store update, even after reinstall?
Is there any system-level WebKit state that survives app deletion?
Are there best practices for transitioning from a SwiftUI landing view to WKWebView to avoid dead-ends?
Any known iOS versions / device classes where this behavior is more common?
Any debugging techniques beyond Crashlytics / Analytics that could surface what WebKit is failing on?
We’re not looking for generic “clear cache” advice — we’ve already gone far down that path.
We’re trying to understand whether this is a known WebKit edge case or something we are fundamentally missing.
Thanks in advance for any pointers or shared experiences.
Topic:
UI Frameworks
SubTopic:
SwiftUI
https://developer.apple.com/forums/thread/788293
In the above thread, I received the following response:
"When building with the SDK from the next major release after iOS 26, iPadOS 26, macOS 26 and visionOS 26, UIKit will assert that all apps have adopted UIScene life cycle. Apps that fail this assert will crash on launch."
does this mean that there will be no app crashes caused by UIKit in iOS 26, but there is a possibility of app crashes when building with the SDK provided from iOS 27 onwards?
I’m building an iOS SDK that is distributed as a binary XCFramework and consumed via Swift Package Manager using a binaryTarget.
What I’ve done so far:
Built the SDK using xcodebuild archive for device and simulator
Created the XCFramework using xcodebuild -create-xcframework
The SDK contains a resource bundle with JSON/config files
The XCFramework is wrapped using SPM (code-only wrapper target)
Currently, the resource bundle exists outside the XCFramework, and the host app needs to add it manually during integration. I want to avoid this and make the SDK completely self-contained.
What I’m trying to achieve:
Embed the resource bundle inside the SDK framework so that each XCFramework slice contains it
Ensure the SDK can load its assets internally at runtime without any host app changes
Questions:
What is the correct way to embed a .bundle inside a framework so it gets packaged into each XCFramework slice during archiving?
Which Xcode build phases or build settings are required for this (e.g., Copy Bundle Resources, SKIP_INSTALL, etc.)?
At runtime, what is the recommended approach for locating and loading this embedded bundle from within the SDK code?
Any guidance or best practices for achieving this would be helpful.
On pressing the secondary button on my ShieldConfigurationExtension, I remove the shields by setting shields in the named ManagedStore to nil in my ShieldActionExtension.
// ShieldActionExtension.swift
let store = ManagedSettingsStore()
store.shield.applications = nil
store.shield.applicationCategories = nil
Now after some duration I want to re-apply the shields again for which I do the following:
// ShieldActionExtension.swift
DispatchQueue.main.asyncAfter(deadline: .now() + unlockDuration) { [weak self] in
self?.reapplyShields(for: sessionId, application: application)
}
private func reapplyShields(for sessionId: String, application: ApplicationToken) {
store.shield.applications = Set([application])
}
Followed by the completionHandler:
// ShieldActionExtension.swift
completionHandler(.defer)
Now the expectation is ShieldConfigurationExtension should be re-triggered with store.shield.applications = Set([application]), however I see the default iOS screen time shield.
This behavior is experience when the blocked app is running in the foreground. However, if I close and re-open the blocked app - the ShieldConfigurationExtension is trigerred again correctly.
If I do a completionHandler(.none) instead, the overriden configuration method in ShieldConfigurationExtension is not triggered.
How do I make sure ShieldConfigurationExtension is triggered if the blocked app is running in the foreground when the shields are re-applied again?
Is there any way I can know that another app has gone full screen? Please note that this is not what NSWindowDidEnterFullScreenNotification does, that only works for my own windows.
As for why I need to know: Say you're playing a YouTube video full screen. The video fills up the main display, and if there's a second display, it goes black. Well, mostly. I have a utility app with small status windows that remain on top. I'd like to be polite and hide them in this scenario.
I have SwiftData models containing arrays of Codable structs that worked fine before adding CloudKit capability. I believe they are the reason I started seeing errors after enabling CloudKit.
Example model:
@Model
final class ProtocolMedication {
var times: [SchedulingTime] = [] // SchedulingTime is Codable
// other properties...
}
After enabling CloudKit, I get this error logged to the console:
'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
CloudKit Console shows this times data as "plain text" instead of "bplist" format.
Other struct/enum properties display correctly (I think) as "bplist" in CloudKit Console.
The local SwiftData storage handled these arrays fine - this issue only appeared with CloudKit integration.
What's the recommended approach for storing arrays of Codable structs in SwiftData models that sync with CloudKit?
I have this sample code
import SwiftUI
struct ContentView: View {
var body: some View {
ParentView()
}
}
struct ParentView: View {
@State var id = 0
var body: some View {
VStack {
Button {
id+=1
} label: {
Text("update id by 1")
}
TestView(id: id)
}
}
}
struct TestView: View {
var sequence = DoubleGenerator()
let id: Int
var body: some View {
VStack {
Button {
sequence.next()
} label: {
Text("print next number").background(content: {
Color.green
})
}
Text("current id is \(id)")
}.task {
for await number in sequence.stream {
print("next number is \(number)")
}
}
}
}
final class DoubleGenerator {
private var current = 1
private let continuation: AsyncStream<Int>.Continuation
let stream: AsyncStream<Int>
init() {
var cont: AsyncStream<Int>.Continuation!
self.stream = AsyncStream { cont = $0 }
self.continuation = cont
}
func next() {
guard current >= 0 else {
continuation.finish()
return
}
continuation.yield(current)
current &*= 2
}
}
the print statement is only ever executed if I don't click on the update id by 1 button. If i click on that button, and then hit the print next number button, the print statement doesn't print in the xcode console. I'm thinking it is because the change in id triggered the view's init function to be called, resetting the sequence property and so subsequent clicks to the print next number button is triggering the new version of sequence but the task is still referring its previous version.
Is this expected behaviour? Why in onChange and Button, the reference to the properties is always up to date but in .task it is not?
既然 iOS 26 必须启用 UIScene 生命周期,那么 UIAlertView/UIActionSheet 就实际已经无法使用了,所以为什么不直接将它们标记为不可用,或者直接移除?
Hi all,
I’m working on the alternative marketplace app and using MarketplaceKit and ActionButton. On the main page, users see a list of items, each with an ActionButton. I’m experiencing significant UI hangs when this page loads.
What I’ve Observed:
Instruments (Hangs and SwiftUI profilers) show that the hangs occur when ActionButton instances are rendered.
Creating or updating ActionButton properties triggers synchronous XPC communication with the managedappdistributiond process on the main thread.
Each XPC call takes about 2-3 ms, but with many ActionButtons, the cumulative delay is noticeable and impacts the user experience.
I have tested on iOS 18.7 and 26.1, using Xcode 26.2. But in general, the issue is not specific to a device or iOS version.
The problem occurs in both Debug and Release builds.
Hangs can be severe depending on the number of items in a section, generally between 200-600 ms, resulting in noticeable lag and a poor user experience.
I haven’t found much documentation on the internal workings of ActionButton or why these XPC calls are necessary.
I have tried Lazy loading and reducing the amount of ActionButton instances. That makes the hangs less noticeable, but there are still hitches when new sections with items are added to the view hierarchy.
This is not an issue with SwiftUI or view updates in general. If I replace ActionButton with UIButton, the hangs are completely gone.
Minimal Example:
Here’s a simplified version of how I’m using ActionButton in my SwiftUI view. The performance issue occurs when many of these views are rendered in the list:
struct ActionButtonView: UIViewRepresentable {
let viewModel: ActionButtonViewModel
let style: ActionButtonStyle
func makeUIView(context: Context) -> ActionButton {
return ActionButton(action: viewModel.action)
}
func updateUIView(_ uiView: ActionButton, context: Context) {
uiView.update(\.size, with: context.coordinator.size)
uiView.update(\.label, with: viewModel.title)
uiView.update(\.isEnabled, with: context.environment.isEnabled)
uiView.update(\.fontSize, with: style.scaledFont(for: viewModel.title))
uiView.update(\.backgroundColor, with: style.backgroundColor.color)
uiView.update(\.tintColor, with: style.textAndIconColor)
uiView.update(\.cornerRadius, with: style.cornerRadius(height: uiView.frame.size.height))
uiView.update(\.accessibilityLabel, with: viewModel.accessibilityLabel)
uiView.update(\.accessibilityTraits, with: .button)
uiView.update(\.accessibilityUserInputLabels, with: viewModel.accesibilityUserInputLabels)
uiView.update(\.tintAdjustmentMode, with: .normal)
}
func makeCoordinator() -> Coordinator {
Coordinator(viewModel: viewModel)
}
class Coordinator: NSObject {
...
}
}
extension ActionButton {
fileprivate func update<T>(_ keyPath: WritableKeyPath<ActionButton, T>, with value: T)
where T: Equatable {
if self[keyPath: keyPath] == value { return }
var mutableSelf = self
mutableSelf[keyPath: keyPath] = value
}
}
From the Instruments samples, it’s clear that the performance issues originate from NativeActionButtonView.makeUIView(context:) and NativeActionButtonView.updateUIView(_:context:). The following stack trace is common for all blocking calls, indicating that NSXPCConnection is being used for cross-process communication:
mach_msg2_trap
mach_msg2_internal
mach_msg_overwrite
mach_msg
_dispatch_mach_send_and_wait_for_reply
dispatch_mach_send_with_result_and_wait_for_reply
xpc_connection_send_message_with_reply_sync
__NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__
-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]
___forwarding___
_CF_forwarding_prep_0
__35-[_UISlotView _setContentDelegate:]_block_invoke_2
-[_UISlotView _updateContent]
...
NativeActionButtonView.sizeThatFits(_:uiView:context:)
protocol witness for UIViewRepresentable.sizeThatFits(_:uiView:context:) in conformance NativeActionButtonView
...
Additionally, the Thread State Trace shows that during the XPC calls, the main thread is blocked and is later made runnable by managedappdistributiond. This confirms that the app is indeed communicating with the managedappdistributiond process.
Since there is limited documentation and information available, I have some questions:
Is there a way to batch update ActionButton properties to reduce the number of XPC calls?
Is it possible to avoid or defer XPC communication when creating/updating ActionButton instances?
Are there best practices for efficiently rendering large numbers of ActionButtons in SwiftUI?
Is this a known issue, and are there any recommended workarounds?
Can Apple provide more details on ActionButton’s internal behavior and XPC usage?
Any insights or suggestions would be greatly appreciated!
Topic:
UI Frameworks
SubTopic:
SwiftUI
I’m running into a problem with SwiftUI/AppKit event handling on macOS Tahoe 26.2.
I have a layered view setup:
Bottom: AppKit NSView (NSViewRepresentable)
Middle: SwiftUI view in an NSHostingView with drag/tap gestures
Top: Another SwiftUI view in an NSHostingView
On macOS 26.2, the middle NSHostingView no longer receives mouse or drag events when the top NSHostingView is present. Events pass through to the AppKit view below. Removing the top layer immediately restores interaction. Everything works correctly on macOS Sequoia.
I’ve posted a full reproducible example and detailed explanation on Stack Overflow, including a single-file demo:
Stack Overflow post:
https://stackoverflow.com/q/79862332
I also found a related older discussion here, but couldn’t get the suggested workaround to apply:
https://developer.apple.com/forums/thread/759081
Any guidance would be appreciated.
Thanks!
Consider this code:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
EmptyView()
}
}
}
Which looks like this:
How can I prevent the sidebar from being resized by a mouse and from being hidden?
P.S. Can consider using AppKit if it can help.
Why there is a working animation with ScrollView + ForEach of items removal, but there is none with List?
ScrollView + ForEach:
struct ContentView: View {
@State var items: [String] = Array(1...5).map(\.description)
var body: some View {
ScrollView(.vertical) {
ForEach(items, id: \.self) { item in
Text(String(item))
.frame(maxWidth: .infinity, minHeight: 50)
.background(.gray)
.onTapGesture {
withAnimation(.linear(duration: 0.1)) {
items = items.filter { $0 != item }
}
}
}
}
}
}
List:
struct ContentView: View {
@State var items: [String] = Array(1...5).map(\.description)
var body: some View {
List(items, id: \.self) { item in
Text(String(item))
.frame(maxWidth: .infinity, minHeight: 50)
.background(.gray)
.onTapGesture {
withAnimation(.linear(duration: 0.1)) {
items = items.filter { $0 != item }
}
}
}
}
}```
I failed to resize the icon image from instances of NSRunningApplication. I can only get 32×32 while I'm expecting 16×16.
I felt it unintuitive in first minutes… Then I figured out that macOS menu seems not allowing many UI customizations (for stability?), especially in SwiftUI.
What would be my best solution in SwiftUI? Must I write some boilerplate SwiftUI-AppKit bridging?
We noticed in multiple apps that readableContentGuide is way too wide on iOS 26.x.
Here are changes between iPad 13inch iOS 18.3 and the same device iOS 26.2 (but this affects also iOS 26.0 and iOS 26.1):
13 inch iOS 18
Landscape ContentSizeCategory:
XS, Width: 1376.0 , Readable Width: 560.0
S, Width: 1376.0 , Readable Width: 600.0
M, Width: 1376.0 , Readable Width: 632.0
L, Width: 1376.0 , Readable Width: 664.0
XL, Width: 1376.0 , Readable Width: 744.0
XXL, Width: 1376.0 , Readable Width: 816.0
XXXL,Width: 1376.0 , Readable Width: 896.0
A_M, Width: 1376.0 , Readable Width: 1096.0
A_L, Width: 1376.0 , Readable Width: 1280.0
A_XL,Width: 1376.0 , Readable Width: 1336.0
13 inch iOS 26
Landscape ContentSizeCategory:
XS, Width: 1376.0 , Readable Width: 752.0
S, Width: 1376.0 , Readable Width: 800.0
M, Width: 1376.0 , Readable Width: 848.0
L, Width: 1376.0 , Readable Width: 896.0
XL, Width: 1376.0 , Readable Width: 1000.0
XXL, Width: 1376.0 , Readable Width: 1096.0
XXXL,Width: 1376.0 , Readable Width: 1200.0
A_M, Width: 1376.0 , Readable Width: 1336.0
The code I used:
class ViewController: UIViewController {
lazy var readableView: UIView = {
let view = UIView()
view.backgroundColor = .systemBlue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(readableView)
NSLayoutConstraint.activate([
readableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
readableView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor),
readableView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor),
readableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if readableView.frame.width > 0 {
let orientation = UIDevice.current.orientation
print("""
ContentSizeCategory: \(preferredContentSizeCategoryAsString())
Width: \(view.frame.width) , Readable Width: \(readableView.frame.width), Ratio: \(String(format: "%.1f", (readableView.frame.width / view.frame.width) * 100))%
""")
}
}
func preferredContentSizeCategoryAsString() -> String {
switch UIApplication.shared.preferredContentSizeCategory {
case UIContentSizeCategory.accessibilityExtraExtraExtraLarge:
return "A_XXXL"
case UIContentSizeCategory.accessibilityExtraExtraLarge:
return "A_XXL"
case UIContentSizeCategory.accessibilityExtraLarge:
return "A_XL"
case UIContentSizeCategory.accessibilityLarge:
return "A_L"
case UIContentSizeCategory.accessibilityMedium:
return "A_M"
case UIContentSizeCategory.extraExtraExtraLarge:
return "XXXL"
case UIContentSizeCategory.extraExtraLarge:
return "XXL"
case UIContentSizeCategory.extraLarge:
return "XL"
case UIContentSizeCategory.large:
return "L"
case UIContentSizeCategory.medium:
return "M"
case UIContentSizeCategory.small:
return "S"
case UIContentSizeCategory.extraSmall:
return "XS"
case UIContentSizeCategory.unspecified:
return "U"
default:
return "D"
}
}
}
Please advise, it feels completely broken.
Thank you.
I created an application extension that uses IdentityLookup framework for SMS filtering. How can I deploy my product as a library? I tried wrapping it as a framework, but it was not successful.