Skip to content

Commit

Permalink
fix: 🐛 [IOSSDKBUG-485]Filter layout issue for very large fonts (#930)
Browse files Browse the repository at this point in the history
  • Loading branch information
restaurantt authored Dec 9, 2024
1 parent ee0bb49 commit f9623ab
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 62 deletions.
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

0 comments on commit f9623ab

Please sign in to comment.