Protocols
The following protocols are available globally.
-
Define
AttributedText
keys using this protocol. Keys must have an attribute name and an associated type for the attribute.After defining a key, enable dynamic member access to it by extending
See moreTextAttributeContainer
with a property for getting and setting setting the value. This property should generally be optional, since the text may not have that property defined.Declaration
Swift
public protocol AttributedTextKey
-
Provides performance information for blueprint layouts and updates.
See moreDeclaration
Swift
public protocol BlueprintViewMetricsDelegate : AnyObject
-
An element type which makes it easier to wrap an existing
UIView
instance that provides its own sizing viasizeThatFits
. An instance of the view is used for sizing and measurement, so that you do not need to re-implement your own measurement.Note
The sizing and measurement prototype view is kept alive for the lifetime of the containing application. Do not pass anything to the initializer of this type that you expect to be quickly released.
Example
If you were implementing a very basic
Switch
element, your implementation would look something like this:
See morestruct Switch : UIViewElement { var isOn : Bool typealias UIViewType = UISwitch func makeUIView() -> UISwitch { UISwitch() } func updateUIView(_ view: UISwitch, with context: UIViewElementContext) { view.isOn = self.isOn } }
Declaration
Swift
public protocol UIViewElement : Element
-
Types used to identify alignment guides.
Types conforming to
See moreAlignmentID
have a corresponding alignment guide value, typically declared as a static constant property ofHorizontalAlignment
orVerticalAlignment
.Declaration
Swift
public protocol AlignmentID
-
Defines a way for an
See moreElement
to be implicitly converted into the conforming type (the child of a container). In practice, this allows us to pass anElement
directly into the result builder without manually converting toChild
(i.e. ConvertingElement
->StackLayout.Child
.Declaration
Swift
public protocol ElementBuilderChild
-
A type that defines the geometry of a collection of elements.
You traditionally arrange views in your app’s user interface using built-in layout containers like
Row
andColumn
. If you need more complex layout behavior, you can define a custom layout container by creating a type that conforms to theLayout
protocol and implementing its required methods:sizeThatFits(proposal:subelements:environment:cache:)
reports the sizes of the composite layout.placeSubelements(in:subelements:environment:cache:)
assigns positions to the container’s subelements.
You can define a basic layout type with only these two methods (see note below):
struct BasicLayout: Layout { func sizeThatFits( proposal: SizeConstraint, subelements: Subelements, cache: inout () ) -> CGSize { // Calculate and return the size of the layout container. } func placeSubelements( in size: CGSize, subelements: Subelements, cache: inout () ) { // Tell each subelement where to appear. } }
Add your layout to an element by passing it to the
ElementContent
initializerinit(layout:configure:)
. If your layout has parameters that come from the element, pass them at initialization time. Use theconfigure
block to add your element’s children to the content.struct BasicContainer: Element { var alignment: Alignment = .center var children: [Element] var content: ElementContent { ElementContent(layout: BasicLayout(alignment: alignment)) { builder in for child in children { builder.add(element: child) } } } func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? { nil } }
If your layout is specialized for laying out a single subelement, you can use the
SingleChildLayout
protocol instead. It has similar methods, but is strongly typed for a single subelement instead of a collection.Note
During the transition from Blueprint’s legacy layout system to Caffeinated Layout, theLayout
protocol is composed of two sets of layout methods:LegacyLayout
andCaffeinatedLayout
. While this documentation focuses on the newer layout API, you must currently implement both. Fortunately, the methods are similar, and you may be able to reuse logic.Interact with subelements through their proxies
To perform layout, you need information about all of your container’s subelements, which are the child elements that your container arranges. While your layout can’t interact directly with its subelements, it can access a set of subelement proxies through the
Subelements
collection that each protocol method receives as an input parameter. That type is an alias for theLayoutSubelements
collection type, which in turn containsLayoutSubelement
instances that are the subelement proxies.You can get information about each subelement from its proxy, like its dimensions and traits. This enables you to measure subelements before you commit to placing them. You also assign a position to each subelement by calling its proxy’s
place(at:anchor:size:)
method. Call the method on each subelement from within your implementation of the layout’splaceSubelements(in:subelements:environment:cache:)
method.Access layout traits
Subelements may have traits that are specific to their container’s layout. The traits are of the
Layout
protocol’s associated typeTraits
, and each subelement can have a distinctTraits
value assigned. You can set this in theconfigure
block ofinit(layout:configure:)
, when you calladd(traits:key:element:)
. If you do not specify aTraits
type for your layout, it defaults to the void type,()
.Containers can choose to condition their behavior according to the traits of their subelements. For example, the
Row
andColumn
types allocate space for their subelements based in part on the grow and shrink priorities that you set on each child. Your layout container accesses the traits for a subelement by callingtraits(forLayoutType:)
on theLayoutSubelement
proxy.Note
TheLayout
API, and its documentation, are modeled after SwiftUI’s Layout, with major differences noted.Declaration
Swift
public protocol Layout : CaffeinatedLayout, LegacyLayout
-
Declaration
Swift
public protocol LegacyLayout
-
Declaration
Swift
public protocol CaffeinatedLayout
-
A type that defines the geometry of a single element.
For convenience, you can implement this protocol instead of
Layout
when building a container that always has a single child element.For more information about writing custom layouts, see
Layout
.Declaration
Swift
public protocol SingleChildLayout : CaffeinatedSingleChildLayout, LegacySingleChildLayout
-
Declaration
Swift
public protocol LegacySingleChildLayout
-
Declaration
Swift
public protocol CaffeinatedSingleChildLayout
-
Conforming types can calculate the size that they require within a layout.
See moreDeclaration
Swift
public protocol Measurable
-
Marker protocol used by generic extensions to native views (e.g.
See moreUIView
).Declaration
Swift
public protocol NativeView
-
Conform to this protocol to handle links tapped in an
AttributedLabel
.Use the
See moreURLHandlerEnvironmentKey
orEnvironment.urlHandler
property to override the link handler in the environment.Declaration
Swift
public protocol URLHandler