Răsfoiți Sursa

Merge pull request #1307 from deltachat/scroll-up-button

Scroll down button
cyBerta 4 ani în urmă
părinte
comite
e5a203fb36

+ 23 - 0
deltachat-ios/Assets.xcassets/ic_scrolldown.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "ic_scroll_down_1x.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ic_scroll_down_2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ic_scroll_down_3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
deltachat-ios/Assets.xcassets/ic_scrolldown.imageset/ic_scroll_down_1x.png


BIN
deltachat-ios/Assets.xcassets/ic_scrolldown.imageset/ic_scroll_down_2x.png


BIN
deltachat-ios/Assets.xcassets/ic_scrolldown.imageset/ic_scroll_down_3x.png


+ 13 - 4
deltachat-ios/Chat/ChatViewController.swift

@@ -346,6 +346,7 @@ class ChatViewController: UITableViewController {
                         self.highlightedMsg = nil
                         self.isInitial = false
                         self.ignoreInputBarChange = false
+                        self.messageInputBar.scrollDownButton.isHidden = self.isLastRowVisible()
                     }
                 })
             } else {
@@ -476,7 +477,6 @@ class ChatViewController: UITableViewController {
         nc.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
         nc.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
         audioController.stopAnyOngoingPlaying()
-
     }
 
     override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
@@ -542,6 +542,7 @@ class ChatViewController: UITableViewController {
 
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         _ = handleUIMenu()
+        messageInputBar.scrollDownButton.isHidden = isInitial || isLastRowVisible()
 
         let id = messageIds[indexPath.row]
         if id == DC_MSG_ID_DAYMARKER {
@@ -736,6 +737,10 @@ class ChatViewController: UITableViewController {
         }
         _ = handleUIMenu()
     }
+    
+    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
+        messageInputBar.inputTextView.layer.borderColor = DcColors.colorDisabled.cgColor
+    }
 
     func configureMessageStyle(for message: DcMsg, at indexPath: IndexPath) -> UIRectCorner {
 
@@ -836,7 +841,11 @@ class ChatViewController: UITableViewController {
         let lastIndexPath = IndexPath(item: messageIds.count - 1, section: 0)
         return tableView.indexPathsForVisibleRows?.contains(lastIndexPath) ?? false
     }
-
+    
+    private func scrollToBottom() {
+        scrollToBottom(animated: true)
+    }
+    
     private func scrollToBottom(animated: Bool) {
         if !messageIds.isEmpty {
             DispatchQueue.main.async { [weak self] in
@@ -919,8 +928,7 @@ class ChatViewController: UITableViewController {
         messageInputBar.inputTextView.placeholderTextColor = DcColors.placeholderColor
         messageInputBar.inputTextView.textContainerInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 38)
         messageInputBar.inputTextView.placeholderLabelInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 38)
-        messageInputBar.inputTextView.layer.borderColor = UIColor.themeColor(light: UIColor(red: 200 / 255, green: 200 / 255, blue: 200 / 255, alpha: 1),
-                                                                             dark: UIColor(red: 55 / 255, green: 55/255, blue: 55/255, alpha: 1)).cgColor
+        messageInputBar.inputTextView.layer.borderColor = DcColors.colorDisabled.cgColor
         messageInputBar.inputTextView.layer.borderWidth = 1.0
         messageInputBar.inputTextView.layer.cornerRadius = 13.0
         messageInputBar.inputTextView.layer.masksToBounds = true
@@ -930,6 +938,7 @@ class ChatViewController: UITableViewController {
         if let inputTextView = messageInputBar.inputTextView as? ChatInputTextView {
             inputTextView.imagePasteDelegate = self
         }
+        messageInputBar.onScrollDownButtonPressed = scrollToBottom
     }
 
     private func evaluateInputBar(draft: DraftModel) {

+ 53 - 0
deltachat-ios/Chat/Views/ChatInputBar.swift

@@ -8,6 +8,17 @@ public class ChatInputBar: InputBarAccessoryView {
     var hasDraft: Bool = false
     var hasQuote: Bool = false
     var keyboardHeight: CGFloat = 0
+    
+    var onScrollDownButtonPressed: (() -> Void)?
+    
+    lazy var scrollDownButton: UIButton = {
+        let button = UIButton(frame: .zero)
+        button.translatesAutoresizingMaskIntoConstraints = false
+        button.addTarget(self, action: #selector(onScrollDownPressed), for: .touchUpInside)
+        button.isHidden = true
+        return button
+    }()
+    
 
     public convenience init() {
         self.init(frame: .zero)
@@ -26,8 +37,15 @@ public class ChatInputBar: InputBarAccessoryView {
 
     override open func setup() {
         replaceInputBar()
+        setupScrollDownButton()
         super.setup()
     }
+    
+    @objc func onScrollDownPressed() {
+        if let callback = onScrollDownButtonPressed {
+            callback()
+        }
+    }
 
     func replaceInputBar() {
         inputTextView = ChatInputTextView()
@@ -101,6 +119,7 @@ public class ChatInputBar: InputBarAccessoryView {
             updateTextViewHeight()
             delegate?.inputBar(self, didChangeIntrinsicContentTo: intrinsicContentSize)
         }
+        scrollDownButton.layer.borderColor = DcColors.colorDisabled.cgColor
     }
 
     private func updateTextViewHeight() {
@@ -113,4 +132,38 @@ public class ChatInputBar: InputBarAccessoryView {
             setShouldForceMaxTextViewHeight(to: false, animated: false)
         }
     }
+    
+    func setupScrollDownButton() {
+        self.addSubview(scrollDownButton)
+        NSLayoutConstraint.activate([
+            scrollDownButton.constraintAlignTopTo(self, paddingTop: -52),
+            scrollDownButton.constraintAlignTrailingTo(self, paddingTrailing: 12),
+            scrollDownButton.constraintHeightTo(40),
+            scrollDownButton.constraintWidthTo(40)
+        ])
+        scrollDownButton.backgroundColor = DcColors.defaultBackgroundColor
+        scrollDownButton.setImage(UIImage(named: "ic_scrolldown")?.sd_tintedImage(with: .systemBlue), for: .normal)
+        scrollDownButton.layer.cornerRadius = 20
+        scrollDownButton.layer.borderColor = DcColors.colorDisabled.cgColor
+        scrollDownButton.layer.borderWidth = 1
+        scrollDownButton.layer.masksToBounds = true
+        scrollDownButton.accessibilityLabel = String.localized("menu_scroll_to_bottom")
+    }
+    
+    public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+        if !scrollDownButton.isHidden {
+            let scrollButtonViewPoint = self.scrollDownButton.convert(point, from: self)
+            if let view = scrollDownButton.hitTest(scrollButtonViewPoint, with: event) {
+                return view
+            }
+        }
+        return super.hitTest(point, with: event)
+    }
+    
+    public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
+        if !scrollDownButton.isHidden && scrollDownButton.point(inside: convert(point, to: scrollDownButton), with: event) {
+            return true
+        }
+        return super.point(inside: point, with: event)
+    }
 }