This method on UIEvent gets you more touch positions, and I think it's useful for a drawing app, to respond with greater precision to the position of the Pencil stylus.
Is there a similar thing in macOS, for mouse or tablet events? I found this property mouseCoalescingEnabled, but the docs there don't describe how to get the extra events.
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 am building a centralized event handling system for UIKit controls and gesture recognizers. My current approach registers events using static methods inside a handler class, like this:
internal class TWOSInternalCommonEventKerneliOS {
internal static func RegisterTouchUpInside(_ pWidget: UIControl) -> Void {
pWidget.addTarget(
TWOSInternalCommonEventKerneliOS.self,
action: #selector(TWOSInternalCommonEventKerneliOS.WidgetTouchUpInsideListener(_:)),
for: .touchUpInside
)
}
@objc
internal static func WidgetTouchUpInsideListener(_ pWidget: UIView) -> Void {
print("WidgetTouchUpInside")
}
}
This works in my testing because the methods are marked @objc and static, but I couldn’t find Apple documentation explicitly confirming whether using ClassName.self (instead of an object instance) is officially supported.
Questions:
Is this approach (passing ClassName.self as the target) recommended or officially supported by UIKit?
If not, what is the safer alternative to achieve a similar pattern, where event registration can remain in static methods but still follow UIKit conventions?
Would using a shared singleton instance as the target (e.g., TWOSInternalCommonEventKerneliOS.shared) be the correct approach, or is there a better pattern?
Looking for official guidance to avoid undefined behavior in production.
Hi all,
Sharing a reproducible UIKit issue I’m seeing across multiple iPadOS 26 betas, with a tiny sample attached and a short video.
Short video
https://youtu.be/QekYNnHsfYk
Tiny project
https://github.com/yoasha/ListSwipeOvershootReproSwift
Summary
In a UISplitViewController (.doubleColumn), a UICollectionView using list layout shows a large leading-swipe overshoot when the split view is expanded (isCollapsed == false). The cell content translates roughly 3–4× the action width.
Repros with appearance = .plain and .grouped
Does not repro with .insetGrouped
Independent of trailing provider (issue persists when trailing provider is nil)
Collapsed split (compact width) behaves correctly
Environment
Devices: iPad Air (3rd gen), iPadOS 26.0 (23A5326a) → Repro
Simulators: iPad Pro 11-inch (M4), iPadOS 26.0 beta 6 → Repro
Also tested on device: iPadOS 26 beta 5, 6, 7, 8
Xcode: 26.0 beta 6 (17A5305f)
Steps to reproduce
Launch the sample; ensure the split is expanded (isCollapsed == false).
In the secondary list, set Appearance = Plain (also repros with Grouped).
Perform a leading swipe (LTR: swipe right) on any row.
Actual: content shifts ~3–4× the action width (overshoot).
Expected: content translates exactly the action width.
Switch Appearance = InsetGrouped and repeat the leading (swipe right) gesture → correct (no overshoot).
Feedback Assistant
FB ID: FB19785883 (full report + attachments filed; this forum thread mirrors the repro for wider visibility)
Minimal code (core of the sample)
If anyone from Apple needs additional traces or a sysdiagnose, I can attach promptly. Thanks!
// Secondary column VC (snippet)
var cfg = UICollectionLayoutListConfiguration(appearance: .plain) // also .grouped / .insetGrouped
cfg.showsSeparators = true
cfg.headerMode = .none
cfg.leadingSwipeActionsConfigurationProvider = { _ in
let read = UIContextualAction(style: .normal, title: "Read") { _,_,done in done(true) }
read.backgroundColor = .systemBlue
let s = UISwipeActionsConfiguration(actions: [read])
s.performsFirstActionWithFullSwipe = false
return s
}
// Trailing provider can be nil and the bug still repros for leading swipe:
cfg.trailingSwipeActionsConfigurationProvider = nil
let layout = UICollectionViewCompositionalLayout.list(using: cfg)
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
// … standard data source with UICollectionViewListCell + UIListContentConfiguration
// Split setup (snippet)
let split = UISplitViewController(style: .doubleColumn)
split.preferredDisplayMode = .oneBesideSecondary
split.viewControllers = [
UINavigationController(rootViewController: PrimaryTableViewController()),
UINavigationController(rootViewController: SecondaryListViewController())
]
I am developing an App in iPadOS26 beta. I try to switch "Multitasking & Gestures" setting to “Full Screen Apps“ in the code of App. Is there any public API available to implement it.
By the way, my App is a Cordova App.
Thank you
Topic:
UI Frameworks
SubTopic:
General
In the current beta of iPadOS 26.0 (23A5297m), the camera does not function properly when the following conditions are met:
The device is set to Windowed Apps mode in the Settings app.
Multiple application windows are present on one screen.
Using AVCaptureVideoPreviewLayer.
On the other hand, UIImagePicker works properly.
Is this a specification of iPadOS 26 that cannot be avoided? Or is there an official solution or workaround available?
Normally, the camera feed should appear within the square frame of the lower window in the attached image, but it does not.
Topic:
UI Frameworks
SubTopic:
General
I’ve been testing out PaperKit from beta 1 up until 3, then took a break and on my return at beta 7 I find that the .drawing property of the PaperMarkup data model has been removed, i.e. a PKDrawing can no longer be added / modified on PaperKit. Also, the shape recognition feature seems to have been removed.
I see this as a tremendous drawback. I filed feedback already: FB19893338
Please bring it back.
Is it possible to add an ornament below a tab bar like this? Or does the whole side bar have to be an ornament to build this?
I have a standard Mac project created using Xcode templates with Storyboard. I manually removed the window from the Storyboard file and use ViewController.h as the base class for other ViewControllers. I create new windows and ViewControllers programmatically, implementing the UI entirely through code.
However, I've discovered that on all macOS versions prior to macOS 26 beta, the application would trigger automatic termination due to App Nap under certain circumstances. The specific steps are:
Close the application window (the application doesn't exit immediately at this point)
Click on other windows or the desktop, causing the application to lose focus (though this description might not be entirely accurate - the app might have already lost focus when the window closed, but the top menu bar still shows the current application immediately after window closure)
The application automatically terminates
In previous versions, I worked around this issue by manually executing [[NSApplication sharedApplication] run]; to create an additional main event loop, keeping the application active (although I understand this isn't an ideal approach).
However, in macOS 26 beta, I've found that calling [[NSApplication sharedApplication] run]; causes all NSButton controls I created in the window to become unresponsive to click events, though they still respond to mouse enter events.
Through recent research, I've learned that the best practice for preventing App Nap automatic termination is to use [[NSProcessInfo processInfo] disableAutomaticTermination:@"User interaction required"]; to increment the automatic termination reference count.
My questions are:
Why did calling [[NSApplication sharedApplication] run]; work properly on macOS versions prior to 15.6.1?
Why does calling [[NSApplication sharedApplication] run]; in macOS 26 beta cause buttons to become unresponsive to click events?
I have a few view controllers in a large UIKit application that previously started showing content right below the bottom of the top navigation toolbar.
When testing the same code on iOS 26, these same views have their content extend under the navigation bar and toolbar. I was able to fix it with:
if #available(iOS 26, *, *) {
self.edgesForExtendedLayout = [.bottom]
}
when running on iOS 26. I also fixed one or two places where the main view was anchored to self.view.topAnchor instead of self.view.safeAreaLayoutGuide.topAnchor.
Although this seems to work, I wonder if this was an intended change in iOS 26 or just a temporary bug in the beta that will be resolved.
Were changes made to the safe area and edgesForExtendedLayout logic in iOS 26? If so, is there a place I can see what the specific changes were, so I know my code is handling it properly?
Thanks!
Topic:
UI Frameworks
SubTopic:
UIKit
What is the correct way to track the number of items in a relationship using SwiftData and SwiftUI?
Imagine a macOS application with a sidebar that lists Folders and Tags. An Item can belong to a Folder and have many Tags. In the sidebar, I want to show the name of the Folder or Tag along with the number of Items in it.
I feel like I'm missing something obvious within SwiftData to wire this up such that my SwiftUI views correctly updated whenever the underlying modelContext is updated.
// The basic schema
@Model final class Item {
var name = "Untitled Item"
var folder: Folder? = nil
var tags: [Tag] = []
}
@Model final class Folder {
var name = "Untitled Folder"
var items: [Item] = []
}
@Model final class Tag {
var name = "Untitled Tag"
var items: [Item] = []
}
// A SwiftUI view to show a Folder.
struct FolderRowView: View {
let folder: Folder
// Should I use an @Query here??
// @Query var items: [Item]
var body: some View {
HStack {
Text(folder.name)
Spacer()
Text(folder.items.count.formatted())
}
}
}
The above code works, once, but if I then add a new Item to that Folder, then this SwiftUI view does not update. I can make it work if I use an @Query with an #Predicate but even then I'm not quite sure how the #Predicate is supposed to be written. (And it seems excessive to have an @Query on every single row, given how many there could be.)
struct FolderView: View {
@Query private var items: [Item]
private var folder: Folder
init(folder: Folder) {
self.folder = folder
// I've read online that this needs to be captured outside the Predicate?
let identifier = folder.persistentModelID
_items = Query(filter: #Predicate { link in
// Is this syntax correct? The results seem inconsistent in my app...
if let folder = link.folder {
return folder.persistentModelID == identifier
} else {
return false
}
})
}
var body: some View {
HStack {
Text(folder.name)
Spacer()
// This mostly works.
Text(links.count.formatted())
}
}
}
As I try to integrate SwiftData and SwiftUI into a traditional macOS app with a sidebar, content view and inspector I'm finding it challenging to understand how to wire everything up.
In this particular example, tracking the count, is there a "correct" way to handle this?
Right now, the traffic light buttons overlapped on my iPad app top corner on windows mode (full screen is fine).
How do I properly design my app to avoid the traffic light buttons? Detect that it is iPadOS 26?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello,
First of all, I've already made a bug report here : https://feedbackassistant.apple.com/feedback/19731998
I'm facing a problem while using UIGraphicsImageRenderer to create an image, that is use to create a UIColor with a pattern via UIColor(patternImage:).
It's well displayed for iOS 18.2 and lower, whereas the whole color is blank with iOS 26.
-> Please find a sample project linked to the bug report
ViewController.swift
post that illustrates the issue, in the ViewController.swift file. I'll also link screenshots of the sample app, one built with iOS 18.2 and another with iOS 26.0.
Reproduction steps :
I create an image with UIGraphicsImageRenderer : let image = UIGraphicsImageRenderer().image { context in // Do anything here }
Then I use this image to create a UIColor : UIColor(patternImage: image)
I apply this color to the fillColor of a CAShapeLayer : shapeLayer.fillColor = UIColor(patternImage: image)
Expected result :
Run on iOS 26 and lower and the layer filled with the pattern color is correctly displayed, as it is on iOS 18.2 and lower.
Observed result :
Run on iOS 26 and the layer is filled with a blank/white color instead of the intended pattern color.
Has anyone been facing the problem ?
Thanks,
Thibault Poujat
In iPadOS 26, Apple introduced macOS-style window control buttons (close, minimize, fullscreen) for iPad apps running in a floating window. I'm working on a custom toolbar (UIView) positioned near the top of the window, and I'd like to avoid overlapping with these new controls.
However, I haven't found any public API that exposes the frame, layout margins, or safe area insets related to this new UI region. I've checked the window's safeAreaInsets, additionalSafeAreaInsets, and UIWindowSceneDelegate APIs, but none of them seem to reflect the area occupied by these buttons.
Is there an officially supported way to:
Get the layout information (frame, insets, or margins) of the window control buttons on iPadOS 26?
Or, is there a system-defined guideline or padding value we should use to avoid overlapping this new UI?
Any clarification or guidance would be appreciated!
Hi
Is there a way to create a dynamic app clip card experience? I have advanced app clip experiences set up and working fine already and but I am looking to provider a more dynamic experience.
For example, my invocation url now is https://mycompany.com/profile/<profile_slug>, this URL shows the app clip card with the title, subheading, and cover image as configured in app store connect which is right. But I would like to show a different title, subheading, and cover image based on the <profile_slug> in the invocation URL. Like we can show the name as the title, job title as the subheading, and profile's banner image as the cover image for the app clip
It seems like this is possible as I have seen one company do this for their product. Apple has no mention for such a thing in their documentation from what I have seen.
Any help would be appreciated.
Thanks
When an Advanced Experience is created for an App Clip, using the Camera app to scan a QR Code whose URL matches the pattern configured in the Advanced Experience will present the App Clip card. Currently, this App Clip card is presented even if the App Clip or main app is already installed In the device.
Is it possible to show the card only when neither the App Clip nor main app is installed?
For example:
User who does not have the App Clip/main app installed on their device scans a QR code that matches an Advanced Experience
User taps the yellow button and sees the App Clip card
User taps ”Open” on the card and launches the App Clip, the App Clip is now installed in the device.
User returns to the Camera app and scans the same QR code again
Camera recognizes the QR code, yellow button appears, user taps it
At this point, is it possible for the user to be taken directly to the installed App Clip instead of presenting the App Clip card again?
I am trying to use Zone Sharing in my SwiftUI app. I have been attempting to get the UICloudSharingController to show an initial share screen to pick users and the mechanism to send the invitation.
From the documentation, it appears that the UICloudSharingController .init(preparationHandler:) API is deprecated so I am not using that approach. Following the Apple documentation, I am creating a Zone Share and NOT saving it and presenting using the UICloudSharingController(share:container:) API. However, this presents a UI that is the 'mgmt' API for a Share. I can get to the UI I was expecting by tapping on the 'Share with More People' option, but I want to start on that screen for the user when they have not shared this before.
So, I found an example app from Apple at: https://github.com/apple/sample-cloudkit-zonesharing. It has the same behavior. So we can simply discuss this problem based on that example code.
How do I get the next View presented when tapping 'Share Group' to be the invitation for new users screen?
Here is the UI it presents initially:
And here is the UI (on the bottom half of the screen) I am trying to start the share process with:
Thanks,
Charlie
When performing custom layout in AppKit, it's essential that you pixel align frames using methods like backingAlignedRect. The alignment differs depending on the backingScaleFactor of the parent window.
When building custom Layouts in SwiftUI, how should you compute the alignment of a subview.frame in placeSubviews() before calling subview.place(...)?
Surprisingly, I haven't seen any mention of this in the WWDC videos. However, if I create a Rectangle of width 1px and then position it on fractional coordinates, I get a blurry view, as I would expect.
Rounding to whole numbers works, but on Retina screens you should be able to round to 0.5 as well.
func placeSubviews(
in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout Void
) {
// This should be backing aligned based on the parent window's backing scale factor.
var frame = CGRect(
x: 10.3,
y: 10.8,
width: 300.6,
height: 300.1
)
subview.place(
at: frame.origin,
anchor: .topLeading,
proposal: ProposedViewSize(frame.size)
)
}
Issue Description:
When toggling between the system keyboard and a custom input view, the keyboard height reported in subsequent keyboard notifications becomes incorrect!!! specifically missing the predictive text/suggestion bar height.
Environment:
Device: iPhone 11
Expected keyboard height: 346pt
Actual reported height: 301pt (missing 45pt suggestion bar)
Reproduction Steps:
Present system keyboard → Height correctly reported as 346pt
Switch to custom input view → Custom view displayed
Switch back to system keyboard(no suggestion bar) → Height correctly reported as 301pt
Trigger keyboard frame change → Height still incorrectly reported as 301pt despite suggestion bar being visible
Expected Behavior:
Keyboard height should consistently include the suggestion bar height (346pt total).
Actual Behavior:
After switching from custom input view, keyboard height excludes suggestion bar height (301pt instead of 346pt).
key code
private func bindEvents() {
customTextField.toggleInputViewSubject.sink { [weak self] isShowingCustomInput in
guard let strongSelf = self else {
return
}
if isShowingCustomInput {
strongSelf.customTextField.inputView = strongSelf.customInputView
strongSelf.customInputView.frame = CGRect(x: 0, y: 0, width: strongSelf.view.frame.size.width, height: strongSelf.storedKeyboardHeight)
} else {
strongSelf.cusTextField.inputView = nil
}
strongSelf.customTextField.reloadInputViews()
strongSelf.customTextField.becomeFirstResponder()
}.store(in: &cancellables)
}
In our app we have a UICollectionView with Drag&Drop functionality enable and collection view is covering the entire screen. When we drag a collection view item to the edge of the screen it does not scroll the UICollectionView instead that our item turns into the app icon and scrolling blocked. It is happening only if Stage Manager is enabled in the device and if Stage Manager is disabled it is working fine.
This issue we are facing after iOS 18.6 release, before 18.6 it was working fine i.e, collection view was scrolling to next items when we dragging an item to edge of the screen, similar to the iOS calendar app when we drag an event to edge it starts scrolling the date.
And in iOS 26 if we drag an item to edge, Springboard is getting crashed.
It's related to the passByValue nature of structs. In the sample code below, I'm displaying a list of structs (and I can add instances to my list using Int.random(1..<3) to pick one of two possible predefined versions of the struct).
I also have a detail view that can modify the details of a single struct. However when I run this code, it will instead modify all the instances (ie either Sunday or Monday) in my list.
To see this behaviour, run the following code and:
tap New Trigger enough times that there are multiple of at least one of the sunday/monday triggers
tap one of the matching trigger rows
modify either the day, or the int
expected: only one of the rows will reflect the edit
actual: all the matching instances will be updated.
This suggests to me that my Sunday and Monday static instances are being passed by reference when they get added to the array. But I had thought structs were strictly pass by value. What am I missing?
thanks in advance for any wisdom,
Mike
struct ContentView: View {
@State var fetchTriggers: [FetchTrigger] = []
var body: some View {
NavigationView {
VStack {
Button("New Trigger") {
fetchTriggers.append(Int.random(in: 1..<3) == 1 ? .sunMorning : .monEvening)
}
List($fetchTriggers) { fetchTrigger in
NavigationLink(destination: FetchTriggerDetailView(fetchTrigger: fetchTrigger)
.navigationBarTitle("Back", displayMode: .inline))
{
Text(fetchTrigger.wrappedValue.description)
.padding()
}
}
}
}
}
}
struct FetchTrigger: Identifiable {
static let monEvening: FetchTrigger = .init(dayOfWeek: .monday, hour: 6)
static let sunMorning: FetchTrigger = .init(dayOfWeek: .sunday, hour: 3)
let id = UUID()
enum DayOfWeek: Int, Codable, CaseIterable, Identifiable {
var id: Int { self.rawValue }
case sunday = 1
case monday
case tuesday
var description: String {
switch self {
case .sunday: return "Sunday"
case .monday: return "Monday"
case .tuesday: return "Tuesday"
}
}
}
var dayOfWeek: DayOfWeek
var hour: Int
var description: String {
"\(dayOfWeek.description), \(hour):00"
}
}
struct FetchTriggerDetailView: View {
@Binding var fetchTrigger: FetchTrigger
var body: some View {
HStack {
Picker("", selection: $fetchTrigger.dayOfWeek) {
ForEach(FetchTrigger.DayOfWeek.allCases) { dayOfWeek in
Text(dayOfWeek.description)
.tag(dayOfWeek)
}
}
Picker("", selection: $fetchTrigger.hour) {
ForEach(1...12, id: \.self) { number in
Text("\(number)")
.tag(number)
}
}
}
}
}