@@ -17,13 +17,18 @@ struct MyCollectionProfileSettingsSection: View {
1717
1818 var body : some View {
1919 GeometryReader { geometry in
20+ let bottomContentPadding = resolvedBottomContentPadding (
21+ safeAreaBottomInset: geometry. safeAreaInsets. bottom
22+ )
23+ let containerMinHeight = resolvedContainerMinHeight (
24+ availableHeight: geometry. size. height,
25+ bottomContentPadding: bottomContentPadding
26+ )
27+
2028 ScrollView {
2129 VStack ( alignment: . leading, spacing: 0 ) {
2230 MyCollectionProfileSettingPageContainerView (
23- minHeight: max (
24- geometry. size. height - ( AppSpacing . l + bottomSafeAreaPadding) ,
25- 0
26- )
31+ minHeight: containerMinHeight
2732 ) {
2833 MyCollectionProfileSettingsHeaderView ( onBackTap: onBackTap)
2934 profileEditorCard
@@ -46,10 +51,10 @@ struct MyCollectionProfileSettingsSection: View {
4651 isProcessing: viewModel. isProcessing,
4752 action: onAccountActionTap
4853 )
54+ . padding ( . bottom, AppSpacing . xs)
4955 }
5056 }
51-
52- . padding ( . bottom, max ( AppSpacing . l, bottomSafeAreaPadding) )
57+ . padding ( . bottom, bottomContentPadding + keyboardBottomInset)
5358 }
5459 . scrollIndicators ( . hidden)
5560 . scrollDismissesKeyboard ( . interactively)
@@ -65,16 +70,12 @@ struct MyCollectionProfileSettingsSection: View {
6570 }
6671 . onReceive ( NotificationCenter . default. publisher ( for: UIResponder . keyboardWillChangeFrameNotification) ) {
6772 notification in
68- keyboardBottomInset = resolvedKeyboardInset ( from: notification)
69- }
70- . onReceive ( NotificationCenter . default. publisher ( for: UIResponder . keyboardWillHideNotification) ) { _ in
71- keyboardBottomInset = 0
73+ applyKeyboardInset ( from: notification)
7274 }
73- . safeAreaInset ( edge : . bottom ) {
74- Color . clear
75- . frame ( height : keyboardBottomInset )
75+ . onReceive ( NotificationCenter . default . publisher ( for : UIResponder . keyboardWillHideNotification ) ) {
76+ notification in
77+ applyKeyboardInset ( from : notification )
7678 }
77- . animation ( . easeOut( duration: 0.2 ) , value: keyboardBottomInset)
7879 . frame ( maxWidth: . infinity, alignment: . topLeading)
7980 }
8081 }
@@ -257,30 +258,58 @@ struct MyCollectionProfileSettingsSection: View {
257258 tagValidationFeedback = . unavailable
258259 }
259260
260- private var bottomSafeAreaPadding : CGFloat {
261- currentSafeAreaBottomInset ( ) + AppSpacing. s
261+ private func resolvedBottomContentPadding( safeAreaBottomInset: CGFloat ) -> CGFloat {
262+ let adaptiveInset = safeAreaBottomInset + AppSpacing. s
263+ if UIDevice . current. userInterfaceIdiom == . pad {
264+ return max ( adaptiveInset, AppSpacing . l + AppSpacing. xl)
265+ }
266+ return max ( AppSpacing . l, adaptiveInset)
262267 }
263268
264- private func resolvedKeyboardInset( from notification: Notification ) -> CGFloat {
265- guard
266- let frame = notification. userInfo ? [ UIResponder . keyboardFrameEndUserInfoKey] as? CGRect
267- else {
269+ private func resolvedContainerMinHeight(
270+ availableHeight: CGFloat ,
271+ bottomContentPadding: CGFloat
272+ ) -> CGFloat {
273+ if UIDevice . current. userInterfaceIdiom == . pad {
268274 return 0
269275 }
270276
271- let screenHeight = UIScreen . main. bounds. height
272- let rawOverlap = max ( 0 , screenHeight - frame. minY)
273- return max ( rawOverlap - currentSafeAreaBottomInset( ) , 0 )
277+ let reservedBottomSpace = AppSpacing . l + bottomContentPadding + keyboardBottomInset
278+ return max ( availableHeight - reservedBottomSpace, 0 )
274279 }
275280
276- private func currentSafeAreaBottomInset( ) -> CGFloat {
281+ private func applyKeyboardInset( from notification: Notification ) {
282+ let duration = ( notification. userInfo ? [ UIResponder . keyboardAnimationDurationUserInfoKey] as? Double )
283+ ?? 0.25
284+ let inset = resolvedKeyboardInset ( from: notification)
285+
286+ withAnimation ( . easeOut( duration: duration) ) {
287+ keyboardBottomInset = inset
288+ }
289+ }
290+
291+ private func resolvedKeyboardInset( from notification: Notification ) -> CGFloat {
277292 guard
278- let windowScene = UIApplication . shared . connectedScenes . first as? UIWindowScene ,
279- let keyWindow = windowScene . windows . first ( where : { $0 . isKeyWindow } )
293+ let userInfo = notification . userInfo ,
294+ let endFrame = userInfo [ UIResponder . keyboardFrameEndUserInfoKey ] as? CGRect
280295 else {
281296 return 0
282297 }
283- return keyWindow. safeAreaInsets. bottom
298+
299+ let keyWindow = UIApplication . shared. connectedScenes
300+ . compactMap { $0 as? UIWindowScene }
301+ . flatMap ( \. windows)
302+ . first ( where: \. isKeyWindow)
303+
304+ if let keyWindow {
305+ let endFrameInWindow = keyWindow. convert ( endFrame, from: nil )
306+ return max (
307+ 0 ,
308+ keyWindow. bounds. maxY - endFrameInWindow. minY - keyWindow. safeAreaInsets. bottom
309+ )
310+ }
311+
312+ return max ( 0 , UIScreen . main. bounds. maxY - endFrame. minY)
284313 }
285314}
286315
0 commit comments