Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into kve/fix-natural-measu…
Browse files Browse the repository at this point in the history
…rements

* origin/main:
  Update CHANGELOG.md
  Allow other panning to work on other cells while another is open
  Remove `isTouchWithinSwipeActionView`
  Update swipe actions to more closely match iOS behavior
  Update CHANGELOG.md
  Release 13.1.0
  Only return existing view if there is a contained first responder
  Self code review
  Fixed an issue where a crash would occur when applying an external update to list content while a live reorder event was occurring.
  Remove override of performBatchUpdates, it causes warnings for consumers
  Update CHANGELOG.md (#508)
  Revert "Supplementary Tracking Fixes (#433)"
  Revert "Force layout before appear, to avoid animated updates (#505)"
  • Loading branch information
kyleve committed Dec 8, 2023
2 parents 19f3cdf + 5d989dc commit b7aa283
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 168 deletions.
20 changes: 15 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@

### Fixed

- Fixed a bug that resulted in header/footer views not properly updating, by fixing the underlying tracking of collection view supplementary views.
- Fixed an issue where supplementary views (headers or footers) that contained a first responder would result in the view being duplicated when scrolled off-screen.
- Fixed an issue where animations would occur when dequeuing / reusing cells. A layout is now forced without animation before presentation.

### Added

### Removed

### Changed

- Update the swipe action interactions to more closely match iOS behavior.

### Misc

### Internal

# Past Releases

# [13.1.0] - 2023-11-30

### Fixed

- Fixed an issue where supplementary views (headers or footers) that contained a first responder would result in the view being duplicated when scrolled off-screen.
- Fixed an issue where a crash would occur when applying an external update to list content while a live reorder event was occurring.

### Internal

- Remove override of `performBatchUpdates` from our internal `UICollectionView` subclass, it causes warnings for consumers.

# [13.0.0] - 2023-09-06

### Fixed
Expand Down Expand Up @@ -977,7 +986,8 @@ listActions.scrolling.scrollToSection(
Earlier releases were ad-hoc and not tracked. To see all changes, please reference [closed PRs on Github](https://github.com/kyleve/Listable/pulls?q=is%3Apr+is%3Aclosed).


[Main]: https://github.com/square/Listable/square/13.0.0...HEAD
[Main]: https://github.com/square/Listable/compare/13.1.0...main
[13.1.0]: https://github.com/square/Listable/square/13.0.0...13.1.0
[13.0.0]: https://github.com/square/Listable/square/12.0.0...13.0.0
[12.0.0]: https://github.com/square/Listable/compare/11.0.0...12.0.0
[11.0.0]: https://github.com/square/Listable/compare/10.3.1...11.0.0
Expand Down
4 changes: 0 additions & 4 deletions Demo/Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
0AC2A1962489F93E00779459 /* PagedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC2A1952489F93E00779459 /* PagedViewController.swift */; };
0AC839A525EEAD110055CEF5 /* OnTapItemAnimationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC839A425EEAD110055CEF5 /* OnTapItemAnimationViewController.swift */; };
0ACF96D624A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACF96D524A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift */; };
0AD0CF6728B57759000ECF0C /* SupplementaryTestingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD0CF6628B57759000ECF0C /* SupplementaryTestingViewController.swift */; };
0AD6767A25423BE500A49315 /* MultiSelectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD6767925423BE500A49315 /* MultiSelectViewController.swift */; };
0AD827DC2752C8A700D42B4A /* CarouselLayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD827DB2752C8A700D42B4A /* CarouselLayoutViewController.swift */; };
0ADC3B3524907C80008DF2C0 /* XcodePreviewDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADC3B3424907C80008DF2C0 /* XcodePreviewDemo.swift */; };
Expand Down Expand Up @@ -90,7 +89,6 @@
0AC2A1952489F93E00779459 /* PagedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagedViewController.swift; sourceTree = "<group>"; };
0AC839A425EEAD110055CEF5 /* OnTapItemAnimationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnTapItemAnimationViewController.swift; sourceTree = "<group>"; };
0ACF96D524A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInsertAndRemoveAnimationsViewController.swift; sourceTree = "<group>"; };
0AD0CF6628B57759000ECF0C /* SupplementaryTestingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupplementaryTestingViewController.swift; sourceTree = "<group>"; };
0AD6767925423BE500A49315 /* MultiSelectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSelectViewController.swift; sourceTree = "<group>"; };
0AD827DB2752C8A700D42B4A /* CarouselLayoutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselLayoutViewController.swift; sourceTree = "<group>"; };
0ADC3B3424907C80008DF2C0 /* XcodePreviewDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodePreviewDemo.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -150,7 +148,6 @@
isa = PBXGroup;
children = (
0A49210324E5E11300D17038 /* AccordionViewController.swift */,
0AD0CF6628B57759000ECF0C /* SupplementaryTestingViewController.swift */,
0A66420A254A317A007F6B2F /* AutoLayoutDemoViewController.swift */,
0AA4D9B4248064A300CF95A5 /* AutoScrollingViewController.swift */,
0AA4D9AC248064A300CF95A5 /* BlueprintListDemoViewController.swift */,
Expand Down Expand Up @@ -465,7 +462,6 @@
buildActionMask = 2147483647;
files = (
0AA4D9BE248064A300CF95A5 /* DemosRootViewController.swift in Sources */,
0AD0CF6728B57759000ECF0C /* SupplementaryTestingViewController.swift in Sources */,
0A57BA2D274FFCE000A118BD /* FlowLayoutViewController.swift in Sources */,
0AA4D9C2248064A300CF95A5 /* HorizontalLayoutViewController.swift in Sources */,
1F46FB6B26010F4900760961 /* RefreshControlOffsetAdjustmentViewController.swift in Sources */,
Expand Down
73 changes: 70 additions & 3 deletions Demo/Sources/Demos/Demo Screens/PaymentTypesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,19 @@ import BlueprintUICommonControls

final class PaymentTypesViewController : ListViewController {

override func viewDidLoad() {
super.viewDidLoad()

self.updateNavigationItems()
}

override func configure(list: inout ListProperties) {

list.layout = .table { table in
table.layout.interSectionSpacingWithNoFooter = 10.0
table.bounds = .init(
padding: UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0)
padding: UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0),
width: .atMost(600)
)
}

Expand All @@ -30,21 +37,31 @@ final class PaymentTypesViewController : ListViewController {
list += Section(SectionID.main) { section in

section.header = PaymentTypeHeader(title: SectionID.main.title)

section += types.filter { $0.isEnabled }
.filter { $0.isMain }
.sorted { $0.sortOrder < $1.sortOrder }
.map(makeItem(with:))

if section.items.isEmpty {
section += EmptyRow()
}
}

list += Section(SectionID.more) { section in

section.header = PaymentTypeHeader(title: SectionID.more.title)

section.reordering.minItemCount = 0

section += types.filter { $0.isEnabled }
.filter { $0.isMain == false }
.sorted { $0.sortOrder < $1.sortOrder }
.map(makeItem(with:))

if section.items.isEmpty {
section += EmptyRow()
}
}

list += Section(SectionID.disabled) { section in
Expand All @@ -63,6 +80,56 @@ final class PaymentTypesViewController : ListViewController {
}
}

private var reloadingListTimer : Timer? = nil {
didSet {
oldValue?.invalidate()
}
}

private func updateNavigationItems() {

if reloadingListTimer == nil {
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
title: "Start Reloading",
style: .plain,
target: self,
action: #selector(beginReloading)
)
} else {
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
title: "Stop Reloading",
style: .plain,
target: self,
action: #selector(endReloading)
)
}
}

