[ad_1]
I’ve a compositional structure for my UICollectionView. That is the code for creating the structure.
func createLayout() -> UICollectionViewLayout {
let structure = UICollectionViewCompositionalLayout { [weak self] part, _ -> NSCollectionLayoutSection? in
guard
let self = self,
let sections = self.viewModel?.sections,
let sectionData = sections[safe: section] else { return nil }
swap sectionData {
case .firstSection:
return self.createFirstSectionSection()
case .secondSection:
return self.createSecondSection()
case .buttons(_, let topSpacing):
return self.createButtonsSection(topSpacing: topSpacing)
}
}
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(108))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize,
elementKind: "header",
alignment: .high)
let config = UICollectionViewCompositionalLayoutConfiguration()
config.boundarySupplementaryItems = [header]
config.scrollDirection = .vertical
config.interSectionSpacing = 0
structure.configuration = config
return structure
}
func createFirstSection() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(144))
let merchandise = NSCollectionLayoutItem(layoutSize: itemSize, supplementaryItems: [borderItem])
let group = NSCollectionLayoutGroup.vertical(layoutSize: itemSize, subitems: [item])
group.contentInsets = NSDirectionalEdgeInsets(high: 0, main: 60, backside: 0, trailing: 20)
let layoutSection = NSCollectionLayoutSection(group: group)
return layoutSection
}
func createSecondSection() -> NSCollectionLayoutSection {
let borderItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
let borderItem = NSCollectionLayoutSupplementaryItem(layoutSize: borderItemSize, elementKind: "item-border-view", containerAnchor: NSCollectionLayoutAnchor(edges: .high))
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(58))
let merchandise = NSCollectionLayoutItem(layoutSize: itemSize, supplementaryItems: [borderItem])
let group = NSCollectionLayoutGroup.vertical(layoutSize: itemSize, subitems: [item])
group.contentInsets = NSDirectionalEdgeInsets(high: 0, main: hasCheckboxes ? 20 : 60, backside: 0, trailing: 20)
let layoutSection = NSCollectionLayoutSection(group: group)
return layoutSection
}
func createButtonsSection(topSpacing: CGFloat) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(41))
let merchandise = NSCollectionLayoutItem(layoutSize: itemSize)
let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: itemSize.widthDimension, heightDimension: itemSize.heightDimension), subitems: [item])
let part = NSCollectionLayoutSection(group: group)
part.contentInsets = NSDirectionalEdgeInsets(high: topSpacing, main: 60, backside: 0, trailing: 20)
return part
}
My mannequin seems like this:
enum Part {
case firstSection(gadgets: [FirstSectionItem])
case secondSection(gadgets: [SecondSectionItem])
case buttons(cellViewModel: ButtonsCellViewModel, topSpacing: CGFloat)
var gadgets: [AnyHashable] {
swap self {
case .firstSection(let firstSectionItems):
return firstSectionItems
case .quotes(let secondSectionItems):
return secondSectionItems
case .buttons(let cellViewModel, _):
return [cellViewModel]
}
}
}
// MARK: - Hashable
extension Part: Hashable {
static func == (lhs: Part, rhs: Part) -> Bool {
swap (lhs, rhs) {
case (.firstSection(let leftItems), .firstSection(let rightItems)):
return leftItems == rightItems
case (.secondSection(let leftItems), .secondSection(let rightItems)):
return leftItems == rightItems
case (.buttons(let leftCellViewModel, let leftTopSpacing), .buttons(let rightCellViewModel, let rightTopSpacing)):
return true
default:
return false
}
}
func hash(into hasher: inout Hasher) {
swap self {
case .firstSection(let gadgets):
hasher.mix(gadgets)
case .secondSection(let gadgets):
hasher.mix(gadgets)
case .buttons(let cellViewModel, let topSpacing):
hasher.mix("Identical") // I take advantage of this to be sure that there isn't any distinction within the buttons part. What I attempt to accomplish is that the buttons part (part on the backside) doesn't animate out of display to reload it is UI.
}
}
}
The information mannequin is far more complicated, however for the sake of the query, I eliminated some stuff that I feel just isn’t related right here and can solely create litter.
The reloading of the collectionView with DiffableDataSource seems like this:
func refreshUI() {
guard let viewModel = viewModel else { return }
let newDataSource = WorkApprovalDataSource(sections: viewModel.sections)
var snapshot = NSDiffableDataSourceSnapshot<APIWorkApprovalSection, AnyHashable>()
newDataSource.sections.forEach {
snapshot.appendSections([$0])
snapshot.appendItems($0.gadgets, toSection: $0)
}
dataSource?.apply(snapshot, animatingDifferences: true)
}
The purpose is, I need 3 sections on display:
- First part: with some rows/gadgets under one another
- Second part: like the primary part, however the rows/gadgets are selectable
- Third part: the buttons part. This part is ALWAYS current. It has at the least one button in it. This part all the time incorporates 1 cell: the cell incorporates a horizontal stack view with buttons. However, as I stated, there’s all the time 1 button, at the least. By checking/unchecking the rows/gadgets from part 2, there’s an additional button within the buttons part. When no row is chosen –> no further button. When checking further rows, the title of the button modifications, based on the variety of chosen/checked rows: –> “Ship (5)” for instance. When solely 4 rows are checked, this title wants to alter to “Ship (4)”. When no rows are chosen, this button ought to be hidden.
I’ve had hassle for the reason that starting with the reloading of the sections. It jumps up and down. When checking the rows from part 2, and de buttons part just isn’t seen, as a result of the merchandise listing of part 2 is just too giant for instance, the primary time checking/choosing a row, it jumps. After that, if the buttons part remains to be not on the display, choosing and deselecting rows is not any drawback, no leap happens.
However: once I scroll to the underside, in order that the buttons part is seen, after which I choose a row, the gathering View scrolls a bit in order that the buttons are out of sight. After I scroll the buttons in sight once more, the info within the cells seems positive, so the reload occurs “accurately”. What I need is that the buttons part does not scroll out of display to reload the UI. I’ve dealt with this by making the Hashable protocol all the time hash the identical textual content, so there isn’t any distinction, proper? The change of the title of the button and the visibility of it, I deal with through the cellViewModel of the buttons. In order that works completely positive. However the buttons preserve scrolling out of sight to reload. And I do not know what’s inflicting it.
I really want the compositional structure for adornment gadgets and stuff, so I can not drop this.
Thanks upfront for looking and possibly posting some options/fixes.
[ad_2]
