From 9d1dcd20656f6627ce2a5700937efa3f763bf137 Mon Sep 17 00:00:00 2001 From: "Gu, Jiajun (external - Project)" Date: Wed, 13 Nov 2024 17:35:50 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=F0=9F=90=9B=20[IOSSDKBUG-416]fiterF?= =?UTF-8?q?eedBackBar=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iPhone,iPad,VisionPro popover size limit --- .../Views/OptionListPickerItem+View.swift | 8 +- .../Views/SearchListPickerItem+View.swift | 132 +++++++++--------- .../FilterFeedbackBarItem+View.swift | 8 +- .../SortFilter/SortFilterView+View.swift | 6 +- .../_SortFilterCFGItemContainer.swift | 32 +++-- 5 files changed, 99 insertions(+), 87 deletions(-) diff --git a/Sources/FioriSwiftUICore/Views/OptionListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/OptionListPickerItem+View.swift index 37c777b1d..972474b6f 100644 --- a/Sources/FioriSwiftUICore/Views/OptionListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/OptionListPickerItem+View.swift @@ -61,11 +61,11 @@ extension OptionListPickerItem: View { GeometryReader { geometry in Color.clear .onAppear { - let popverHeight = Screen.bounds.size.height - StatusBar.height + let popverHeight = Screen.bounds.size.height let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 8 : 16) * 2 let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) * 2 let safeAreaInset = self.getSafeAreaInsets() - let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 210 : 30) + let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 210 : 60) self._height = min(geometry.size.height, maxScrollViewHeight) } } @@ -94,11 +94,11 @@ extension OptionListPickerItem: View { GeometryReader { geometry in Color.clear .onAppear { - let popverHeight = Screen.bounds.size.height - StatusBar.height + let popverHeight = Screen.bounds.size.height let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 8 : 16) * 2 let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) * 2 let safeAreaInset = self.getSafeAreaInsets() - let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 210 : 30) + let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 210 : 60) self._height = min(geometry.size.height, maxScrollViewHeight) } } diff --git a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift index 316f32e6c..5e26a6de6 100644 --- a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift @@ -27,43 +27,13 @@ public extension SearchListPickerItem { extension SearchListPickerItem: View { public var body: some View { - VStack(spacing: 0) { - List { - if !disableListEntriesSection, _value.count > 0 { - Section { - self.selectionHeader() - let selectedOptions = _value.wrappedValue.map { _valueOptions[$0] } - ForEach(selectedOptions.filter { _searchText.isEmpty || $0.localizedStandardContains(_searchText) }, id: \.self) { item in - self.rowView(value: item, isSelected: true) - .padding(0) - .contentShape(Rectangle()) - .onTapGesture { - guard let index = findIndex(of: item) else { - return - } - _onTap?(index) - } - } - - Rectangle().fill(Color.preferredColor(.primaryGroupedBackground)) - .frame(height: 30) - .listRowInsets(EdgeInsets()) - } - } - + List { + if !disableListEntriesSection, _value.count > 0 { Section { - if allowsMultipleSelection { - if _value.count != _valueOptions.count || allowsEmptySelection { - self.selectAllView() - } - } else if _value.count == _valueOptions.count { - self.selectAllView() - } else { - EmptyView() - } - ForEach(_valueOptions.filter { _searchText.isEmpty || $0.localizedStandardContains(_searchText) }, id: \.self) { item in - let isSelected = self.isItemSelected(item) - self.rowView(value: item, isSelected: isSelected) + self.selectionHeader() + let selectedOptions = _value.wrappedValue.map { _valueOptions[$0] } + ForEach(selectedOptions.filter { _searchText.isEmpty || $0.localizedStandardContains(_searchText) }, id: \.self) { item in + self.rowView(value: item, isSelected: true) .padding(0) .contentShape(Rectangle()) .onTapGesture { @@ -73,43 +43,69 @@ extension SearchListPickerItem: View { _onTap?(index) } } + + Rectangle().fill(Color.preferredColor(.primaryGroupedBackground)) + .frame(height: 30) + .listRowInsets(EdgeInsets()) } } - .modifier(FioriIntrospectModifier { scrollView in - if !_searchText.isEmpty { - return - } - DispatchQueue.main.async { - let popverHeight = Screen.bounds.size.height - StatusBar.height - let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 8 : 16) * 2 - let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) * 2 - let safeAreaInset = self.getSafeAreaInsets() - var maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - (self.isSearchBarHidden ? 0 : 52) - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 250 : 30) - maxScrollViewHeight -= self._keyboardHeight - if self._keyboardHeight > 0 { - maxScrollViewHeight += 56 + + Section { + if allowsMultipleSelection { + if _value.count != _valueOptions.count || allowsEmptySelection { + self.selectAllView() } - self._height = min(scrollView.contentSize.height, maxScrollViewHeight) - updateSearchListPickerHeight?(self._height) + } else if _value.count == _valueOptions.count { + self.selectAllView() + } else { + EmptyView() } - }) - .listStyle(PlainListStyle()) - .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? popoverWidth : nil) - .scrollContentBackground(.hidden) - .padding(0) - .environment(\.defaultMinListRowHeight, 0) - .environment(\.defaultMinListHeaderHeight, 0) - .ifApply(!isSearchBarHidden, content: { v in - v.searchable(text: $_searchText, placement: .navigationBarDrawer(displayMode: .always)) - .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidShowNotification)) { notif in - let rect = (notif.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect) ?? .zero - self._keyboardHeight = rect.height - } - .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidHideNotification)) { _ in - self._keyboardHeight = 0 - } - }) + ForEach(_valueOptions.filter { _searchText.isEmpty || $0.localizedStandardContains(_searchText) }, id: \.self) { item in + let isSelected = self.isItemSelected(item) + self.rowView(value: item, isSelected: isSelected) + .padding(0) + .contentShape(Rectangle()) + .onTapGesture { + guard let index = findIndex(of: item) else { + return + } + _onTap?(index) + } + } + } } + .modifier(FioriIntrospectModifier { scrollView in + if !_searchText.isEmpty { + return + } + DispatchQueue.main.async { + let popverHeight = Screen.bounds.size.height + let safeAreaInset = self.getSafeAreaInsets() + var maxScrollViewHeight = popverHeight - (self.isSearchBarHidden ? 0 : 52) - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 250 : 30) + maxScrollViewHeight -= self._keyboardHeight + if self._keyboardHeight > 0 { + maxScrollViewHeight += 56 + } + self._height = min(scrollView.contentSize.height, maxScrollViewHeight) + updateSearchListPickerHeight?(self._height) + } + }) + .listStyle(PlainListStyle()) + .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? self.popoverWidth : nil) + .scrollContentBackground(.hidden) + .padding(0) + .environment(\.defaultMinListRowHeight, 0) + .environment(\.defaultMinListHeaderHeight, 0) + .ifApply(!isSearchBarHidden, content: { v in + v.searchable(text: $_searchText, placement: .navigationBarDrawer(displayMode: .always)) + .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidShowNotification)) { notif in + let rect = (notif.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect) ?? .zero + self._keyboardHeight = rect.height + } + .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidHideNotification)) { _ in + self._keyboardHeight = 0 + } + }) } private func rowView(value: String, isSelected: Bool) -> some View { diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift index 33f122b53..999af68cc 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift @@ -270,7 +270,7 @@ struct PickerMenuItem: View { } Spacer() } - .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393 : nil) + .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? self.popoverWidth : nil) .frame(height: UIDevice.current.userInterfaceIdiom != .phone ? self.detentHeight + (self.item.isSearchBarHidden ? 0 : 52) + (self._keyboardHeight == 0 ? 56 : 0) + 93 : nil) .presentationDetents([.height(self.detentHeight + (self.item.isSearchBarHidden ? 0 : 52) + (self._keyboardHeight == 0 ? 56 : 0) + 93), .medium, .large]) } @@ -313,7 +313,11 @@ struct DateTimeMenuItem: View { var onUpdate: () -> Void - let popoverWidth = 393.0 + #if !os(visionOS) + let popoverWidth = 393.0 + #else + let popoverWidth = 480.0 + #endif public init(item: Binding, onUpdate: @escaping () -> Void) { self._item = item diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift b/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift index 1580a47c2..cfdfffe43 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift @@ -81,7 +81,11 @@ extension SortFilterView: View { }) .environmentObject(context) } - .frame(width: UIDevice.current.userInterfaceIdiom != .phone ? popoverWidth : nil) + #if !os(visionOS) + .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393.0 : nil) + #else + .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 480.0 : nil) + #endif .frame(height: UIDevice.current.userInterfaceIdiom != .phone ? size.height + 130 : nil) .presentationDetents([.large]) .background(Color.preferredColor(.chromeSecondary)) diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift index 313c77aef..0ba53dfe1 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift @@ -14,7 +14,11 @@ public struct _SortFilterCFGItemContainer { @Binding var _items: [[SortFilterItem]] @State var height = 88.0 - let popoverWidth = 393.0 + #if !os(visionOS) + let popoverWidth = 393.0 + #else + let popoverWidth = 480.0 + #endif @State var stepperViewHeight: CGFloat = 110 @State var searchListHeight: CGFloat = 88.0 @State var _keyboardHeight: CGFloat = 0.0 @@ -34,6 +38,7 @@ extension _SortFilterCFGItemContainer: View { self.rowView(row: r, column: c) .listRowSeparator(c == self._items[r].count - 1 ? .hidden : .visible, edges: .all) .padding([.leading, .trailing], UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) + .frame(width: UIDevice.current.userInterfaceIdiom != .phone ? self.popoverWidth : nil) } } footer: { Rectangle().fill(Color.preferredColor(.primaryGroupedBackground)) @@ -50,12 +55,12 @@ extension _SortFilterCFGItemContainer: View { .background(Color.preferredColor(.secondaryGroupedBackground)) .modifier(FioriIntrospectModifier { scrollView in DispatchQueue.main.async { - let popverHeight = Screen.bounds.size.height - StatusBar.height - let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 8 : 16) * 2 - let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) * 2 + let popverHeight = Screen.bounds.size.height let safeAreaInset = self.getSafeAreaInsets() - var maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 130 : 30) - maxScrollViewHeight -= self._keyboardHeight + var maxScrollViewHeight = popverHeight - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom != .phone ? 180 : 150) + if UIDevice.current.userInterfaceIdiom == .pad { + maxScrollViewHeight -= self._keyboardHeight + } self.height = min(scrollView.contentSize.height, maxScrollViewHeight) } }) @@ -129,7 +134,6 @@ extension _SortFilterCFGItemContainer: View { .padding([.top], 12) case .datetime: self.datetimePicker(row: r, column: c) - .frame(width: UIDevice.current.userInterfaceIdiom != .phone ? self.popoverWidth : Screen.bounds.size.width) .padding([.top, .bottom], 12) case .stepper: self.stepper(row: r, column: c) @@ -151,13 +155,17 @@ extension _SortFilterCFGItemContainer: View { } selectAll: { isAll in self._items[r][c].picker.selectAll(isAll) } updateSearchListPickerHeight: { height in - if self._keyboardHeight > 0 { - self.searchListHeight = height + (UIDevice.current.userInterfaceIdiom != .phone ? 230 : 150) - } else { - self.searchListHeight = self.height + if UIDevice.current.userInterfaceIdiom == .pad { + if self._keyboardHeight > 0 { + self.searchListHeight = height + (UIDevice.current.userInterfaceIdiom != .phone ? 180 : 150) + } else { + self.searchListHeight = self.height + } } } - .frame(height: self.searchListHeight) + .ifApply(UIDevice.current.userInterfaceIdiom == .pad, content: { v in + v.frame(height: self.searchListHeight) + }) .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidShowNotification)) { notif in let rect = (notif.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect) ?? .zero self._keyboardHeight = rect.height From f8e12863ffd8634b16c38f563f50ad34850e7510 Mon Sep 17 00:00:00 2001 From: "Gu, Jiajun (external - Project)" Date: Thu, 14 Nov 2024 09:17:27 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=F0=9F=90=9B=20[IOSSDKBUG-416]fiterF?= =?UTF-8?q?eedBackBar=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/CancellableResettableForm.swift | 3 --- .../Views/SortFilter/SortFilterView+View.swift | 5 +++-- .../Views/SortFilter/_SortFilterCFGItemContainer.swift | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Sources/FioriSwiftUICore/Components/CancellableResettableForm.swift b/Sources/FioriSwiftUICore/Components/CancellableResettableForm.swift index 6cc6c46dc..6ab8ea3b7 100644 --- a/Sources/FioriSwiftUICore/Components/CancellableResettableForm.swift +++ b/Sources/FioriSwiftUICore/Components/CancellableResettableForm.swift @@ -62,8 +62,6 @@ struct CancellableResettableDialogNavigationForm Title, @ViewBuilder cancelAction: () -> CancelAction, @ViewBuilder resetAction: () -> ResetAction, @@ -100,7 +98,6 @@ struct CancellableResettableDialogNavigationForm 0 { - self.searchListHeight = height + (UIDevice.current.userInterfaceIdiom != .phone ? 180 : 150) + self.searchListHeight = height + (UIDevice.current.userInterfaceIdiom != .phone ? 190 : 150) } else { self.searchListHeight = self.height } @@ -347,7 +347,7 @@ extension _SortFilterCFGItemContainer: View { .font(.fiori(forTextStyle: .subheadline, weight: .bold, isItalic: false, isCondensed: false)) .foregroundColor(Color.preferredColor(.primaryLabel)) Spacer() - }.padding([.leading, .trailing], UIDevice.current.userInterfaceIdiom != .phone ? 13 : 16) + }.padding([.leading, .trailing], UIDevice.current.userInterfaceIdiom != .phone ? 0 : 16) StepperView( title: { Text(self._items[r][c].stepper.stepperTitle) }, From 39a5739f6574a35766fc557865f36a14524361cd Mon Sep 17 00:00:00 2001 From: "Gu, Jiajun (external - Project)" Date: Thu, 14 Nov 2024 13:54:56 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=F0=9F=90=9B=20[IOSSDKBUG-416]fiterF?= =?UTF-8?q?eedBackBar=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift | 2 +- .../Views/SortFilter/SortFilterView+View.swift | 2 +- .../Views/SortFilter/_SortFilterCFGItemContainer.swift | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift index 5e26a6de6..14fb08580 100644 --- a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift @@ -28,7 +28,7 @@ public extension SearchListPickerItem { extension SearchListPickerItem: View { public var body: some View { List { - if !disableListEntriesSection, _value.count > 0 { + if !disableListEntriesSection, !_value.isEmpty { Section { self.selectionHeader() let selectedOptions = _value.wrappedValue.map { _valueOptions[$0] } diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift b/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift index be62ace77..a802fa140 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/SortFilterView+View.swift @@ -85,7 +85,7 @@ extension SortFilterView: View { .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393.0 : nil) .background(Color.preferredColor(.chromeSecondary)) #else - .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 480.0 : nil) + .frame(minWidth: 480.0) .background(Color.clear) #endif .frame(height: UIDevice.current.userInterfaceIdiom != .phone ? size.height + 150 : nil) diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift index 0524bd58d..abeabfec1 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift @@ -347,7 +347,8 @@ extension _SortFilterCFGItemContainer: View { .font(.fiori(forTextStyle: .subheadline, weight: .bold, isItalic: false, isCondensed: false)) .foregroundColor(Color.preferredColor(.primaryLabel)) Spacer() - }.padding([.leading, .trailing], UIDevice.current.userInterfaceIdiom != .phone ? 0 : 16) + } + .padding([.leading, .trailing], UIDevice.current.userInterfaceIdiom != .phone ? 0 : 16) StepperView( title: { Text(self._items[r][c].stepper.stepperTitle) },