Hi,
I am trying to add a custom (create) button next to the automatic "toggle sidebar" button in a NavigationSplitView.
When the sidebar is collapsed that button should be displayed in a group with that automatic toggle button.
Basically I want exact the same behaviour as in the Apple "Reminders" App.
How could I archive that?
Thanks for your help :-)
Jan
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 have checked the sample project from the documentation page
and noticed there is an issue with image/images not being preselected. The issue happens on iOS 26.1 and above (checked iOS 26.2 beta).
I couldn't find any change to the PhotoPicker in the documentation.
Topic:
UI Frameworks
SubTopic:
UIKit
Description of the current implementation:
A section, UIView, has been added to UITableView. This section is a UICollectionView that displays an array of images. Each UICollectionViewCell is an image displayed via a UIImageView.
Issue:
When UITableView is scrolled vertically, the section with the image collection flickers.
Attempts made to solve the problem:
if #available(iOS 26.0, *) {
tableView.bottomEdgeEffect.isHidden = true
tableView.topEdgeEffect.isHidden = true
tableView.leftEdgeEffect.isHidden = true
tableView.rightEdgeEffect.isHidden = true
} else {
// Fallback on earlier versions
}
This helped with a similar issue. I tried it on UITableView and UICollectionView, but it didn't work.
I’m working on a SwiftUI screen where I need to hide a header when the user scrolls down and show it again when the user scrolls up. I’m currently using a ScrollView combined with GeometryReader to detect scroll offset changes and update state variables like isScrolling or isScrollingDown.
The issue is that the behavior is inconsistent. When I scroll down, the header hides correctly, but when I scroll back up, the header often doesn’t appear again even though the offset is changing. Sometimes the header comes back with a delay, and other times it never appears at all. Along with this, I’m also seeing noticeable UI lag whenever I try to calculate content height or read multiple geometry values inside the ScrollView. It looks like the frequent state updates inside the scroll offset tracking are causing layout recalculations and frame drops.
I’ve tried placing the header in different positions (inside a ZStack aligned to the top, inside the VStack above the ScrollView, and with transitions like .push(from: .top)), but the result is still the same: smooth scrolling breaks, and the header doesn’t reliably animate back when scrolling upward.
What I’m looking for is a minimal and efficient approach to detect scroll direction and trigger the header hide/show animation without causing performance issues or recomputing expensive layout values. Any guidance or a simplified pattern that works well for dynamic headers in SwiftUI would be very helpful.
if isScrolling {
headerStackView() //Includes Navigation Bar
.transition(
.asymmetric(
insertion: .push(from: .top),
removal: .push(from: .bottom)
)
)
}
GeometryReader { outer in
let outerHeight = outer.size.height
ScrollView(.vertical) {
VStack {
content() // Heavy view + contains its own ScrollView
}
.background {
GeometryReader { proxy in
let contentHeight = proxy.size.height
let minY = max(
min(0, proxy.frame(in: .named("ScrollView")).minY),
outerHeight - contentHeight
)
if #available(iOS 17.0, *) {
Color.clear
.onChange(of: minY) { oldVal, newVal in
// Scroll direction detection
if (isScrolling && newVal < oldVal) ||
(!isScrolling && newVal > oldVal) {
isScrolling = newVal > oldVal
}
}
}
}
}
}
.coordinateSpace(name: "ScrollView")
}
.padding(.top, 1)
After updating from iOS 26 to iOS 26.1, all my transparent system elements (i.e. UITabBar, UIBarButtonItem) started rendering with a dark background tint. In iOS 26 the same configuration looked fully transparent / glassy.
The strange part is that the tint only appears in normal UIViewControllers. In UITableViewController the tab bar still looks correct and transparent, even on iOS 26.1.
I am using the same appearance code as before:
func setupTabBarAppearance() {
guard let tabBar = tabBarController?.tabBar else { return }
if #available(iOS 26.0, *) {
let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = .clear
appearance.backgroundEffect = nil
appearance.shadowColor = .clear
tabBar.standardAppearance = appearance
tabBar.scrollEdgeAppearance = appearance
tabBar.isTranslucent = true
tabBar.backgroundColor = .clear
tabBar.barTintColor = .clear
} else {
tabBar.isTranslucent = true
tabBar.backgroundImage = UIImage()
tabBar.shadowImage = UIImage()
tabBar.backgroundColor = .clear
}
}
I tried removing backgroundEffect, forcing .clear colors, using configureWithDefaultBackground, changing edgesForExtendedLayout, extendedLayoutIncludesOpaqueBars, etc. I noticed that if I change Liquid Glass in iOS 26 settings from Clear to Tinted, then I get a black tint everywhere and the interface becomes consistent, but not the way I want.
Nothing removes the new dark tint in iOS 26.1. Is this an intentional change in iOS 26.1, a bug, or is there a new way to make the tab bar fully transparent again?
Hello. I'm making an app with several different views. I'm trying to switch views using a button but I can't seem to figure out how. I know Navigation Links work, but my case doesn't work. The reasons for this are because I need to run other code when they click the button and I don't want them to be able to navigate back (to CustomizationView/CreateAccountView). I know that you can hide the back button but my problem with that is the fact that i will be navigating to a view (MainView) that will also have navigation buttons in it, so if i'm thinking correctly, the button will be hidden but when they press the next navigationlink (in MainView) it will show again and then they can go back (to CustomizationView/CreateAccountView). i don't want them to go back because they will be navigating from a login/account view that wont be needed anymore. I'm currently using .fullScreenCover() and it works fine except for performance (I'm assuming). here's the code:
import SwiftUI
struct CustomizationView: View {
@State private var showMain = false
var body: some View {
Button("Done") {
// some more code here
showMain = true
}
.fullScreenCover(isPresented: $showMain) {
MainView()
}
}
}
here's a visual for the navigation if you're confused
I’m trying to implement smooth zoom and drag interactions for an image on watchOS—similar to the Photos app. DTS recommended using digitalCrownRotation + scaleEffect in SwiftUI, and ChatGPT also suggests a similar approach. However, the experience still isn’t as smooth or polished as the Photos app.
Before I commit fully to this direction, I want to confirm:
1. Is SwiftUI with digitalCrownRotation, scaleEffect, and DragGesture the officially recommended approach for zoom + pan on watchOS?
2. Is there any public API that provides built-in Photos-style behavior, or is a custom SwiftUI implementation expected?
3. Are there best-practice patterns for smooth scaling, maintaining image bounds, and constrained panning?
Thanks for any guidance
Topic:
UI Frameworks
SubTopic:
SwiftUI
When a subclass of UIInputView is created programmatically, a memory leak occurs.
This issue can be easily reproduced even with a very simple sample project, so I’m submitting this report along with a minimal reproducible example.
When a custom view subclassing UIInputView is instantiated in code,
_InputViewContent retains the custom view, and the custom view also holds a reference back to _InputViewContent,
creating a strong reference cycle that prevents deallocation.
The issue consistently occurs and has been confirmed on Xcode 16.4, 26.0, and 26.1.
As a workaround, initializing the view via Storyboard allows it to be properly deallocated from memory.
(Please refer to the CustomInputView in the attached sample code.)
import UIKit
final class LeakInputView: UIInputView {
deinit {
print("LeakInputView deinit") // not called
}
}
final class CustomInputView: UIInputView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect, inputViewStyle: UIInputView.Style) {
super.init(frame: frame, inputViewStyle: inputViewStyle)
}
deinit {
print("CustomInputView deinit") // called
}
}
extension CustomInputView {
static func loadFromNib() -> CustomInputView {
let nib = UINib(nibName: "CustomInputView", bundle: nil)
guard let view = nib.instantiate(withOwner: nil, options: nil).first as? CustomInputView else {
fatalError("Failed to load CustomInputView from nib.")
}
return view
}
}
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
LeakInputView()
LeakInputView()
LeakInputView()
CustomInputView.loadFromNib()
CustomInputView.loadFromNib()
CustomInputView.loadFromNib()
DispatchQueue.main.async {
print("Next runloop tick")
}
}
}
Topic:
UI Frameworks
SubTopic:
UIKit
I use the following bit of code to snapshot a View as a UIImage, but it's causing a memory leak:
extension View {
@ViewBuilder func snapshot(trigger: Bool, onComplete: @escaping (UIImage) -> ()) -> some View {
self.modifier(SnapshotModifier(trigger: trigger, onComplete: onComplete))
}
}
fileprivate struct SnapshotModifier: ViewModifier {
var trigger: Bool
var onComplete: (UIImage) -> ()
@State private var view: UIView = .init(frame: .zero)
func body(content: Content) -> some View {
content
.background(ViewExtractor(view: view))
.compositingGroup()
.onChange(of: trigger) {
generateSnapshot()
}
}
private func generateSnapshot() {
if let superView = view.superview?.superview {
let render = UIGraphicsImageRenderer(size: superView.bounds.size)
let image = render.image { _ in
superView.drawHierarchy(in: superView.bounds, afterScreenUpdates: true)
}
onComplete(image)
}
}
}
fileprivate struct ViewExtractor: UIViewRepresentable {
var view: UIView
func makeUIView(context: Context) -> UIView {
view.backgroundColor = .clear
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
// No process
}
}
Taking the snapshot is triggered like this:
struct ContentView: View {
@State private var triggerSnapshot: Bool = false
var body: some View {
Button("Press to snapshot") {
triggerSnapshot = true
}
TheViewIWantToSnapshot()
.snapshot(trigger: triggerSnapshot) { image in
// Save the image; you don't have to do anything here to get the leak.
}
}
}
I'm not the best at Instruments, and this is what the Leaks template produces. There are no method names, just memory addresses:
Is this leak in an internal iOS library, is there something wrong with Instruments, or am I missing something obvious in my code?
Thanks.
Why a TipKit configured with a weekly frequency, on the following example, when the app is launched on the View1, the tip is displayed. I thought that going to View2 and come back to View1 should not redisplayed the tip (at least until one week).
What do I miss?
import SwiftUI
import TipKit
struct FavoriteLandmarkTip: Tip {
var title: Text {
Text("Save as a Favorite")
}
var message: Text? {
Text("Your favorite landmarks always appear at the top of the list.")
}
var image: Image? {
Image(systemName: "star")
}
}
@main
struct LandmarkTips: App {
var body: some Scene {
WindowGroup {
TabView {
View1()
.tabItem {
Label("View1", systemImage: "house")
}
View2()
.tabItem {
Label("View2", systemImage: "house")
}
}
.task {
do {
// uncomment to reset all tips status
// try? Tips.resetDatastore()
try Tips.configure([
.displayFrequency(.weekly),
.datastoreLocation(.applicationDefault)
])
}
catch {
print("Error initializing TipKit \(error.localizedDescription)")
}
}
}
}
}
struct View1: View {
let favoriteLandmarkTip = FavoriteLandmarkTip()
var body: some View {
VStack {
TipView(favoriteLandmarkTip, arrowEdge: .bottom)
Image(systemName: "star")
}
}
}
struct View2: View {
var body: some View {
Text("View2")
}
}
When I run the following code and change "Is On", I get a problem with the layout of the Picker.
There is no problem when using Text(), but when using only Image, it works fine on iOS but there is a problem on macOS.
Tested on macOS 26.1, Xcode 26.1.
import SwiftUI
struct ContentView: View {
@State var model = Model()
var body: some View {
Form {
Picker("Category", selection: $model.category) {
ForEach(Category.allCases) { item in
Image(systemName: item.icon)
.tag(item)
}
}
.pickerStyle(.segmented)
Toggle("Is On", isOn: $model.isOn)
}
.formStyle(.grouped)
}
}
struct Model {
var category: Category = .a
var isOn: Bool = false
}
enum Category: Int, Identifiable, CaseIterable {
case a, b, c
var id: Int { rawValue }
var icon: String {
switch self {
case .a: return "a.circle.fill"
case .b: return "b.circle.fill"
case .c: return "c.circle.fill"
}
}
var name: String {
switch self {
case .a: return "a"
case .b: return "b"
case .c: return "c"
}
}
}
code-block
We are creating a Replicated FileProvider based application, where we need to change folder icons for root level folders.
I tried below two approaches.
This using NSFileProviderDecorations + Custom UTType, this changed the UI as shown:
This using Custom UTType, this had no UI change:
How can we change the default folder icon, to our custom icon?
Description
On iOS 26.1, a ToolbarItem placed in .keyboard is no longer exposed to the accessibility hierarchy. As a result:
VoiceOver cannot focus or activate the toolbar button
XCUITest cannot discover the element, making the UI impossible to test
TextEditor()
.toolbar {
ToolbarItem(placement: .keyboard) {
Button("Done") { /* action */ }
}
}
This worked correctly on previous iOS versions.
The button appears visually but is missing from both VoiceOver navigation and XCUI accessibility queries.
Steps to Reproduce
Create a new SwiftUI project.
Use a simple text field with a keyboard toolbar button.
Run on an iOS 26.1 device or simulator.
Focus the text field to show the keyboard.
Turn on VoiceOver and attempt to navigate to the toolbar button.
Run an XCUITest attempting to locate the button
I know iPhone Cannot prohibit screenshots, but I have seen someone else's solution, which is to capture a white page instead of the current design page when taking screenshots. I want to use swift implement iPhone The photo generated when taking a screenshot is a white screen, and I don't want my page to be seen by others
Topic:
UI Frameworks
SubTopic:
General
Looking at Brainrot's UI, they display both "Screen Time: 6h 31m" and a calculated "Health: 91/100" score with a "Tap to Fix" button. This suggests manual sync or a workaround.
Specific Questions:
Can DeviceActivityReport extensions communicate data back to the main app? (CloudKit, Notifications, Shared files?)
Can extensions write to UserDefaults on physical devices?
Do commercial apps rely on manual user sync?
Is there an alternative API I'm overlooking?
Do threshold-based approximations work reliably for daily tracking?
I can extract exact minutes in the extension but can't export them to the main app due to sandbox restrictions. Either a technical solution or confirmation that manual sync is the industry standard would help greatly.
Broken TabView + NavigationStacks functionality on iOS 26.1.
Even the most basic navigation made impossible.
Example:
TabView {
Tab(...) {
NavigationStack(path: $homePath) {
HomeView()
.navigationDestination { ... }
}
}
Tab(...) {
NavigationStack(path: $settingsPath) {
SettingsView()
.navigationDestination { ... }
}
}
}
Anything passed to settingsPath is just ignored and would never appear onscreen.
(26.0 and prior versions work as expected.)
Are there any workarounds?
I'm reading a bit outdated book about Cocoa/Objective-C applications development and I'm trying to code some examples. And so I ended up with an almost empty NSDocument-based app with runtime errors like that:
Internal inconsistency in menus - menu <NSMenu: 0xbc726d040>
Title: Window
Supermenu: 0xbc726d080 (Main Menu), autoenable: YES
Previous menu: 0x0 (None)
Next menu: 0x0 (None)
Items: (
"<NSMenuItem: 0xbc6fcd9a0 Minimize, ke='Command-M'>",
"<NSMenuItem: 0xbc6fcda40 Zoom, ke mask=''>",
"<NSMenuItem: 0xbc6fcdae0, separator, ke mask=''>",
"<NSMenuItem: 0xbc6fcd900 Bring All to Front, ke mask=''>"
) believes it has <NSMenu: 0xbc726d080>
Title: Main Menu
Supermenu: 0x0 (None), autoenable: YES
Previous menu: 0x0 (None)
Next menu: 0x0 (None)
Items: (
) as a supermenu, but the supermenu does not seem to have any item with that submenu
It looks like as if the menu tries to include itself as a submenu. Am I right? I have no ideas what led to this. If I'm not mistaken this has started since macOS Tahoe.
The code that is not a boilerplate one I have:
// Document.m
#import "Document.h"
@implementation Document
@synthesize text;
- (NSString *)windowNibName {
return @"SampleDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController {
[super windowControllerDidLoadNib:aController];
if (self.text == nil) {
self.text = @"";
}
self.textField.stringValue = self.text;
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
self.text = self.textField.stringValue;
return [self.text dataUsingEncoding:NSUTF8StringEncoding];
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
if ([data length] > 0) {
NSString * string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
self.text = string;
}
else {
self.text = @"";
}
return YES;
}
+ (BOOL)autosavesInPlace {
return YES;
}
@end
There are two xib's: MainMenu.xib and Document.xib but I won't include them here.
Please advise how to fix this menu issue.
Try this simple code:
import SwiftUI
import StoreKit
struct ReviewView: View {
@Environment(\.requestReview) var requestReview
var body: some View {
Button("Leave a review") {
requestReview()
}
}
}
When the Review Alert shows, the "Not Now" button is disabled for some reason!? It was always tappable in all iOS versions that I remember. And there is no way to opt out, unless the user taps on the stars first. Is it a bug or a feature?
Thanks for looking into it!
A MacOS SwiftUI app using WindowGroup with a NavigationStack results in having the navigation title overlay the back button. Note that this does not occur if a tabbed interface is used.
The work around is simply to hide the navigation bar back button and add a tool bar item that is custom back button. I found a fix on this forum, and it was similar to:
#if os(macOS)
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigation) {
Button(action: { dismiss() }) {
Label("Back", systemImage: "arrow.left.circle")
}
}
}
#endif
modifying the NavigationLink targets and where the dismiss() function was provided by:
@Environment(\.dismiss) private var dismiss
Is there any means to sign up for a notification to inform me that this bug has been fixed?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello Apple Team,
I’ve encountered a regression in iOS 26.1 when building my app with Xcode 26 (iOS 26 SDK).
The issue affects PKPaymentButtonType.plain, which now renders as fully invisible and produces transparent snapshots, even though the same code worked correctly in previous Xcode/iOS versions.
This has a real-world impact because many apps generate static images from PKPaymentButton for payment selection UIs using UIGraphicsImageRenderer, layer.render(in:), or custom snapshot utilities.
When using
PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
on iOS 26.1, when built with Xcode 26, the button:
Appears blank / invisible
Cannot be snapshotted
Produces a fully transparent UIImage, even though the CGImage object exists
Behaves differently than older SDKs (Xcode 16.x / iOS < 26.1
This regression only appears when compiling with the new SDK.
Other button types work fine.
Expected Behavior
.plain button should render glyphs as documented
snapshot generated via UIGraphicsImageRenderer or drawHierarchy(in:) should produce a visible image
Behavior should be consistent with older SDKs unless explicitly deprecated in release notes
Expected Behavior
.plain button should render glyphs as documented
Snapshot generated via UIGraphicsImageRenderer or drawHierarchy(in:) should produce a visible image
Behavior should be consistent with older SDKs unless explicitly deprecated in release notes
Actual Behavior
.plain button renders no glyph at all
Snapshot image is fully transparent (alpha = 0), even though size and CGImage metadata are correct
Only happens when built with Xcode 26 SDK
Same build from Xcode 16.x does not reproduce the issue
Steps to Reproduce
Create a minimal sample project in Xcode 26
Add the following code:
let button = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
button.frame = CGRect(x: 0, y: 0, width: 180, height: 48)
let renderer = UIGraphicsImageRenderer(size: button.bounds.size)
let image = renderer.image { _ in
button.drawHierarchy(in: button.bounds, afterScreenUpdates: true)
}
print(image)
Run on iOS 26.1 device or simulator
Observe that:
The button appears visually empty
The generated image is fully transparent
Environment
Xcode: 26.x (iOS 26 SDK)
iOS: 26.1 (iPhone 15 Pro tested)
Device: Real device
Framework: UIKit + PassKit
Button type: .plain ONLY
Other types: .pay/.buy/.checkout = OK