{"id":53121,"date":"2026-09-08T16:12:55","date_gmt":"2026-09-08T20:12:55","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=53121"},"modified":"2026-09-08T16:13:48","modified_gmt":"2026-09-08T20:13:48","slug":"swiftui-toolbars","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2026\/09\/08\/swiftui-toolbars\/","title":{"rendered":"SwiftUI Toolbars"},"content":{"rendered":"<p><a href=\"https:\/\/nilcoalescing.com\/blog\/AGuideToMacOSToolbarStylesInSwiftUI\/\">Natalia Panferova<\/a>:<\/p>\n<blockquote cite=\"https:\/\/nilcoalescing.com\/blog\/AGuideToMacOSToolbarStylesInSwiftUI\/\">\n<p>I thought it would be useful to have a single reference for the different ways we can style the toolbar in SwiftUI on macOS 26.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/philz.blog\/adopting-customizable-swiftui-toolbars\/\">Phil Zakharchenko<\/a>:<\/p>\n<blockquote cite=\"https:\/\/philz.blog\/adopting-customizable-swiftui-toolbars\/\">\n<p>The toolbar <code>id<\/code> creates a stable customization domain, and each item <code>id<\/code> gives the framework something stable to persist when the user adds, removes, or reorders controls. This identifiability of toolbar items is a requirement for customization. Under the hood, when SwiftUI inevitably bridges your toolbar contents to <code>NSToolbar<\/code>, these identifiers will be directly translated to the <code>NSToolbarItem<\/code>&rsquo;s <code>itemIdentifier<\/code>s.<\/p>\n<p>As we continue the migration to a customizable toolbar, we are likely to encounter a few surprises related to this model.<\/p>\n<p>[&#8230;]<\/p>\n<p>After a closer inspection, and perhaps a few minutes of digging through the documentation, we come to the bleak realization: <strong>there is no customizable <code>ToolbarItemGroup<\/code> API.<\/strong><\/p>\n<p>[&#8230;]<\/p>\n<p>The regular toolbar model and the customizable toolbar model overlap, but they are not interchangeable. You cannot give a <code>ToolbarItemGroup<\/code> an <code>id<\/code>, and you cannot place one directly inside <code>toolbar(id:content:)<\/code>.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/swiftwithmajid.com\/2026\/06\/23\/taking-control-of-toolbar-items-in-swiftui\/\">Majid Jabrayilov<\/a>:<\/p>\n<blockquote cite=\"https:\/\/swiftwithmajid.com\/2026\/06\/23\/taking-control-of-toolbar-items-in-swiftui\/\">\n<p>Let&rsquo;s take a look at another example. This one is a bit tricky, because on macOS, you will get Action 1 in the top trailing position and the whole group of actions centered in the navigation bar. On iOS, you will get Action 1 pinned to trailing and all other items collapsed.<\/p>\n<p>[&#8230;]<\/p>\n<p>The final addition to the Toolbar API is the <em>toolbarMinimizeBehavior<\/em> view modifier allowing us to minimize toolbars while scrolling up or down. You can minimize tab, bottom, window and navigation bars with it.<\/p>\n<p>With new modifiers SwiftUI gives us a much better balance between system-driven adaptation and explicit control. We can now decide which actions are more important, which items should always stay visible, which groups should intentionally live in the overflow menu, and how toolbars should react to scrolling.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/nilcoalescing.com\/blog\/AdaptiveSwiftUIToolbarsInIOS27\/\">Natalia Panferova<\/a>:<\/p>\n<blockquote cite=\"https:\/\/nilcoalescing.com\/blog\/AdaptiveSwiftUIToolbarsInIOS27\/\">\n<p>iOS 27 includes a few smaller additions that make toolbar content easier to configure.<\/p>\n<p>We can remove the default padding around an item whose content should extend to its edges with <a href=\"https:\/\/developer.apple.com\/documentation\/swiftui\/toolbarcontent\/contentmarginsremoved(_:)\">contentMarginsRemoved(_:)<\/a>[&#8230;]<\/p>\n<p>[&#8230;]<\/p>\n<p>The status bar is now represented by <a href=\"https:\/\/developer.apple.com\/documentation\/swiftui\/toolbarplacement\/statusbar\">ToolbarPlacement.statusBar<\/a>, so its visibility can be controlled through the same toolbar API as other bars[&#8230;]<\/p>\n<p>[&#8230;]<\/p>\n<p>ForEach now conforms to ToolbarContent, which means we can generate toolbar items directly from a collection[&#8230;]<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/tanaschita.com\/swiftui-toolbar-visibility-overflow\/\">Natascha Fadeeva<\/a>:<\/p>\n<blockquote cite=\"https:\/\/tanaschita.com\/swiftui-toolbar-visibility-overflow\/\">\n<p>Together, the toolbar APIs let us express the importance of each action while SwiftUI continues to handle the toolbar&rsquo;s layout across different sizes.<\/p>\n<\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/09\/08\/nstoolbar-in-golden-gate\/\">NSToolbar in Golden Gate<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/06\/19\/swiftui-in-appleos-27\/\">SwiftUI in appleOS 27<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/06\/09\/golden-gate-window-corners\/\">Golden Gate Window Corners<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/06\/09\/golden-gate-sidebars-and-toolbars\/\">Golden Gate Sidebars and Toolbars<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/06\/04\/where-did-swiftui-leave-you-hanging\/\">Where Did SwiftUI Leave You Hanging?<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/10\/16\/liquid-glass-content-vs-controls\/\">Liquid Glass: Content vs. Controls<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Natalia Panferova: I thought it would be useful to have a single reference for the different ways we can style the toolbar in SwiftUI on macOS 26. Phil Zakharchenko: The toolbar id creates a stable customization domain, and each item id gives the framework something stable to persist when the user adds, removes, or reorders [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2026-09-08T20:12:59Z","apple_news_api_id":"e50eca63-69aa-4f93-a599-e06f78216e87","apple_news_api_modified_at":"2026-09-08T20:13:51Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAQ==","apple_news_api_share_url":"https:\/\/apple.news\/A5Q7KY2mqT5OlmeBveCFuhw","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[31,2887,30,2784,71,901,1812],"class_list":["post-53121","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-ios","tag-ios-27","tag-mac","tag-macos-27","tag-programming","tag-swift-programming-language","tag-swiftui"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/53121","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=53121"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/53121\/revisions"}],"predecessor-version":[{"id":53126,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/53121\/revisions\/53126"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=53121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=53121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=53121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}