Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 🐛 [IOSSDKBUG-485]Filter layout issue for very large fonts(cherrypick) #930

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/FioriSwiftUICore/Models/ModelDefinitions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,8 @@ public protocol FilterFeedbackBarButtonModel: LeftIconComponent, TitleComponent
// sourcery: add_env_props = "filterFeedbackBarStyle"
// sourcery: generated_component_not_configurable
// sourcery: virtualPropHeight = "@State var _height: CGFloat = 0"
// sourcery: virtualPropUpdateSearchListPickerHeight = "var updateSearchListPickerHeight: ((CGFloat) -> ())? = nil"
// sourcery: virtualPropBarItemFrame = "var barItemFrame: CGRect = .zero"
public protocol OptionListPickerItemModel: OptionListPickerComponent {
// sourcery: default.value = .fixed
// sourcery: no_view
Expand Down
65 changes: 47 additions & 18 deletions Sources/FioriSwiftUICore/Views/OptionListPickerItem+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ public enum OptionListPickerItemLayoutType {
case flexible
}

public extension OptionListPickerItem {
/// create a filter picker which is used in FilterFeedbackBarItem
/// - Parameters:
/// - value: Indexes for selected values.
/// - valueOptions: The data for constructing the list picker.
/// - hint: Hint message.
/// - itemLayout: Option item layout type.
/// - barItemFrame: The frame of the item in FilterFeedbackBar, which toggle to show this view.
/// - onTap: The closure when tap on item.
/// - updateSearchListPickerHeight: The closure to update the parent view.
init(value: Binding<[Int]>, valueOptions: [String] = [], hint: String? = nil, itemLayout: OptionListPickerItemLayoutType = .fixed, barItemFrame: CGRect = .zero, onTap: ((_ index: Int) -> Void)? = nil, updateSearchListPickerHeight: ((CGFloat) -> Void)? = nil) {
self.init(value: value, valueOptions: valueOptions, hint: hint, itemLayout: itemLayout, onTap: onTap)

self.barItemFrame = barItemFrame
self.updateSearchListPickerHeight = updateSearchListPickerHeight
}
}

extension OptionListPickerItem: View {
public var body: some View {
if _itemLayout == .flexible {
Expand Down Expand Up @@ -61,19 +79,11 @@ extension OptionListPickerItem: View {
GeometryReader { geometry in
Color.clear
.onAppear {
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 : 60)
self._height = min(geometry.size.height, maxScrollViewHeight)
self.updateSearchListPickerHeight?(self.calculateHeight(scrollViewContentHeight: geometry.size.height))
}
}
)
}
.ifApply(UIDevice.current.userInterfaceIdiom == .phone, content: { v in
v.frame(height: _height)
})
}

private func generateFlexibleContent() -> some View {
Expand All @@ -94,19 +104,14 @@ extension OptionListPickerItem: View {
GeometryReader { geometry in
Color.clear
.onAppear {
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 : 60)
self._height = min(geometry.size.height, maxScrollViewHeight)
self.updateSearchListPickerHeight?(self.calculateHeight(scrollViewContentHeight: geometry.size.height))
}
.onChange(of: geometry.size) { _ in
self.updateSearchListPickerHeight?(self.calculateHeight(scrollViewContentHeight: geometry.size.height))
}
}
)
}
.ifApply(UIDevice.current.userInterfaceIdiom == .phone, content: { v in
v.frame(height: _height)
})
}

private func getSafeAreaInsets() -> UIEdgeInsets {
Expand All @@ -119,6 +124,30 @@ extension OptionListPickerItem: View {
}
return keyWindow.safeAreaInsets
}

private func calculateHeight(scrollViewContentHeight: CGFloat) -> CGFloat {
let screenHeight = Screen.bounds.size.height
let safeAreaInset = self.getSafeAreaInsets()
var maxScrollViewHeight = screenHeight - self.additionalHeight()
if UIDevice.current.userInterfaceIdiom != .phone {
if self.barItemFrame.arrowDirection() == .top {
maxScrollViewHeight -= (self.barItemFrame.maxY + 80)
} else if self.barItemFrame.arrowDirection() == .bottom {
maxScrollViewHeight -= (screenHeight - self.barItemFrame.minY + 80) + safeAreaInset.bottom + 13
}
} else {
maxScrollViewHeight -= (safeAreaInset.top + 30)
}
return min(scrollViewContentHeight, maxScrollViewHeight)
}

private func additionalHeight() -> CGFloat {
let isNotIphone = UIDevice.current.userInterfaceIdiom != .phone
var height = 0.0
height += self.getSafeAreaInsets().bottom + (isNotIphone ? 13 : 16)
height += isNotIphone ? 50 : 56
return height
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import SwiftUI
import UIKit

public extension SearchListPickerItem {
/// create a list picker which used in FilterFeedbackBarItem
/// create a list picker which is used in FilterFeedbackBarItem
/// - Parameters:
/// - value: Selected value indexs.
/// - value: Indexes for selected values.
/// - valueOptions: The data for constructing the list picker.
/// - hint: Hint message.
/// - allowsMultipleSelection: A boolean value to indicate to allow multiple selections or not.
Expand All @@ -14,7 +14,7 @@ public extension SearchListPickerItem {
/// - updateSearchListPickerHeight: The closure to update the parent view.
/// - disableListEntriesSection: A boolean value to indicate to disable entries section or not.
/// - allowsDisplaySelectionCount: A boolean value to indicate to display selection count or not.
/// - barItemFrame: The frame of the bar item, which toggle to show this view.
/// - barItemFrame: The frame of the item in FilterFeedbackBar, which toggle to show this view.
init(value: Binding<[Int]>, valueOptions: [String] = [], hint: String? = nil, allowsMultipleSelection: Bool, allowsEmptySelection: Bool, isSearchBarHidden: Bool = false, disableListEntriesSection: Bool, allowsDisplaySelectionCount: Bool, barItemFrame: CGRect = .zero, onTap: ((_ index: Int) -> Void)? = nil, selectAll: ((_ isAll: Bool) -> Void)? = nil, updateSearchListPickerHeight: ((CGFloat) -> Void)? = nil) {
self.init(value: value, valueOptions: valueOptions, hint: hint, onTap: onTap)

Expand Down
Loading
Loading