Skip to content

Commit d26da55

Browse files
committed
Added keepContentAtBottomOfVisibleArea flag
1 parent c26d49c commit d26da55

File tree

76 files changed

+221
-144
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+221
-144
lines changed

ChatLayout.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'ChatLayout'
3-
s.version = '2.0.4'
3+
s.version = '2.0.5'
44
s.summary = 'Chat UI Library. It uses custom UICollectionViewLayout to provide you full control over the presentation.'
55
s.swift_version = '5.8'
66

ChatLayout/Classes/Core/CollectionViewChatLayout.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ open class CollectionViewChatLayout: UICollectionViewLayout {
5252
}
5353
}
5454

55-
/// Default `UIScrollView` behaviour is to keep content offset constant from the top edge. If this flag is set to `true`
55+
/// The default `UIScrollView` behaviour is to keep content offset constant from the top edge. If this flag is set to `true`
5656
/// `CollectionViewChatLayout` should try to compensate batch update changes to keep the current content at the bottom of the visible
5757
/// part of `UICollectionView`.
5858
///
@@ -61,6 +61,11 @@ open class CollectionViewChatLayout: UICollectionViewLayout {
6161
/// the animation starts and wont be able to compensate that change too. It should be done manually.
6262
public var keepContentOffsetAtBottomOnBatchUpdates: Bool = false
6363

64+
/// The default behavior of UICollectionView is to maintain UICollectionViewCells at the top of the visible rectangle
65+
/// when the content size is smaller than the visible area. By setting the respective flag to true, this behavior can be
66+
/// reversed to achieve the result like in Telegram..
67+
public var keepContentAtBottomOfVisibleArea: Bool = false
68+
6469
/// Sometimes `UIScrollView` can behave weirdly if there are too many corrections in it's `contentOffset` during the animation. Especially when content size of the `UIScrollView`
6570
// is getting smaller first and then expands again as the newly appearing cells sizes are being calculated. That is why `CollectionViewChatLayout`
6671
/// tries to process only the elements that are currently visible on the screen. But often it is not needed. This flag allows you to have fine control over this behaviour.

ChatLayout/Classes/Core/Model/StateController.swift

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protocol ChatLayoutRepresentation: AnyObject {
2727

2828
var keepContentOffsetAtBottomOnBatchUpdates: Bool { get }
2929

30+
var keepContentAtBottomOfVisibleArea: Bool { get }
31+
3032
var processOnlyVisibleItemsOnAnimatedBatchUpdates: Bool { get }
3133

3234
func numberOfItems(in section: Int) -> Int
@@ -359,6 +361,11 @@ final class StateController<Layout: ChatLayoutRepresentation> {
359361
if isFinal {
360362
offsetByCompensation(frame: &itemFrame, at: itemPath, for: state, backward: true)
361363
}
364+
if layoutRepresentation.keepContentAtBottomOfVisibleArea == true,
365+
!(kind == .header && itemPath.section == 0),
366+
!isLayoutBiggerThanVisibleBounds(at: state, withFullCompensation: false, visibleBounds: visibleBounds) {
367+
itemFrame.offsettingBy(dx: 0, dy: visibleBounds.height.rounded() - contentSize(for: state).height.rounded())
368+
}
362369
return itemFrame
363370
}
364371

Example/ChatLayout/Chat/View/ChatViewController.swift

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ final class ChatViewController: UIViewController {
133133
chatLayout.settings.additionalInsets = UIEdgeInsets(top: 8, left: 5, bottom: 8, right: 5)
134134
chatLayout.keepContentOffsetAtBottomOnBatchUpdates = true
135135
chatLayout.processOnlyVisibleItemsOnAnimatedBatchUpdates = false
136+
chatLayout.keepContentAtBottomOfVisibleArea = true
136137

137138
collectionView = UICollectionView(frame: view.frame, collectionViewLayout: chatLayout)
138139
view.addSubview(collectionView)
@@ -453,6 +454,10 @@ extension ChatViewController: UICollectionViewDelegate {
453454

454455
extension ChatViewController: ChatControllerDelegate {
455456
func update(with sections: [Section], requiresIsolatedProcess: Bool) {
457+
// if `chatLayout.keepContentAtBottomOfVisibleArea` is enabled and content size is actually smaller than the visible size - it is better to process each batch update
458+
// in isolation. Example: If you insert a cell animatingly and then reload some cell - the reload animation will appear on top of the insertion animation.
459+
// Basically everytime you see any animation glitches - process batch updates in isolation.
460+
let requiresIsolatedProcess = chatLayout.keepContentAtBottomOfVisibleArea == true && chatLayout.collectionViewContentSize.height < chatLayout.visibleBounds.height ? true : requiresIsolatedProcess
456461
processUpdates(with: sections, animated: true, requiresIsolatedProcess: requiresIsolatedProcess)
457462
}
458463

Example/Podfile.lock

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
PODS:
2-
- ChatLayout (2.0.3):
3-
- ChatLayout/Ultimate (= 2.0.3)
4-
- ChatLayout/Core (2.0.3)
5-
- ChatLayout/Extras (2.0.3):
2+
- ChatLayout (2.0.5):
3+
- ChatLayout/Ultimate (= 2.0.5)
4+
- ChatLayout/Core (2.0.5)
5+
- ChatLayout/Extras (2.0.5):
66
- ChatLayout/Core
7-
- ChatLayout/Ultimate (2.0.3):
7+
- ChatLayout/Ultimate (2.0.5):
88
- ChatLayout/Core
99
- ChatLayout/Extras
1010
- DifferenceKit (1.3.0):
@@ -35,7 +35,7 @@ EXTERNAL SOURCES:
3535
:path: "../"
3636

3737
SPEC CHECKSUMS:
38-
ChatLayout: 0e958d11b184b64116eb8b37009e4f1aa5b9385f
38+
ChatLayout: 73e77fd1d5f3ea46dfee7045804d00116395bf04
3939
DifferenceKit: ab185c4d7f9cef8af3fcf593e5b387fb81e999ca
4040
FPSCounter: 884afec377de66637808c4f52ecc3b85a404732b
4141
InputBarAccessoryView: 1d7b0a672b36e370f01f264b3907ef39d03328e3

Example/Tests/MockCollectionLayout.swift

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class MockCollectionLayout: ChatLayoutRepresentation, ChatLayoutDelegate {
4444

4545
let keepContentOffsetAtBottomOnBatchUpdates: Bool = true
4646

47+
let keepContentAtBottomOfVisibleArea: Bool = false
48+
4749
let processOnlyVisibleItemsOnAnimatedBatchUpdates: Bool = true
4850

4951
func numberOfItems(in section: Int) -> Int {

docs/Classes/CellLayoutContainerView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -464,7 +464,7 @@ <h4>Parameters</h4>
464464
</article>
465465
</div>
466466
<section class="footer">
467-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
467+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
468468
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
469469
</section>
470470
</body>

docs/Classes/ChatLayoutAttributes.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -450,7 +450,7 @@ <h4>Declaration</h4>
450450
</article>
451451
</div>
452452
<section class="footer">
453-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
453+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
454454
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
455455
</section>
456456
</body>

docs/Classes/ChatLayoutInvalidationContext.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -208,7 +208,7 @@ <h4>Declaration</h4>
208208
</article>
209209
</div>
210210
<section class="footer">
211-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
211+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
212212
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
213213
</section>
214214
</body>

docs/Classes/CollectionViewChatLayout.html

+32-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -269,7 +269,7 @@ <h4>Declaration</h4>
269269
<section class="section">
270270
<div class="pointer"></div>
271271
<div class="abstract">
272-
<p>Default <code>UIScrollView</code> behaviour is to keep content offset constant from the top edge. If this flag is set to <code>true</code>
272+
<p>The default <code>UIScrollView</code> behaviour is to keep content offset constant from the top edge. If this flag is set to <code>true</code>
273273
<code>CollectionViewChatLayout</code> should try to compensate batch update changes to keep the current content at the bottom of the visible
274274
part of <code>UICollectionView</code>.</p>
275275

@@ -289,6 +289,35 @@ <h4>Declaration</h4>
289289
</section>
290290
</div>
291291
</li>
292+
<li class="item">
293+
<div>
294+
<code>
295+
<a name="/s:10ChatLayout014CollectionViewaB0C32keepContentAtBottomOfVisibleAreaSbvp"></a>
296+
<a name="//apple_ref/swift/Property/keepContentAtBottomOfVisibleArea" class="dashAnchor"></a>
297+
<a class="token" href="#/s:10ChatLayout014CollectionViewaB0C32keepContentAtBottomOfVisibleAreaSbvp">keepContentAtBottomOfVisibleArea</a>
298+
</code>
299+
</div>
300+
<div class="height-container">
301+
<div class="pointer-container"></div>
302+
<section class="section">
303+
<div class="pointer"></div>
304+
<div class="abstract">
305+
<p>The default behavior of UICollectionView is to maintain UICollectionViewCells at the top of the visible rectangle
306+
when the content size is smaller than the visible area. By setting the respective flag to true, this behavior can be
307+
reversed to achieve the result like in Telegram..</p>
308+
309+
</div>
310+
<div class="declaration">
311+
<h4>Declaration</h4>
312+
<div class="language">
313+
<p class="aside-title">Swift</p>
314+
<pre class="highlight swift"><code><span class="kd">public</span> <span class="k">var</span> <span class="nv">keepContentAtBottomOfVisibleArea</span><span class="p">:</span> <span class="kt">Bool</span></code></pre>
315+
316+
</div>
317+
</div>
318+
</section>
319+
</div>
320+
</li>
292321
<li class="item">
293322
<div>
294323
<code>
@@ -1421,7 +1450,7 @@ <h4>Declaration</h4>
14211450
</article>
14221451
</div>
14231452
<section class="footer">
1424-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
1453+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
14251454
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
14261455
</section>
14271456
</body>

docs/Classes/ContainerCollectionReusableView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -384,7 +384,7 @@ <h4>Parameters</h4>
384384
</article>
385385
</div>
386386
<section class="footer">
387-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
387+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
388388
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
389389
</section>
390390
</body>

docs/Classes/ContainerCollectionViewCell.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -384,7 +384,7 @@ <h4>Parameters</h4>
384384
</article>
385385
</div>
386386
<section class="footer">
387-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
387+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
388388
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
389389
</section>
390390
</body>

docs/Classes/EdgeAligningView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -536,7 +536,7 @@ <h4>Declaration</h4>
536536
</article>
537537
</div>
538538
<section class="footer">
539-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
539+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
540540
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
541541
</section>
542542
</body>

docs/Classes/EdgeAligningView/Edge.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -288,7 +288,7 @@ <h4>Declaration</h4>
288288
</article>
289289
</div>
290290
<section class="footer">
291-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
291+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
292292
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
293293
</section>
294294
</body>

docs/Classes/ImageMaskedView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -408,7 +408,7 @@ <h4>Declaration</h4>
408408
</article>
409409
</div>
410410
<section class="footer">
411-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
411+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
412412
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
413413
</section>
414414
</body>

docs/Classes/MessageContainerView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -354,7 +354,7 @@ <h4>Parameters</h4>
354354
</article>
355355
</div>
356356
<section class="footer">
357-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
357+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
358358
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
359359
</section>
360360
</body>

docs/Classes/RoundedCornersContainerView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -354,7 +354,7 @@ <h4>Declaration</h4>
354354
</article>
355355
</div>
356356
<section class="footer">
357-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
357+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
358358
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
359359
</section>
360360
</body>

docs/Classes/SwappingContainerView.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<header class="header">
2222
<p class="header-col header-col--primary">
2323
<a class="header-link" href="../index.html">
24-
ChatLayout 2.0.4 Docs
24+
ChatLayout 2.0.5 Docs
2525
</a>
2626
(100% documented)
2727
</p>
@@ -599,7 +599,7 @@ <h4>Declaration</h4>
599599
</article>
600600
</div>
601601
<section class="footer">
602-
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-03-11)</p>
602+
<p>&copy; 2024 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2024-04-30)</p>
603603
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
604604
</section>
605605
</body>

0 commit comments

Comments
 (0)