Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3946a41
Add FlatSection
JosephDuffy Dec 22, 2020
babdadf
Mark `append(_:)` public
JosephDuffy Dec 22, 2020
59daa65
Add `section(at:)`
JosephDuffy Dec 22, 2020
c4fe225
Add support for flat UI sections, with mixed cells
JosephDuffy Dec 22, 2020
aa527de
Aid migration from `CollectionSectionProvider`
JosephDuffy Dec 22, 2020
0b5350f
Add `public init` to `FlatSection`
JosephDuffy Dec 22, 2020
d3dee27
Fix `section(at:)` logic
JosephDuffy Dec 22, 2020
66d5fed
Conform `FlatSection` to `CustomReflectable`
JosephDuffy Dec 22, 2020
f51dc04
Become update delegate of inserted children
JosephDuffy Dec 22, 2020
e1e7fd5
Add more insert and removal functions
JosephDuffy Dec 22, 2020
c597da9
Remove associated type from `CollectionElement`
JosephDuffy Dec 22, 2020
fd21a2f
Add header invalidation
JosephDuffy Dec 23, 2020
ec63ce7
[SBI-519] Fix crash due to using removed section inside didEndDisplay…
bill201207 Dec 24, 2020
ad9dc00
[SBI-519] Cache registered nib names to avoid multiple redundant call…
bill201207 Dec 24, 2020
7320206
Merge pull request #1 from opennetltd/hotfix/SBI-519-ComposedUI-issues
bill201207 Dec 24, 2020
7b27a38
Merge branch 'main' of github.com:opennetltd/Composed into feature/Fl…
JosephDuffy Dec 28, 2020
f0ab34c
Fix test compilation
JosephDuffy Dec 28, 2020
06449c3
Fix `cellSectionMap` for per-row cells
JosephDuffy Dec 28, 2020
f6a4b2c
Delegate `SelectionHandler` calls to children
JosephDuffy Dec 28, 2020
eb3a33a
Add `FlatUICollectionViewSection`
JosephDuffy Dec 28, 2020
986674a
Support adding `SectionProvider`s to `FlatSection`
JosephDuffy Dec 29, 2020
ad73a5a
Reload header when `header` is set
JosephDuffy Dec 29, 2020
f6cd79c
Cache nib registrations to improve performance
JosephDuffy Jan 1, 2021
b35ea17
Merge branch 'cache-nib-registrations'
JosephDuffy Jan 1, 2021
1614657
Merge branch 'main' into feature/FlatSection
JosephDuffy Jan 1, 2021
ecdd0fa
Fix `SectionProvider` sections not being removed
JosephDuffy Jan 4, 2021
fd0fb6a
Account for child `AggregateSectionProvider`s
JosephDuffy Jan 4, 2021
ee87162
Update `sectionOffset(for:)` to return an optional
JosephDuffy Jan 4, 2021
9684f62
Fix `ComposedSectionProvider` compilation
JosephDuffy Jan 4, 2021
987e496
Account for empty sections
JosephDuffy Jan 4, 2021
ad450d5
Remove `defer`s to ease debugging
JosephDuffy Jan 4, 2021
c1a438e
Become delegate of inserted sections
JosephDuffy Jan 5, 2021
00cfff2
Document `sectionIndex(of:)`
JosephDuffy Jan 5, 2021
90db5e5
Call `willAppear` for headers/footers
JosephDuffy Jan 5, 2021
e7c88de
Configure headers/footers on appear
JosephDuffy Jan 5, 2021
c52b6e4
Fix element offset when inserting in `FlatSection`
JosephDuffy Jan 7, 2021
e45ea84
Fix incorrect index when provider removes sections
JosephDuffy Jan 11, 2021
9e1b8bd
Mark `updateDelegate` as `weak`
JosephDuffy Jan 12, 2021
710efde
Remove/reduce some `FlatSection` bugs
JosephDuffy Jan 12, 2021
f1cdd0d
Add foundation of `FlatSection` tests
JosephDuffy Jan 12, 2021
42c05c9
Do not check to unset update delegate of sections
JosephDuffy Jan 12, 2021
3fb3c8f
Remove `Child` from public API
JosephDuffy Jan 12, 2021
a9a3c94
Add more `FlatSection` tests
JosephDuffy Jan 12, 2021
791b088
Change `index` to `childIndex`
JosephDuffy Jan 12, 2021
a1cafc9
Remove check for unsetting update delegate
JosephDuffy Jan 12, 2021
f49d0c5
Add more `FlatSection` tests
JosephDuffy Jan 12, 2021
0345565
Propagate updates from sections
JosephDuffy Jan 13, 2021
eb49837
Fix incorrect header and footer in flat sections
JosephDuffy Jan 18, 2021
6e3c578
Add support for footers
JosephDuffy Jan 19, 2021
5532266
Merge branch '2.0-beta' into feature/FlatSection
JosephDuffy Jan 19, 2021
75df0f0
Unset `updateDelegate` on section provider removal
JosephDuffy Feb 1, 2021
1813669
Update assertion message to ease debugging
JosephDuffy Feb 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Sources/Composed/Core/Section.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,13 @@ public protocol SectionUpdateDelegate: class {
/// - destinationIndex: The final index where the element will be moved to
func section(_ section: Section, move sourceIndex: Int, to destinationIndex: Int)

/// Notifies the delegate that the section invalidated its header.
/// - Parameters:
/// - section: The section that invalidated its header.
func sectionDidInvalidateHeader(_ section: Section)

/// Notifies the delegate that the section invalidated its footer.
/// - Parameters:
/// - section: The section that invalidated its footer.
func sectionDidInvalidateFooter(_ section: Section)
}
20 changes: 20 additions & 0 deletions Sources/Composed/Core/SectionProviderMapping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ public protocol SectionProviderMappingDelegate: class {
/// - destinationIndexPath: The final indexPath
func mapping(_ mapping: SectionProviderMapping, move sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

/// Notifies the delegate that the section invalidated its header.
/// - Parameters:
/// - sectionIndex: The index of the section that invalidated its header.
func mappingDidInvalidateHeader(at sectionIndex: Int)

/// Notifies the delegate that the section invalidated its footer.
/// - Parameters:
/// - sectionIndex: The index of the section that invalidated its footer.
func mappingDidInvalidateFooter(at sectionIndex: Int)

}

/// An object that encapsulates the logic required to map `SectionProvider`s to a global context,
Expand Down Expand Up @@ -229,6 +239,16 @@ public final class SectionProviderMapping: SectionProviderUpdateDelegate, Sectio
delegate?.mapping(self, didMoveElementsAt: [(source, destination)])
}

