Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Aranoledur committed Sep 18, 2023
2 parents d739a41 + 0cbfff8 commit 52481e1
Show file tree
Hide file tree
Showing 78 changed files with 274 additions and 152 deletions.
2 changes: 1 addition & 1 deletion ChatLayout.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'ChatLayout'
s.version = '1.3.0'
s.version = '1.3.4'
s.summary = 'Chat UI Library. It uses custom UICollectionViewLayout to provide you full control over the presentation.'
s.swift_version = '5.8'

Expand Down
33 changes: 32 additions & 1 deletion ChatLayout/Classes/Core/CollectionViewChatLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public final class CollectionViewChatLayout: UICollectionViewLayout {

private let _flipsHorizontallyInOppositeLayoutDirection: Bool

private var reconfigureItemsIndexPaths: [IndexPath] = []

// MARK: IOS 15.1 fix flags

private var needsIOS15_1IssueFix: Bool {
Expand Down Expand Up @@ -283,17 +285,29 @@ public final class CollectionViewChatLayout: UICollectionViewLayout {
guard let collectionView else {
return
}

// We do not want to return attributes while we just looking for a position so that `UICollectionView` wont
// create unnecessary cells that may not be used when we find the actual position.
dontReturnAttributes = true
collectionView.setNeedsLayout()
collectionView.layoutIfNeeded()
currentPositionSnapshot = snapshot
let context = ChatLayoutInvalidationContext()
context.invalidateLayoutMetrics = false
invalidateLayout(with: context)

dontReturnAttributes = false
collectionView.setNeedsLayout()
collectionView.layoutIfNeeded()
currentPositionSnapshot = nil
}

/// If you want to use new `UICollectionView.reconfigureItems(..)` api and expect the reconfiguration to happen animated as well
/// - you must call this method next to the `UICollectionView` one. `UIKit` in its classic way uses private API to process it.
public func reconfigureItems(at indexPaths: [IndexPath]) {
reconfigureItemsIndexPaths = indexPaths
}

// MARK: Providing Layout Attributes

/// Tells the layout object to update the current layout.
Expand Down Expand Up @@ -523,7 +537,7 @@ public final class CollectionViewChatLayout: UICollectionViewLayout {
let newItemSize = itemSize(with: preferredMessageAttributes)
let newInterItemSpacing = interItemSpacing(for: preferredMessageAttributes.kind, at: preferredMessageAttributes.indexPath)
let newItemAlignment: ChatItemAlignment
if controller.reloadedIndexes.contains(preferredMessageAttributes.indexPath) {
if controller.reloadedIndexes.contains(preferredMessageAttributes.indexPath) || reconfigureItemsIndexPaths.contains(preferredMessageAttributes.indexPath) {
newItemAlignment = alignment(for: preferredMessageAttributes.kind, at: preferredMessageAttributes.indexPath)
} else {
newItemAlignment = preferredMessageAttributes.alignment
Expand Down Expand Up @@ -684,6 +698,23 @@ public final class CollectionViewChatLayout: UICollectionViewLayout {
controller.process(changeItems: changeItems)
state = .afterUpdate
dontReturnAttributes = false

if !reconfigureItemsIndexPaths.isEmpty,
let collectionView {
reconfigureItemsIndexPaths
.filter { collectionView.indexPathsForVisibleItems.contains($0) && !controller.reloadedIndexes.contains($0) }
.forEach { indexPath in
let cell = collectionView.cellForItem(at: indexPath)

if let originalAttributes = controller.itemAttributes(for: indexPath.itemPath, kind: .cell, at: .beforeUpdate),
let preferredAttributes = cell?.preferredLayoutAttributesFitting(originalAttributes),
shouldInvalidateLayout(forPreferredLayoutAttributes: preferredAttributes, withOriginalAttributes: originalAttributes) {
_ = invalidationContext(forPreferredLayoutAttributes: preferredAttributes, withOriginalAttributes: originalAttributes)
}
}
reconfigureItemsIndexPaths = []
}

super.prepare(forCollectionViewUpdates: updateItems)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ extension RandomAccessCollection where Index == Int {

while lowerBound < upperBound {
let midIndex = lowerBound &+ (upperBound &- lowerBound) / 2
if predicate(self[midIndex]) == .orderedSame {
let result = predicate(self[midIndex])
if result == .orderedSame {
return midIndex
} else if predicate(self[midIndex]) == .orderedAscending {
} else if result == .orderedAscending {
lowerBound = midIndex &+ 1
} else {
upperBound = midIndex
Expand Down
10 changes: 5 additions & 5 deletions ChatLayout/Classes/Core/Model/StateController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ final class StateController<Layout: ChatLayoutRepresentation> {
let predicate: (ChatLayoutAttributes) -> ComparisonResult = { attributes in
if attributes.frame.intersects(rect) {
return .orderedSame
} else if attributes.frame.minY > rect.maxY {
} else if attributes.frame.minY >= rect.maxY {
return .orderedDescending
} else if attributes.frame.maxY < rect.minY {
} else if attributes.frame.maxY <= rect.minY {
return .orderedAscending
}
return .orderedSame
Expand Down Expand Up @@ -790,7 +790,7 @@ final class StateController<Layout: ChatLayoutRepresentation> {
if visibleRect.intersects(rect) {
return true
} else {
if rect.minY > visibleRect.maxY + batchUpdateCompensatingOffset + proposedCompensatingOffset {
if rect.minY >= visibleRect.maxY + batchUpdateCompensatingOffset + proposedCompensatingOffset {
traverseState = .done
}
return false
Expand Down Expand Up @@ -835,9 +835,9 @@ final class StateController<Layout: ChatLayoutRepresentation> {
}
if itemFrame.intersects(visibleRect) {
return .orderedSame
} else if itemFrame.minY > visibleRect.maxY {
} else if itemFrame.minY >= visibleRect.maxY {
return .orderedDescending
} else if itemFrame.maxX < visibleRect.minY {
} else if itemFrame.maxX <= visibleRect.minY {
return .orderedAscending
}
return .orderedSame
Expand Down
14 changes: 7 additions & 7 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
PODS:
- ChatLayout (1.3.0):
- ChatLayout/Ultimate (= 1.3.0)
- ChatLayout/Core (1.3.0)
- ChatLayout/Extras (1.3.0):
- ChatLayout (1.3.3):
- ChatLayout/Ultimate (= 1.3.3)
- ChatLayout/Core (1.3.3)
- ChatLayout/Extras (1.3.3):
- ChatLayout/Core
- ChatLayout/Ultimate (1.3.0):
- ChatLayout/Ultimate (1.3.3):
- ChatLayout/Core
- ChatLayout/Extras
- DifferenceKit (1.3.0):
Expand Down Expand Up @@ -35,11 +35,11 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
ChatLayout: 620aaa4cf30ce188cef80eb1dad391c9c250c5e2
ChatLayout: 9a12f3e2d446ac3096b6539c70b4654fa35f1401
DifferenceKit: ab185c4d7f9cef8af3fcf593e5b387fb81e999ca
FPSCounter: 884afec377de66637808c4f52ecc3b85a404732b
InputBarAccessoryView: 1d7b0a672b36e370f01f264b3907ef39d03328e3

PODFILE CHECKSUM: 0bbac6c60b293f3e90bba25beda75886a6fbcb05

COCOAPODS: 1.11.3
COCOAPODS: 1.12.1
28 changes: 28 additions & 0 deletions Example/Tests/HelpersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ final class HelpersTests: XCTestCase {
XCTAssertEqual((150...170).map { $0 }.binarySearch(predicate: predicate), nil)
}

func testBinarySearchWithCGRect() {
let visibleRect = CGRect(origin: .init(x: 0, y: 100), size: .init(width: 100, height: 100))
let predicate: (CGRect) -> ComparisonResult = { frame in
if frame.intersects(visibleRect) {
return .orderedSame
} else if frame.minY >= visibleRect.maxY {
return .orderedDescending
} else if frame.maxX <= visibleRect.minY {
return .orderedAscending
}
XCTFail("Should not get here")
return .orderedSame
}
XCTAssertEqual([CGRect]().binarySearch(predicate: predicate), nil)
XCTAssertEqual((0...5).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearch(predicate: predicate), 3)
XCTAssertEqual((-1...1).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearch(predicate: predicate), nil)
XCTAssertEqual((1...1).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearch(predicate: predicate), nil)
XCTAssertEqual((4...7).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearch(predicate: predicate), nil)
XCTAssertEqual((4...4).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearch(predicate: predicate), nil)

XCTAssertEqual([CGRect]().binarySearchRange(predicate: predicate), [])
XCTAssertEqual((0...5).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearchRange(predicate: predicate).count, 2)
XCTAssertEqual((-1...1).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearchRange(predicate: predicate).count, 0)
XCTAssertEqual((1...1).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearchRange(predicate: predicate).count, 0)
XCTAssertEqual((4...7).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearchRange(predicate: predicate).count, 0)
XCTAssertEqual((4...4).map { CGRect(origin: .init(x: 0, y: $0 * 50), size: .init(width: 100, height: 50)) }.binarySearchRange(predicate: predicate).count, 0)
}

func testSearchInRange() {
let predicate: (Int) -> ComparisonResult = { integer in
if integer < 100 {
Expand Down
2 changes: 1 addition & 1 deletion Example/Tests/PerformanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class PerformanceTests: XCTestCase {

let rect = CGRect(origin: CGPoint(x: 0, y: 99999), size: CGSize(width: 300, height: 2))
let attributes = layout.controller.layoutAttributesForElements(in: rect, state: .beforeUpdate, ignoreCache: true)
XCTAssertEqual(attributes.count, 4)
XCTAssertEqual(attributes.count, 2)
measure {
for _ in 0..<10 {
_ = layout.controller.layoutAttributesForElements(in: rect, state: .beforeUpdate, ignoreCache: true)
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
source "https://rubygems.org"

gem "slather", "2.6.1"
gem "slather", "2.7.4"
gem "cocoapods"
gem "jazzy"
4 changes: 2 additions & 2 deletions docs/Classes/CellLayoutContainerView.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -464,7 +464,7 @@ <h4>Parameters</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/ChatLayoutAttributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -423,7 +423,7 @@ <h4>Declaration</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/ChatLayoutInvalidationContext.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -208,7 +208,7 @@ <h4>Declaration</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
35 changes: 33 additions & 2 deletions docs/Classes/CollectionViewChatLayout.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -750,6 +750,37 @@ <h4>Parameters</h4>
</section>
</div>
</li>
<li class="item">
<div>
<code>
<a name="/s:10ChatLayout014CollectionViewaB0C16reconfigureItems2atySay10Foundation9IndexPathVG_tF"></a>
<a name="//apple_ref/swift/Method/reconfigureItems(at:)" class="dashAnchor"></a>
<a class="token" href="#/s:10ChatLayout014CollectionViewaB0C16reconfigureItems2atySay10Foundation9IndexPathVG_tF">reconfigureItems(at:<wbr>)</a>
</code>
</div>
<div class="height-container">
<div class="pointer-container"></div>
<section class="section">
<div class="pointer"></div>
<div class="abstract">
<p>If you want to use new <code>UICollectionView.reconfigureItems(..)</code> api and expect the reconfiguration to happen animated as well</p>

<ul>
<li>you must call this method next to the <code>UICollectionView</code> one. <code>UIKit</code> in its classic way uses private API to process it.</li>
</ul>

</div>
<div class="declaration">
<h4>Declaration</h4>
<div class="language">
<p class="aside-title">Swift</p>
<pre class="highlight swift"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">reconfigureItems</span><span class="p">(</span><span class="n">at</span> <span class="nv">indexPaths</span><span class="p">:</span> <span class="p">[</span><span class="kt">IndexPath</span><span class="p">])</span></code></pre>

</div>
</div>
</section>
</div>
</li>
</ul>
</div>
<div class="task-group">
Expand Down Expand Up @@ -1354,7 +1385,7 @@ <h4>Declaration</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/ContainerCollectionReusableView.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -384,7 +384,7 @@ <h4>Parameters</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/ContainerCollectionViewCell.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -384,7 +384,7 @@ <h4>Parameters</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/EdgeAligningView.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<header class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="../index.html">
ChatLayout 1.3.0 Docs
ChatLayout 1.3.4 Docs
</a>
(100% documented)
</p>
Expand Down Expand Up @@ -536,7 +536,7 @@ <h4>Declaration</h4>
</article>
</div>
<section class="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-05-19)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/ekazaev" target="_blank" rel="external noopener">Evgeny Kazaev</a>. All rights reserved. (Last updated: 2023-08-16)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</body>
Expand Down
Loading

0 comments on commit 52481e1

Please sign in to comment.