@objc private func beginReloading() {

let alert = UIAlertController(
title: "Will Repeatedly Reload List",
message: "The list will be reloaded every 0.5 seconds to verify that reordering + reloading does not cause a crash.",
preferredStyle: .alert
)

alert.addAction(.init(title: "OK", style: .default) { [weak self] _ in
self?.reloadingListTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: { _ in
self?.reload(animated: true)
})

self?.updateNavigationItems()
})

self.present(alert, animated: true)
}

@objc private func endReloading() {
self.reloadingListTimer = nil

updateNavigationItems()
}

private func save(with info : ListStateObserver.ItemReordered) {
let main = info.sections.first { $0.identifier == Section.identifier(with: SectionID.main) }!
let more = info.sections.first { $0.identifier == Section.identifier(with: SectionID.more) }!
Expand Down Expand Up @@ -136,7 +203,7 @@ fileprivate struct PaymentTypeHeader : BlueprintHeaderFooterContent, Equatable {

var elementRepresentation: Element {
Label(text: title) {
$0.font = .systemFont(ofSize: 18.0, weight: .medium)
$0.font = .systemFont(ofSize: 18.0, weight: .bold)
}
.inset(uniform: 15.0)
}
Expand Down

This file was deleted.

8 changes: 0 additions & 8 deletions Demo/Sources/Demos/DemosRootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,6 @@ public final class DemosRootViewController : ListViewController
self?.push(UpdateFuzzingViewController())
}
)

