Duncan Groenewald
Duncan Groenewald

Reputation: 9008

How does one use SwiftUI's ToolbarItemGroup?

I clear don't understand the meaning of the definition syntax for SwiftUI because I can't figure out how one would use ToolbarItemGroup.

I can define a toolbar with toolbar items like this:

.toolbar {
            
            ToolbarItem {
                Button("200%", action: zoom200).foregroundColor(controller.scale == 2.0 ? selectedButtonColor : defaultButtonColor)
            }
            ToolbarItem {
                Button("100%", action: zoom100).foregroundColor(controller.scale == 1.0 ? selectedButtonColor : defaultButtonColor)
            }
}

But have been unable to get ToolbarItemGroup to work. Logically I would have expected something like this:

.toolbar {
   ToolbarItemGroup {
            
         ToolbarItem {
                Button("200%", action: zoom200).foregroundColor(controller.scale == 2.0 ? selectedButtonColor : defaultButtonColor)
            }
         ToolbarItem {
                Button("100%", action: zoom100).foregroundColor(controller.scale == 1.0 ? selectedButtonColor : defaultButtonColor)
            }
   }
   ToolbarItemGroup {
         ToolbarItem {
                Button("Open", action: open)
            }
         ToolbarItem {
                Button("Close", action: close)
            }
   }
}

Upvotes: 18

Views: 18011

Answers (2)

Asperi
Asperi

Reputation: 258345

The ToolbarItemGroup is output entity, not input - as it is clear from the following toolbar builders:

/// Populates the toolbar or navigation bar with the specified items.
///
/// - Parameter items: The items representing the content of the toolbar.
public func toolbar<Items>(@ToolbarContentBuilder<Void> items: () -> ToolbarItemGroup<Void, Items>) -> some View


/// Populates the toolbar or navigation bar with the specified items,
/// allowing for user customization.
///
/// - Parameters:
///   - id: A unique identifier for this toolbar.
///   - items: The items representing the content of the toolbar.
public func toolbar<Items>(id: String, @ToolbarContentBuilder<String> items: () -> ToolbarItemGroup<String, Items>) -> some View

Thus groups are generated automatically by .toolbar based on toolbar items placement (in predefined order).

Here is example (tested with Xcode 12b / iOS 14)

demo

.toolbar {
    ToolbarItem(placement: .primaryAction) {
        Button(action: {}) { Image(systemName: "book") }
    }
    ToolbarItem(placement: .primaryAction) {
        Button(action: {}) { Image(systemName: "gear") }
    }
    ToolbarItem(placement: .principal) {
        Button(action: {}) { Image(systemName: "car") }
    }
    ToolbarItem(placement: .principal) {
        Button(action: {}) { Image(systemName: "gear") }
    }
    ToolbarItem(placement: .bottomBar) {
        Button(action: {}) { Image(systemName: "1.square") }
    }
    ToolbarItem(placement: .bottomBar) {
        Button(action: {}) { Image(systemName: "2.square") }
    }
}

Upvotes: 14

user652038
user652038

Reputation:

ToolbarItemGroup is designed to group views in the same toolbar. It removes the need for explicit usage of ToolbarItem, as both conform to ToolbarContent.

e.g.

.toolbar {
  ToolbarItemGroup {
    Button("200%",  action: zoom200)
      .foregroundColor(controller.scale == 2.0 ? selectedButtonColor : defaultButtonColor)
    Button("100%", action: zoom100)
      .foregroundColor(controller.scale == 1.0 ? selectedButtonColor : defaultButtonColor)
  }
  ToolbarItemGroup(placement: .bottomBar) {
    Spacer()
    Button("Open", action: open)
    Spacer()
    Button("Close", action: close)
    Spacer()
  }
}

It's also the only way I know of to get Spacers to work, between toolbar items.

Upvotes: 32

Related Questions