I had take screenshots by following code
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
self.uiImage = window?.rootViewController?.view!.getImage(rect: rect)
View has two views. One is ImageView contains some image and overlay of image detection results with .overlay. another view is InfoView contains several info and button which above code fired. on iOS 17, I can take screenshots as I saw, but on iOS26, missing on image of ImageView. Overlay(detected rectangle) in Imageview and InfView can be taken.
How can I take screenshots as I saw on iOS26?(iPad)
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Posts under UIKit tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi there. I want to use Adobe XD for designing and prototyping apps, and I would like to get the UIKit design resources working. I downloaded it and tried to open it with Adobe XD, but it threw this error:
There was an error opening the file Apple iOS 26 UI Kit.sketch
(Error code: 115)
I really prefer to use the UIKit in Adobe XD rather than paying for Figma or Sketch. Thanks.
Apple Design Resources
In iOS 26, keyboardLayoutGuide does not provide the correct constraint when using third-party input method.
A demo’s source code is attached to FB18594298 to illustrate the issue.
The setup includes:
An inputAccessoryView above keyboard
An input box anchored to the top of the inputAccessoryView using the following constraint:
[self.view.keyboardLayoutGuide.topAnchor constraintEqualToAnchor:self.inputBoxContainerView.bottomAnchor]
Expected Behavior:
Before iOS 26, when keyboard toggled by clicking the input box, the input box should move above the inputAccessoryView.
Actual Behavior:
However, on iOS 26, when switching to a third-party IME (e.g. 百度输入法baidu,搜狗输入法sogou,微信输入法wechat), then click the input box, the input box is above the keyboard instead of the inputAccessoryView, and is covered by the inputAccessoryView.
I am struggling to change the tint of the back button in an UINavigationItem. In iOS 18.6 it looks like this
while on iOS 26 the same looks like this
I can live without the Dictionary but I'd like to get the blue color back.
In viewDidLoad() I have tried
navigationItem.backBarButtonItem?.tintColor = .link
but this did not work since navigationItem.backBarButtonItem is nil. My second attempt was
navigationController?.navigationBar.tintColor = .link
but this didn't work either.
I have even set the Global Tint to Link Color
but this had no effect either.
Does anyone have an idea how to change the tint of the back button in an UINavigationItem on iOS 26?
After reviewing the following Apple Technote, I have confirmed the statement below: https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle
In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won’t launch. While supporting multiple scenes is encouraged, only adoption of scene life-cycle is required.
Based on the above, I would appreciate it if you could confirm the following points:
Is my understanding correct that the term “latest SDK” refers to Xcode 27?
Is it correct that an app built with the latest SDK (Xcode 27, assuming the above understanding is correct) will not launch without adopting the UIScene lifecycle, with no exceptions?
Is it correct that an app built with Xcode 26 without UIScene lifecycle support will still launch without issues on an iPhone updated to iOS 27?
Setup:
I have a segment view with 3 segments, and the last on (at index 2) is disabled.
Issue:
When I drag the liquid glass handle of the segment view from what was previously selected to the disabled segment, the liquid glass handle freezes mid-air.
Workaround:
I can still interact with the handle and manually restore its position, or tap on any other segment to restore its position.
Notes:
I'm using UIKit, and no extra customizations are applied.
class ViewController: UIViewController {
@IBOutlet weak var segmentView: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
segmentView.removeAllSegments()
let segments = ["Option 1", "Option 2", "Option 3"]
for (index, title) in segments.enumerated() {
segmentView.insertSegment(withTitle: title, at: index, animated: false)
}
// Select the first one by default
segmentView.selectedSegmentIndex = 0
// Disable the last segment
segmentView.setEnabled(false, forSegmentAt: 2)
}
}
Hello!
I'm making a list of app icons for users to choose, but when I increase or decrease the font size, the image is still in the same spot and isn't centered vertically with the text. I have it initialized with a frame with hard-coded values, but I was wondering if there was a better way of doing it, such as with constraints or some sort of image scaling.
I've provided code blocks and an image of what is happening.
ImageView Configuration
// App Icon Image
UIImageView *appIconImageView = [[UIImageView alloc] initWithFrame: CGRectMake(12.5, 17, 22.5, 22.5)];
// Configurations
UIImageSymbolConfiguration *multicolorConfiguration = [UIImageSymbolConfiguration configurationPreferringMulticolor];
UIImageSymbolConfiguration *sizeConfiguration = [UIImageSymbolConfiguration configurationWithScale: UIImageSymbolScaleSmall];
UIImageSymbolConfiguration *appIconConfiguration = [multicolorConfiguration configurationByApplyingConfiguration: sizeConfiguration];
appIconImageView.preferredSymbolConfiguration = appIconConfiguration;
appIconImageView.contentMode = UIViewContentModeScaleAspectFill;
self.appIconImage = appIconImageView;
[appIconImageView release];
ImageView Constraints
[self.appIconImage.firstBaselineAnchor constraintEqualToAnchor: self.contentView.firstBaselineAnchor constant: 5.0],
[self.appIconImage.leadingAnchor constraintEqualToAnchor: self.contentView.layoutMarginsGuide.leadingAnchor],
// Label
[self.colorLabel.leadingAnchor constraintEqualToAnchor:self.appIconImage.trailingAnchor constant: 10],
[self.colorLabel.trailingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.trailingAnchor],
[self.colorLabel.topAnchor constraintEqualToAnchor: self.contentView.layoutMarginsGuide.topAnchor],
[self.colorLabel.bottomAnchor constraintEqualToAnchor: self.contentView.layoutMarginsGuide.bottomAnchor],
Image
We are seeing a strange lifecycle issue on multiple MDM-managed iPads where
application(_:didFinishLaunchingWithOptions:) is not called after the device is idle overnight.
Even if we terminate the app manually via the app switcher, the next morning the system does not perform a cold launch. Instead, the app resumes directly in:
applicationDidBecomeActive(_:)
This causes all initialization logic that depends on didFinishLaunching to be completely skipped.
This behavior is consistent across four different supervised MDM devices.
Environment
Devices: iPads enrolled in MDM (supervised)
iOS version: 18.3
Xcode: 16.4
macOS: Sequoia 15.7.2
App type: Standard UIKit iOS app
App: Salux Audiometer (App Store app)
Expected Behavior
If the app was terminated manually using the app switcher, the next launch should:
Start a new process
Trigger application(_:didFinishLaunchingWithOptions:)
Follow the normal cold-start lifecycle
Actual Behavior
After leaving the iPad idle overnight (8–12 hours):
The next launch skips didFinishLaunching
The app resumes directly in applicationDidBecomeActive
No new process is started
App behaves as if it had been suspended, even though it was manually terminated
Logs (Relevant Extracts)
Day 1 — Normal cold launch
[12:06:44.152 PM] PROCESS_STARTED
[12:06:44.214 PM] DID_FINISH_LAUNCHING_START launchOptions=[]
[12:06:44.448 PM] DID_FINISH_LAUNCHING_END
We then used the app and terminated it via app switcher.
Day 2 — Unexpected resume without cold start
[12:57:49.328 PM] APP_DID_BECOME_ACTIVE
No PROCESS_STARTED
No didFinishLaunching
No cold-start logs
This means the OS resumed the app from a previous state that should not exist.
Reproducible Steps
Use an MDM-enrolled iPad.
Launch the app normally.
Terminate it manually via the multitasking app switcher.
Leave the device idle overnight (8–12 hours).
Launch the app the next morning.
Observe that:
didFinishLaunching does not fire
applicationDidBecomeActive fires directly
Questions for Apple Engineers / Community
Is this expected behavior on MDM-supervised devices in iOS 18?
Are there any known OS-level changes where terminated apps may be revived from disk/memory?
Could MDM restrictions or background restoration policies override app termination?
How can we ensure that our app always performs a clean initialization when launched after a long idle period?
Additional Information
We have full logs from four separate MDM iPads showing identical behavior.
Happy to share a minimal reproducible sample if required.
I have an application that needs to make a USSD call, but on some devices the * and # don't work on the dialer, on others it does.
if let phoneNumber = ussdNumberTextfield.text {
let encoded = "telprompt:\(phoneNumber)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
if let url = URL(string: encoded) {
if application.canOpenURL(url){
DispatchQueue.main.async {
self.application.open(url, options: [:]) { success in
}
}
}
}
}
Description
I am seeing inconsistent clipping behavior in UICollectionViewCell when presenting a context menu by long press on a subview that uses UIGlassEffect.
Summary of behavior:
Long-pressing a normal view inside a UICollectionViewCell presents the menu correctly (no clipping).
Long-pressing a view wrapped in UIVisualEffectView using UIGlassEffect causes the sub-view with glass effect to be clipped at the cell’s bounds.
clipsToBounds = false is set on:
the cell
the cell’s contentView
This behavior is reproducible and appears to be specifically related to UIGlassEffect.
Description
I'm developing a custom keyboard extension using UIInputViewController and need to set a specific height of 268 points. The keyboard functions correctly, but there's a visible flicker and resize animation during launch that I cannot eliminate.
The Problem
When the keyboard launches, iOS provides incorrect heights before settling on the correct one. At launch, the view starts at 0×0. Around 295ms later, iOS sets the frame to 440×956 which is full screen height and wrong. Around 373ms, iOS changes it to 440×452 which is still wrong. Finally around 390ms, iOS settles at 440×268 which matches our constraint.
This causes visible flicker as the view resizes three times rapidly. The keyboard appears to shrink from full screen down to the correct height, and users can clearly see this animation happening.
What I've Tried
I've tried adding a height constraint on self.view which gives me the correct height but causes the visible flicker.
I created a custom UIInputView subclass and overrode intrinsicContentSize to return my desired height. iOS completely ignores this and gives random heights like 471pt, 680pt, or 956pt instead.
I set allowsSelfSizing to true on my UIInputView subclass. iOS ignores this property.
I set preferredContentSize on the view controller. iOS ignores this as well.
I tried adding the constraint in viewDidAppear instead of viewDidLoad, thinking iOS might have settled by then. It still causes flicker.
I overrode the frame and bounds setters on my UIInputView to clamp the height to my desired value. iOS bypasses these overrides somehow.
I overrode layoutSubviews to force the correct height after the super call. iOS still applies its own height.
Specific Question
What is the correct API or technique to specify a keyboard extension's height that iOS will respect immediately upon launch, without triggering the resize animation sequence?
Other third-party keyboards like Grammarly and SwiftKey appear to have solved this problem. Their keyboards appear at the correct height without any visible flicker. How do they achieve this?
Expected Outcome
The keyboard should appear at 268pt height on the first frame with no visible resize animation.
Steps to Reproduce
Create a new iOS App project in Xcode and add a Keyboard Extension target. In KeyboardViewController.swift, add a height constraint in viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let heightConstraint = view.heightAnchor.constraint(equalToConstant: 268)
heightConstraint.priority = .defaultHigh
heightConstraint.isActive = true
let label = UILabel()
label.text = "Demo Keyboard"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
Build and run on a physical device. Enable the keyboard in Settings, then General, then Keyboard, then Keyboards. Open any app with a text field and switch to the custom keyboard using the globe button. Observe the height changing from around 956pt to 452pt to 268pt with visible animation.
Environment
iOS 17 and iOS 18 and 26.2, Xcode 16 and Xcode 26, affects all iPhone models tested, reproducible on both simulator and physical device.
crash stack:
Crashed: com.apple.main-thread
0 libsystem_pthread.dylib 0x90c thread_chkstk_darwin + 60
1 libsystem_pthread.dylib 0x90c ___chkstk_darwin + 60
2 CoreAutoLayout 0x14c4 -[NSISEngine _flushPendingRemovals] + 56
3 CoreAutoLayout 0x2de08 -[NSISEngine _coreReplaceMarker:withMarkerPlusDelta:].cold.1 + 64
4 CoreAutoLayout 0x15d78 -[NSISEngine _coreReplaceMarker:withMarkerPlusDelta:] + 204
5 CoreAutoLayout 0x2ce38 -[NSISEngine constraintDidChangeSuchThatMarker:shouldBeReplacedByMarkerPlusDelta:] + 108
6 CoreAutoLayout 0x15f1c -[NSISEngine tryToChangeConstraintSuchThatMarker:isReplacedByMarkerPlusDelta:undoHandler:] + 100
7 CoreAutoLayout 0x2fdbc -[NSLayoutConstraint _tryToChangeContainerGeometryWithUndoHandler:] + 252
8 CoreAutoLayout 0x3020c -[NSLayoutConstraint _setSymbolicConstant:constant:symbolicConstantMultiplier:] + 452
9 CoreAutoLayout 0x30378 -[NSLayoutConstraint setConstant:] + 84
10 UIKitCore 0x51c3c __74-[UIView(UIConstraintBasedLayout) _autoresizingConstraints_frameDidChange]_block_invoke + 140
11 UIKitCore 0x1841174 -[UIView(AdditionalLayoutSupport) _withUnsatisfiableConstraintsLoggingSuspendedIfEngineDelegateExists:] + 112
12 UIKitCore 0x51b28 -[UIView(UIConstraintBasedLayout) _autoresizingConstraints_frameDidChange] + 452
13 UIKitCore 0x2c894 -[UIView _constraints_frameDidChange] + 100
14 UIKitCore 0x18fac08 -[UIView(Geometry) setFrame:] + 576
15 UIKitCore 0x96712c -[UITabBar setFrame:] + 128
16 UIKitCore 0x1666f4 -[_UITabBarControllerVisualStyle updateTabBarLayout] + 360
17 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
18 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
19 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
20 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
21 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
22 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
23 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
24 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
25 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
26 UIKitCore 0x16671c -[_UITabBarControllerVisualStyle updateTabBarLayout] + 400
27 UIKitCore 0x16642c -[UITabBarController _prepareTabBar] + 128
28 UIKitCore 0x166a10 -[UITabBarController _layoutContainerView] + 376
29 UIKitCore 0x1677a8 -[UITabBarController __viewWillLayoutSubviews] + 28
30 UIKitCore 0x147078 -[UILayoutContainerView layoutSubviews] + 176
31 UIKit 0xb14a0 -[UILayoutContainerViewAccessibility layoutSubviews] + 60
for a more detail crash stack, can see attach file:
crash.txt
crash probabilistic happed after app enter background, and our app support landscape, when crash appear, the system method:
/*
This method is called when the view controller's view's size is changed by its parent (i.e. for the root view controller when its window rotates or is resized).
If you override this method, you should either call super to propagate the change to children or manually forward the change to children.
*/
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator API_AVAILABLE(ios(8.0));
is called;
but for a normal not crash case, when enter background and rotate device, the viewWillTransitionToSize method is not called until app enter foreground;
Are there any suggestions that can help solve this problem, thank you.
Environment
macOS 15.7.3
Xcode 26.1.1 / 26.2
iOS 18.5 / 26.2
iPhone 16 Pro Simulator and physical device
Problem Description
When tapping an unselected UISegmentedControl, the selected segment does not match the tapped position. Specifically, tapping the rightmost segment (index: 3) results in the leftmost segment (index: 0) being selected instead.
Conditions for Reproduction
This issue occurs when all of the following conditions are met:
Built with Xcode 26.x
UIDesignRequiresCompatibility is set to YES in Info.plist
UISegmentedControl is positioned using Auto Layout with leading alignment
Segments are added dynamically using insertSegment(withTitle:at:animated:)
Note: The issue does not occur when segments are defined statically in Storyboard.
Steps to Reproduce
Create a subclass of UISegmentedControl that dynamically sets segments:
class CustomSegmentedControl: UISegmentedControl {
func setSegments(titles: [String]) {
removeAllSegments()
titles.forEach { title in
insertSegment(withTitle: title, at: numberOfSegments, animated: false)
}
}
}
In the ViewController, configure the control:
override func viewDidLoad() {
super.viewDidLoad()
segmentedControl.setSegments(titles: ["Item A", "Item B", "Item C", "Item D"])
segmentedControl.selectedSegmentIndex = UISegmentedControl.noSegment
}
Set UIDesignRequiresCompatibility to YES in Info.plist:
<key>UIDesignRequiresCompatibility</key>
<true/>
Run the app and tap the rightmost segment ("Item D")
Expected vs Actual Behavior
Expected
Actual
Tap rightmost segment
"Item D" (index: 3) is selected
"Item A" (index: 0) is selected
What I Tried (Did Not Work)
Calling layoutIfNeeded() after adding segments:
segmentedControl.setSegments(titles: ["Item A", "Item B", "Item C", "Item D"])
segmentedControl.layoutIfNeeded() // No effect
Workarounds
Set UIDesignRequiresCompatibility to NO (enables Liquid Glass design)
Define segments statically in Storyboard instead of dynamically
Sample Project
Minimal reproduction project is available here:
https://github.com/CH3COOH/Samples/tree/master/SampleSelectSegmentedControl
Feedback Assistant
This issue has been reported via Feedback Assistant: FB21712773
Has anyone else encountered this issue or found alternative workarounds?
The default app menu on iPadOS 26 includes an Edit menu with items (among others) Cut, Copy, Paste, Paste and Match Style. I want to remove the last one.
I tried the following but nothing worked:
let configuration = UIMainMenuSystem.Configuration()
configuration.textFormattingPreference = .removed
UIMainMenuSystem.shared.setBuildConfiguration(configuration) { builder in
builder.remove(action: .pasteAndMatchStyle)
if let command = builder.menu(for: .edit)?.children.first(where: { ($0 as? UICommand)?.action == #selector(UIResponderStandardEditActions.pasteAndMatchStyle(_:)) }) as? UICommand {
command.attributes.insert(.hidden)
}
}
Hi,
I am implementing a sidebar navigation using UITabBarController with the new UITabGroup API on and above iPadOS 18. I’ve encountered an issue where selecting a child UITab within a group does not seem to trigger the child's own viewControllerProvider. Instead, the UITabBarController displays the ViewController associated with the parent UITabGroup.
The Issue: In the snippet below, when I tap "Item 2A" or "Item 2B" in the iPad sidebar, the app displays the emptyVC (clear background) defined in the section2Group provider, rather than the teal or cyan ViewControllers defined in the individual child tabs.
let item2A = UITab(
title: "Item 2A",
image: UIImage(systemName: "a.circle"),
identifier: "tab.section2.item2a"
) { _ in
self.createViewController(
title: "Section 2 - Item 2A",
color: .systemTeal,
description: "Part of Section 2A group"
)
}
let item2B = UITab(
title: "Item 2B",
image: UIImage(systemName: "b.circle"),
identifier: "tab.section2.item2b"
) { _ in
self.createViewController(
title: "Section 2 - Item 2B",
color: .systemCyan,
description: "Part of Section 2B group"
)
}
item2A.preferredPlacement = .sidebarOnly
item2B.preferredPlacement = .sidebarOnly
let section2Group = UITabGroup(
title: "Section 2",
image: UIImage(systemName: "folder.fill"),
identifier: "tabgroup.section2",
children: [item2A, item2B]
) { _ in
// This provider seems to take precedence over children
let emptyVC = UIViewController()
emptyVC.view.backgroundColor = .clear
return emptyVC
}
section2Group.preferredPlacement = .sidebarOnly
tabs.append(section2Group)
The Crash: If I attempt to resolve this by removing the viewControllerProvider from the UITabGroup (with the intent that only children should provide views), the application crashes at runtime. The exception indicates that all tabs within the sidebar must have an associated ViewController, suggesting that the UITabGroup requires a provider even if it is intended to act purely as a visual container.
Kindly clarify the following:
Is it the intended behavior for UITabGroup to override the viewControllerProvider of its children during sidebar selection?
Why does the API require the UITabGroup to return a ViewController if the selection target is a child UITab?
Is there a specific configuration or delegate method required to allow the UITabBarController to "pass through" the selection to the child tab's provider?
I would appreciate any guidance on whether this is an API limitation or if there is a different structural approach recommended for grouped sidebar items.
Hi,
How to enable multitouch on ARView?
Touch functions (touchesBegan, touchesMoved, ...) seem to only handle one touch at a time. In order to handle multiple touches at a time with ARView, I have to either:
Use SwiftUI .simultaneousGesture on top of an ARView representable
Position a UIView on top of ARView to capture touches and do hit testing by passing a reference to ARView
Expected behavior:
ARView should capture all touches via touchesBegan/Moved/Ended/Cancelled.
Here is what I tried, on iOS 26.1 and macOS 26.1:
ARView Multitouch
The setup below is a minimal ARView presented by SwiftUI, with touch events handled inside ARView. Multitouch doesn't work with this setup.
Note that multitouch wouldn't work either if the ARView is presented with a UIViewController instead of SwiftUI.
import RealityKit
import SwiftUI
struct ARViewMultiTouchView: View {
var body: some View {
ZStack {
ARViewMultiTouchRepresentable()
.ignoresSafeArea()
}
}
}
#Preview {
ARViewMultiTouchView()
}
// MARK: Representable ARView
struct ARViewMultiTouchRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARViewMultiTouch(frame: .zero)
let anchor = AnchorEntity()
arView.scene.addAnchor(anchor)
let boxWidth: Float = 0.4
let boxMaterial = SimpleMaterial(color: .red, isMetallic: false)
let box = ModelEntity(mesh: .generateBox(size: boxWidth), materials: [boxMaterial])
box.name = "Box"
box.components.set(CollisionComponent(shapes: [.generateBox(width: boxWidth, height: boxWidth, depth: boxWidth)]))
anchor.addChild(box)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) { }
}
// MARK: ARView
class ARViewMultiTouch: ARView {
required init(frame: CGRect) {
super.init(frame: frame)
/// Enable multi-touch
isMultipleTouchEnabled = true
cameraMode = .nonAR
automaticallyConfigureSession = false
environment.background = .color(.gray)
/// Disable gesture recognizers to not conflict with touch events
/// But it doesn't fix the issue
gestureRecognizers?.forEach { $0.isEnabled = false }
}
required dynamic init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
/// # Problem
/// This should print for every new touch, up to 5 simultaneously on an iPhone (multi-touch)
/// But it only fires for one touch at a time (single-touch)
print("Touch began at: \(touch.location(in: self))")
}
}
}
Multitouch with an Overlay
This setup works, but it doesn't seem right. There must be a solution to make ARView handle multi touch directly, right?
import SwiftUI
import RealityKit
struct MultiTouchOverlayView: View {
var body: some View {
ZStack {
MultiTouchOverlayRepresentable()
.ignoresSafeArea()
Text("Multi touch with overlay view")
.font(.system(size: 24, weight: .medium))
.foregroundStyle(.white)
.offset(CGSize(width: 0, height: -150))
}
}
}
#Preview {
MultiTouchOverlayView()
}
// MARK: Representable Container
struct MultiTouchOverlayRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
/// The view that SwiftUI will present
let container = UIView()
/// ARView
let arView = ARView(frame: container.bounds)
arView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
arView.cameraMode = .nonAR
arView.automaticallyConfigureSession = false
arView.environment.background = .color(.gray)
let anchor = AnchorEntity()
arView.scene.addAnchor(anchor)
let boxWidth: Float = 0.4
let boxMaterial = SimpleMaterial(color: .red, isMetallic: false)
let box = ModelEntity(mesh: .generateBox(size: boxWidth), materials: [boxMaterial])
box.name = "Box"
box.components.set(CollisionComponent(shapes: [.generateBox(width: boxWidth, height: boxWidth, depth: boxWidth)]))
anchor.addChild(box)
/// The view that will capture touches
let touchOverlay = TouchOverlayView(frame: container.bounds)
touchOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
touchOverlay.backgroundColor = .clear
/// Pass an arView reference to the overlay for hit testing
touchOverlay.arView = arView
/// Add views to the container.
/// ARView goes in first, at the bottom.
container.addSubview(arView)
/// TouchOverlay goes in last, on top.
container.addSubview(touchOverlay)
return container
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
// MARK: Touch Overlay View
/// A UIView to handle multi-touch on top of ARView
class TouchOverlayView: UIView {
weak var arView: ARView?
override init(frame: CGRect) {
super.init(frame: frame)
isMultipleTouchEnabled = true
isUserInteractionEnabled = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let totalTouches = event?.allTouches?.count ?? touches.count
print("--- Touches Began --- (New: \(touches.count), Total: \(totalTouches))")
for touch in touches {
let location = touch.location(in: self)
/// Hit testing.
/// ARView and Touch View must be of the same size
if let arView = arView {
let entity = arView.entity(at: location)
if let entity = entity {
print("Touched entity: \(entity.name)")
} else {
print("Touched: none")
}
}
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
let totalTouches = event?.allTouches?.count ?? touches.count
print("--- Touches Cancelled --- (Cancelled: \(touches.count), Total: \(totalTouches))")
}
}
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?
既然 iOS 26 必须启用 UIScene 生命周期,那么 UIAlertView/UIActionSheet 就实际已经无法使用了,所以为什么不直接将它们标记为不可用,或者直接移除?
My app start up has became horrid. It takes 1 minute to open SQLlite database for my rust core. Impossible to work...
I have Address Sanitizer, Thread Perf Checker and Thread Sanitizer disabled...
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.