Skip to content

Commit

Permalink
Introduce custom animations for inserting and removing items. Introdu…
Browse files Browse the repository at this point in the history
…ce ListViewController for easier embedding of lists.
  • Loading branch information
kyleve committed Jun 22, 2020
1 parent 3795056 commit 21c3d8f
Show file tree
Hide file tree
Showing 21 changed files with 743 additions and 323 deletions.
12 changes: 1 addition & 11 deletions BlueprintLists/Sources/List.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,7 @@ public struct List : Element
/// Create a new list with the provided options.
public init(build : ListProperties.Build)
{
self.properties = ListProperties(
animatesChanges: UIView.inheritedAnimationDuration > 0.0,
layout: .list(),
appearance: .init(),
behavior: .init(),
autoScrollAction: .none,
scrollInsets: .init(),
accessibilityIdentifier: nil,
debuggingIdentifier: nil,
build: build
)
self.properties = .default(with: build)
}

//
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@

- Add `customInterSectionSpacing` property to `Section.Layout` which allows the user to specify [custom spacing after a section](https://github.com/kyleve/Listable/pull/172), overriding the calculated spacing.

- [Add `insertAndRemoveAnimations` to `Item`](https://github.com/kyleve/Listable/pull/176) to allow customizing the animations used when an `Item` is inserted or removed from a list. Note that customizing this option when responding to `SwipeActions` will come at a later date.

- [Add `ListViewController`](https://github.com/kyleve/Listable/pull/176) make it easy to create view controllers backed by a Listable `ListView`.

### Removed

### Changed
Expand Down
4 changes: 4 additions & 0 deletions Demo/Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
0AA4D9C8248064A300CF95A5 /* ReorderingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA4D9B7248064A300CF95A5 /* ReorderingViewController.swift */; };
0AA4D9C9248064A300CF95A5 /* CollectionViewBasicDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA4D9B8248064A300CF95A5 /* CollectionViewBasicDemoViewController.swift */; };
0AC2A1962489F93E00779459 /* PagedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC2A1952489F93E00779459 /* PagedViewController.swift */; };
0ACF96D624A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ACF96D524A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift */; };
0ADC3B3524907C80008DF2C0 /* XcodePreviewDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ADC3B3424907C80008DF2C0 /* XcodePreviewDemo.swift */; };
0AE855512390933100F2E245 /* Test_Targets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE855502390933100F2E245 /* Test_Targets.swift */; };
0AEB96B922FBCBA600341DFF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AEB96B822FBCBA600341DFF /* Assets.xcassets */; };
Expand Down Expand Up @@ -60,6 +61,7 @@
0AA4D9B7248064A300CF95A5 /* ReorderingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReorderingViewController.swift; sourceTree = "<group>"; };
0AA4D9B8248064A300CF95A5 /* CollectionViewBasicDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewBasicDemoViewController.swift; sourceTree = "<group>"; };
0AC2A1952489F93E00779459 /* PagedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagedViewController.swift; sourceTree = "<group>"; };
0ACF96D524A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInsertAndRemoveAnimationsViewController.swift; sourceTree = "<group>"; };
0ADC3B3424907C80008DF2C0 /* XcodePreviewDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodePreviewDemo.swift; sourceTree = "<group>"; };
0AE8554E2390933100F2E245 /* Test Targets.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Test Targets.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0AE855502390933100F2E245 /* Test_Targets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test_Targets.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -127,6 +129,7 @@
0AA4D9B7248064A300CF95A5 /* ReorderingViewController.swift */,
0AA4D9AA248064A200CF95A5 /* ScrollViewEdgesPlaygroundViewController.swift */,
0AA4D9B5248064A300CF95A5 /* SwipeActionsViewController.swift */,
0ACF96D524A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift */,
0AA4D9AE248064A300CF95A5 /* WidthCustomizationViewController.swift */,
2B8804642490844A003BB351 /* SpacingCustomizationViewController.swift */,
);
Expand Down Expand Up @@ -423,6 +426,7 @@
2B8804652490844A003BB351 /* SpacingCustomizationViewController.swift in Sources */,
0AA4D9BD248064A300CF95A5 /* BlueprintListDemoViewController.swift in Sources */,
0AA4D9BB248064A300CF95A5 /* ScrollViewEdgesPlaygroundViewController.swift in Sources */,
0ACF96D624A0094D0090EAC4 /* ItemInsertAndRemoveAnimationsViewController.swift in Sources */,
0AA4D9C7248064A300CF95A5 /* CollectionViewDictionaryDemoViewController.swift in Sources */,
0ADC3B3524907C80008DF2C0 /* XcodePreviewDemo.swift in Sources */,
0AA4D9C4248064A300CF95A5 /* ItemizationEditorViewController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// ItemInsertAndRemoveAnimationsViewController.swift
// Demo
//
// Created by Kyle Van Essen on 6/21/20.
// Copyright © 2020 Kyle Van Essen. All rights reserved.
//

import Foundation
import BlueprintLists


final class ItemInsertAndRemoveAnimationsViewController : ListViewController
{
struct Animations : Equatable
{
let id : String
let animations : ItemInsertAndRemoveAnimations

static func == (lhs: Self, rhs: Self) -> Bool
{
lhs.id == rhs.id
}
}

var deleted : Animations? = nil

let animations : [Animations] = [
Animations(
id: "Fade",
animations: .fade
),
Animations(
id: "Right",
animations: .right
),
Animations(
id: "Left",
animations: .left
),
Animations(
id: "Top",
animations: .top
),
Animations(
id: "Bottom",
animations: .bottom
),
Animations(
id: "Scale Up",
animations: .scaleUp
),
Animations(
id: "Scale Down",
animations: .scaleDown
),
]

override func configure(list: inout ListProperties)
{
list.appearance = .demoAppearance
list.layout = .demoLayout

list += Section(identifier: "animations") { section in

section.header = HeaderFooter(DemoHeader(title: "Item Animations"))

for animations in self.animations {

guard self.deleted != animations else {
continue
}

section += Item(
DemoItem(text: animations.id),
selectionStyle: .tappable,
insertAndRemoveAnimations: animations.animations,
onSelect: { _ in
self.view.isUserInteractionEnabled = false

Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false) { _ in
self.deleted = animations
self.reload(animated: true)

Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
self.view.isUserInteractionEnabled = true

self.deleted = nil
self.reload(animated: true)
}
}
})
}

section += DemoItem(text: "Extra Row 1")
section += DemoItem(text: "Extra Row 2")
section += DemoItem(text: "Extra Row 3")
}
}
}
7 changes: 7 additions & 0 deletions Demo/Sources/Demos/DemosRootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ public final class DemosRootViewController : UIViewController
onSelect : { _ in
self.push(CoordinatorViewController())
})

section += Item(
DemoItem(text: "Item Insert & Remove Animations"),
selectionStyle: .tappable,
onSelect: { _ in
self.push(ItemInsertAndRemoveAnimationsViewController())
})
}

list += Section(identifier: "layouts") { section in
Expand Down
5 changes: 3 additions & 2 deletions Listable/Sources/HeaderFooter/HeaderFooter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

public protocol AnyHeaderFooter : AnyHeaderFooter_Internal
{
var sizing : Sizing { get set }
var layout : HeaderFooterLayout { get set }
}

public protocol AnyHeaderFooter_Internal
Expand Down Expand Up @@ -56,8 +58,7 @@ public struct HeaderFooter<Content:HeaderFooterContent> : AnyHeaderFooter
_ content : Content,
sizing : Sizing = .thatFitsWith(.init(.atLeast(.default))),
layout : HeaderFooterLayout = HeaderFooterLayout()
)
{
) {
self.content = content

self.sizing = sizing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ extension ItemCell {
final class ContentContainerView : UIView {

let contentView : Content.ContentView

private var swipeConfiguration: SwipeConfiguration?

private var swipeState: SwipeActionState = .closed {
didSet {
if oldValue != swipeState {
Expand Down Expand Up @@ -194,6 +195,7 @@ extension ItemCell {
}

private func didPerformAction(expandActions: Bool) {

if expandActions {
self.set(state: .expandActions, animated: true)
} else {
Expand Down
2 changes: 1 addition & 1 deletion Listable/Sources/Internal/ItemCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class ItemCell<Content:ItemContent> : UICollectionViewCell
self.selectedBackground = Content.createReusableSelectedBackgroundView(frame: bounds)

super.init(frame: frame)

self.backgroundView = self.background
self.selectedBackgroundView = self.selectedBackground

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protocol AnyPresentationItemState : AnyObject
var anyModel : AnyItem { get }

var reorderingActions : ReorderingActions { get }

var cellRegistrationInfo : (class:AnyClass, reuseIdentifier:String) { get }

func dequeueAndPrepareCollectionViewCell(in collectionView : UICollectionView, for indexPath : IndexPath) -> UICollectionViewCell
Expand Down Expand Up @@ -51,8 +51,8 @@ protocol ItemContentCoordinatorDelegate : AnyObject

public struct ItemStateDependencies
{
internal var reorderingDelegate : ReorderingActionsDelegate
internal var coordinatorDelegate : ItemContentCoordinatorDelegate
var reorderingDelegate : ReorderingActionsDelegate
var coordinatorDelegate : ItemContentCoordinatorDelegate
}


Expand Down Expand Up @@ -88,7 +88,7 @@ extension PresentationState
let storage : Storage

init(with model : Item<Content>, dependencies : ItemStateDependencies)
{
{
self.reorderingActions = ReorderingActions()
self.itemPosition = .single

Expand Down Expand Up @@ -224,7 +224,7 @@ extension PresentationState
for: reason,
with: applyInfo
)

// Apply Swipe To Action Appearance
if let actions = self.model.swipeActions {
cell.contentContainer.registerSwipeActionsIfNeeded(actions: actions, reason: reason)
Expand Down
14 changes: 14 additions & 0 deletions Listable/Sources/Item/Item.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public protocol AnyItem : AnyItem_Internal
var sizing : Sizing { get set }
var layout : ItemLayout { get set }
var selectionStyle : ItemSelectionStyle { get set }
var insertAndRemoveAnimations : ItemInsertAndRemoveAnimations? { get set }
var swipeActions : SwipeActionsConfiguration? { get set }

var reordering : Reordering? { get set }
Expand All @@ -49,6 +50,8 @@ public struct Item<Content:ItemContent> : AnyItem

public var selectionStyle : ItemSelectionStyle

public var insertAndRemoveAnimations : ItemInsertAndRemoveAnimations?

public var swipeActions : SwipeActionsConfiguration?

public var reordering : Reordering?
Expand Down Expand Up @@ -83,6 +86,7 @@ public struct Item<Content:ItemContent> : AnyItem
sizing : Sizing? = nil,
layout : ItemLayout? = nil,
selectionStyle : ItemSelectionStyle? = nil,
insertAndRemoveAnimations : ItemInsertAndRemoveAnimations? = nil,
swipeActions : SwipeActionsConfiguration? = nil,
reordering : Reordering? = nil,
onDisplay : OnDisplay.Callback? = nil,
Expand Down Expand Up @@ -117,6 +121,12 @@ public struct Item<Content:ItemContent> : AnyItem
self.selectionStyle = .notSelectable
}

if let insertAndRemoveAnimations = insertAndRemoveAnimations {
self.insertAndRemoveAnimations = insertAndRemoveAnimations
} else if let insertAndRemoveAnimations = content.defaultItemProperties.insertAndRemoveAnimations {
self.insertAndRemoveAnimations = insertAndRemoveAnimations
}

if let swipeActions = swipeActions {
self.swipeActions = swipeActions
} else if let swipeActions = content.defaultItemProperties.swipeActions {
Expand Down Expand Up @@ -222,17 +232,21 @@ public struct DefaultItemProperties<Content:ItemContent>

public var selectionStyle : ItemSelectionStyle?

public var insertAndRemoveAnimations : ItemInsertAndRemoveAnimations?

public var swipeActions : SwipeActionsConfiguration?

public init(
sizing : Sizing? = nil,
layout : ItemLayout? = nil,
selectionStyle : ItemSelectionStyle? = nil,
insertAndRemoveAnimations : ItemInsertAndRemoveAnimations? = nil,
swipeActions : SwipeActionsConfiguration? = nil
) {
self.sizing = sizing
self.layout = layout
self.selectionStyle = selectionStyle
self.insertAndRemoveAnimations = insertAndRemoveAnimations
self.swipeActions = swipeActions
}
}
Expand Down
Loading

0 comments on commit 21c3d8f

Please sign in to comment.