Skip to content

Commit 160740c

Browse files
committed
Workaround geometry reading by PreferenceKey observing
1 parent 82c7879 commit 160740c

File tree

1 file changed

+120
-101
lines changed

1 file changed

+120
-101
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Creation/OrderForm.swift

Lines changed: 120 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ struct OrderForm: View {
222222

223223
@State private var shouldShowGiftCardForm = false
224224

225+
@State private var bannerWidth: CGFloat = 0
226+
225227
@Environment(\.adaptiveModalContainerPresentationStyle) var presentationStyle
226228

227229
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@@ -251,137 +253,145 @@ struct OrderForm: View {
251253
}
252254

253255
@ViewBuilder private func orderFormSummary(_ presentProductSelector: (() -> Void)?) -> some View {
254-
GeometryReader { geometry in
255-
ScrollViewReader { scroll in
256-
ScrollView {
257-
Group {
258-
VStack(spacing: Layout.noSpacing) {
259-
Spacer(minLength: Layout.sectionSpacing)
256+
ScrollViewReader { scroll in
257+
ScrollView {
258+
Group {
259+
VStack(spacing: Layout.noSpacing) {
260+
Spacer(minLength: Layout.sectionSpacing)
260261

262+
if viewModel.shouldShowNonEditableIndicators {
261263
Group {
262264
Divider() // Needed because `NonEditableOrderBanner` does not have a top divider
263-
NonEditableOrderBanner(width: geometry.size.width)
265+
NonEditableOrderBanner(width: bannerWidth)
264266
}
265-
.renderedIf(viewModel.shouldShowNonEditableIndicators)
266-
267-
Group {
268-
OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators)
269-
Spacer(minLength: Layout.sectionSpacing)
270-
}
271-
.renderedIf(flow == .editing)
272-
273-
ProductsSection(scroll: scroll,
274-
flow: flow,
275-
presentProductSelector: presentProductSelector,
276-
viewModel: viewModel,
277-
navigationButtonID: $navigationButtonID,
278-
isLoading: isLoading)
279-
.disabled(viewModel.shouldShowNonEditableIndicators)
267+
}
280268

281-
Group {
282-
Divider()
283-
Spacer(minLength: Layout.sectionSpacing)
284-
Divider()
285-
}
286-
.renderedIf(viewModel.shouldSplitProductsAndCustomAmountsSections)
269+
Group {
270+
OrderStatusSection(viewModel: viewModel, topDivider: !viewModel.shouldShowNonEditableIndicators)
271+
Spacer(minLength: Layout.sectionSpacing)
272+
}
273+
.renderedIf(flow == .editing)
287274

288-
OrderCustomAmountsSection(viewModel: viewModel, sectionViewModel: viewModel.customAmountsSectionViewModel)
289-
.disabled(viewModel.shouldShowNonEditableIndicators)
275+
ProductsSection(scroll: scroll,
276+
flow: flow,
277+
presentProductSelector: presentProductSelector,
278+
viewModel: viewModel,
279+
navigationButtonID: $navigationButtonID,
280+
isLoading: isLoading)
281+
.disabled(viewModel.shouldShowNonEditableIndicators)
290282

283+
Group {
291284
Divider()
292-
293285
Spacer(minLength: Layout.sectionSpacing)
286+
Divider()
287+
}
288+
.renderedIf(viewModel.shouldSplitProductsAndCustomAmountsSections)
294289

295-
Group {
296-
OrderShippingSection(viewModel: viewModel.shippingLineViewModel)
297-
.disabled(viewModel.shouldShowNonEditableIndicators)
298-
Spacer(minLength: Layout.sectionSpacing)
299-
}
300-
.renderedIf(viewModel.shippingLineViewModel.shippingLineRows.isNotEmpty)
301-
302-
Group {
303-
OrderCouponSectionView(viewModel: viewModel, couponViewModel: viewModel.couponLineViewModel)
304-
.disabled(viewModel.shouldShowNonEditableIndicators)
305-
Spacer(minLength: Layout.sectionSpacing)
306-
}
307-
.renderedIf(viewModel.couponLineViewModel.couponLineRows.isNotEmpty)
308-
309-
AddOrderComponentsSection(
310-
viewModel: viewModel.paymentDataViewModel,
311-
shippingLineViewModel: viewModel.shippingLineViewModel,
312-
couponLineViewModel: viewModel.couponLineViewModel,
313-
shouldShowCouponsInfoTooltip: $shouldShowInformationalCouponTooltip,
314-
shouldShowGiftCardForm: $shouldShowGiftCardForm)
315-
.addingTopAndBottomDividers()
290+
OrderCustomAmountsSection(viewModel: viewModel, sectionViewModel: viewModel.customAmountsSectionViewModel)
316291
.disabled(viewModel.shouldShowNonEditableIndicators)
317292

293+
Divider()
294+
295+
Spacer(minLength: Layout.sectionSpacing)
296+
297+
Group {
298+
OrderShippingSection(viewModel: viewModel.shippingLineViewModel)
299+
.disabled(viewModel.shouldShowNonEditableIndicators)
318300
Spacer(minLength: Layout.sectionSpacing)
319301
}
302+
.renderedIf(viewModel.shippingLineViewModel.shippingLineRows.isNotEmpty)
320303

321-
VStack(spacing: Layout.noSpacing) {
322-
Group {
323-
NewTaxRateSection(text: viewModel.taxRateRowText) {
324-
viewModel.onSetNewTaxRateTapped()
325-
switch viewModel.taxRateRowAction {
326-
case .storedTaxRateSheet:
327-
shouldShowStoredTaxRateSheet = true
328-
viewModel.onStoredTaxRateBottomSheetAppear()
329-
case .taxSelector:
330-
shouldShowNewTaxRateSelector = true
331-
}
304+
Group {
305+
OrderCouponSectionView(viewModel: viewModel, couponViewModel: viewModel.couponLineViewModel)
306+
.disabled(viewModel.shouldShowNonEditableIndicators)
307+
Spacer(minLength: Layout.sectionSpacing)
308+
}
309+
.renderedIf(viewModel.couponLineViewModel.couponLineRows.isNotEmpty)
310+
311+
AddOrderComponentsSection(
312+
viewModel: viewModel.paymentDataViewModel,
313+
shippingLineViewModel: viewModel.shippingLineViewModel,
314+
couponLineViewModel: viewModel.couponLineViewModel,
315+
shouldShowCouponsInfoTooltip: $shouldShowInformationalCouponTooltip,
316+
shouldShowGiftCardForm: $shouldShowGiftCardForm)
317+
.addingTopAndBottomDividers()
318+
.disabled(viewModel.shouldShowNonEditableIndicators)
319+
320+
Spacer(minLength: Layout.sectionSpacing)
321+
}
332322

333-
}
334-
.sheet(isPresented: $shouldShowNewTaxRateSelector) {
335-
NewTaxRateSelectorView(viewModel: NewTaxRateSelectorViewModel(siteID: viewModel.siteID,
336-
onTaxRateSelected: { taxRate in
337-
viewModel.onTaxRateSelected(taxRate)
338-
}),
339-
taxEducationalDialogViewModel: viewModel.paymentDataViewModel.taxEducationalDialogViewModel,
340-
onDismissWpAdminWebView: viewModel.paymentDataViewModel.onDismissWpAdminWebViewClosure,
341-
storeSelectedTaxRate: viewModel.shouldStoreTaxRateInSelectorByDefault)
342-
}
343-
.sheet(isPresented: $shouldShowStoredTaxRateSheet) {
344-
if #available(iOS 16.0, *) {
345-
storedTaxRateBottomSheetContent
346-
.presentationDetents([.medium])
347-
.presentationDragIndicator(.visible)
348-
} else {
349-
storedTaxRateBottomSheetContent
350-
}
323+
VStack(spacing: Layout.noSpacing) {
324+
Group {
325+
NewTaxRateSection(text: viewModel.taxRateRowText) {
326+
viewModel.onSetNewTaxRateTapped()
327+
switch viewModel.taxRateRowAction {
328+
case .storedTaxRateSheet:
329+
shouldShowStoredTaxRateSheet = true
330+
viewModel.onStoredTaxRateBottomSheetAppear()
331+
case .taxSelector:
332+
shouldShowNewTaxRateSelector = true
351333
}
352334

353-
Spacer(minLength: Layout.sectionSpacing)
354335
}
355-
.renderedIf(viewModel.shouldShowNewTaxRateSection)
356-
357-
Divider()
358-
359-
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.subscriptionsInOrderCreationCustomers) {
360-
OrderCustomerSection(viewModel: viewModel.customerSectionViewModel)
361-
} else {
362-
LegacyOrderCustomerSection(viewModel: viewModel, addressFormViewModel: viewModel.addressFormViewModel)
336+
.sheet(isPresented: $shouldShowNewTaxRateSelector) {
337+
NewTaxRateSelectorView(viewModel: NewTaxRateSelectorViewModel(siteID: viewModel.siteID,
338+
onTaxRateSelected: { taxRate in
339+
viewModel.onTaxRateSelected(taxRate)
340+
}),
341+
taxEducationalDialogViewModel: viewModel.paymentDataViewModel.taxEducationalDialogViewModel,
342+
onDismissWpAdminWebView: viewModel.paymentDataViewModel.onDismissWpAdminWebViewClosure,
343+
storeSelectedTaxRate: viewModel.shouldStoreTaxRateInSelectorByDefault)
344+
}
345+
.sheet(isPresented: $shouldShowStoredTaxRateSheet) {
346+
if #available(iOS 16.0, *) {
347+
storedTaxRateBottomSheetContent
348+
.presentationDetents([.medium])
349+
.presentationDragIndicator(.visible)
350+
} else {
351+
storedTaxRateBottomSheetContent
352+
}
363353
}
364354

365-
Group {
366-
Divider()
355+
Spacer(minLength: Layout.sectionSpacing)
356+
}
357+
.renderedIf(viewModel.shouldShowNewTaxRateSection)
367358

368-
Spacer(minLength: Layout.sectionSpacing)
359+
Divider()
369360

370-
Divider()
371-
}
372-
.renderedIf(viewModel.shouldSplitCustomerAndNoteSections)
361+
if ServiceLocator.featureFlagService.isFeatureFlagEnabled(.subscriptionsInOrderCreationCustomers) {
362+
OrderCustomerSection(viewModel: viewModel.customerSectionViewModel)
363+
} else {
364+
LegacyOrderCustomerSection(viewModel: viewModel, addressFormViewModel: viewModel.addressFormViewModel)
365+
}
373366

374-
CustomerNoteSection(viewModel: viewModel)
367+
Group {
368+
Divider()
369+
370+
Spacer(minLength: Layout.sectionSpacing)
375371

376372
Divider()
377373
}
374+
.renderedIf(viewModel.shouldSplitCustomerAndNoteSections)
375+
376+
CustomerNoteSection(viewModel: viewModel)
377+
378+
Divider()
378379
}
379-
.disabled(viewModel.disabled)
380380
}
381-
.accessibilityIdentifier(Accessibility.orderFormScrollViewIdentifier)
382-
.background(Color(.listBackground).ignoresSafeArea())
383-
.ignoresSafeArea(.container, edges: [.horizontal])
381+
.disabled(viewModel.disabled)
384382
}
383+
.accessibilityIdentifier(Accessibility.orderFormScrollViewIdentifier)
384+
.background(Color(.listBackground).ignoresSafeArea())
385+
.ignoresSafeArea(.container, edges: [.horizontal])
386+
.background(
387+
GeometryReader { geometryProxy in
388+
Color.clear
389+
.preference(key: WidthPreferenceKey.self, value: geometryProxy.size.width)
390+
}
391+
)
392+
}
393+
.onPreferenceChange(WidthPreferenceKey.self) { newWidth in
394+
bannerWidth = newWidth
385395
}
386396
.safeAreaInset(edge: .bottom) {
387397
VStack {
@@ -863,6 +873,15 @@ private extension OrderForm {
863873
}
864874
}
865875

876+
private extension OrderForm {
877+
struct WidthPreferenceKey: PreferenceKey {
878+
static var defaultValue: CGFloat = .zero
879+
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
880+
value = max(value, nextValue())
881+
}
882+
}
883+
}
884+
866885
struct OrderForm_Previews: PreviewProvider {
867886
static var previews: some View {
868887
let viewModel = EditableOrderViewModel(siteID: 123)

0 commit comments

Comments
 (0)