Skip to content

Commit

Permalink
add swipe action to UICollectionViewCompositionalLayout example
Browse files Browse the repository at this point in the history
Summary: Lets add swipe to delete.

Differential Revision: D52262785

fbshipit-source-id: b95cdee116374c561967dd585d02110a4d877e16
  • Loading branch information
Maxime Ollivier authored and facebook-github-bot committed Dec 19, 2023
1 parent 309e1d7 commit d01784b
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@
56C05B751E49B33C0026DB39 /* InteractiveCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C05B741E49B33C0026DB39 /* InteractiveCell.m */; };
56C05B781E49B3A50026DB39 /* PhotoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C05B771E49B3A50026DB39 /* PhotoCell.m */; };
576D20072B2CB50E0012C5B8 /* CompositionLayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20062B2CB50E0012C5B8 /* CompositionLayoutViewController.swift */; };
576D20092B2CB6C20012C5B8 /* SwipeActionComposabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20082B2CB6C20012C5B8 /* SwipeActionComposabelSectionController.swift */; };
576D200B2B2CC6DF0012C5B8 /* CompositionLayoutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D200A2B2CC6DF0012C5B8 /* CompositionLayoutCell.swift */; };
576D200E2B2CE9EC0012C5B8 /* ExpandableComposableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D200D2B2CE9EC0012C5B8 /* ExpandableComposableSectionController.swift */; };
576D20102B2CEC4E0012C5B8 /* GridComposableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D200F2B2CEC4E0012C5B8 /* GridComposableSectionController.swift */; };
576D20122B2CF04F0012C5B8 /* UserComposableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20112B2CF04F0012C5B8 /* UserComposableSectionController.swift */; };
576D20142B2CF15C0012C5B8 /* GridItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20132B2CF15C0012C5B8 /* GridItem.swift */; };
576D20162B2CF1A50012C5B8 /* HorizontalCardsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20152B2CF1A50012C5B8 /* HorizontalCardsSection.swift */; };
576D20182B2CF24F0012C5B8 /* HorizontalComposableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20172B2CF24F0012C5B8 /* HorizontalComposableSectionController.swift */; };
576D201A2B2CF82C0012C5B8 /* SwipeActionSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576D20192B2CF82C0012C5B8 /* SwipeActionSection.swift */; };
821BC4B61DB8B3DC00172ED0 /* StoryboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B51DB8B3DC00172ED0 /* StoryboardViewController.swift */; };
821BC4B81DB8B48300172ED0 /* StoryboardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B71DB8B48300172ED0 /* StoryboardCell.swift */; };
821BC4BA1DB8B61200172ED0 /* StoryboardLabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B91DB8B61200172ED0 /* StoryboardLabelSectionController.swift */; };
Expand Down Expand Up @@ -242,13 +244,15 @@
56C05B761E49B3A50026DB39 /* PhotoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoCell.h; sourceTree = "<group>"; };
56C05B771E49B3A50026DB39 /* PhotoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoCell.m; sourceTree = "<group>"; };
576D20062B2CB50E0012C5B8 /* CompositionLayoutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionLayoutViewController.swift; sourceTree = "<group>"; };
576D20082B2CB6C20012C5B8 /* SwipeActionComposabelSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeActionComposabelSectionController.swift; sourceTree = "<group>"; };
576D200A2B2CC6DF0012C5B8 /* CompositionLayoutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionLayoutCell.swift; sourceTree = "<group>"; };
576D200D2B2CE9EC0012C5B8 /* ExpandableComposableSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableComposableSectionController.swift; sourceTree = "<group>"; };
576D200F2B2CEC4E0012C5B8 /* GridComposableSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridComposableSectionController.swift; sourceTree = "<group>"; };
576D20112B2CF04F0012C5B8 /* UserComposableSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserComposableSectionController.swift; sourceTree = "<group>"; };
576D20132B2CF15C0012C5B8 /* GridItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridItem.swift; sourceTree = "<group>"; };
576D20152B2CF1A50012C5B8 /* HorizontalCardsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalCardsSection.swift; sourceTree = "<group>"; };
576D20172B2CF24F0012C5B8 /* HorizontalComposableSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalComposableSectionController.swift; sourceTree = "<group>"; };
576D20192B2CF82C0012C5B8 /* SwipeActionSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeActionSection.swift; sourceTree = "<group>"; };
821BC4B51DB8B3DC00172ED0 /* StoryboardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardViewController.swift; sourceTree = "<group>"; };
821BC4B71DB8B48300172ED0 /* StoryboardCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardCell.swift; sourceTree = "<group>"; };
821BC4B91DB8B61200172ED0 /* StoryboardLabelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardLabelSectionController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -505,6 +509,7 @@
2991F91D1D7BB30C00B0C58F /* User.swift */,
576D20132B2CF15C0012C5B8 /* GridItem.swift */,
576D20152B2CF1A50012C5B8 /* HorizontalCardsSection.swift */,
576D20192B2CF82C0012C5B8 /* SwipeActionSection.swift */,
EB02899E202A11DF007E17D5 /* RemodelGeneratedModels */,
2926585C1E74A0360041B56D /* ViewModels */,
);
Expand All @@ -526,6 +531,7 @@
576D200F2B2CEC4E0012C5B8 /* GridComposableSectionController.swift */,
576D20112B2CF04F0012C5B8 /* UserComposableSectionController.swift */,
576D20172B2CF24F0012C5B8 /* HorizontalComposableSectionController.swift */,
576D20082B2CB6C20012C5B8 /* SwipeActionComposabelSectionController.swift */,
);
path = "With Composable Layout";
sourceTree = "<group>";
Expand Down Expand Up @@ -874,6 +880,7 @@
2942FF8F1D9F39E00015D24B /* GridSectionController.swift in Sources */,
821BC4B81DB8B48300172ED0 /* StoryboardCell.swift in Sources */,
56C05B781E49B3A50026DB39 /* PhotoCell.m in Sources */,
576D201A2B2CF82C0012C5B8 /* SwipeActionSection.swift in Sources */,
2942FF921D9F39E00015D24B /* RemoveSectionController.swift in Sources */,
26271C8E1DAE9D3F0073E116 /* SingleSectionViewController.swift in Sources */,
2961B3AD1D68B0B5001C9451 /* LabelCell.swift in Sources */,
Expand All @@ -893,6 +900,7 @@
296DD7571DD2163800206780 /* ManuallySelfSizingCell.swift in Sources */,
292658571E749EDC0041B56D /* CalendarViewController.swift in Sources */,
29C6297F1DCFD9E9004A5BB1 /* FeedItemSectionController.swift in Sources */,
576D20092B2CB6C20012C5B8 /* SwipeActionComposabelSectionController.swift in Sources */,
2942FF8E1D9F39E00015D24B /* ExpandableSectionController.swift in Sources */,
29F7E2AA1E9283FF00197586 /* AnnouncingDepsViewController.swift in Sources */,
9DB684E1251B10C2002023DD /* UIColor+Extension.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import IGListKit
import Foundation

final class SwipeActionSection: NSObject {

}

extension SwipeActionSection: ListDiffable {

func diffIdentifier() -> NSObjectProtocol {
return self
}

func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
return self === object ? true : self.isEqual(object)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import IGListKit
import UIKit

final class SwipeActionComposabelSectionController: ListSectionController, CompositionLayoutCapable {

private var object:SwipeActionSection?

private var items = ["1. Swipe to delete me", "2. Swipe to delete me", "3. Swipe to delete me"]

override func numberOfItems() -> Int {
return items.count
}

override func sizeForItem(at index: Int) -> CGSize {
// Compositional layout doesn't request sizes per NSIndexPath
return CGSizeZero
}

override func cellForItem(at index: Int) -> UICollectionViewCell {
let cell: CompositionLayoutCell = collectionContext.dequeueReusableCell(for: self, at: index)
cell.text = items[index]
return cell
}

override func didUpdate(to object: Any) {
self.object = object as? SwipeActionSection
}

func collectionViewSectionLayout(layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? {
var config = UICollectionLayoutListConfiguration(appearance: .plain)

config.trailingSwipeActionsConfigurationProvider = {[weak self] indexPath in
// Sections should match, but just in case
guard let self = self, indexPath.section == self.section else {
return nil
}
return self.swipeActionFor(index: indexPath.item)
}

return NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
}

// MARK: CompositionLayoutCapable

private func swipeActionFor(index:Int) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .destructive, title: "Delete") {[weak self] action, view, block in
self?.deleteItem(index: index, block: block)
}
return UISwipeActionsConfiguration(actions: [action])
}

private func deleteItem(index:Int, block: @escaping (Bool) -> ()) {
self.collectionContext.performBatch(animated: true) {updates in
self.items.remove(at: index)
updates.delete(in: self, at: IndexSet(integer: index))
} completion: { completed in
block(completed)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class CompositionLayoutViewController: UIViewController, ListAdapterDataSo
GridItem(color: UIColor(red: 237 / 255.0, green: 73 / 255.0, blue: 86 / 255.0, alpha: 1), itemCount: 6),
User(pk: 2, name: "Ryan Olson", handle: "ryanolsonk"),
HorizontalCardsSection(cardCount: 10),
SwipeActionSection(),
"Praesent commodo cursus magna, vel scelerisque nisl consectetur et.",
User(pk: 4, name: "Oliver Rickard", handle: "ocrickard"),
HorizontalCardsSection(cardCount: 2),
Expand Down Expand Up @@ -84,6 +85,8 @@ final class CompositionLayoutViewController: UIViewController, ListAdapterDataSo
return UserComposableSectionController()
case is HorizontalCardsSection:
return HorizontalComposableSectionController()
case is SwipeActionSection:
return SwipeActionComposabelSectionController()
default:
return ListSectionController()
}
Expand Down

0 comments on commit d01784b

Please sign in to comment.