Duplicate bar buttons appear when .toolbar is applied to a Group View

Is it normal behaviour that when I apply a .toolbar to a Group that I see duplicate buttons equal to the number of Views in the Group? e.g.

Group {
    Text("1")
    Text("2")
    Text("3")
}
.toolbar {
    Button("Hi") {
    }
}

Results in 3 toolbar buttons appearing in the UI, like in this screenshot:

If not, then I'll submit feedback about this bug but thought I'd ask first.

Xcode Version 16.0 beta 6 (16A5230g) iPhone 15 Pro Simulator

Answered by darkpaw in 801959022

I think that's expected behaviour. As you've said, it applies the modifier to each item in the Group.

With .onAppear it wouldn't make sense to do the same thing three times. All three Text views appeared, why would you want to call a method three times, or change a variable three times?

For .toolbar you're adding three Buttons, and I would say that's what you would want to happen, no? Three buttons with the same format, style, etc.

Additional info (unable to edit my initial post anymore):

I know Group is designed to apply the modifier to each item in the group however that isn't the case for .onAppear or .onChange and it seems a bit odd for me for this to happen with .toolbar because it seems like it should only be applicable to style modifiers, e.g. .font etc.

I think that's expected behaviour. As you've said, it applies the modifier to each item in the Group.

With .onAppear it wouldn't make sense to do the same thing three times. All three Text views appeared, why would you want to call a method three times, or change a variable three times?

For .toolbar you're adding three Buttons, and I would say that's what you would want to happen, no? Three buttons with the same format, style, etc.

I'm beginning to think this is a bug because when adding ids the unexpected behaviour causes a crash:

Group {
    Text("1")
    Text("2")
    Text("3")
}
.toolbar(id: "myToolbar") {
    ToolbarItem(id: "myItem", placement: .primaryAction) {
        Button("Hi") {
        }
    }
}

Crash log

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'index out of bounds for arranged subview: index = 3 expected to be less than or equal to 2'
*** First throw call stack:
(
	0   CoreFoundation                      0x00000001804b70ec __exceptionPreprocess + 172
	1   libobjc.A.dylib                     0x000000018008ede8 objc_exception_throw + 72
	2   CoreFoundation                      0x00000001804b6ffc -[NSException initWithCoder:] + 0
	3   UIKitCore                           0x0000000185f1da54 -[UIStackView insertArrangedSubview:atIndex:] + 144
	4   UIKitCore                           0x0000000184fa94c4 -[_UIButtonBar _layoutBar] + 2444
	5   UIKitCore                           0x0000000184fabb14 __42-[_UIButtonBarStackView updateConstraints]_block_invoke + 40
	6   UIKitCore                           0x000000018600b380 +[UIView(Animation) performWithoutAnimation:] + 68
	7   UIKitCore                           0x0000000184fabac0 -[_UIButtonBarStackView updateConstraints] + 84
	8   UIKitCore                           0x0000000185f3508c -[UIView(AdditionalLayoutSupport) _sendUpdateConstraintsIfNecessaryForSecondPass:] + 316
	9   UIKitCore                           0x0000000185f354e0 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 760
	10  UIKitCore                           0x0000000185f353fc -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 532
	11  CoreAutoLayout                      0x00000001daa63668 -[NSISEngine withBehaviors:performModifications:] + 76
	12  UIKitCore                           0x0000000185f35aec __100-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:]_block_invoke + 92
	13  UIKitCore                           0x0000000185f34728 -[UIView(AdditionalLayoutSupport) _withUnsatisfiableConstraintsLoggingSuspendedIfEngineDelegateExists:] + 104
	14  UIKitCore                           0x0000000185f35778 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:] + 144
	15  UIKitCore                           0x000000018501b2a4 -[_UINavigationBarContentViewLayout layoutSubviews] + 156
	16  UIKitCore                           0x000000018500fb48 -[_UINavigationBarContentView layoutSubviews] + 148
	17  UIKitCore                           0x0000000186016438 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2404
	18  QuartzCore                          0x000000018b059eb0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 432
	19  UIKitCore                           0x000000018600583c -[UIView(Hierarchy) layoutBelowIfNeeded] + 308
	20  UIKitCore                           0x0000000185284068 -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] + 584
	21  UIKitCore                           0x000000018528423c -[UINavigationController _positionNavigationBarHidden:edge:] + 292
	22  UIKitCore                           0x0000000185293d7c -[UINavigationController __viewWillLayoutSubviews] + 128
	23  UIKitCore                           0x000000018527bb00 -[UILayoutContainerView layoutSubviews] + 168
	24  UIKitCore                           0x0000000186016438 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2404
	25  QuartzCore                          0x000000018b059eb0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 432
	26  QuartzCore                          0x000000018b064c34 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 124
	27  QuartzCore                          0x000000018af99c58 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 464
	28  QuartzCore                          0x000000018afc8468 _ZN2CA11Transaction6commitEv + 652
	29  UIKitCore                           0x0000000185ab8260 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 32
	30  CoreFoundation                      0x000000018041b0ec __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20
	31  CoreFoundation                      0x000000018041a824 __CFRunLoopDoBlocks + 352
	32  CoreFoundation                      0x00000001804150c8 __CFRunLoopRun + 812
	33  CoreFoundation                      0x0000000180414960 CFRunLoopRunSpecific + 536
	34  GraphicsServices                    0x000000019016fb10 GSEventRunModal + 160
	35  UIKitCore                           0x0000000185a9f650 -[UIApplication _run] + 796
	36  UIKitCore                           0x0000000185aa3848 UIApplicationMain + 124
	37  SwiftUI                             0x00000001d1cedae4 $s7SwiftUI17KitRendererCommon33_ACC2C5639A7D76F611E170E831FCA491LLys5NeverOyXlXpFAESpySpys4Int8VGSgGXEfU_ + 164
	38  SwiftUI                             0x00000001d1ced80c $s7SwiftUI6runAppys5NeverOxAA0D0RzlF + 84
	39  SwiftUI                             0x00000001d1a2fe1c $s7SwiftUI3AppPAAE4mainyyFZ + 148
	40  Test.debug.dylib                    0x0000000102f20fac $s4Test0A3AppV5$mainyyFZ + 40
	41  Test.debug.dylib                    0x0000000102f21294 __debug_main_executable_dylib_entry_point + 12
	42  dyld                                0x0000000100259410 start_sim + 20
	43  ???                                 0x0000000100426154 0x0 + 4299317588
	44  ???                                 0xe735800000000000 0x0 + 16660363134015373312
)
libc++abi: terminating due to uncaught exception of type NSException

Submitted feedback on this crash and linked to this forum. FB15011577

Duplicate bar buttons appear when .toolbar is applied to a Group View
 
 
Q