- Enabled accessibility ordering, but only propagating the accessibility label reordering is possible and VoiceOver is active to avoid conflicting matches in KIF tests.
containerHeaders
in table and flow layouts now stretch to fill the available width of the view. Previously, they were inset with the content.
- When using
BlueprintUILists
, layout is no longer forced during element updates. This will cause animations to no longer be inherited. Please use.transition
, etc. to control animations.
- Removed item reordering with VoiceOver as it caused issues with KIF tests.
3.2.0 - 2022-03-21
- Fixed list measurements with container headers.
- Item reordering is now possible when using VoiceOver.
3.1.0 - 2022-02-08
ListReorderGesture.Begins
added. This controls when the reorder gesture starts:onTap
andonLongPress
.
3.0.0 - 2022-01-15
TableAppearance.ItemLayout
now properly initializes theitemToSectionFooterSpacing
value.- A swipe actions memory leak has been fixed for
ItemCell.ContentContainerView
.
LayoutDescription
now conforms toEquatable
.ListLayoutAppearance
now has afunc
to modify the default layout.- You can now construct a layout description from a
ListLayoutAppearance
, allowing the underlyingListLayout
to remain internal to a module.
2.0.0 - 2021-12-15
- The signature of
ListLayout.layout(delegate:in:)
has been changed to return aListLayoutResult
value, to make it clearer which values must be provided as the output of a layout.
1.0.2 - 2021-12-14
- When measuring a
List
in an unconstrained size constraint, and.fillParent
is passed, a better assertion message is provided.
- Ensure that
.fillParent
List
measurements returns the right height.
1.0.1 - 2021-12-06
-
You may now set the
contentInsetAdjustmentBehavior
on.table
layouts. This is useful when presenting in a sheet, to more directly control the safe area inset. -
You can now control underflow bounce behavior on
.table
layouts, viabounceOnUnderflow
.
1.0.0 - 2021-12-06
- Insert and removal animations for items now respect
UIAccessibility.isReduceMotionEnabled
, falling back to.fade
ifisReduceMotionEnabled
is true.
-
Added support for
.horizontal
.table
layouts. To get a horizontal table; just set thelayout.direction = .horizontal
when configuring your list's layout. Additionally, some properties were renamed from left/right to leading/trailing to better reflect they can now be on the left/top and right/bottom of a list view, respectively. -
Expose
layoutAppearanceProperties
onLayoutDescription
, to access standard layout appearance properties without creating an instance of the backing layout. -
The
.flow
layout type has been added, to support flow and grid style layouts. -
ListView.contentSize
will now also provide access to the natural width of a layout if the layout supports natural width calculation. This is useful, for example, to show a.table
layout in a popover – you can now know how wide to render the popover. -
Added
.pagingBehaviour
to.table
and.flow
style layouts, which allows implementing carousel-style layouts, by enabling scroll paging alongside item boundaries.
-
The
.experimental_grid
layout type has been removed; it is replaced by.flow
. -
Default sizes have been removed. Please ensure your elements correctly implement
sizeThatFits
, or use fixed sizes.
-
scrollViewProperties
has moved fromListLayout
toListLayoutAppearance
. -
The various
.table { ... }
,.paged { ... }
, etc,LayoutDescription
functions no longer take an escaping closure. -
precondition
is now overridden withinListableUI
andBlueprintUILists
to point at an inlined function, which calls through tofatalError
. This ensures that error messages are reported in crash reports.
0.30.1 - 2021-11-16
- Fix keyboard inset calculations by using
adjustedContentInset
.
0.30.0 - 2021-11-02
-
Added support for result builders when creating lists, sections, and swipe actions:
List { Section("id") { ExampleContent(text: "First Item") ExampleContent(text: "Second Item") } header: { ExampleHeader(title: "This Is My Section") } footer: { ExampleFooter(text: "Rules apply. Prohibited where void.") } }
ListLayout
and its associated types are now public, allowing you to make custom layouts. Note that these APIs are still experimental and subject to change.
0.29.3 - 2021-10-22
- Ensure we properly pass through the
ListEnvironment
when updating on-screen views.
0.29.2 - 2021-10-21
- Fixed an erroneous
weak
reference inSupplementaryContainerView
which lead to contents being deallocated too early – this is not actually needed.HeaderFooterViewStatePair
holds the reference to the containedAnyPresentationHeaderFooterState
, there are not direct strong references fromAnyPresentationHeaderFooterState
toSupplementaryContainerView
.
0.29.1 - 2021-10-18
- Ensure that when comparing header/footer types during updates, we are comparing the correct underlying types in a
type(of:)
check.
0.29.0 - 2021-10-13
- Introduced
swipeActionsStyle
property inItemContent
protocol. This allows clients to configure and specify different visual styles for swipe action views (such asrounded
swipe actions).
onTap
onHeaderFooter
now takes no parameters, to disambiguate it fromconfigure
.
0.28.0 - 2021-09-28
-
Introduced
AnyHeaderFooterConvertible
forHeaderFooters
contained in lists and sections, so you no longer need to wrap yourHeaderFooterContent
in aHeaderFooter
to receive default values. Eg, you can now do:section.header = MyHeaderContent(title: "Albums")
Instead of:
section.header = HeaderFooter(MyHeaderContent(title: "Albums"))
0.27.1 - 2021-09-28
- Change the default sizing of
Item
andHeaderFooter
to.thatFits(.noConstraint)
from requiring the min from the layout. This is more common for self-sizing cells.
0.27.0 - 2021-09-15
clearsSelectionOnViewWillAppear
was moved toListViewController
.
0.26.1 - 2021-09-03
- Includes fix for header reuse from 0.25.1.
0.26.0 - 2021-08-14
- You can now provide default list bounds for participating layouts via the
environment.listContentBounds
property. This allows your containing screen, eg, to provide default bounds to ensure content lays out correctly. Thetable
andgrid
layout types have been updated to read these content bounds.
ListSizing
was renamed toList.Measurement
, to reflect that it affects measurement and to align with Blueprint's terminology for measurement.
0.25.0 - 2021-08-12
- Add support for
containerHeader
, a header which can be added by the container which is displaying the list. This is useful for, eg, a custom navigation controller to add its large title view to the list's content. This header is not affected by the list's vertical padding.
0.24.0 - 2021-08-07
- Add support for
ReappliesToVisibleView
, which allows controlling when an on-screen view should have its content re-applied.
0.23.2 - 2021-08-05
- Ensure that scroll actions work with horizontal lists.
0.23.1 - 2021-07-26
- Fix two reordering crashes, which could happen when 1) a reorder signal resulted in an immediate deletion at the end of the list, and 2) a crash during scrolling during a reorder event.
0.23.0 - 2021-06-29
- Introduce
defaultHeaderFooterProperties
onHeaderFooterContent
, to allow specifying default values for aHeaderFooter
when values are not passed to the initializer.
0.22.2 - 2021-06-23
- Fixed
identifier(for:)
onSection
to match name ofidentifier(with:)
onItemContent
.
0.22.1 - 2021-06-22
- Fixed
Identifiable
conformance forItemContent
.
0.22.0 - 2021-06-22
- Listable now depends on Blueprint
0.27.0
which has major breaking changes. There are no public changes to Listable, except public interfaces determined by Blueprint protocol conformance.
0.21.0 - 2021-06-17
- When applying an update to visible views during content updates, the update now occurs within an animation block. This allows your view to inherit implicit animations more easily.
- Reordering between multiple sections is now supported.
- Introduced type safe access to
Section
content following reorder events. SeeSection.filtered
. ListStateObserver.onItemReordered
was added to observe reorder events at a list-wide level.ListLayout
was extended to allow customization of in-progress moves. Note thatListLayout
is not yet public.
Reordering
has been renamed toItemReordering
, and a newSectionReordering
has been introduced. This allows finer-grained control over validating reorder events at both the item level and section level.ListReorderGesture
andItemReordering.GestureRecognizer
have been heavily refactored to reduce visibility of internal state concerns.Item.identifier
has been renamed toItem.anyIdentifier
. The newItem.identifier
property is now a fully type safe identifier.ReorderingActions
was refactored to expose less public state and ease use in UIView-backed list elements.Identifier<Represented>
is nowIdentifier<Represented, Value>
; egIdentifier<MyContent, UUID>
. This is done to support reacting to reordering events in a more type safe manner, and to makeIdentifier
creation more type safe. This is a large breaking change.- Changed how
identifier
s forItemContent
are represented.ItemContent
now returns a an identifier of a specificIdentifierValue
(eg,String
,UUID
, etc), which is then assembled into anIdentifier
by the containing item. Additional APIs have been added for creatingIdentifier
s in a more type safe manner. This is a large breaking change.
0.20.2 - 2021-04-19
- Fixed the spacing between the header and the first section of a
TableListLayout
to not add the top padding.
0.20.1 - 2021-04-06
0.20.0 - 2021-03-29
- Changed how
ListView.contentSize
is implemented in order to improve performance. An internal list is no longer used, instead we create a layout and ask it to lay out its elements.List.Measurement
also moved toBlueprintUILists
, as that is the only place it was used.
0.19.0 - 2021-03-22
- Add support for adjusting the content offset when the refresh control becomes visible with the
offsetAdjustmentBehavior
property.
Example usage:
list.content.refreshControl = RefreshControl(
isRefreshing: isRefreshing,
offsetAdjustmentBehavior: .displayWhenRefreshing(animate: true, scrollToTop: true),
onRefresh: onRefresh
)
0.18.0 - 2021-03-12
- When calling
scrollToItem
with a.top
scroll position, the item no longer appears underneath sticky section headers.
- Adds
scrollToSection
toListActions
andListView
. To support this functionality,Section
can now be queried with anIdentifier
. Also addedSectionPosition
to specify the top or bottom within aSection
.
Example usage:
listActions.scrolling.scrollToSection(
with: MyItem.identifier(with: id),
sectionPosition: .top,
scrollPosition: ScrollPosition(position: .centered)
)
0.17.0 - 2021-03-10
-
When swiping to delete, limit overscrolling to 20% of the cell width. This prevents undesirable visual state while maintaining swipe bounciness. Additionally, ignore initial swipes to the right which do not "open" the cell.
-
Fixed a crash that occurred when the list's width or height would become zero.
- Updates to
ItemContentCoordinator
to properly support animations in Blueprint-backed rows. This change also generalizes the contained animation type toViewAnimation
, for use in both scrolling and content updates.
0.16.0 - 2021-02-08
- When updating
contentInset
, retain the values pulled from theCollectionView
. This is to avoid clobbering the content inset potentially set by other things like navigation controllers.
- Rename
build
parameters toconfigure
, in order to be more consistent within the framework and with Blueprint.
0.15.1 - 2021-01-25
- Fix a memory leak in
ListView
that caused allListViews
with content in them to leak.
0.15.0 - 2021-01-22
-
Introduce support for layout customization for
Item
,HeaderFooter
, andSection
for allListLayout
types, not just.table
. -
Add
inserted
andremoved
items to.onContentChanged
, to easily determine what content was added or removed from the list a central location.
- Rename
.list
layout to.table
, which is clearer, and also reduces confusion betweenListLayout
(the base protocol for layouts), and the specific table-type layout.
SwipeActionsConfiguration.performsFirstActionWithFullSwipe
is now respected when set tofalse
.
0.14.1 - 2021-01-06
-
Ensure that
ItemContent
s andHeaderFooter
s are a value type. This is generally assumed by Listable, but was previously not validated. This is only validated inDEBUG
builds, to avoid otherwise affecting performance. -
Fix a regression that caused content to be re-measured during each application of an
Appearance
, even if the newAppearance
was equal.
- Adds a way to create items or header/footers for Blueprint lists without requiring the creation of a
BlueprintItemContent
orBlueprintHeaderFooterContent
.
0.13.0 - 2020-12-14
- Introduce
LocalizedItemCollator
, a list-friendly version ofUILocalizedIndexedCollation
which allows collating a list of content at one time.
0.12.1 - 2020-12-01
0.12.0 - 2020-12-01
-
Changed behavior of
scrollInsets
(nowscrollIndicatorInsets
), which now only affects the scroll indicator insets of the contained scroll view, and does not affect the content inset of the scroll view. Please usingpadding
, etc, on the various list layout types instead to control visual padding. -
Ensure we respect both
frame
andbounds
changes to update the innerCollectionView
's frame. We previously used to only respectframe
changes, but we should also respectbounds
changes, as these are used by auto layout. -
Fix support for
autolayout
items and headers/footers by ensuring we pass through the correctsystemLayoutSizeFitting
calls to content. Add assertions that measured sizing is within a reasonable bound. -
Appearance.backgroundColor
now respects the currentUITraitCollection.userInterfaceStyle
. This means that the background color will default towhite
in light mode, andblack
in dark mode. -
Update
ListView.contentSize(in:for:)
to properly validate the providedfittingSize
. This ensures that.unconstrained
measurements along the wrong axis will now assert; instead of freeze.
-
Introduce
onSelectionChanged
onListStateObserver
to allow observing when the selected rows change. -
Pass through
BlueprintUI.Environment
to theElement
s being rendered fromBlueprintItemContent
andBlueprintHeaderFooterContent
. This ensures that the content you put into aList
respects theBlueprintUI.Environment
of theList
itself. This PR also introducesListEnvironment
to facilitate this, which allows similar passthrough of environment variables within Listable. -
Add a
didPerform
callback toAutoScrollAction
, which allows registering a callback when an auto scroll action occurs. -
Change
animated
option on scrolling to ananimation
option`, to allow customizing the animation's behavior.
0.11.0 - 2020-10-20
- Allow setting the
sizing
type on aList
. This controls how the list should be sized by Blueprint: Should it take up all allowed space, or should it size to fit based on its content.
0.10.1 - 2020-10-01
- Fixed import of Swift bridging header, so Cocoapods can build with or without
use_frameworks!
.
0.10.0 - 2020-09-24
- Adjust calculated keyboard inset in both
setFrame
andlayoutSubviews
. This resolves issues that can occur if the list frame changes while the keyboard is visible.
- Add support for
onInsert
,onRemove
,onMove
,onUpdate
, onItem
to track when when items are added, removed, moved, or updated. ChangedonContentChanged
toonContentUpdated
onListStateObserver
; it is always called during updates; you can check thehadChanges
property.
- Removed support for iOS 10. Future releases will only support iOS 11 and later.
-
Change how keyboard are observed to avoid a pitfall where the keyboard would not be accounted for if a
ListView
is created while a keyboard is already on screen. To avoid this problem, we switch to a globally sharedKeyboardObserver
which is loaded at app startup time. -
isEmpty
onContent
andSection
have been replaced withcontains(any:)
, which allows more granular comparison of the content in the whole list and in individual sections, respectively. This allows you to check if the list or sections contain headers, footers, items, all, or some combination of them. -
Listable has been renamed to ListableUI, and BlueprintLists is now named BlueprintUILists. This is done to be more consistent with other Square UI libraries, and to avoid a conflict with an existing published Cocoapod, also named Listable.
-
Simplify
Sizing
now that enums support default associated values.. Now instead of separate.thatFits
and.thatFitsWith(Constraint)
enums, there is a single.thatFits(Constraint = .noConstraint)
case (the same applies forautolayout
). -
Changed how
zIndexes
are assigned to header and items, and support tapping headers / footers. This allows registering anonTap
handler for any HeaderFooter, and providing a background to display while the tap's press is active.
-
Add support for
ListStateObserver
so that you can observe changes made to the list such as insertions, removals, scroll events, etc. -
Add support for
ListActions
which allows performing actions on the underlying list view when used in a declarative environment, or when you otherwise do not have access to the underlying view instance (ListStateViewController
). -
Add support for Behavior.KeyboardAdjustmentMode, which allows for disabling automatic keyboard adjustment behavior. This is useful if your container view is managing the size of or insets on a
ListView
itself. -
Introduced
callAsFunction
support when building with Xcode 11.4 or later. This allows you to replace code like this:List { list in list += Section("first") { section in ... } }
With this:
List { list in list("first") { section in ... } }
Improving terseness when building sections in a list.
-
.paged()
is now a supported layout type. This allows implementing your list to render similarly to aUIPageViewController
, in either horizontal or vertical alignment.
- Removed support for .
horiztonal
layouts on.table()
layouts. Now only.vertical
is supported (this could return at a later date if needed).
-
Changed
Section
initialization APIs fromSection(identifier: "my-id") { ... }
toSection("my-id") { ... }
– it's clear from the API what the first param is for, so the param name just made callsites longer. -
Renamed
setContent
andsetProperties
methods onListView
toconfigure
. -
Significant refactors to how the custom layout APIs work. While this is mostly an internal concern, it continues to refine these APIs to set them up for public exposure and usage at a later date to customize layouts.
- Significant performance improvements for list updates which contain either no changes, or only in-place updates to existing items and sections. In many cases, these updates will now be 80% faster. This change also improves performance for other types of changes such as insertions, removals, or moves, but not to the same degree.
-
Added additional layout configuration options:
headerToFirstSectionSpacing
andlastSectionToFooterSpacing
now let you control the spacing between the list header and content, and the content and the list footer. -
Add support for snapshot testing
Item
s via theItemPreviewView
class. This is a view type which takes in some configuration options, and anItem
, which you can then use in snapshot tests to verify the appearance of yourItem
andItemContent
.let view = ItemPreviewView() view.update( with: 300.0, state: .init(isSelected: false, isHighlighted: false), item: Item(MyItemContent(...)) ) self.takeSnapshot(of: view)
-
Add support for Xcode previews via the
ItemPreview
type. This allows easy previewing yourItemContent
during development like so:struct ElementPreview : PreviewProvider { static var previews: some View { ItemPreview.withAllItemStates( for: Item(XcodePreviewDemoContent( text: "Lorem ipsum dolor sit amet (...)" )) ) } }
There are included options like
withAllItemStates
which allow seeing previews across the various possible selection and highlight states. -
Add
customInterSectionSpacing
property toSection.Layout
which allows the user to specify custom spacing after a section, overriding the calculated spacing. -
Add
insertAndRemoveAnimations
toItem
to allow customizing the animations used when anItem
is inserted or removed from a list. Note that customizing this option when responding toSwipeActions
will come at a later date. -
Add
ListViewController
make it easy to create view controllers backed by a ListableListView
.
-
Update
Item
callbacks to allow for providing more info to the callback parameters. -
ListAppearance.Layout.padding
is now applied around all content in the list, not only around sections. To regain the previous behavior, useheaderToFirstSectionSpacing
andlastSectionToFooterSpacing
. -
Significantly change how layout configuration is done to make it clearer which type of layout is currently in use, and which options are available on which layouts.
Previously, to configure a layout, you would write code like this:
list.appearance.layoutType = .table list.appearance.table.layout.padding = UIEdgeInsets(...)
Now, you configure the layout like this:
list.layout = .table { $0.layout.padding = UIEdgeInsets(...) }
Or, for your custom layouts, like this:
list.layout = MyCustomLayout.describe { $0.myLayoutsProperty = .foo }
- Change
Item
'sonSelect
andonDeselect
to be performed asynchronously after a single runloop spin, to giveUICollectionView
time to schedule animations if these callbacks are slow. - Add improved signpost logging for selection and deselection, to more easily identify slow callbacks.
- Fixed multiple selection and highlight issues: Highlighting cells now only occurs if the
selectionStyle
istappable
orselectable
. Ensure that whentappable
is provided, the content of a cell is updated when the cell is deselected.
- Added type aliases for
HeaderFooter
andHeaderFooterContent
to reduce verbosity of use. Now instead of typingHeaderFooter(MyHeader())
, you can useHeader(MyHeader())
. - Replace unused / experimental
Binding
type withCoordinator
, which allows you to independently manage item state in a similar manner to SwiftUI'sUIViewRepresentable
'sCoordinator
.
- Major Change:
ItemElement
andHeaderFooterElement
were renamed toItemContent
andHeaderFooterContent
, respectively. This is intended to be a clearer indicaton as to what they are for (the content of an item or header/footer), and fixes a name collision with Blueprint, where we overloaded the meaning ofElement
when using Blueprint integration viaBlueprintUILists
. - Changed
BlueprintHeaderFooter{Content/Element}
's main method to beelementRepresentation
instead ofelement
. This allows easier conformance ofBlueprintUI.ProxyElement
types toBlueprintHeaderFooter{Content/Element}
. SelectionMode
was moved fromContent
toBehavior
, which is in line with other collection view behaviours like scrolling and underflow.- Rename
ItemSelectionStyle.none
toItemSelectionStyle.notSelectable
. This is to avoid conflicts withOptional.none
when working withItemSelectionStyle
as anOptional
.
- Added support for conditionally scrolling to items on insert, based on the
shouldPerform
block passed to theAutoScrollAction
.
Earlier releases were ad-hoc and not tracked. To see all changes, please reference closed PRs on Github.