public protocol Element {
var content: ElementContent { get }
func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription?
}
struct BlueSquare: Element {
var content: ElementContent {
ElementContent(intrinsicSize: CGSize(width: 90.0, height: 90.0))
}
func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? {
UIView.describe { config in
config[\.backgroundColor] = .blue
}
}
}
If the element is view-backed, it should return a view description from this method.
This method is called after layout is complete, and the passed in context provides information about the layout:
context.bounds
Contains the extent of the element after the layout is calculated in the element's local coordinate space.
context.subtreeExtent
A rectangle, given within the element's local coordinate space, that completely contains all of the element's children. nil
will be provided if the element has no children.
Most view-backed elements will not need to care about the bounds or subtree extent, but they are provided for the rare cases when they are needed.
context.environment
The Environment the element is rendered with.
struct MyElement: Element {
// ...
func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? {
UIImageView.describe { config in
config[\.image] = UIImage(named: "cat")
config[\.contentMode] = .scaleAspectFill
}
}
}
ElementContent
represents the content within an element.
Elements can contain multiple children with a complex layout, a single child, or simply an intrinsic size that allows the element to participate in a layout.
public struct ElementContent : Measurable {
public func measure(in constraint: SizeConstraint) -> CGSize
public var childCount: Int { get }
}
extension ElementContent {
public static func container<LayoutType>(layout: LayoutType, configure: (inout Builder<LayoutType>) -> Void = { _ in }) -> ElementContent where LayoutType : Layout
public static func container(element: Element, layout: SingleChildLayout) -> ElementContent
public static func container(element: Element) -> ElementContent
public static func leaf(measurable: Measurable) -> ElementContent
public static func leaf(measureFunction: @escaping (SizeConstraint) -> CGSize) -> ElementContent
public static func leaf(intrinsicSize: CGSize) -> ElementContent
}
var content: ElementContent {
ElementContent(intrinsicSize: CGSize(width: 100, height: 100))
}
var content: ElementContent {
ElementContent(measurable: CustomMeasurer())
}
var content: ElementContent {
ElementContent { constraint in
CGSize(
width: constraint.max.width,
height: 44.0
)
}
}
var content: ElementContent {
ElementContent(child: WrappedElement())
}
var content: ElementContent {
ElementContent(child: WrappedElement(), layout: MyCustomLayout())
}
var content: ElementContent {
ElementContent(layout: MyCustomLayout()) { builder in
builder.add(child: WrappedElementA())
builder.add(child: WrappedElementB())
builder.add(child: WrappedElementC())
}
}