Skip to content

Commit 95aefee

Browse files
author
Eugene Kazaev
committed
Minor performance improvements
1 parent 51bacfa commit 95aefee

File tree

188 files changed

+4507
-3897
lines changed

Some content is hidden

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

188 files changed

+4507
-3897
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 = '1.1.15'
3+
s.version = '1.1.16'
44
s.summary = 'Chat UI Library. It uses custom UICollectionViewLayout to provide you full control over the presentation.'
55
s.swift_version = '5.2'
66

ChatLayout/Classes/Core/ChatItemAlignment.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatItemAlignment.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayout.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayout.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayoutAttributes.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayoutAttributes.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayoutDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayoutDelegate.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayoutInvalidationContext.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayoutInvalidationContext.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayoutPositionSnapshot.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayoutPositionSnapshot.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/ChatLayoutSettings.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatLayoutSettings.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Extensions/CGRect+Extension.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// CGRect+Extension.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Extensions/IndexPath+Extension.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// IndexPath+Extension.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ChangeItem.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChangeItem.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ItemKind.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ItemKind.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ItemModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ItemModel.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ItemPath.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ItemPath.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ItemSize.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ItemSize.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/LayoutModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// LayoutModel.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/ModelState.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ModelState.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/SectionModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// SectionModel.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Core/Model/StateController.swift

+50-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// StateController.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

@@ -99,17 +99,33 @@ final class StateController {
9999
func layoutAttributesForElements(in rect: CGRect,
100100
state: ModelState,
101101
ignoreCache: Bool = false) -> [ChatLayoutAttributes] {
102+
let predicate: (ChatLayoutAttributes) -> ComparisonResult = { attributes in
103+
if attributes.frame.intersects(rect) {
104+
return .orderedSame
105+
}
106+
if attributes.frame.minY > rect.maxY {
107+
return .orderedDescending
108+
}
109+
return .orderedAscending
110+
}
111+
102112
if !ignoreCache,
103113
let cachedAttributesState = cachedAttributesState,
104114
cachedAttributesState.rect.contains(rect) {
105-
return cachedAttributesState.attributes.filter { $0.frame.intersects(rect) }
115+
return cachedAttributesState.attributes.binarySearchRange(predicate: predicate)
106116
} else {
107-
let totalRect = rect.inset(by: UIEdgeInsets(top: -rect.height / 2, left: -rect.width / 2, bottom: -rect.height / 2, right: -rect.width / 2))
117+
let totalRect: CGRect
118+
switch state {
119+
case .beforeUpdate:
120+
totalRect = rect.inset(by: UIEdgeInsets(top: -rect.height / 2, left: -rect.width / 2, bottom: -rect.height / 2, right: -rect.width / 2))
121+
case .afterUpdate:
122+
totalRect = rect
123+
}
108124
let attributes = allAttributes(at: state, visibleRect: totalRect)
109125
if !ignoreCache {
110126
cachedAttributesState = (rect: totalRect, attributes: attributes)
111127
}
112-
let visibleAttributes = attributes.filter { $0.frame.intersects(rect) }
128+
let visibleAttributes = rect != totalRect ? attributes.binarySearchRange(predicate: predicate) : attributes
113129
return visibleAttributes
114130
}
115131
}
@@ -650,10 +666,10 @@ final class StateController {
650666

651667
// Find if any of the items of the section is visible
652668
if [ComparisonResult.orderedSame, .orderedDescending].contains(predicate(itemIndex: section.items.count - 1)),
653-
let firstMatchIndex = Array(0...section.items.count - 1).binarySearch(predicate: predicate) {
669+
let firstMatchingIndex = Array(0...section.items.count - 1).binarySearch(predicate: predicate) {
654670
// Find first item that is visible
655-
startingIndex = firstMatchIndex
656-
for itemIndex in (0..<firstMatchIndex).reversed() {
671+
startingIndex = firstMatchingIndex
672+
for itemIndex in (0..<firstMatchingIndex).reversed() {
657673
let itemPath = ItemPath(item: itemIndex, section: sectionIndex)
658674
guard let itemFrame = itemFrame(for: itemPath, kind: .cell, at: state, isFinal: true) else {
659675
continue
@@ -725,6 +741,7 @@ final class StateController {
725741
return self.itemAttributes(for: path, kind: kind, predefinedFrame: frame, at: state)
726742
}
727743
} else {
744+
// Debug purposes only.
728745
var attributes = [ChatLayoutAttributes]()
729746
attributes.reserveCapacity(layout.sections.count * 1000)
730747
layout.sections.enumerated().forEach { sectionIndex, section in
@@ -835,7 +852,7 @@ final class StateController {
835852

836853
}
837854

838-
private extension RandomAccessCollection where Index == Int {
855+
extension RandomAccessCollection where Index == Int {
839856

840857
func binarySearch(predicate: (Element) -> ComparisonResult) -> Index? {
841858
var lowerBound = startIndex
@@ -854,4 +871,29 @@ private extension RandomAccessCollection where Index == Int {
854871
return nil
855872
}
856873

874+
func binarySearchRange(predicate: (Element) -> ComparisonResult) -> [Element] {
875+
guard let firstMatchingIndex = binarySearch(predicate: predicate) else {
876+
return []
877+
}
878+
879+
var startingIndex = firstMatchingIndex
880+
for index in (0..<firstMatchingIndex).reversed() {
881+
let attributes = self[index]
882+
guard predicate(attributes) == .orderedSame else {
883+
break
884+
}
885+
startingIndex = index
886+
}
887+
888+
var lastIndex = firstMatchingIndex
889+
for index in (firstMatchingIndex + 1)..<count {
890+
let attributes = self[index]
891+
guard predicate(attributes) == .orderedSame else {
892+
break
893+
}
894+
lastIndex = index
895+
}
896+
return Array(self[startingIndex...lastIndex])
897+
}
898+
857899
}

ChatLayout/Classes/Extras/CellLayoutContainerView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// CellLayoutContainerView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/ContainerCollectionReusableView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ContainerCollectionReusableView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ContainerCollectionViewCell.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/ContainerCollectionViewCellDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ContainerCollectionViewCellDelegate.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/EdgeAligningView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// EdgeAligningView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/ImageMaskedView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ImageMaskedView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/MessageContainerView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// MessageContainerView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/RoundedCornersContainerView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RoundedCornersContainerView.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

ChatLayout/Classes/Extras/StaticViewFactory.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// StaticViewFactory.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

Example/ChatLayout/AppDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// AppDelegate.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

Example/ChatLayout/Chat/Builder/ChatViewControllerBuilder.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatViewControllerBuilder.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

Example/ChatLayout/Chat/Constants.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Constants.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

Example/ChatLayout/Chat/Controller/ChatController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatController.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

Example/ChatLayout/Chat/Controller/ChatControllerDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ChatControllerDelegate.swift
44
// https://github.com/ekazaev/ChatLayout
55
//
6-
// Created by Eugene Kazaev in 2020-2021.
6+
// Created by Eugene Kazaev in 2020-2022.
77
// Distributed under the MIT license.
88
//
99

0 commit comments

Comments
 (0)