Post

Replies

Boosts

Views

Activity

How to get an anchored action sheet without the popover arrow on iOS 26?
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
3
1
329
4w
How to disable the ability to collapse the SwiftUI Inspector?
I'm using the new SwiftUI Inspector API. Is it possible to disable the ability to collapse the inspector (when dragging the mouse cursor on the ionspector splitter)? Also, as a workaround, when the inspector is collapsed, I didn't find how I could expand the inspector programmatically? import SwiftUI struct SampleContentView: View { @State var inspectorPresented = true var body: some View { NavigationStack() { Text("Main View") .inspector(isPresented: $inspectorPresented, content: { Text("Inspector") .inspectorColumnWidth(200) }) } } }
1
0
887
Jul ’23
How to set the holding priority with NavigationSplitView
My question concerns a macOS SwiftUI app. I would like to have a split view with 2 horizontal panes without sidebar: content on the left and inspector on the right. The inspector should act like the inspector panel on the right side side of the Xcode's window: when the window is resized, the inspector keeps it's current width and the user can resize the inspector using the split divider. Using macOS Monterey SDK, I tried to achieve this with HSplitView but the problem is that the left/right panels are both resized when the window is resized. struct ContentView: View { var body: some View { HSplitView { Rectangle().fill(.red) Rectangle().fill(.yellow) } } } Using Ventura SDK, I just tried the new view NavigationSplitView. I'm using .constant(.doubleColumn) to hide the sidebar but the problem is the same as HSplitView, the left/right panel are both resized when the window is resized. struct ContentView: View { var body: some View { NavigationSplitView(columnVisibility: .constant(.doubleColumn)) { Text("not used") } content: { Rectangle().fill(.red) } detail: { Rectangle().fill(.yellow) } } } When using NSSplitViewController with AppKit, the holdingPriority (https://developer.apple.com/documentation/appkit/nssplitviewitem/1388887-holdingpriority?language=objc) allows to manage this case: The view with the lowest priority is the first to gain additional width if the split view grows or shrinks. Is it possible to achieve this with SwiftUI?
2
1
1.8k
Jun ’22
What are the best practices for managing custom properties with cells configurations?
I'm not sure if I need to store any variable used in updateConfiguration(using:) in the custom key value store of UICellConfigurationState. I'm skeptical because some of these variables do not semantically represent a "state". If I look at the sample WWDC sample code for custom cells configurations, all the variables used in updateConfiguration(using:) method are stored in the custom key value store of UICellConfigurationState. In fact, in this sample code, it's the whole model that it's stored in a state custom key. It seems weird because the base properties of UICellConfigurationState are real "state" properties: like selected, highlighted. In the same way, for the cells provided by UIKit, non state properties are stored in the configuration. For example, UIListContentConfiguration.imageProperties.tintColor, UIListContentConfiguration.imageToTextPadding. For a custom cell, we could imagine to subclass UIListContentConfiguration but it's not possible because it's a struct. Imagine you have a custom UICollectionViewListCell with a custom checkmark view. Associated to this checkmark, you have: checkmarkTintColor: an “appearance” property to set the tint color of the checkmark. checkmarkChecked: a ”state” property associated to the checkmark state. What is the good practice? Storing them the state key value store like this? var checkmarkChecked: Bool = false { 		didSet { 				guard oldValue != checked else { 						return 				} 				setNeedsUpdateConfiguration() 		} } 		 var checkmarkTintColor: UIColor? = nil { 		didSet { 				guard oldValue != checkmarkTintColor else { 						return 				} 				setNeedsUpdateConfiguration() 		} } var configuration: UIListContentConfiguration? { 		didSet { 				guard oldValue != configuration else { 						return 				} 				setNeedsUpdateConfiguration() 		} } override var configurationState: UICellConfigurationState { 		var state = super.configurationState 		state.checkmarkChecked = checkmarkChecked 		state.checkmarkTintColor = checkmarkTintColor 		return state } override func updateConfiguration(using state: UICellConfigurationState) { 		... 		checkmarkImageView.image = state.checked ? UIImage(systemName: "checkmark.circle.fill") : UIImage(systemName: "circle") 		checkmarkImageView.tintColor = checkmarkTintColor }
5
0
5.2k
Dec ’20