Item(
DemoItem(text: "Testing Header Association"),
selectionStyle: .selectable(),
onSelect : { _ in
self?.push(SupplementaryTestingViewController())
}
)
} header: {
DemoHeader(title: "Fuzz Testing")
}
Expand Down
25 changes: 17 additions & 8 deletions ListableUI/Sources/Internal/ItemCell.ContentViewContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ extension ItemCell {
}
}

func isTouchWithinSwipeActionView(touch: UITouch) -> Bool {
configurations.values.first { $0.swipeView.contains(touch: touch) } != nil
}

// MARK: - Swipe Registration

func deregisterLeadingSwipeIfNeeded() {
Expand Down Expand Up @@ -161,6 +157,9 @@ extension ItemCell {

let panGestureRecognizer = DirectionalPanGestureRecognizer(direction: side.gestureDirection, target: self, action: #selector(handlePan))
addGestureRecognizer(panGestureRecognizer)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapGestureRecognizer.require(toFail: panGestureRecognizer)
addGestureRecognizer(tapGestureRecognizer)

configurations[side] = SwipeConfiguration(
panGestureRecognizer: panGestureRecognizer,
Expand All @@ -182,6 +181,11 @@ extension ItemCell {

private weak var listView : ListView? = nil

@objc private func handleTap(sender: UITapGestureRecognizer) {
// if we're tapped (and we're not panning, which is required to fail above) just close
set(state: .closed, animated: true)
}

@objc private func handlePan(sender: UIPanGestureRecognizer) {

if self.listView == nil {
Expand Down Expand Up @@ -210,8 +214,12 @@ extension ItemCell {
&& configuration.performsFirstActionWithFullSwipe

if sender.state == .began {
self.listView?.liveCells.perform {
$0.closeSwipeActions()
// If currently open, and attempting to swipe the other side, close.
if case let .open(currentSide) = swipeState, currentSide != side {
self.performAnimatedClose()
// Cancel the current pan gesture
sender.isEnabled = false
sender.isEnabled = true
}
}

Expand All @@ -221,7 +229,7 @@ extension ItemCell {
let swipeState = SwipeActionState.swiping(side, willPerformAction: willPerformAction)
set(state: swipeState)

case .ended, .cancelled:
case .ended:

let velocity = sender.velocity(in: self).x

Expand All @@ -248,6 +256,8 @@ extension ItemCell {

set(state: swipeState, animated: true)

case .cancelled:
set(state: .closed)
default:
set(state: .closed)

Expand All @@ -272,7 +282,6 @@ extension ItemCell {
}

private func set(state: SwipeActionState, animated: Bool = false) {

swipeState = state

if animated {
Expand Down
6 changes: 0 additions & 6 deletions ListableUI/Sources/Internal/ItemCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ protocol AnyItemCell : UICollectionViewCell

var areSwipeActionsVisible : Bool { get }

func isTouchWithinSwipeActionView(touch: UITouch) -> Bool

func wasDequeued(with liveCells : LiveCells)
}

Expand Down Expand Up @@ -205,10 +203,6 @@ final class ItemCell<Content:ItemContent> : UICollectionViewCell, AnyItemCell
}
}

func isTouchWithinSwipeActionView(touch: UITouch) -> Bool {
self.contentContainer.isTouchWithinSwipeActionView(touch: touch)
}

private var hasBeenDequeued = false

func wasDequeued(with liveCells : LiveCells) {
Expand Down
Loading

0 comments on commit b7aa283

Please sign in to comment.