diff --git a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift index dba435894..45f8a69b2 100644 --- a/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift +++ b/Sources/FioriSwiftUICore/Models/ModelDefinitions.swift @@ -535,6 +535,7 @@ public protocol OptionListPickerItemModel: OptionListPickerComponent { // sourcery: virtualPropAllowsEmptySelection = "var allowsEmptySelection: Bool = false" // sourcery: virtualPropIsSearchBarHidden = "var isSearchBarHidden: Bool = false" // sourcery: virtualPropPopoverWidth = "let popoverWidth = 393.0" +// sourcery: virtualPropKeyboardHeight = "@State var _keyboardHeight: CGFloat = 0.0" public protocol SearchListPickerItemModel: OptionListPickerComponent { // sourcery: default.value = nil // sourcery: no_view diff --git a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift index 707c697ea..0f6977832 100644 --- a/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SearchListPickerItem+View.swift @@ -72,7 +72,8 @@ extension SearchListPickerItem: View { let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 8 : 16) * 2 let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 13 : 16) * 2 let safeAreaInset = self.getSafeAreaInsets() - let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - (self.isSearchBarHidden ? 0 : 52) - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 230 : 30) + var maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - (self.isSearchBarHidden ? 0 : 52) - 56 - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 250 : 30) + maxScrollViewHeight -= self._keyboardHeight self._height = min(scrollView.contentSize.height, maxScrollViewHeight) var isSelectAllViewShow = false if allowsMultipleSelection { @@ -91,6 +92,13 @@ extension SearchListPickerItem: View { .padding(0) .ifApply(!isSearchBarHidden, content: { v in v.searchable(text: $_searchText, placement: .automatic) + .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 + } }) } } diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift index ce4b5f0e1..90e2acb03 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/FilterFeedbackBarItem+View.swift @@ -123,6 +123,7 @@ struct PickerMenuItem: View { @State var detentHeight: CGFloat = ((UIDevice.current.userInterfaceIdiom == .phone || UIDevice.current.userInterfaceIdiom == .pad) ? 88 : 0) let popoverWidth = 393.0 + @State var _keyboardHeight = 0.0 public init(item: Binding, onUpdate: @escaping () -> Void) { self._item = item @@ -255,8 +256,15 @@ struct PickerMenuItem: View { } updateSearchListPickerHeight: { height in self.detentHeight = max(height, 88) } - .frame(maxHeight: UIDevice.current.userInterfaceIdiom != .phone ? (self.detentHeight) : nil) + .frame(maxHeight: UIDevice.current.userInterfaceIdiom != .phone ? (self.detentHeight + (self._keyboardHeight > 0 ? 52 : 0)) : nil) .padding(0) + .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 + } Spacer() } .frame(minWidth: UIDevice.current.userInterfaceIdiom != .phone ? 393 : nil) diff --git a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift index ffbd5054b..5075b06d8 100644 --- a/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift +++ b/Sources/FioriSwiftUICore/Views/SortFilter/_SortFilterCFGItemContainer.swift @@ -16,7 +16,9 @@ public struct _SortFilterCFGItemContainer { let popoverWidth = 393.0 @State var stepperViewHeight: CGFloat = 110 - + @State var searchListHeight: CGFloat = 88.0 + @State var _keyboardHeight: CGFloat = 0.0 + public init(items: Binding<[[SortFilterItem]]>) { self.__items = items } @@ -54,7 +56,8 @@ extension _SortFilterCFGItemContainer: View { let totalSpacing: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 8 : 16) * 2 let totalPadding: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad ? 13 : 16) * 2 let safeAreaInset = self.getSafeAreaInsets() - let maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 150 : 30) + var maxScrollViewHeight = popverHeight - totalSpacing - totalPadding - safeAreaInset.top - safeAreaInset.bottom - (UIDevice.current.userInterfaceIdiom == .pad ? 150 : 30) + maxScrollViewHeight -= self._keyboardHeight self.height = min(scrollView.contentSize.height, maxScrollViewHeight) } }) @@ -149,6 +152,21 @@ extension _SortFilterCFGItemContainer: View { self._items[r][c].picker.onTap(option: self._items[r][c].picker.valueOptions[index]) } selectAll: { isAll in self._items[r][c].picker.selectAll(isAll) + } updateSearchListPickerHeight: { height in + if self._keyboardHeight > 0 { + let safeAreaInset = self.getSafeAreaInsets() + self.searchListHeight = height + StatusBar.height + safeAreaInset.top + safeAreaInset.bottom + (UIDevice.current.userInterfaceIdiom == .pad ? 150 : 30) + } else { + self.searchListHeight = height + 52 + (UIDevice.current.userInterfaceIdiom == .pad ? 150 : 30) + } + } + .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 + } + .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardDidHideNotification)) { _ in + self._keyboardHeight = 0 } Spacer() } label: { diff --git a/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift b/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift index 482b6a608..e29c8b060 100644 --- a/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift +++ b/Sources/FioriSwiftUICore/_generated/ViewModels/API/SearchListPickerItem+API.generated.swift @@ -9,6 +9,7 @@ public struct SearchListPickerItem { var _valueOptions: [String] var _hint: String? = nil var _onTap: ((_ index: Int) -> Void)? = nil + var updateSearchListPickerHeight: ((CGFloat) -> ())? = nil var allowsMultipleSelection: Bool = false var isSearchBarHidden: Bool = false @@ -18,7 +19,8 @@ public struct SearchListPickerItem { @State var _searchText: String = "" var allowsEmptySelection: Bool = false let popoverWidth = 393.0 - + @State var _keyboardHeight: CGFloat = 0.0 + public init(model: SearchListPickerItemModel) { self.init(value: Binding<[Int]>(get: { model.value }, set: { model.value = $0 }), valueOptions: model.valueOptions, hint: model.hint, onTap: model.onTap) }