Releases: DeclarativeHub/Bond
6.10.3
- Make Bond v6 work with Swift 5 / Xcode 10.2.
7.3.1
- Make
Array2D.Section
initializer public.
7.3.0
Bond v7.3 improves ergonomics around Tree types.
Simpler conformance
Trees no long need to be index-based. Conforming to TreeProtocol
(renamed from TreeNodeProtocol
) now requires only that the children property is provided.
/// A protocol that provides abstraction over a tree type.
/// A tree can be any containter type that encapsulates objects or values that are also trees.
public protocol TreeProtocol {
/// A collection of child nodes that are trees and whose children are also trees
associatedtype Children: Collection where
Children.Element: TreeProtocol,
Children.Element.Children == Children,
Children.Index == Int
/// Child nodes of the current tree node.
var children: Children { get }
}
Not that you'll ever need to conform UIView
, bet let's use it as an example:
extension UIView: TreeProtocol {
public var children: [UIView] {
return subviews
}
}
This will automatically provide you index path subscripting capability:
let pickerView = UIPickerView()
let secondSubviewOfFirstSubview = pickerView[childAt: [0, 1]]
Tree Views
Consuming trees is now done through "tree views". Bond provides two views out of the box: DFS and BFS views thorough .depthFirst
and .breadthFirst
properties on any TreeProtocol
.
For example, the snippet
for descendent in pickerView. depthFirst {
print(descendent)
}
will print all descendent views of the pickerView
in depth-first search order. Note that descendent implies not only children, but also children of the children and so on.
Tree view is a flat collection of tree nodes. It's of type Collection
whose indices are of type IndexPath
. That means that we can do all the stuff on trees that we can do with collections, like:
let firstImageViewDescendent = pickerView.breadthFirst.first(where: { $0 is UIImageView })
let allVisible = pickerView.breadthFirst.allSatisfy { !$0.isHidden }
let totalWidth = pickerView.breadthFirst.reduce(0, { $0 + $1.frame.size.width })
Mutable Trees
To add support for various mutating methods on the tree, conform to RangeReplaceableTreeProtocol
protocol. All that is needed is to add setter to children
property:
extension UIView: RangeReplaceableTreeProtocol {
public var children: [UIView] {
get {
return subviews
}
set {
subviews.forEach { $0.removeFromSuperview() }
newValue.forEach { addSubview($0) }
}
}
}
We can then do stuff like inserting, deleting or moving children:
// Moves child at index path [0, 1] to index path [2, 3]
pickerView.move(from: IndexPath(indexes: [0, 1]), to: IndexPath(indexes: [2, 3]))
(Mutable) Observable Trees
Now that our tree type conforms to TreeProtocol
(or RangeReplaceableTreeProtocol
) we can wrap it onto MutableObservableTree
and use the wrapper to enable observation of the tree changes:
let tree = MutableObservableTree(pickerView)
tree.observeNext { changeset in
print(changeset.collection, changeset.diff, changeset.patch)
}
tree.insert(UIImageView(), at: [0, 0])
Simpler Array2D
Array2D
is refactored into a simple struct. Changes should be backward compatible if Array2D
typealias has been used.
public struct Array2D<SectionMetadata, Item>: Array2DProtocol {
/// Represents a single section of Array2D.
public struct Section {
/// Section metadata, e.g. section title.
public var metadata: SectionMetadata
/// Items contained in the section.
public var items: [Item]
}
/// All sections of Array2D.
public var sections: [Section]
/// Create a new Array2D with the given sections.
public init(sections: [Section] = []) {
self.sections = sections
}
}
7.2.1
- Support for Swift 5 compiler (in Swift 4.2 compatibility mode).
Note that this does not update the project to use Swift 5 syntax, it only makes the project compilable with Swift 5 compiler by reworking parts that are affected by Swift 5 breaking changes. You can keep using Swift 4.2 (Xcode 10/10.1).
7.2.0
7.1.0
- Support for Tree diffing. Also implies Array2D diffing.
You can now calculate diffs between trees. For example, a mutable tree can be updated like this:
aMutableTree.replace(with: newTree, performDiff: true)
7.0.0
Bond 7 brings refactored observable collections that are much more powerful and makes it easy to customize binders and create your own variants of observable collections. Anything that conforms to Swift.Collection
can now be made observable. Bond supports observable trees now! Check out observable collections documentation, new playgrounds in the project workspace and the migration guide.
Bond 7 updates only observable collections APIs. All other APIs remain unchanged.
7.0.0-beta.2
- Expose convenience collection methods on immutable changeset container.
- Add
removeSubrange()
method to mutable observable array. - Make UIButton image and backgroundImage bonds of optional type.
- Make table and collection view properties of binder data source
open
.
7.0.0-beta.1
Bond 7 brings refactored observable collections that are much more powerful and makes it easy to customize binders and create your own variants of observable collections. Anything that conforms to Swift.Collection
can now be made observable. Bond also supports observable trees now! Check out observable collections documentation and new playgrounds in the project workspace.
Bond 7 updates only observable collections APIs. All other APIs remain unchanged. APIs for use cases like creating, mutating and binding collections remain mostly unchanged, however there are breaking changes in the collection binders and the observable collection event type. Make sure to check out playgrounds in the project workspace to learn about new stuff.
6.10.2
- Fix submodules protocol (ssh -> https).