public func sectionDidInvalidateHeader(_ section: Section) {
guard let sectionOffset = self.sectionOffset(of: section) else { return }
delegate?.mappingDidInvalidateHeader(at: sectionOffset)
}

public func sectionDidInvalidateFooter(_ section: Section) {
guard let sectionOffset = self.sectionOffset(of: section) else { return }
delegate?.mappingDidInvalidateFooter(at: sectionOffset)
}

// Rebuilds the cached providers to improve lookup performance.
// This is generally only required when a sections are either inserted or removed, so it should be fairly efficient.
private func rebuildSectionOffsets() {
Expand Down
105 changes: 105 additions & 0 deletions Sources/Composed/Sections/FlatSection+SelectionHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
extension FlatSection: SelectionHandler {
public final var selectionHandlingSections: [SelectionHandler] {
sections.compactMap { $0 as? SelectionHandler }
}

open var allowsMultipleSelection: Bool {
let selectionHandlingSection = sections.compactMap { $0 as? SelectionHandler }
if selectionHandlingSection.isEmpty {
return false
} else if selectionHandlingSection.count == 1 {
return selectionHandlingSection.first!.allowsMultipleSelection
} else {
return true
}
}

/// Returns all element indexes that are currently selected
open var selectedIndexes: [Int] {
return sections.flatMap { section -> [Int] in
guard let section = section as? SelectionHandler else { return [] }
let offset = self.indexForFirstElement(of: section)!
return section.selectedIndexes.map { $0 + offset }
}
}

/// When a highlight is attempted, this method will be called giving the caller a chance to prevent it
/// - Parameter index: The element index
open func shouldHighlight(at index: Int) -> Bool {
guard let sectionMeta = self.sectionForElementIndex(index) else { return false }
guard let section = sectionMeta.section as? SelectionHandler else { return false }

let sectionIndex = index - sectionMeta.offset
return section.shouldHighlight(at: sectionIndex)
}

/// When a selection is attempted, this method will be called giving the caller a chance to prevent it
/// - Parameter index: The element index
open func shouldSelect(at index: Int) -> Bool {
guard let sectionMeta = self.sectionForElementIndex(index) else { return false }
guard let section = sectionMeta.section as? SelectionHandler else { return false }

let sectionIndex = index - sectionMeta.offset
return section.shouldSelect(at: sectionIndex)
}

/// When a selection occurs, this method will be called to notify the section
/// - Parameter index: The element index
open func didSelect(at index: Int) {
guard let sectionMeta = self.sectionForElementIndex(index) else { return }
guard let section = sectionMeta.section as? SelectionHandler else { return }

let sectionIndex = index - sectionMeta.offset
section.didSelect(at: sectionIndex)
}

/// When a deselection is attempted, this method will be called giving the caller a chance to prevent it
/// - Parameter index: The element index
open func shouldDeselect(at index: Int) -> Bool {
guard let sectionMeta = self.sectionForElementIndex(index) else { return false }
guard let section = sectionMeta.section as? SelectionHandler else { return false }

let sectionIndex = index - sectionMeta.offset
return section.shouldDeselect(at: sectionIndex)
}

/// When a deselection occurs, this method will be called to notify the section
/// - Parameter index: The element index
open func didDeselect(at index: Int) {
guard let sectionMeta = self.sectionForElementIndex(index) else { return }
guard let section = sectionMeta.section as? SelectionHandler else { return }

let sectionIndex = index - sectionMeta.offset
return section.didDeselect(at: sectionIndex)
}

/// Selects the element at the specified index
/// - Parameter index: The element index
open func select(index: Int) {
guard let sectionMeta = self.sectionForElementIndex(index) else { return }
guard let section = sectionMeta.section as? SelectionHandler else { return }

let sectionIndex = index - sectionMeta.offset
section.select(index: sectionIndex)
}

/// Deselects the element at the specified index
/// - Parameter index: The element index
open func deselect(index: Int) {
guard let sectionMeta = self.sectionForElementIndex(index) else { return }
guard let section = sectionMeta.section as? SelectionHandler else { return }

let sectionIndex = index - sectionMeta.offset
section.deselect(index: sectionIndex)
}

/// Selects all elements in this section
open func selectAll() {
selectionHandlingSections.forEach { $0.selectAll() }
}

/// Deselects all elements in this section
open func deselectAll() {
selectionHandlingSections.forEach { $0.deselectAll() }
}
}
Loading