When you use .navigationTransition(.zoom(sourceID: "placeholder", in: placehoder)) for navigation animation, going back using the swipe gesture is still very buggy on IOS26. I know it has been mentioned in other places like here: https://developer.apple.com/forums/thread/796805?answerId=856846022#856846022 but nothing seems to have been done to fix this issue.
Here is a video showing the bug comparing when the back button is used vs swipe to go back: https://imgur.com/a/JgEusRH
I wish there was a way to at least disable the swipe back gesture until this bug is fixed.
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
Hello. I have an 12 year old app that still has some objective-c code in it. I have a place where i have a flip animation between 2 view controllers that looks like this:
[UIView transitionFromView:origView
toView:newViewController.view
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
It has looked like this since 2012 at least.
In our production release, it works prior to 26.1, but in 26.1 and 26.2, the flip is off-center and looks weird. it's like both edges flip the same way. It's a little bit hard to explain.
If seen at least 2 other app store apps that i have installed behave this way too, from 26.1 and onwards.
Anyone else seen this? Is there anything that can be done about it?
Thankful for thoughts.
When I use the .zoom transition in a navigation stack, I get a glitch when interrupting the animation by swiping back before it completes.
When doing this, the source view disappears. I can still tap it to trigger the navigation again, but its not visible on screen.
This seems to be a regression in iOS 26, as it works as expected when testing on iOS 18.
Has someone else seen this issue and found a workaround? Is it possible to disable interrupting the transition?
Filed a feedback on the issue FB19601591
Screen recording:
https://share.icloud.com/photos/04cio3fEcbR6u64PAgxuS2CLQ
Example code
@State var showDetail = false
@Namespace var namespace
var body: some View {
NavigationStack {
ScrollView {
showDetailButton
}
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.inline)
.navigationDestination(isPresented: $showDetail) {
Text("Detail")
.navigationTransition(.zoom(sourceID: "zoom", in: namespace))
}
}
}
var showDetailButton: some View {
Button {
showDetail = true
} label: {
Text("Show detail")
.padding()
.background(.green)
.matchedTransitionSource(id: "zoom", in: namespace)
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I've worked through Apple's dice demo for SwiftUI, so far so good. I've got a single Die view with a button to "roll" the die. This works perfectly using the code below:
struct DieView: View {
init(dieType: DieType) {
self.dieValue = Int.random(in: 1...dieType.rawValue)
self.dieType = dieType
}
@State private var dieValue: Int
@State private var dieType: DieType
var body: some View {
VStack {
if self.dieType == DieType.D6 {
Image(systemName: "die.face.\(dieValue)")
.resizable()
.frame(width: 100, height: 100)
.padding()
}
else {//self.dieType == DieType.D12{
Text("\(self.dieValue)")
.font(.largeTitle)
}
Button("Roll"){
withAnimation{
dieValue = Int.random(in: 1...dieType.rawValue)
}
}
.buttonStyle(.bordered)
}
Spacer()
}
}
Now I want to do a DiceSetView with an arbitrary number of dice. I've got the UI working with the following;
struct DiceSetView: View {
@State private var totalScore: Int = 0
var body: some View {
ScrollView(.horizontal) {
HStack{
DieView(dieType: DieType.D6)
DieView(dieType: DieType.D6)
DieView(dieType: DieType.D6)
}
}
HStack{
Button("Roll All"){}
.buttonStyle(.bordered)
Text("Score \(totalScore)")
.font(.callout)
}
Spacer()
}
}
Where I'm struggling is how to get the total of all the dice in a set and to roll all the dice in a set on a button click.
I can't iterate through the dice, and just "click" the buttons in the child views from their parents, and I can't think how it should be structured to achieve this (I'm new to this style of programming!) - can anyone point me in the right direction for how to achieve what I want? I realise that I'm probably missing something fundamentally conceptual here....
Topic:
UI Frameworks
SubTopic:
SwiftUI
I'm sure this is a basic question, but I'm new to this style of development, so thought Id ask...
I've worked through Apple's dice roller demo, so far so good - I'm using the code below to render and roll a single die;
struct DieView: View {
init(dieType: DieType) {
self.dieValue = Int.random(in: 1...dieType.rawValue)
self.dieType = dieType
}
@State private var dieValue: Int
@State private var dieType: DieType
var body: some View {
VStack {
if self.dieType == DieType.D6 {
Image(systemName: "die.face.\(dieValue)")
.resizable()
.frame(width: 100, height: 100)
.padding()
}
else {
Text("\(self.dieValue)")
.font(.largeTitle)
}
}
Button("Roll"){
withAnimation{
dieValue = Int.random(in: 1...dieType.rawValue)
}
}
.buttonStyle(.bordered)
Spacer()
}
}
Again, so far so good - works as I'd expect. I can now also add multiple DieViews to a DiceSetView and they display as I'd expect.
Where I'm stuck is in the DiceSetView, I want to both determine the total score across the dice, and also offer the ability to Roll All the dice in a set. (Ultimately I want another level above the set, so I'll be looking to roll all dice in all sets)
I can't simply call a func / method on the child view (i.e. iterate through them and sum their values, and roll each), I suspect I need to change how it's all structured, but not sure where to go from here...
Can anyone point me in the right direction?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hi, new developer here.
I have an issue where an image I have on app is not showing up on some devices.
The image is: Resources/Assets/logo:
I am using it in my app like:
ZStack {
Color.white
.ignoresSafeArea()
VStack {
Spacer()
Image("logo")
Spacer()
Text(dateString)
.font(.custom("LinLibertine", size: 17))
.fontWeight(.bold)
.tracking(5)
.padding(.bottom, 50)
}
}
The image appears fine on all simulators. And also on my real device iPad with A14. But when I run it on iPhone 8 or iPad Air M4, it shows empty space in place of image.
I tried many different options like:
Image("logo")
.renderingMode(.original)
.resizable()
.scaledToFit()
frame(width: 300)
.background(Color.red.opacity(0.3))
But nothing works. What can be the issue?
Hello dear developers!
Recently, I stumbled upon some really strange behavior of SwiftUI and I’m very curious why it works this way
struct ContentView: View {
@State private var title: String?
@State private var isSheetPresented: Bool = false
var body: some View {
Button("Hello, world!") {
title = "Sheet title"
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented, content: {
if let title {
Text(title)
} else {
EmptyView()
}
})
}
}
Why in this case when we tap the button and sheet comes in we go to the branch else even though we set title before isSheetPresented but it still somehow nil
But what really drive me crazy is that if we change a little bit code to this:
I just added another @State property 'number' and use it as the Button's title. In this scenario it works 😃 and Text in the sheet view appearing
struct ContentView: View {
@State private var title: String?
@State private var number = 0
@State private var isSheetPresented = false
var body: some View {
Button("\(number)") {
title = "Sheet title"
number += 0
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented, content: {
if let title {
Text(title)
} else {
EmptyView()
}
})
}
}
Is this somehow related to what happens under the hood like View Tree and Render Tree (Attribute Graph)?
Maybe because ContentView’s body doesn't capture title it cannot be stored in the Render Tree so it always would have the initial value of nil?
if there are any well-informed folks here, please help me figure out this mystery, I’d appreciate it!!!
p.s.
Don’t get me wrong. Im not interested in how to make it work. I’m interested in why this doesn’t work and what really happens under the hood that led to this result
I have a Menu in a Toolbar (specifically, the .bottomBar). If I open the menu quickly after it appears (within a few seconds), it flies to the top of the screen. I've created a minimum woking example below.
This appears to be a pretty glaring iOS 26 bug that has been present since the early betas, but I can't seem to find much discussion about it (apart from this post from 8 months ago), so I'm wondering if I might be doing something wrong. Or maybe someone managed to figure out a workaround.
If the Menu is very simple (just Text items), it seems to be okay. But if the Menu is even slightly complex (e.g. includes icons), then it exhibits the flying behavior. I've also been able to reproduce this bug under different types of navigation component (e.g. NavigationSplitView).
I'm seeing this behavior in the current version of iOS (26.2.1), both on device and in the simulator.
MWE
struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
NavigationLink("Go to Detail") {
DetailView()
}
}
.navigationTitle("Root")
}
}
}
struct DetailView: View {
var body: some View {
VStack {
Text("Detail View")
}
.navigationTitle("Detail")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .bottomBar) {
Menu {
Button {
} label: {
Label("Delete", systemImage: "trash")
}
} label: {
Image(systemName: "ellipsis.circle")
}
}
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I can't seem to find information on this but this is causing a critical bug where the Strong Password suggestion sheet presents on any secure field (UIKit) and clears the others when closing it. This means the user cannot enter a password when there is a secure confirm password field because switching fields clears the other.
This looks to be a recent issue but I can't tell when this was introduced or if this is SDK / OS version related. I am finding it in both Xcode 26.2 and 16.4 when running on device (iOS 26.2.1 and XC 26 simulators).
Code to reproduce:
class ViewController: UIViewController {
override func loadView() {
let v = UIStackView()
v.axis = .vertical
v.layoutMargins = .init(top: 16, left: 16, bottom: 16, right: 16)
v.isLayoutMarginsRelativeArrangement = true
view = v
let t1 = UITextField()
t1.textContentType = .username
t1.placeholder = "Username"
v.addArrangedSubview(t1)
let t2 = UITextField()
t2.isSecureTextEntry = true
t2.textContentType = .newPassword
t2.placeholder = "Password"
t2.clearsOnInsertion = false
t2.clearsOnBeginEditing = false
t2.passwordRules = nil
t2.clearButtonMode = .always
v.addArrangedSubview(t2)
let t3 = UITextField()
t3.isSecureTextEntry = true
t3.textContentType = .newPassword
t3.placeholder = "Confirm Password"
t3.clearsOnInsertion = false
t3.clearsOnBeginEditing = false
t3.passwordRules = nil
t3.clearButtonMode = .always
v.addArrangedSubview(t3)
v.addArrangedSubview(UIView())
}
}
No matter what textContentType is used the strong password still forcefully breaks the flow and blocks the user.
It seems to me that NSStagedMigrationManager has algorithmic issues. It doesn't perform staged migration, if all its stages are NSLightweightMigrationStage.
You can try it yourself. There is a test project with three model versions V1, V2, V3, V4. Migrating V1->V2 is compatible with lightweight migration, V2->V3, V3->V4 is also compatible, but V1->V3 is not. I have following output:
Migrating V1->V2, error: nil
Migrating V2->V3, error: nil
Migrating V3->V4, error: nil
Migrating V1->V3, no manager, error: Optional("Persistent store migration failed, missing mapping model.")
Migrating V1->V3, lightweight[1, 2, 3], error: Optional("Persistent store migration failed, missing mapping model.")
Migrating V1->V3, lightweight[1]->lightweight[2]->lightweight[3], error: Optional("Persistent store migration failed, missing mapping model.")
Migrating V1->V3, custom[1->2]->lightweight[3], error: nil
Migrating V1->V3, lightweight[1]->custom[2->3], error: nil
Migrating V1->V3, custom[1->2]->custom[2->3], error: nil
Migrating V1->V4, error: Optional("Persistent store migration failed, missing mapping model.")
Migrating V2->V4, error: nil
Migrating V1->V4, custom[1->2]->lightweight[3, 4], error: nil
Migrating V1->V4, lightweight[3, 4]->custom[1->2], error: Optional("A store file cannot be migrated backwards with staged migration.")
Migrating V1->V4, lightweight[1, 2]->lightweight[3, 4], error: Optional("Persistent store migration failed, missing mapping model.")
Migrating V1->V4, lightweight[1]->custom[2->3]->lightweight[4], error: nil
Migrating V1->V4, lightweight[1,4]->custom[2->3], error: nil
Migrating V1->V4, custom[2->3]->lightweight[1,4], error: Optional("Persistent store migration failed, missing mapping model.")
I think that staged migration should satisfy the following rules for two consecutive stages:
Any version of lightweight stage to any version of lightweight stage;
Any version of lightweight stage to current version of custom stage;
Next version of custom stage to any version of lightweight stage;
Next version of custom stage to current version of custom stage.
However, rule 1 doesn't work, because migration manager skips intermediate versions if they are inside lightweight stages, even different ones.
Note that lightweight[3, 4]->custom[1->2] doesn't work, lightweight[1,4]->custom[2->3] works, but custom[2->3]->lightweight[1,4] doesn't work again.
Would like to hear your opinion on that, especially, from Core Data team, if possible.
Thanks!
I have a problem when applying rotationEffect to a map in in SwiftUI. The legal text in the map is transformed as shown in this image:
The following code is part of a much larger and complex view; it is a minimal example to reproduce the error:
import SwiftUI
import MapKit
struct ContentView: View {
@State private var offset = CGSize.zero
var body: some View {
ZStack {
let drag = DragGesture()
.onChanged { g in
offset.width = g.translation.width
offset.height = g.translation.height
}
Map(interactionModes: [.zoom])
.frame(width: 320, height: 220)
.rotationEffect(.degrees(Double(offset.width / 12)))
.highPriorityGesture(drag)
}
}
}
I hope you can help me with this problem.
Fatal Exception: NSInternalInconsistencyException
Cannot remove an observer <WKWebView 0x135137800> for the key path "configuration.enforcesChildRestrictions" from <STScreenTimeConfigurationObserver 0x13c6d7460>, most likely because the value for the key "configuration" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the STScreenTimeConfigurationObserver [class.]
I noticed that on iOS 26, WKWebView registers STScreenTimeConfigurationObserver, Is this an iOS 26 system issue? What should I do?
I’m developing a share extension for iOS 26 with Xcode 26. When the extension’s sheet appears, it always shows a full white background, even though iOS 26 introduces a new “Liquid Glass” effect for partial sheets.
Expected:
The sheet background should use the iOS 26 glassmorphism effect as seen in full apps.
Actual behavior:
Custom sheets in my app get the glass effect, but the native system sheet in the share extension always opens as plain white.
Steps to reproduce:
Create a share extension using UIKit
Present any UIViewController as the main view
Set modalPresentationStyle = .pageSheet (or leave as default)
Observe solid white background, not glassmorphism
Sample code:
swift
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .clear
preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 300)
}
Troubleshooting attempted:
Tried adding UIVisualEffectView with system blur/materials
Removed all custom backgrounds
Set modalPresentationStyle explicitly
Questions:
Is it possible to enable or force the Liquid Glass effect in share extensions on iOS 26?
Is this a limitation by design or a potential bug?
Any workaround to make extension sheet backgrounds match system glass appearance?
Hi.
In my project, I use the following property to access the safe area via UIApplication:
UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }?.safeAreaInsets
However, in Xcode 26 and iOS 26, this no longer works, and in some cases the app crashes. Views that rely on this property stop behaving as expected. For example, if it’s a sheet, it does not appear.
The same app built with Xcode 16 and distributed via TestFlight runs on iOS 26 without any issues.
What is the correct and safe way to obtain safeAreaInsets outside of a View now?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I’m developing a share extension for iOS 26 with Xcode 26. When the extension’s sheet appears, it always shows a full white background, even though iOS 26 introduces a new “Liquid Glass” effect for partial sheets.
Expected:
The sheet background should use the iOS 26 glassmorphism effect as seen in full apps.
Actual behavior:
Custom sheets in my app get the glass effect, but the native system sheet in the share extension always opens as plain white.
Steps to reproduce:
Create a share extension using UIKit
Present any UIViewController as the main view
Set modalPresentationStyle = .pageSheet (or leave as default)
Observe solid white background, not glassmorphism
Sample code:
swift
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .clear
preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 300)
}
Troubleshooting attempted:
Tried adding UIVisualEffectView with system blur/materials
Removed all custom backgrounds
Set modalPresentationStyle explicitly
Questions:
Is it possible to enable or force the Liquid Glass effect in share extensions on iOS 26?
Is this a limitation by design or a potential bug?
Any workaround to make extension sheet backgrounds match system glass appearance?
Hi — I’m seeing the DocumentGroup rename/title affordance get clipped on iPad when I populate the navigation bar with SwiftUI toolbar items in .topBarLeading, .principal, and .topBarTrailing (trailing is an HStack of controls). Example:
.toolbar {
ToolbarItem(placement: .topBarLeading) { UndoRedoControlsView(...) }
ToolbarItem(placement: .principal) { Text(canvasInfoTitle).lineLimit(1) }
ToolbarItem(placement: .topBarTrailing) { HStack { ... } }
}
.navigationBarTitleDisplayMode(.inline)
Is there a recommended way to structure toolbar content so the system’s document title/rename control always has space (or a way to reserve space / avoid clipping), short of removing .principal or moving items into menus?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I have the following snippet (but you can see my entire code in GitHub, if you want):
LazyVGrid(columns: columns) {
ForEach(books) { book in
BookView(book: book)
.draggable(Book.BookTransferable(persistanceIdentifier: book.id))
}
}
and BookView is:
VStack {
Image(nsImage: book.image)
.resizable()
.frame(width: 150, height: 200)
.scaledToFill()
Text(book.title)
.lineLimit(1)
.font(.headline)
HStack {
ForEach(book.tags.sorted(), id: \.self) { tag in
TagView(tag: tag, showText: false)
}
}
}
.padding()
This will render each BookView on a different base-line because of the fact that the Text view sometimes takes 1, 2 or even 3 lines (as shown).
How can I have all BookViews alligned at a common base-line (as it would if Text would only take one line, for example)?
I noticing that Monterey defaults to the NSWindowToolbarStyleAutomatic / NSWindowToolbarStyleUnified toolbar style, which suppresses the "use Small Size" menu item and customization checkbox.
So I've set the window to use NSWindowToolbarStyleExpanded. However, the toolbar will no longer change to a smaller icon size, as it did in MacOS 10.14, 10.15, and 11.0.
I've tried to set the toolbar item sizing to "Automatic" for all of our toolbar icons, but that results in bad positioning in both Regular and Small Size mode -- the height is way too big.
The native size of the icon .png files are 128 x 128. What's odd is that if I resize the window with the toolbar to be wider, the NSToolbarItems in the overflow area will be displayed in the toolbar are 128 x 128, where the rest of the toolbar icons get displayed as a 32 x 32 icon.
The only way to get it to layout remotely correct is to make the NSToolbarItem to have an explicit minimum size of 24 x 24 and maximum size of 32 x 32. And that USED to allow "small size", but on Monterey, it no longer does.
Anyone had any success with small size icons on Monterey?
Hello,
I am developing a macOS app using AudioToolbox's MusicSequence and MusicPlayer APIs to play Standard MIDI Files.
The MIDI playback works correctly and I can hear sound from the external MIDI device. However, the user callback registered via MusicSequenceSetUserCallback is never invoked during playback.
Details:
Callback registration returns no error.
MusicPlayer is properly started and prerolled.
The callback is defined as a global function with the correct @convention(c) signature.
I have tried commenting out MusicTrackSetDestMIDIEndpoint to avoid known callback suppression issues.
The clientData pointer is passed and correctly unwrapped in the callback.
Minimal reproducible example shows the same behavior.
Environment:
macOS version: [Tahoe 26.2]
Xcode version: [26.2]
Is it expected that MusicSequenceSetUserCallback callbacks may not be called in some cases?
Are there additional steps or configurations required to ensure the callback is triggered during MIDI playback?
Thank you for any advice or pointers.
Execute playTest() in the viewDidLoad() method of the ViewController.
extension ViewController {
private func playTest() {
NewMusicSequence(&sequence)
if let midiFileURL = Bundle.main.url(forResource: "etude", withExtension: "mid") {
MusicSequenceFileLoad(sequence!, midiFileURL as CFURL, .midiType,MusicSequenceLoadFlags())
NewMusicPlayer(&player)
MusicPlayerSetSequence(player!, sequence!)
MusicPlayerPreroll(player!)
let status = MusicSequenceSetUserCallback(sequence!, musicSequenceUserCallback, Unmanaged.passUnretained(self).toOpaque())
if status == noErr {
print("Callback registered successfully")
} else {
print("Callback registration failed: \(status)")
}
MusicPlayerStart(player!)
} else {
print("MIDI File Not Found")
}
}
}
The callback function was generated by Xcode and defined outside the ViewController.
func musicSequenceUserCallback(
clientData: UnsafeMutableRawPointer?,
sequence: MusicSequence,
track: MusicTrack,
eventTime: MusicTimeStamp,
eventData: UnsafePointer<MusicEventUserData>,
startSliceBeat: MusicTimeStamp,
endSliceBeat: MusicTimeStamp
) {
print("User callback fired at eventTime: \(eventTime)")
if let clientData = clientData {
let controller = Unmanaged<ViewController>.fromOpaque(clientData).takeUnretainedValue()
// Example usage to prove round-trip works (avoid strong side effects in callback)
_ = controller.view // touch to silence unused warning if needed
print("Callback has access to ViewController: \(controller)")
} else {
print("clientData was nil")
}
}
In this app I use tooltips extensively.
They work perfectly well, except in a popover where they may appear or not (just some flash and immediately disappear).
In the popover there are 12 colour buttons, each with its own tracking area and 3 control buttons, with their tracking areas.
Here when it works, hovering over "C" button or "Annuler" button:
But then, when I move to another colour button, a few 2 or 3 may work, but most don't display their tooltip at all.
I know that the tooltip is set because I replicate the message in a help line at the bottom of the screen and this line always update:
Let messageForColor = "Choisir la couleur…"
if button.isEnabled { // show tooltip
button.toolTip = messageForColor
} else {
button.toolTip = nil
}
if button.isEnabled { // Shows helpline at the bottom of screen
button.helpMessage = messageForColor
}
Maybe it comes from some useDefault (I modified NSInitialTool TipDelay and I'm not sure I have reset to the default value)
I noted that if I wait for 10 seconds or so (keeping the popover opened), everything seems to work properly again. Just as if there was some lengthy initialisation going on.
So questions:
Is there a known issue of Tooltips in a popover ?
Are there other parameters to set in userDefaults to avoid immediate disparition of the tooltip in popover ?
How to reset the factory setting for the UserDefaults in the app ?