I have written this function:
@available(macOS 26.0, *)
func instancing() async -> Entity {
let entity = Entity()
do {
// 1. Create a CustomMaterial
let library = offscreenRenderer.pointRenderer!.device.makeDefaultLibrary()!
let surfaceShader = CustomMaterial.SurfaceShader(
named: "surfaceShaderWithCustomUniforms", // This must match the function name in Metal
in: library
)
let instanceCount = 10
// No idea how to actually use this...
// let bufferSize = instanceCount * MemoryLayout<UInt32>.stride
//
// // Create the descriptor
// var descriptor = LowLevelBuffer.Descriptor(capacity: bufferSize, sizeMultiple: MemoryLayout<UInt32>.stride)
//
// // Initialize the buffer
// let lowLevelBuffer = try LowLevelBuffer(descriptor: descriptor)
// lowLevelBuffer.withUnsafeMutableBytes { rawBytes in
// // Bind the raw memory to the UInt32 type
// let pointer = rawBytes.bindMemory(to: UInt32.self)
// pointer[1] = 0xff_0000
// pointer[0] = 0x00_ff00
// pointer[2] = 0x00_00ff
// pointer[3] = 0xff_ff00
// pointer[4] = 0xff_00ff
// pointer[5] = 0x00_ffff
// pointer[6] = 0xff_ffff
// pointer[7] = 0x7f_0000
// pointer[8] = 0x00_7f00
// pointer[9] = 0x00_007f
// }
var material = try CustomMaterial(surfaceShader: surfaceShader, lightingModel: .lit)
material.withMutableUniforms(ofType: SurfaceCustomUniforms.self, stage: .surfaceShader) { params, resources in
params.argb = 0xff_0000
}
// 2. Create the ModelComponent (provides the MESH and MATERIAL)
let mesh = MeshResource.generateSphere(radius: 0.5)
let modelComponent = ModelComponent(mesh: mesh, materials: [material])
// 3. Create the MeshInstancesComponent (provides the INSTANCE TRANSFORMS)
let instanceData = try LowLevelInstanceData(instanceCount: instanceCount)
instanceData.withMutableTransforms { transforms in
for i in 0..<instanceCount {
let instanceAngle = 2 * .pi * Float(i) / Float(instanceCount)
let radialTranslation: SIMD3<Float> = [-sin(instanceAngle), cos(instanceAngle), 0] * 4
// Position each sphere around a circle.
let transform = Transform(
scale: .one,
rotation: simd_quatf(angle: instanceAngle, axis: [0, 0, 1]),
translation: radialTranslation
)
transforms[i] = transform.matrix
}
}
let instancesComponent = try MeshInstancesComponent(mesh: mesh, instances: instanceData)
// 4. Attach BOTH to the same entity
entity.components.set(modelComponent)
entity.components.set(instancesComponent)
} catch {
print("Failed to create mesh instances: \(error)")
}
return entity
}
and this is the corresponding Metal shader
typedef struct {
uint32_t argb;
} SurfaceCustomUniforms;
[[stitchable]]
void surfaceShaderWithCustomUniforms(realitykit::surface_parameters params,
constant SurfaceCustomUniforms &customParams)
{
half3 color = {
static_cast<half>((customParams.argb >> 16) & 0xff),
static_cast<half>((customParams.argb >> 8) & 0xff),
static_cast<half>(customParams.argb & 0xff) };
params.surface().set_base_color(color);
}
which works well and generates 10 red spheres. While listening to the WWDC25 presentation on what's new in RealityKit I am positive to hear the presenter saying that it is possible to customise each instance using a LowLevelBuffer, but so far all my attempts have failed.
Is it possible, and if so how ?
Thanks for reading and for your help.
Kind regards,
Christian
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
[Also submitted as FB20636175]
In iOS 26.1 Seed 2 (23B5059e), ToolbarItem menus with .bottomBar placement cause the toolbar item to disappear and rebuild after the menu is dismissed, instead of smoothly morphing back. The bottom toolbar can take 1–2 seconds to reappear.
This also seems to coincide with this console error:
Adding 'UIKitToolbar' as a subview of UIHostingController.view is not supported and may result in a broken view hierarchy. Add your view above UIHostingController.view in a common superview or insert it into your SwiftUI content in a UIViewRepresentable instead.
This occurs both on device and in a simulator.
Sample Project
This sample ContentView includes two menu buttons—one in the bottom bar and one in the top bar. Dismissing the bottom bar menu causes a short delay before the button reappears, while the top bar menu behaves normally.
struct ContentView: View {
var body: some View {
NavigationStack {
Text("Tap and dismiss both menu buttons and note the difference.")
.navigationTitle("BottomBar Menu Issue")
.navigationSubtitle("Reproduces on iOS 26.1 Seed 2 (23B5059e)")
.toolbar {
// Control: top bar trailing menu animates back smoothly
ToolbarItem(placement: .topBarTrailing) {
Menu {
Button("Dismiss", role: .cancel) { }
Button("Do Nothing") { }
} label: {
Label("More", systemImage: "ellipsis.circle")
.font(.title3)
}
}
// Repro: delay before menu button reappears after menu dismissal
ToolbarItem(placement: .bottomBar) {
Menu {
Button("Dismiss", role: .cancel) { }
Button("Do Nothing") { }
} label: {
Label("Actions", systemImage: "ellipsis.circle")
.font(.title2)
}
}
}
}
}
}
Passwords App
This can also be seen in iOS 26.1 Seed 2 (23B5059e)'s Passwords app ("All" or "Passcodes" views):
I have an NSWindowController with several IBOutlets created in storyboard.
I want to add an NSView and fill it with some color. I need to place it at a specific position in views hierarchy.
I have tried 2 ways, no one succeeds.
First.
include a custom view in storyboard
connect to an IBOutlet
in an init of controller, set the layer for the view
Result: crash
Second
build programmatically
Result: I do not find where to put this code in the controller code
That's basic Cocoa, but way more painful than iOS.
We have crash reports as shown below that we haven't yet been able to repro and could use some help deubgging.
My guess is that the app is giving a label or text view an attributed string with an invalid attribute range, but attributed strings are used in many places throughout the app, and I don't know an efficient way to track this down.
I'm posting the stack trace here in hopes that someone more familiar with the internals of the system frameworks mentioned will be able to provide a clue to help narrow where I should look.
Fatal Exception: NSRangeException
NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds
0 CoreFoundation 0x2d5fc __exceptionPreprocess
1 libobjc.A.dylib 0x31244 objc_exception_throw
2 Foundation 0x47130 blockForLocation
3 UIFoundation 0x2589c -[NSTextLineFragment _defaultRenderingAttributesAtCharacterIndex:effectiveRange:]
4 UIFoundation 0x25778 __53-[NSTextLineFragment initWithAttributedString:range:]_block_invoke
5 CoreText 0x58964 TLine::DrawGlyphsWithAttributeOverrides(TLineDrawContext const&, __CFDictionary const* (long, CFRange*) block_pointer, TDecoratorObserver*) const
6 CoreText 0x58400 CTLineDrawWithAttributeOverrides
7 UIFoundation 0x25320 _NSCoreTypesetterRenderLine
8 UIFoundation 0x24b10 -[NSTextLineFragment drawAtPoint:graphicsContext:]
9 UIFoundation 0x3e634 -[NSTextLineFragment drawAtPoint:inContext:]
10 UIFoundation 0x3e450 -[NSTextLayoutFragment drawAtPoint:inContext:]
11 UIKitCore 0x3e3098 __38-[_UITextLayoutFragmentView drawRect:]_block_invoke
12 UIKitCore 0x3e31cc _UITextCanvasDrawWithFadedEdgesInContext
13 UIKitCore 0x3e3040 -[_UITextLayoutFragmentView drawRect:]
14 UIKitCore 0xd7a98 -[UIView(CALayerDelegate) drawLayer:inContext:]
15 QuartzCore 0x109340 CABackingStoreUpdate_
16 QuartzCore 0x109224 invocation function for block in CA::Layer::display_()
17 QuartzCore 0x917f0 -[CALayer _display]
18 QuartzCore 0x90130 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
19 QuartzCore 0xe50c4 CA::Context::commit_transaction(CA::Transaction*, double, double*)
20 QuartzCore 0x5bd8c CA::Transaction::commit()
21 UIKitCore 0x9f3f0 _UIApplicationFlushCATransaction
22 UIKitCore 0x9c89c __setupUpdateSequence_block_invoke_2
23 UIKitCore 0x9c710 _UIUpdateSequenceRun
24 UIKitCore 0x9f040 schedulerStepScheduledMainSection
25 UIKitCore 0x9cc5c runloopSourceCallback
26 CoreFoundation 0x73f4c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
27 CoreFoundation 0x73ee0 __CFRunLoopDoSource0
28 CoreFoundation 0x76b40 __CFRunLoopDoSources0
29 CoreFoundation 0x75d3c __CFRunLoopRun
30 CoreFoundation 0xc8284 CFRunLoopRunSpecific
31 GraphicsServices 0x14c0 GSEventRunModal
32 UIKitCore 0x3ee674 -[UIApplication _run]
33 UIKitCore 0x14e88 UIApplicationMain
also filed as FB16905066
OS 26.s, Xcode 26.2
TLDR: My pure SwiftUI app freezes the window server, is this a known problem?
My app is pure SwiftUI, no low level calls, no networking, no tricksy pointer use. Somehow, something in my code is terminally confusing the Window Server. As in, I run the app, and before I ever seen a window, the Window Server locks up, and is killed by the OS for being unresponsive.
Using debugging shows that I get to the end of a Canvas, and it simply freezes upon exiting.
I'm about to do the old comment out everything, and bring it back a bit at a time, but I'm wondering if anyone is experiencing this sort of thing? The reaction is so extreme.
And it's not Xcode in particular, I built the program with xcodebuild, Xcode itself not running, and ran my app, and it did the same thing.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Memory leak in CarPlay when using CPTabBarTemplate
Reproduced using the code example "Integrating CarPlay with Your Music App" from the official Apple documentation - https://developer.apple.com/documentation/carplay/integrating-carplay-with-your-music-app
Steps to reproduce the leak:
Download and run the example on CarPlay.
Select the Settings tab.
Click the first item in the list "Use Apple Music".
Click Back button.
Repeat steps 3 and 4 several times.
Open Debug Memory Graph in xCode and search for "CPGridTemplate" - the count will be greater than 0.
Conditions under which the memory leak disappears:
If you open and switch to all tabs one by one, the leak disappears.
Our use case requires short looping videos on the app’s front screen. These videos include subtitles for accessibility, so they are delivered as HLS (m3u8) rather than MP4, allowing subtitles to be natively rendered instead of burned into the video.
Since moving from MP4 to HLS, we’ve observed that video time segments (.ts / .m4s) are not fully cached between loops. When the video reaches the end and restarts, the same time segments are re-requested from the network instead of being served from cache.
This behavior occurs even though:
The playlist and segments are identical between loops
The content is short and fully downloaded during the first playback
No explicit cache-busting headers are present
We have investigated available caching options in AVFoundation but have not found a way to persistently cache HLS segments for looping playback without implementing a full offline download using AVAssetDownloadURLSession, which feels disproportionate for this use case.
Using Proxyman, I can clearly see repeated network requests for the same HLS time segments on every loop, resulting in unnecessary network usage and reduced efficiency.
I would like to understand:
Whether this is expected behavior for HLS playback?
Whether there is a supported way to cache HLS segments across loops?
Or whether there is a recommended alternative approach for looping accessible video with subtitles without re-requesting time segments?
Hi all,
When navigating between two screens where the first uses .inline and the second .large title display mode, the NavigationBar shows visible resizing glitches during the push animation.
This is especially noticeable when using a custom background color (e.g. yellow) via UINavigationBarAppearance or .toolbarBackground(Color.yellow, for: .navigationBar).
I’m already using the same appearance for standard, scrollEdge, and compact, with configureWithOpaqueBackground(), but the issue remains.
Is this a known UIKit or SwiftUI issue?
Any recommended workaround?
Thanks.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Overview
In iOS 26, a List embedded in a NavigationStack inside a TabView exhibits a visual glitch when switching tabs.
When the list is scrolled such that some rows are partially obscured by the navigation bar, the system correctly applies a fade/opacity effect to those rows. However, if the user switches to another tab while rows are in this partially obscured (faded) state, those rows briefly flash at full opacity during the tab transition before disappearing.
This flash is visually distracting and appears to be inconsistent with the intended scroll-edge opacity behavior.
The issue occurs only for rows partially obscured by the navigation bar.
Rows partially obscured by the tab bar do not exhibit this flashing behavior.
Steps to Reproduce:
Run the attached minimal reproduction on iOS 26.
Open the first tab.
Scroll the list so that some rows are partially hidden behind the navigation bar (showing the native faded appearance).
While rows are in this partially faded state, switch to the second tab.
Observe that the faded rows briefly render fully opaque during the tab switch.
Expected Behavior:
Rows that are partially obscured by the navigation bar should maintain consistent opacity behavior during tab transitions, without flashing to full opacity.
import SwiftUI
@main
struct NavBarReproApp: App {
/// Minimal repro for iOS 26:
/// - TabView with two tabs
/// - First tab: NavigationStack + List
/// - Scroll so some rows are partially behind the nav bar (faded)
/// - Switch tabs: those partially-faded rows briefly flash fully opaque. Partially faded rows under the tab bar do not flash
private let items = Array(0..<200).map { "Row \($0)" }
var body: some Scene {
WindowGroup {
TabView {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
}
.navigationTitle("One")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("One", systemImage: "1.circle") }
NavigationStack {
Text("Second tab")
.navigationTitle("Two")
.navigationBarTitleDisplayMode(.inline)
}
.tabItem { Label("Two", systemImage: "2.circle") }
}
}
}
}
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 have TabView in ContentView and I want to add TabView for OnboardingView in OtherView, every things work, but it is throw error for TabView in OtherView like "Trailing closure passed to parameter of type 'Int' that does not accept a closure" I do not know why? Any idea?
ContentView:
struct TabView : View {
var body: some View{
VStack(spacing: 0){
.......
}
OtherView:
VStack {
TabView {
ForEach(onboardingData) { onboardingItem in
OnboardingCard(onboardingItem: onboardingItem)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
.indexViewStyle(PageIndexViewStyle (backgroundDisplayMode:
.always))
.foregroundColor(.white)
}
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?
That's a question for Mac app (Cocoa).
I want to change the standard highlighting.
I thought to use tableView.selectionHighlightStyle.
But there are only 2 values: .none and .regular. Cannot find how to define a custom one.
So I tried a workaround:
set tableView.selectionHighlightStyle to .none
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
tableView.selectionHighlightStyle = .none
keep track of previousSelection
Then, in tableViewSelectionDidChange
reset for previousSelection
func tableViewSelectionDidChange(_ notification: Notification) { }
if previousSelection >= 0 {
let cellView = theTableView.rowView(atRow: previousSelection, makeIfNecessary: false)
cellView?.layer?.backgroundColor = .clear
}
set for the selection to a custom color
let cellView = theTableView.rowView(atRow: row, makeIfNecessary: false)
cellView?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 1, alpha: 0.4)
previousSelection = row
Result is disappointing :
Even though tableView.selectionHighlightStyle is set to .none, it does overlays the cellView?.layer
Is there a way to directly change the color for selection ?
When a Menu is placed inside a ToolbarItem, applying
buttonStyle(.glassProminent) has no visible effect.
The same modifier works correctly when a Button is used instead of a Menu inside the ToolbarItem. In that case, the button is rendered with the accent-colored background as expected.
This suggests that Menu does not respect the .glassProminent button style when embedded in a ToolbarItem, even though other button types do.
Code Example
// Button with accent background color
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: {})
.buttonStyle(.glassProminent)
}
}
// Menu with internal button with no accent background color
.toolbar {
ToolbarItem(placement: .primaryAction) {
Menu(...) {
...
}.buttonStyle(.glassProminent)
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
In SwiftUI, it is recommended not to store ViewBuilder closures in sub-views but instead evaluate them directly in init and store the result (example: https://www.youtube.com/watch?v=yXAQTIKR8fk). That has the advantage, as I understand it, that the closure doesn't need to be re-evaluated on every layout pass.
On the other side, identity is a very important topic in SwiftUI to get the UI working properly.
Now I have this generic view I'm using with a closure which is displayed in two places (HStack & VStack). Should I store the closure result and get the performance improvements, or evaluate it in place and get correct identities (if that is even an issue)?
Simplified example:
struct DynamicStack<Content: View>: View {
@ViewBuilder var content: () -> Content
var body: some View {
ViewThatFits(in: .horizontal) {
HStack {
content()
}
VStack {
content()
}
}
}
}
vs
struct DynamicStack<Content: View>: View {
@ViewBuilder var content: Content
var body: some View {
ViewThatFits(in: .horizontal) {
HStack {
content
}
VStack {
content
}
}
}
}
I found an issue related to Gmail and Email apps. When I try to fetch text using
controller.textDocumentProxy.documentContext, it works fine every time in my original app and in the Messages app. However, in Gmail or Email apps, after pasting text, controller.textDocumentProxy.documentContext returns nil until the pasted text is edited. The same scenario works correctly in Messages and my original app. i'm trying it from my keyboard extension and my keyboard builded bases on KeyboardKit SDK when i jump to text Document Proxy it's referring me to UITextDocumentProxy
Topic:
UI Frameworks
SubTopic:
UIKit
Our project include UIKIt and SwiftUI, and in some case, we need to traverse all subviews, for UIKit implement views, below code:
func findView(byIdentifier identifier: String) -> UIView? {
if self.accessibilityIdentifier == identifier {
return self
}
for subview in subviews {
if let found = subview.findView(byIdentifier: identifier) {
return found
}
}
return nil
}
works well, but for SwiftUI implement views, like below code:
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
.accessibilityIdentifier("Image")
Text("Hello, world!")
.accessibilityIdentifier("Text")
}
.padding()
}
}
it can not find subviews in the ContentView, and only a view with type:
_UIHostingView<ModifiedContent<AnyView, RootModifier>>
can be found, the Image and Text is not found;
And because we have set a accessibilityIdentifier property, so we also try use:
@MainActor
var accessibilityElements: [Any]? { get set }
to find sub node, but this accessibilityElements is not stable, we can find the Image and Text node in iOS26.1 system:
[AX] level=3 AccessibilityNode @ 0x000000010280fb10 id=Image
[AX] level=3 AccessibilityNode @ 0x000000010161fbf0 id=Text
but can not find it in iOS26.0 and below system.
Any suggestion in how to find SwiftUI subviews? thank you
Topic:
UI Frameworks
SubTopic:
SwiftUI
Scenario
A SwiftUI view has an overlay with alignment: .top, the content uses .alignmentGuide(.top) {} to adjust the placement.
Issue
When the content of the overlay is in an if-block, the alignment guide is not adjusted.
Example code
The example shows 2 views.
Not working example, where the content is an if-block.
Working example, where the content is not in an if-block
Screenshot: https://github.com/simonnickel/FB15248296-SwiftUIAlignmentGuideInOverlayConditional/blob/main/screenshot.png
Tested on
- Xcode Version 16.0 RC (16A242) on iOS 18.0
Code
// Not working
.overlay(alignment: .top) {
if true { // This line causes .alignmentGuide() to fail
Text("Test")
.alignmentGuide(.top, computeValue: { dimension in
dimension[.bottom]
})
}
}
// Working
.overlay(alignment: .top) {
Text("Test")
.alignmentGuide(.top, computeValue: { dimension in
dimension[.bottom]
})
}
Also created a Feedback: FB15248296
Example Project is here: https://github.com/simonnickel/FB15248296-SwiftUIAlignmentGuideInOverlayConditional/tree/main
Hey there guys, I'm new on SwiftUI and iOS Development world.
How can I achieve a seamless TabBar transition in SwiftUI? Currently, when I programmatically hide the TabBar on a pushed view and swipe back to the previous view, there is a noticeable delay before the TabBar reappears. How can I make it appear instantly?
Here is the link to the video https://streamable.com/3zz2o2
Thank you in advance
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am new to swiftui and have a very small project I am working on to practice passing data between views. I have this error on a form "Trailing closure passed to parameter of type 'FormStyleConfiguration' that does not accept a closure"
If I comment the first section in the form then I get three errors in the ForEach. If anyone can help explain what is going on and what steps I could take to determine where the problem is coming from I would appreciate the help.
This is the model I created:
import Observation
import SwiftUI
@Model
final class Client {
var id = UUID()
var name: String
var location: String
var selectedJob: Person
init(id: UUID = UUID(), name: String, location: String, selectedJob: Person) {
self.id = id
self.name = name
self.location = location
self.selectedJob = selectedJob
}
}
extension Client {
enum Person: String, CaseIterable, Codable {
case homeOwner = "Home Owner"
case contractor = "Contractor"
case designer = "Designer"
}
}
@Model
class Enclosure {
var id = UUID()
var room: String = ""
var unitType: String = ""
init(id: UUID = UUID(), room: String, unitType: String) {
self.id = id
self.room = room
self.unitType = unitType
}
}
This is the detail view where the error is happening:
import SwiftData
import SwiftUI
struct DetailView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Query(sort: \Enclosure.room, order: .forward, animation: .default) private var enclosures: [Enclosure]
@State private var showingAddEnclosure = false
@State private var showingAddMirror = false
@State private var name: String = ""
@State private var location: String = ""
@State private var selectedJob = Client.Person.homeOwner
@State var clients: Client
var body: some View {
NavigationStack {
Form {
Section("Details") {
TextField("Full Name", text: Client.$name)
TextField("Location", text: Client.location)
Picker("Job Type", selection: $selectedJob) {
ForEach(Client.Person.allCases, id: \.self) { selected in
Text(selected.rawValue).tag(selected)
}
}
}
Section("Enclosures") {
List {
ForEach($clients.enclosures) { enclosure in
NavigationLink(destination: EnclosureDetailView()) {
VStack {
Text(enclosure.room)
Text(enclosure.unitType)
}
}
.swipeActions {
Button("Delete", role: .destructive) {
modelContext.delete(enclosure)
}
}
}
}
}
}
.navigationTitle("Project Details")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Menu {
Button {
showingAddEnclosure.toggle()
} label: {
Text("Add Enclosure")
}
Button {
showingAddMirror.toggle()
} label: {
Text("Add Mirror")
}
} label: {
Label("Add", systemImage: "ellipsis.circle")
}
}
}
.sheet(isPresented: $showingAddEnclosure) {
EnclosureView()
}
.sheet(isPresented: $showingAddMirror) {
EnclosureView()
}
}
}
}