Hello,
I have a question regarding the control over the Dynamic Island UI when my app is in the foreground.
Scenario:
A user is playing a song on Apple Music, so its Live Activity is active and visible in the Dynamic Island.
Then, the user opens my app.
Desired Behavior:
While my app is in the foreground, I would like to temporarily hide or dismiss the dynamic island from Apple Music to provide a more immersive experience. When the user navigates away from my app, it's perfectly fine for the Dynamic Island to show dynamic island again.
Is there an API that allows an app to temporarily suppress a Live Activity that was initiated by another application?
My understanding of the iOS sandbox model suggests this might not be possible for security and privacy reasons, but I wanted to confirm if there's an intended way to handle this, especially for full-screen apps like games or video players.
Thank you!
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
Created
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)
}
})
}
}
Cannot find any guidance in the forums and Developer Doc, the WWDC session Meet TextKit2 says this protocol is served for any location type espacially useful when the underlying doc model is not linear. But when I try to subclass the NSTextLocation with my own type to define a more structured location rather than a linear one, also with my own NSTextContentManager subclass implementation, I keep receiving the system internal Location model like NSCountableTextLocation compare to my location which cause the app to crash.
-[NSCountableTextLocation compare:] receiving unmatching type <MarkdownTK2.ChildIndexPathLocation: 0x9b2402aa0>
In my own NSTextContentManager subclass:
public override func offset(
from: any NSTextLocation,
to: any NSTextLocation
) -> Int {
this method will also both receive my own location and some times receiving the system defined location that I can not calculate the offset then just return zero.
The doc only says
If you provide your own implementation of the NSTextLocation protocol to manage locations in your content, subclass NSTextContentManager and implement your own storage object to support those locations.
OS
Development environment: Xcode 26.0, macOS 26.0
Run-time configuration: macOS 26.0
When a popover is presented from a view that uses glassEffect(.regular.interactive()), I’m seeing mutually exclusive behavior: either the popover’s chrome (its navigation bar / toolbar) uses Liquid Glass or the originating control keeps its Liquid Glass “morph” behavior — but not both at the same time.
There are two ways that I can enable Liquid Glass on the container:
Option 1 (background capsule with .glassEffect) → The popover’s toolbar shows Liquid Glass, but the menu button loses its morph effect.
Option 2 (.glassEffect applied to the HStack) → The menu button keeps the morph effect, but the popover’s toolbar does not have Liquid Glass.
I'm using XCode 26.0.1, with latest iOS 26.0 stable simulator installed.
Here's an example code to reproduce the issue:
import PlaygroundSupport
import SwiftUI
// MARK: - TestView
struct TestView: View {
@State private var isPresented = false
var body: some View {
VStack {
Spacer()
HStack {
Button("", systemImage: "plus") {
isPresented = true
}
.popover(isPresented: $isPresented) {
MyPopover()
}
Menu {
Button("Option 1", action: {})
Button("Option 2", action: {})
Button("Option 3", action: {})
} label: {
Image(systemName: "ellipsis")
.frame(width: 40, height: 40)
}
}
.padding(.horizontal)
// Option 1 - The popover's toolbar will have liquid glass effect, but then the menu button loses liquid glass morph effect
.background {
Capsule()
.fill(Color.white)
.glassEffect(.regular.interactive())
}
// Option 2 - The popover's toolbar will not have liquid glass effect, but the menu button keeps liquid glass morph effect
// .glassEffect(.regular.interactive())
Spacer()
}
.frame(width: 400, height: 800)
}
}
// MARK: - MyPopover
private struct MyPopover: View {
var body: some View {
NavigationStack {
VStack {
ScrollView {
Text(
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
)
.padding(.horizontal)
}
}
.navigationTitle("Welcome")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("", systemImage: "xmark", action: {})
}
}
}
.presentationCompactAdaptation(.popover)
.frame(width: 300, height: 200)
}
}
PlaygroundPage.current.setLiveView(
TestView()
)
Attached the screenshots for the difference.
Simple question - on iOS 26 ContactAccessButton does not appear to show any UI when attempting to search for a contact in either the contact access picker on the ContactAccessButton.
This behavior occurs in the Apple provided sample code , as well as a basic example:
struct ContentView: View {
@State var searchText : String = ""
var body: some View {
VStack {
TextField("Search", text: $searchText)
ContactAccessButton(
queryString: searchText,
ignoredEmails: nil,
ignoredPhoneNumbers: nil,
approvalCallback: { identifiers in
print(identifiers)
})
}
.padding()
}
}
Am I doing something wrong or is this just not working?
Have a data model that sets certain fields as unique. If the user attempts to save a duplicate value, the save fails quietly with no indication to the user that the save failed. The program is on Mac OS 26.0.1
@Environment(\.modelContext) var modelContext
@Query private var typeOfContracts: [TypeOfContract]
@State private var typeName: String = ""
@State private var typeCode: String = ""
@State private var typeDescription: String = ""
@State private var contracts: [Contract] = []
@State private var errorMessage: String? = "Data Entered"
@State private var showAlert: Bool = false
var body: some View {
Form {
Text("Enter New Contract Type")
.font(.largeTitle)
.foregroundStyle(Color(.green))
.multilineTextAlignment(.center)
TextField("Contract Type Name", text: $typeName)
.frame(width: 800, height: 40)
TextField("Contract Type Code", text: $typeCode)
.frame(width: 800, height: 40)
Text("Contract Type Description")
TextEditor(text: $typeDescription)
.frame(width: 800, height: 200)
.scrollContentBackground(.hidden)
.background(Color.teal)
.font(.system(size: 24))
Button(action: {
self.saveContractType()
})
{
Text("Save new contract type")
}
}
}
func saveContractType() {
let typeOfContract = TypeOfContract(contracts: [])
typeOfContract.typeName = typeName
typeOfContract.typeCode = typeCode
typeOfContract.typeDescription = typeDescription
modelContext.insert(typeOfContract)
do {
try modelContext.save()
}catch {
errorMessage = "Error saving data: \(error.localizedDescription)"
}
}
}
I have tried to set alerts but Xcode tells me that the alerts are not in scope
I have an App with a UITabBarController. When one of the Tabs is selected then it presents a UINavigationController. This in turn presents a UIViewController to start with. (Call it myViewVC)
myViewVC has a UITableView. This is the only subview of myViewVC.
When I scroll I expect the UINavigationBar to collapse from a large Title to a small title. But instead I see no small title. This all worked fine in iOS18.x
I have tried various things suggested on forums and by AI and none of these have fixed the problem
I have set both self.navigationItem.title = @"My VC"; and self.navigationItem.largeTitle = @"My VC (New in iOS26)
It was suggested that I tie the UITableView constraints to the top of the view rather than the safe area. That did not help.
I have removed any custom appearance settings for the UINavigationBar. That did not help.
I also tried to add this line but it did not help
myTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
In SwiftUI I am using the manageSubscriptionsSheet modifier to open the iOS subscription screen. When this is presented it immediately flashes a white view and then animated the subscription screen up from the bottom, it looks pretty bad.
The view I am calling manageSubscriptionsSheet on is presented in a sheet, so maybe trying to present the subscriptions view as well is causing the visual glitch. Any way to not have this white flashing view when opening the subscription screen?
When the Table container is scrolled up the data rows just keep moving up and become unreadable with the column headings superimposed over the top.
Prior to scrolling upwards, the display will look like this.
However, if you start to scroll up
This behaviour does not seem to be the expected behaviour without any modifiers etc.
The following is the code I have been using.
import SwiftUI
struct Customer: Identifiable {
let id = UUID()
let name: String
let email: String
let creationDate: Date
}
struct SwiftyPlaceTable: View {
@State var customers = [Customer(name: "John Smith",
email: "john.smith@example.com",
creationDate: Date() + 100),
Customer(name: "Jane Doe",
email: "jane.doe@example.com",
creationDate: Date() - 3000),
Customer(name: "Bob Johnson",
email: "bob.johnson@example.com",
creationDate: Date())]
var body: some View {
Table(customers) {
TableColumn("name", value: \.name)
TableColumn("email", value: \.email)
TableColumn("joined at") { customer in
Text(customer.creationDate, style: .date)
}
}
}
}
#Preview {
SwiftyPlaceTable()
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I open this post to bring attention to overlooked UIManagedDocument. It still marked with @MainActor despite the fact that UIDocument is gonna be nonisolated in iOS 26.1.
Here is what we will have with iOS 26.1 (the fix was there since, at least, beta 2):
UIDocument was incorrectly annotated to be main actor only. This has been corrected. As a result you might see new warnings or errors show up in your Swift code using UIDocument. (149990945)
Seems that UIManagedDocument should also have to be corrected the same way. Otherwise, in Swift 6 we will have crashes.
Feedback report for this issue is FB20555456.
struct ContentView: View {
@State private var showingPopover:Bool = false
private var popOverHeight: CGFloat {
return 566
}
var body: some View {
NavigationStack {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
showingPopover = true
} label: {
Image(systemName: "plus")
.font(Font.system(size: 15))
.foregroundColor(Color.red)
}
.popover(isPresented: $showingPopover) {
FTShelfNewNotePopoverView1()
.frame(minWidth: 340.0)
.frame(height: popOverHeight)
}
}
}
}
}
}
I have a question regarding UITapGestureRecognizer, its configuration, and how it affects the responder chain.
Here’s the situation: I have a UITapGestureRecognizer added to the window, and there is also a UIBarButtonItem. I noticed that depending on the gesture recognizer’s settings, it influences the responder chain in unexpected ways.
I created a minimal reproducible example (MRE) and included a table with print outputs at the bottom. For the first three configuration options, everything works as expected. However, the last two options cause confusion:
If the UITapGestureRecognizer is configured as:
cancelsTouchesInView = false
delaysTouchesBegan = true
the tap is recognized on the window.
If configured as:
cancelsTouchesInView = true
delaysTouchesBegan = true
the tap is recognized on the UIBarButtonItem.
My question is: why does this happen?
I expected that delaysTouchesBegan and cancelsTouchesInView would only affect the gesture recognizer to which they are applied, controlling whether the tap is forwarded and whether gestures are handled simultaneously. However, it appears that these settings influence the entire responder chain.
STEPS TO REPRODUCE
final class ViewController: UIViewController {
private lazy var tapGestureRecognizer = UITapGestureRecognizer(target: self,
action: #selector(tapOnWindow))
private lazy var menuBarButton = UIBarButtonItem(image: .init(systemName: "list.bullet")!,
style: .plain,
target: self,
action: #selector(tapOnMenu))
override func viewDidLoad() {
super.viewDidLoad()
// Option one
// no-op
// Option two
// tapGestureRecognizer.cancelsTouchesInView = false
// Option three
// tapGestureRecognizer.delaysTouchesBegan = true
// Option four
// tapGestureRecognizer.cancelsTouchesInView = false
// tapGestureRecognizer.delaysTouchesBegan = true
// Option five
// tapGestureRecognizer.cancelsTouchesInView = true
// tapGestureRecognizer.delaysTouchesBegan = true
title = "Test"
UIApplication.shared.windows.first?.addGestureRecognizer(tapGestureRecognizer)
navigationItem.leftBarButtonItems = [menuBarButton]
navigationController?.navigationBar.tintColor = .black
}
@objc private func tapOnWindow(_ sender: UITapGestureRecognizer) {
print("Tap on window")
}
@objc private func tapOnMenu() {
print("Tap on menu")
}
}
/*
+---------+----------------+
| Option | Action |
+---------+----------------+
| 1 | Tap on menu |
+---------+----------------+
| 2 | Tap on window |
| | Tap on menu |
+---------+----------------+
| 3 | Tap on menu |
+---------+----------------+
| 4 | Tap on window |
+---------+----------------+
| 5 | Tap on menu |
+---------+----------------+
*/
Topic:
UI Frameworks
SubTopic:
UIKit
Hi. I‘m making an app with SwiftUI for iOS 26, and found that the old ways of changing unselected icons color seem not working as they did in old versions of iOS.
I tried these methods:
TabView() {
Tab {
// some view here
} label: {
Label(title: {
Text("something")
}, icon: {
Image(systemName: "checkmark.seal.fill")
.foregroundStyle(.blue)
}
}
}
I wrapped Image with an if-else, but itisn't able to change any color even without if;
struct ParentView: View {
init() {
UITabBar.appearance()
.unselectedItemTintColor
= UIColor.red
}
var body: some View {
TabView() {
// some tabs here
}
}
}
and an extension of above
struct ParentView: View {
init() {
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithOpaqueBackground()
tabBarAppearance.backgroundColor = UIColor.green
tabBarAppearance.stackedLayoutAppearance
.selected.titleTextAttributes
= [.foregroundColor: UIColor.red]
tabBarAppearance.stackedLayoutAppearance.normal
.titleTextAttributes
= [.foregroundColor: UIColor.black]
tabBarAppearance.stackedLayoutAppearance
.normal.iconColor = UIColor.black
tabBarAppearance.stackedLayoutAppearance
.selected.iconColor = UIColor.red
UITabBar.appearance()
.scrollEdgeAppearance
= tabBarAppearance
UITabBar.appearance()
.standardAppearance
= tabBarAppearance
UITabBar.appearance()
.unselectedItemTintColor
= .black
}
var body: some View {
TabView() {
// some tabs here
}
}
}
I read about this from reddit https://www.reddit.com/r/iOSProgramming/comments/1ftmfoa/tabbartabview_icon_and_text_colors_in_ios_18/,
it successfully changes the color of the texts in the tabbar, but not the icons.
After these, GitHub Copilot suggested me to draw two versions of icons, for different colors, which does work, but out of my capabilities. Is there any other ways to do this on new systems?
Thank you very much for any replies.
There seems to be a regression in the behavior of UIScrollEdgeElementContainerInteraction on iOS 26.1 when it's over a WKWebView. If the web view's scroll view's topEdgeEffect.style is changed to .hard and then back to .soft, it will stop tracking the color of the content underneath it and use the wrong-mix in color in its blur.
I've filed this as FB20655398.
Here's some sample code to illustrate the issue. The test.html file being loaded is just a bunch of div elements with lorem ipsum.
private var webView: WKWebView? = nil
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: config)
webView.navigationDelegate = self
self.view.addSubview(webView)
webView.autoPinEdgesToSuperviewEdges()
webView.isInspectable = true
self.webView = webView
let url = Bundle.main.url(forResource: "test", withExtension: "html")!
webView.loadFileURL(url, allowingReadAccessTo: Bundle.main.bundleURL)
let blurView = UIView()
self.view.addSubview(blurView)
blurView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .bottom)
let label = UILabel()
label.text = "This is a title bar"
blurView.addSubview(label)
label.autoAlignAxis(toSuperviewAxis: .vertical)
label.autoPinEdge(toSuperviewEdge: .bottom, withInset: 8)
label.autoPinEdge(toSuperviewSafeArea: .top, withInset: 8)
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = webView.scrollView
interaction.edge = .top
blurView.addInteraction(interaction)
self.webView?.scrollView.topEdgeEffect.style = .hard
DispatchQueue.main.asyncAfterUnsafe(deadline: .now() + .seconds(2)) {
self.webView?.scrollView.topEdgeEffect.style = .soft
}
registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (self: Self, previousTraitCollection: UITraitCollection) in
self._updateWebViewColors()
}
}
private func _updateWebViewColors() {
let dark = self.traitCollection.userInterfaceStyle == .dark
let text = dark ? "#FFFFFF" : "#000000"
let bg = dark ? "#000000" : "#FFFFFF"
let js = "document.body.style.color = '\(text)';\ndocument.body.style.backgroundColor = '\(bg)';"
self.webView?.evaluateJavaScript(js) { res, err in
if let err {
print("JS error: \(err)")
}
}
}
If you run that, then change the system them to dark mode, you get this. Has anyone else seen this before? Know how to work around it?
After returning from the child view to the parent, the latter one will simply disappear.
This is the full view. See itemsContent where I perform the navigation.
The last tapped rectangle in this example will simply disappear.
struct DashboardView: View {
@State var viewModel: DahsboardViewModel
@Namespace private var namespace
var body: some View {
ScrollView(.vertical) {
LazyVStack(spacing: 24) {
ForEach(viewModel.sections) { section in
VStack(spacing: 16) {
Text(section.title)
itemsContent(for: section)
}
}
}
}
}
func itemsContent(for section: DashboardSection) -> some View {
ForEach(section.items) { item in
NavigationLink {
PatternLearningRouter().rootView
.id(item.id)
.navigationTransition(.zoom(sourceID: item.id, in: namespace))
} label: {
Rectangle()
.fill(Color.yellow)
.frame(width: 80, height: 80)
.overlay {
Text(item.title)
}
.matchedTransitionSource(id: item.id, in: namespace)
}
}
}
}
XCode26 26.0.1(17A400)
iPhone 16 Pro, iOS 26.0.1
Note:
Only reproduced when I swipe back (not reproducing it when using back button)
Only reproduced on real device not simulator
I
I've updated test device to iOS 26.1 (23B5059e) and it looks like topColumnForCollapsingToProposedTopColumn isn't being called.
The code has been fine up until iOS 26.1. Is that a UIKit issue or shall I find another way to get my splitview to show the primary view as default?
I see in iPhone built-in apps that action sheets are presented as popovers without arrows over their originating views.
Here is an example in Messages and Shortcuts apps.
In WWDC 2025 session "Build a UIKit app with the new design", the speaker explains that all you have to do is to configurate the popover like we do for iPad.
Here is the relevant transcript:
14:33
ActionSheets on iPad are anchored to their source views. Starting in iOS 26, they behave the same on iPhone, appearing directly over the originating view.
14:46
On the alertController, make sure to set the sourceItem or the sourceView on popoverPresentationController, regardless of which device it’s displayed on. Assigning the source view automatically applies the new transitions to action sheets as well! Action sheets presented inline don’t have a cancel button because the cancel action is implicit by tapping anywhere else. If you don’t specify a source, the action sheet will be centered, and you will have a cancel button. iOS 26 provides a new, more integrated search experience, letting you position the search field where it best suits the needs of your app.
I do this in this sample code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let actionButton = UIButton(configuration: .bordered())
actionButton.setTitle("Show Action Sheet", for: .normal)
actionButton.addTarget(self, action: #selector(showActionSheet), for: .touchUpInside)
actionButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(actionButton)
NSLayoutConstraint.activate([
actionButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
actionButton.centerYAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 100)
])
}
@objc private func showActionSheet(_ button: UIButton) {
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Option 1", style: .default, handler: { _ in
print("Option 1 selected")
}))
alert.addAction(UIAlertAction(title: "Option 2", style: .default, handler: { _ in
print("Option 2 selected")
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
// Set the popover presentation anchor
if let popover = alert.popoverPresentationController {
popover.sourceItem = button
}
present(alert, animated: true, completion: nil)
}
}
When I run this code in iOS 26, I get a popover (versus a bottom action sheet on iOS 18) but this popover has an arrow.
What do I miss to display this popover like Apple does on iOS 26: without an arrow and over the originating view?
Topic:
UI Frameworks
SubTopic:
UIKit
Hi team,
I’m developing an iOS app that helps manage and translate multilingual content .
The app uses SwiftUI with Localizable.strings and Bundle.localizedString(forKey:). I’m trying to optimize for dynamic language switching inside the app without restarting.
I’ve tested various methods like:
Text(NSLocalizedString("welcome_text", comment: ""))
and some approaches using @Environment(.locale), but the system doesn’t always update views instantly when language changes.
Question:
What’s the recommended approach (or WWDC reference) for real-time language change handling in SwiftUI apps targeting iOS 18+?
I have an app with SwiftData and CloudKit sync enabled, it was working fine but I recently noticed that the sync with CloudKit is not working anymore. All the changes are persisted locally just fine. When running in simulator (iOS 26/iPhone 17 Pro) I get the following error in the console:
CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2317): <NSCloudKitMirroringDelegate: 0x600003d14c30> - Attempting recovery from error: Error Domain=NSCocoaErrorDomain Code=134421 "Export encountered an unhandled exception while analyzing history in the store." UserInfo={NSLocalizedFailureReason=Export encountered an unhandled exception while analyzing history in the store., NSUnderlyingException=-[NSEntityDescription objectID]: unrecognized selector sent to instance 0x60000351aec0}
I already tried Reseting the environment back to production in CloudKit and Erasing all Contents and Settings in the simulator but I keep getting the same error. Is there something else I can do to fix this?
I have a UINavigation controller which on the second viewController has a Google Map view. In iOS 18 you would navigate normally around the map, and swipe your finger from the left side of the screen to move the map, this worked correctly.
However, in iOS 26 swiping from left to right from anywhere but the far right side of the screen will cause the UI to try to pop the viewController.
This does not happen when I add Apple Maps or other map frameworks to the VC.
Is there a way to disable the "swipe from middle" in iOS 26?