Przeglądaj źródła

let ChatInputBars input text field use all available space in horizontal layout, similar to Android

cyberta 4 lat temu
rodzic
commit
f5b5a2d541
1 zmienionych plików z 71 dodań i 8 usunięć
  1. 71 8
      deltachat-ios/Chat/Views/ChatInputBar.swift

+ 71 - 8
deltachat-ios/Chat/Views/ChatInputBar.swift

@@ -1,21 +1,58 @@
 import UIKit
 import InputBarAccessoryView
 
+
 public class ChatInputBar: InputBarAccessoryView {
 
     var hasDraft: Bool = false
     var hasQuote: Bool = false
+    var keyboardHeight: CGFloat = 0
+
+    public convenience init() {
+        self.init(frame: .zero)
+    }
+
+    public override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupKeyboardObserver()
+    }
 
+    required public init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        setupKeyboardObserver()
+    }
+
+    func setupKeyboardObserver() {
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(keyboardChanged),
+            name: UIResponder.keyboardWillShowNotification,
+            object: nil
+        )
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(keyboardChanged),
+            name: UIResponder.keyboardDidHideNotification,
+            object: nil
+        )
+    }
+    
     override open func calculateMaxTextViewHeight() -> CGFloat {
-        let divisor: CGFloat = traitCollection.verticalSizeClass == .regular ? 3 : 5
-        var subtract: CGFloat = 0
-        subtract += hasDraft ? 90 : 0
-        subtract += hasQuote ? 90 : 0
-        let height = (UIScreen.main.bounds.height / divisor).rounded(.down) - subtract
-        if height < 40 {
-            return 40
+        if traitCollection.verticalSizeClass == .regular {
+            let divisor: CGFloat = 3
+            var subtract: CGFloat = 0
+            subtract += hasDraft ? 90 : 0
+            subtract += hasQuote ? 90 : 0
+            let height = (UIScreen.main.bounds.height / divisor).rounded(.down) - subtract
+            if height < 40 {
+                return 40
+            }
+            return height
+        } else {
+            // horizontal layout
+            let height = UIScreen.main.bounds.height - keyboardHeight - 12
+            return height
         }
-        return height
     }
 
     public func configure(draft: DraftModel) {
@@ -29,4 +66,30 @@ public class ChatInputBar: InputBarAccessoryView {
         hasQuote = false
         maxTextViewHeight = calculateMaxTextViewHeight()
     }
+
+    @objc func keyboardChanged(_ notification: Notification) {
+        if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
+            let keyboardRectangle = keyboardFrame.cgRectValue
+            keyboardHeight = keyboardRectangle.height - intrinsicContentSize.height
+            maxTextViewHeight = calculateMaxTextViewHeight()
+            logger.debug("keyboard height: \(keyboardHeight) - intrinsic content size:  \(intrinsicContentSize.height)")
+            forceMaxTextViewHeightForHorizontalLayout()
+        }
+    }
+
+    public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
+        super.traitCollectionDidChange(previousTraitCollection)
+        if (self.traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass)
+                || (self.traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass) {
+            forceMaxTextViewHeightForHorizontalLayout()
+        }
+    }
+
+    private func forceMaxTextViewHeightForHorizontalLayout() {
+        if keyboardHeight > 0, UIApplication.shared.statusBarOrientation.isLandscape {
+            setShouldForceMaxTextViewHeight(to: true, animated: false)
+        } else if shouldForceTextViewMaxHeight {
+            setShouldForceMaxTextViewHeight(to: false, animated: false)
+        }
+    }
 }