Skip to content

Commit 769dc74

Browse files
authored
Merge pull request MessageKit#395 from zhongwuzw/fix-scroll-to-bottm
Fix scrollToBottom && remove scrollsToBottomOnFirstLayout
2 parents 0af6454 + ad4c5c3 commit 769dc74

9 files changed

Lines changed: 81 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
66

77
## Upcoming release
88

9+
### Fixed
10+
11+
- Fixed `indexPathForLastItem` bug when `numberOfSections` equal to 1.
12+
[#395](https://github.com/MessageKit/MessageKit/issues/395) by [@zhongwuzw](https://github.com/zhongwuzw).
13+
14+
- Fixed `scrollToBottom(animated:)` not work in some situations.
15+
[#395](https://github.com/MessageKit/MessageKit/issues/395) by [@zhongwuzw](https://github.com/zhongwuzw).
16+
917
### Changed
1018

1119
- **Breaking Change** Removed the generic constraint `<ContentView: UIView>` from `MessageCollectionViewCell`.
@@ -26,6 +34,11 @@ and `messageLabel` for `TextMessageCell`.
2634
- **Breaking Change** Adds a new view `contentView` of type `UIView` to the MessageInputBar to hold the main subviews of the `MessageInputBar`. Reduces complexity of constraints for easier testing/debugging.
2735
[#384](https://github.com/MessageKit/MessageKit/pull/384) by [@nathantannar4](https://github.com/nathantannar4).
2836

37+
### Removed
38+
39+
- **Breaking Change** Removed `scrollsToBottomOnFirstLayout` flag of `MessagesViewController`.
40+
[#395](https://github.com/MessageKit/MessageKit/pull/395) by [@zhongwuzw](https://github.com/zhongwuzw).
41+
2942
## [[Prerelease] 0.11.0](https://github.com/MessageKit/MessageKit/releases/tag/0.11.0)
3043

3144
### Added

Example/Sources/ConversationViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ConversationViewController: MessagesViewController {
3232
didSet {
3333
DispatchQueue.main.async {
3434
self.messagesCollectionView.reloadData()
35+
self.messagesCollectionView.scrollToBottom()
3536
}
3637
}
3738
}
@@ -55,7 +56,6 @@ class ConversationViewController: MessagesViewController {
5556
messagesCollectionView.messageCellDelegate = self
5657
messageInputBar.delegate = self
5758
messageInputBar.sendButton.tintColor = UIColor(red: 69/255, green: 193/255, blue: 89/255, alpha: 1)
58-
scrollsToBottomOnFirstLayout = true //default false
5959
scrollsToBottomOnKeybordBeginsEditing = true // default false
6060

6161
navigationItem.rightBarButtonItems = [

MessageKit.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0EE91E661FDEC888005420A2 /* CGRect+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE91E651FDEC887005420A2 /* CGRect+Extensions.swift */; };
1011
1F066E131FD90BB600E11013 /* MessagesViewControllerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7FC8CB1FD2700B006CC979 /* MessagesViewControllerSpec.swift */; };
1112
1F066E141FD90BB700E11013 /* MessageLabelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F066E101FD90A0600E11013 /* MessageLabelSpec.swift */; };
1213
1F066E1D1FDA3C1700E11013 /* SenderSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F066E1C1FDA3C1700E11013 /* SenderSpec.swift */; };
@@ -104,6 +105,7 @@
104105
/* End PBXCopyFilesBuildPhase section */
105106

106107
/* Begin PBXFileReference section */
108+
0EE91E651FDEC887005420A2 /* CGRect+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGRect+Extensions.swift"; sourceTree = "<group>"; };
107109
1F066E101FD90A0600E11013 /* MessageLabelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageLabelSpec.swift; sourceTree = "<group>"; };
108110
1F066E1C1FDA3C1700E11013 /* SenderSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SenderSpec.swift; sourceTree = "<group>"; };
109111
1F066E201FDA3DEA00E11013 /* AvatarSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarSpec.swift; sourceTree = "<group>"; };
@@ -351,6 +353,7 @@
351353
B09643981F295D43004D0129 /* Extensions */ = {
352354
isa = PBXGroup;
353355
children = (
356+
0EE91E651FDEC887005420A2 /* CGRect+Extensions.swift */,
354357
B7A03F671F8669EB006AEF79 /* Bundle+Extensions.swift */,
355358
B7A03F681F8669EB006AEF79 /* NSAttributedString+Extensions.swift */,
356359
B7A03F691F8669EB006AEF79 /* String+Extensions.swift */,
@@ -604,6 +607,7 @@
604607
B7A03F251F866895006AEF79 /* NSConstraintLayoutSet.swift in Sources */,
605608
B7A03F341F866940006AEF79 /* MessageFooterView.swift in Sources */,
606609
B7A03F621F8669CA006AEF79 /* MessageInputBarDelegate.swift in Sources */,
610+
0EE91E661FDEC888005420A2 /* CGRect+Extensions.swift in Sources */,
607611
B7A03F181F86682C006AEF79 /* MessagesCollectionViewFlowLayout.swift in Sources */,
608612
B7A03F2A1F866895006AEF79 /* MessageStyle.swift in Sources */,
609613
B7A03F4D1F86694F006AEF79 /* MessagesCollectionView.swift in Sources */,

Sources/Controllers/MessagesViewController.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ open class MessagesViewController: UIViewController {
3434

3535
/// The `MessageInputBar` used as the `inputAccessoryView` in the view controller.
3636
open var messageInputBar = MessageInputBar()
37-
38-
/// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the
39-
/// bottom on the view's first layout.
40-
///
41-
/// The default value of this property is `false`.
42-
open var scrollsToBottomOnFirstLayout: Bool = false
4337

4438
/// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the
4539
/// bottom whenever the `InputTextView` begins editing.
@@ -88,11 +82,6 @@ open class MessagesViewController: UIViewController {
8882
addKeyboardObservers()
8983
messagesCollectionView.contentInset.bottom = keyboardOffsetFrame.height
9084
messagesCollectionView.scrollIndicatorInsets.bottom = keyboardOffsetFrame.height
91-
92-
//Scroll to bottom at first load
93-
if scrollsToBottomOnFirstLayout {
94-
messagesCollectionView.scrollToBottom(animated: false)
95-
}
9685
}
9786
}
9887

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2017 MessageKit
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
import Foundation
26+
27+
extension CGRect {
28+
29+
init(_ x: CGFloat, _ y: CGFloat, _ w: CGFloat, _ h: CGFloat) {
30+
self.init(x: x, y: y, width: w, height: h)
31+
}
32+
33+
}
34+

Sources/Supporting/MessageKit+Availability.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,14 @@ extension MessagesCollectionViewFlowLayout {
8787
}
8888

8989
}
90+
91+
extension MessagesViewController {
92+
/// A Boolean value that determines whether the `MessagesCollectionView` scrolls to the
93+
/// bottom on the view's first layout.
94+
///
95+
/// The default value of this property is `false`.
96+
@available(*, deprecated: 0.11.1, message: "Removed in MessageKit 0.11.1.")
97+
open var scrollsToBottomOnFirstLayout: Bool {
98+
fatalError("Fatal Error: scrollsToBottomOnFirstLayout is no longer supported")
99+
}
100+
}

Sources/Views/AvatarView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ open class AvatarView: UIView {
108108
let textTextHeight: CGFloat = initials.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).height
109109
context.saveGState()
110110
context.clip(to: textRect)
111-
initials.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight) / 2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes)
111+
initials.draw(in: CGRect(textRect.minX, textRect.minY + (textRect.height - textTextHeight) / 2, textRect.width, textTextHeight), withAttributes: textFontAttributes)
112112
context.restoreGState()
113113
guard let renderedImage = UIGraphicsGetImageFromCurrentImageContext() else { assertionFailure("Could not create image from context"); return UIImage()}
114114
return renderedImage
@@ -146,7 +146,7 @@ open class AvatarView: UIView {
146146
let startX = (outerViewWidth - w)/2
147147
let startY = (outerViewHeight - h)/2
148148
// In case the font exactly fits to the region, put 2 pixel both left and right
149-
return CGRect(x: startX+2, y: startY, width: w-4, height: h)
149+
return CGRect(startX+2, startY, w-4, h)
150150
}
151151

152152
required public init?(coder aDecoder: NSCoder) {

Sources/Views/MessagesCollectionView.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ open class MessagesCollectionView: UICollectionView {
4040

4141
private var indexPathForLastItem: IndexPath? {
4242

43-
let lastSection = numberOfSections > 0 ? numberOfSections - 1 : 0
44-
guard lastSection > 0, numberOfItems(inSection: lastSection) > 0 else { return nil }
43+
let lastSection = numberOfSections - 1
44+
guard lastSection >= 0, numberOfItems(inSection: lastSection) > 0 else { return nil }
4545
return IndexPath(item: numberOfItems(inSection: lastSection) - 1, section: lastSection)
4646

4747
}
@@ -65,7 +65,20 @@ open class MessagesCollectionView: UICollectionView {
6565

6666
public func scrollToBottom(animated: Bool = false) {
6767
guard let indexPath = indexPathForLastItem else { return }
68-
scrollToItem(at: indexPath, at: .bottom, animated: animated)
68+
69+
let collectionViewContentHeight = collectionViewLayout.collectionViewContentSize.height
70+
let isContentTooSmall = (collectionViewContentHeight < bounds.height * 2)
71+
72+
if isContentTooSmall {
73+
performBatchUpdates(nil) { _ in
74+
self.scrollRectToVisible(CGRect(0.0, collectionViewContentHeight - 1.0, 1.0, 1.0), animated: animated)
75+
}
76+
return
77+
}
78+
79+
performBatchUpdates(nil) { _ in
80+
self.scrollToItem(at: indexPath, at: .bottom, animated: animated)
81+
}
6982
}
7083

7184
}

Tests/ControllersTest/MessagesViewControllerSpec.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ final class MessagesViewControllerSpec: QuickSpec {
3939

4040
describe("default property values") {
4141
context("after initialization") {
42-
it("sets scrollsToBottomOnFirstLayout to false") {
43-
expect(controller.scrollsToBottomOnFirstLayout).to(beFalse())
44-
}
4542
it("sets scrollsToBottomOnKeyboardBeginsEditing to false") {
4643
expect(controller.scrollsToBottomOnKeybordBeginsEditing).to(beFalse())
4744
}
@@ -139,19 +136,6 @@ final class MessagesViewControllerSpec: QuickSpec {
139136
}
140137
}
141138

142-
describe("scrolling behavior on first layout") {
143-
context("scrollsToBottomOnFirstLayout is true") {
144-
it("should scroll to bottom") {
145-
146-
}
147-
}
148-
context("scrollsToBottomOnFirstLayout is false") {
149-
it("should not scroll to bottom") {
150-
151-
}
152-
}
153-
}
154-
155139
describe("calling messagesCollectionView.scrollToBottom()") {
156140
context("all messages are visible") {
157141
it("should scroll to bottom") {

0 commit comments

Comments
 (0)