Skip to main content

View

Struct View 

Source
pub struct View { /* private fields */ }
Expand description

A SwiftUI view with chainable modifiers.

Implementations§

Source§

impl View

Source

pub fn a11y_hint(self, hint: &str) -> Self

.accessibilityHint(_:) — what happens if the user activates this.

Examples found in repository?
examples/inbox.rs (line 100)
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
More examples
Hide additional examples
examples/settings.rs (line 80)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
Source

pub fn a11y_value(self, value: &str) -> Self

.accessibilityValue(_:) — what the control currently reads as, for one whose value is not its label.

Examples found in repository?
examples/dashboard.rs (line 51)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
More examples
Hide additional examples
examples/todo.rs (line 80)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
Source

pub fn a11y_identifier(self, id: &str) -> Self

.accessibilityIdentifier(_:) — the name a UI test finds this by, not something VoiceOver speaks.

Source

pub fn a11y_add_traits(self, traits: &[AccessibilityTrait]) -> Self

.accessibilityAddTraits(_:)

Source

pub fn a11y_remove_traits(self, traits: &[AccessibilityTrait]) -> Self

.accessibilityRemoveTraits(_:)

Source

pub fn a11y_heading(self, level: HeadingLevel) -> Self

.accessibilityHeading(_:) — which heading level this is, so VoiceOver can navigate by them.

Source

pub fn a11y_sort_priority(self, priority: f64) -> Self

.accessibilitySortPriority(_:) — higher is read first.

Source

pub fn a11y_input_labels(self, labels: &[&str]) -> Self

.accessibilityInputLabels(_:) — the phrases Voice Control accepts for this, when the visible label is awkward to say.

Source

pub fn a11y_responds_to_interaction(self, responds: bool) -> Self

.accessibilityRespondsToUserInteraction(_:)

Source

pub fn a11y_text_content_type(self, kind: TextContentType) -> Self

.accessibilityTextContentType(_:) — what kind of text this is, which changes how VoiceOver reads it.

Source

pub fn a11y_action(self, kind: ActionKind, action: impl Fn() + 'static) -> Self

.accessibilityAction(_:_:) — an action VoiceOver can perform without a visible control for it.

Source

pub fn a11y_actions(self, category: ActionCategory, content: View) -> Self

.accessibilityActions(category:content:) — several, as a group.

Source

pub fn a11y_adjustable_action(self, action: impl Fn(i64) + 'static) -> Self

.accessibilityAdjustableAction(_:) — what a swipe up or down does, which is how VoiceOver drives a slider or stepper.

Source

pub fn a11y_scroll_action(self, action: impl Fn(i64) + 'static) -> Self

.accessibilityScrollAction(_:)

Source

pub fn a11y_zoom_action(self, action: impl Fn() + 'static) -> Self

.accessibilityZoomAction(_:)

Source

pub fn a11y_element(self, children: AccessibilityChildBehavior) -> Self

.accessibilityElement(children:) — whether descendants are merged into one element, kept as a container, or dropped.

Examples found in repository?
examples/dashboard.rs (line 49)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
Source

pub fn a11y_children(self, children: View) -> Self

.accessibilityChildren(children:) — a different subtree for VoiceOver than the one on screen.

Source

pub fn a11y_representation(self, representation: View) -> Self

.accessibilityRepresentation(representation:) — stand in for this view with a description of a standard control.

Source

pub fn a11y_labeled_pair( self, role: LabeledPairRole, id: HashableValue<'_>, ) -> Self

.accessibilityLabeledPair(role:id:) — tie a label to the thing it labels, so they are read together.

Source

pub fn a11y_linked_group<'h>(self, id: impl IntoHashable<'h>) -> Self

.accessibilityLinkedGroup(id:)

Source

pub fn a11y_custom_content( self, key_label: &str, id: &str, value: &str, importance: CustomContentImportance, ) -> Self

.accessibilityCustomContent(_:_:importance:) — extra detail VoiceOver reads on request rather than always.

Source

pub fn a11y_activation_point(self, x: f64, y: f64) -> Self

.accessibilityActivationPoint(_:) — where a VoiceOver double-tap lands, for a control whose centre is not where it should be pressed.

Source

pub fn a11y_drag_point(self, x: f64, y: f64, description: &str) -> Self

.accessibilityDragPoint(_:description:)

Source

pub fn a11y_drop_point(self, x: f64, y: f64, description: &str) -> Self

.accessibilityDropPoint(_:description:)

Source

pub fn a11y_direct_touch( self, enabled: bool, options: &[DirectTouchOption], ) -> Self

.accessibilityDirectTouch(_:options:) — for a view that handles raw touches itself, like an instrument or a drawing canvas.

Source

pub fn a11y_scroll_status(self, status: &str) -> Self

.accessibilityScrollStatus(_:) — what to announce after a scroll.

Source

pub fn a11y_shows_large_content_viewer(self) -> Self

.accessibilityShowsLargeContentViewer()

Source§

impl View

Source

pub fn accessibility_action( self, kind: ActionKind, action: impl Fn() + 'static, ) -> Self

Apply .accessibilityAction(_:_:).

Source

pub fn accessibility_actions( self, category: ActionCategory, content: View, ) -> Self

Apply .accessibilityActions(category:_:).

Source

pub fn accessibility_activation_point(self, x: f64, y: f64) -> Self

Apply .accessibilityActivationPoint(_:).

A UnitPoint is two CGFloats and frozen, so it arrives in d0 and d1 rather than by address.

Source

pub fn accessibility_add_traits(self, traits: &[AccessibilityTrait]) -> Self

Apply .accessibilityAddTraits(_:).

Source

pub fn accessibility_adjustable_action( self, action: impl Fn(i64) + 'static, ) -> Self

Apply .accessibilityAdjustableAction(_:).

The direction reaches the callback as a case number: 0 is .increment, 1 is .decrement.

Source

pub fn accessibility_chart_descriptor(self) -> Self

Apply .accessibilityChartDescriptor(_:) with a synthesized representable.

No public SwiftUI type conforms to AXChartDescriptorRepresentable — the protocol exists for applications to adopt — so the conformance is built at run time and hung on EdgeInsets, which the reference can name too.

Source

pub fn accessibility_children(self, children: View) -> Self

Apply .accessibilityChildren(children:).

Source

pub fn accessibility_custom_content( self, key_label: &str, id: &str, value: &str, importance: CustomContentImportance, ) -> Self

Apply .accessibilityCustomContent(_:_:importance:).

The key is built first, through AccessibilityCustomContentKey.init(_:id:) — four words of LocalizedStringKey and two of String, returning the key through x8 because it is resilient. The modifier then takes that key by address, its own label as another LocalizedStringKey, and the importance in a register.

Source

pub fn accessibility_default_focus(self, value: bool) -> Self

Apply .accessibilityDefaultFocus(_:_:).

The binding’s Value is generic here, which makes FocusState<A>.Binding address-only — unlike the concrete focused(_:), where it travels in three registers.

Source

pub fn accessibility_deprecated_identifier(self, id: &str) -> Self

Apply .accessibility(identifier:), the pre-accessibilityIdentifier name.

Source

pub fn accessibility_direct_touch( self, enabled: bool, options: &[DirectTouchOption], ) -> Self

Apply .accessibilityDirectTouch(_:options:).

Source

pub fn accessibility_drag_point( self, x: f64, y: f64, description: &str, enabled: bool, ) -> Self

Apply .accessibilityDragPoint(_:description:isEnabled:).

Source

pub fn accessibility_drop_point( self, x: f64, y: f64, description: &str, enabled: bool, ) -> Self

Apply .accessibilityDropPoint(_:description:isEnabled:).

Source

pub fn accessibility_element(self, v0: AccessibilityChildBehavior) -> Self

Apply .accessibilityElement(_:).

Source

pub fn accessibility_focused(self) -> Self

Apply .accessibilityFocused(_:).

Source

pub fn accessibility_heading(self, level: HeadingLevel) -> Self

Apply .accessibilityHeading(_:).

Source

pub fn accessibility_hidden(self, hidden: bool) -> Self

Apply .accessibilityHidden(_:).

Source

pub fn accessibility_hint(self, hint: &str) -> Self

Apply .accessibilityHint(_:).

Source

pub fn accessibility_identifier(self, id: &str) -> Self

Apply .accessibilityIdentifier(_:).

Source

pub fn accessibility_ignores_invert_colors(self, value: bool) -> Self

Apply .accessibilityIgnoresInvertColors(_:).

Source

pub fn accessibility_input_labels(self, labels: &[&str], enabled: bool) -> Self

Source

pub fn accessibility_label(self, label: &str) -> Self

Apply .accessibilityLabel(_:).

Source

pub fn accessibility_labeled_pair<'h>( self, role: LabeledPairRole, id: impl IntoHashable<'h>, ) -> Self

Apply .accessibilityLabeledPair(role:id:in:).

Source

pub fn accessibility_linked_group<'h>(self, id: impl IntoHashable<'h>) -> Self

Apply .accessibilityLinkedGroup(id:in:).

Source

pub fn accessibility_remove_traits(self, traits: &[AccessibilityTrait]) -> Self

Apply .accessibilityRemoveTraits(_:).

Source

pub fn accessibility_representation(self, representation: View) -> Self

Apply .accessibilityRepresentation(representation:).

Source

pub fn accessibility_responds_to_user_interaction(self, responds: bool) -> Self

Apply .accessibilityRespondsToUserInteraction(_:).

Source

pub fn accessibility_rotor(self, label: &str, text: &str) -> Self

Apply .accessibilityRotor(_:textRanges:).

The ranges are real Range<String.Index> values taken from text — one spanning the whole string. Range is frozen and its two bounds are stored back to back, so the array elements are built directly rather than through an initialiser.

Source

pub fn accessibility_rotor_entry<'h>(self, id: impl IntoHashable<'h>) -> Self

Apply .accessibilityRotorEntry(id:in:).

Source

pub fn accessibility_scroll_action(self, action: impl Fn(i64) + 'static) -> Self

Apply .accessibilityScrollAction(_:).

The edge reaches the callback as a case number, in Edge’s declared order: top, leading, bottom, trailing.

Source

pub fn accessibility_scroll_status(self, status: &str, enabled: bool) -> Self

Apply .accessibilityScrollStatus(_:isEnabled:).

Source

pub fn accessibility_selection_identifier<'h>( self, id: impl IntoHashable<'h>, ) -> Self

.accessibility(selectionIdentifier:) — which item of a selectable group this is, for assistive technologies.

Deprecated in Swift, with no modern replacement — accessibilityIdentifier is a different thing (a test hook). Bound because it is the one member of that family the crate could not otherwise reach.

The argument is AnyHashable, which is three words: the boxed value, its metadata and its Hashable witness.

Source

pub fn accessibility_shows_large_content_viewer(self) -> Self

Apply .accessibilityShowsLargeContentViewer(_:).

Source

pub fn accessibility_sort_priority(self, priority: f64) -> Self

Apply .accessibilitySortPriority(_:).

Source

pub fn accessibility_text_content_type(self, kind: TextContentType) -> Self

Apply .accessibilityTextContentType(_:).

Source

pub fn accessibility_value(self, value: &str, enabled: bool) -> Self

Apply .accessibilityValue(_:isEnabled:).

Source

pub fn accessibility_zoom_action(self, action: impl Fn() + 'static) -> Self

Apply .accessibilityZoomAction(_:).

Source

pub fn allowed_dynamic_range(self, range: DynamicRange) -> Self

Apply .allowedDynamicRange(_:).

Source

pub fn allows_hit_testing(self, value: bool) -> Self

Apply .allowsHitTesting(_:).

Source

pub fn allows_tightening(self, value: bool) -> Self

Apply .allowsTightening(_:).

Source

pub fn allows_window_activation_events(self, allows: Option<bool>) -> Self

Apply .allowsWindowActivationEvents(_:).

Source

pub fn animation_kind(self, kind: AnimationKind, value: i64) -> Self

.animation(_:value:) with the curve named.

Source

pub fn aspect_ratio_content_mode( self, ratio: Option<f64>, mode: ContentMode, ) -> Self

.aspectRatio(_:contentMode:) with the mode named rather than spelled as a bool.

None for the ratio means “keep whatever the content already has”, which is not the same as Some(1.0).

Source

pub fn background(self, r: f64, g: f64, b: f64, a: f64) -> Self

Apply .background(_:) with a Color.

Source

pub fn background_any_gradient(self, color: u64) -> Self

Apply .background(_:) with an AnyGradient — what .indigo.gradient is.

Source

pub fn background_content(self, content: View, alignment: Alignment) -> Self

Apply .background(alignment:content:).

The same call as .overlay(alignment:content:) with a different symbol: an Alignment in x0/x1, the content closure and its context in x2/x3, four generic words after that. The colour-taking background next door is a different overload entirely — that one is generic over ShapeStyle, this one over View.

Source

pub fn background_extension_effect(self) -> Self

Apply .backgroundExtensionEffect(_:).

Source

pub fn background_in_circle(self) -> Self

Apply .background(in:fillStyle:) — the background style, clipped to a shape.

The shape must be InsettableShape, not merely Shape, so its witness is a different table from the one super::Shape carries.

Source

pub fn background_linear_gradient( self, colors: &[Color], start: (f64, f64), end: (f64, f64), ) -> Self

Apply .background(LinearGradient(colors:startPoint:endPoint:)).

Source

pub fn background_material(self, kind: MaterialKind) -> Self

Apply .background(_: Material) — the blur materials.

Source

pub fn background_radial_gradient( self, colors: &[Color], center: (f64, f64), start_radius: f64, end_radius: f64, ) -> Self

Apply .background(RadialGradient(colors:center:startRadius:endRadius:)).

Source

pub fn background_style_color(self, r: f64, g: f64, b: f64, a: f64) -> Self

.backgroundStyle(_:) with a Color.

background_style_of takes the style as raw bytes and a witness, which is what an arbitrary ShapeStyle needs and what nothing can call without building one first. These three name the styles that have a Rust spelling, so the modifier is reachable the way the documentation writes it.

Not .background(_:): that draws behind this view, while this says what style the views inside should use for their own backgrounds.

Source

pub fn background_style_hierarchical(self, level: Hierarchical) -> Self

.backgroundStyle(_:) with one of the hierarchical levels.

Source

pub fn background_style_value(self, color: u64) -> Self

.backgroundStyle(_:) with an already-resolved Color word.

Source

pub fn badge(self, value: i64) -> Self

Apply .badge(_:).

Source

pub fn border_value(self, color: u64, width: f64) -> Self

Apply .border(_:width:) with a Color that is already built.

For one of SwiftUI’s named colours: Color.gray is semantic and no set of components spells it. See system_color.

Source

pub fn button_style_glass_clear(self) -> Self

Apply .buttonStyle(.glass(.clear)).

.glass(_:) is a static on a PrimitiveButtonStyle extension constrained to GlassButtonStyle — the shape that has been inlinable every other time in this file. This one is exported, which is only knowable by looking.

Source

pub fn clip_rounded_rect(self, radius: f64) -> Self

Apply .clipShape(RoundedRectangle(cornerRadius:)).

Source

pub fn clip_rounded_rect_styled(self, radius: f64, continuous: bool) -> Self

Apply .clipShape(RoundedRectangle(cornerRadius:style:)).

As with super::rounded_rectangle_styled, the style is not optional here even though Swift source can leave it out: leaving it out means .continuous, and writing case 0 builds the other shape.

Source

pub fn color_effect(self, shader: &Shader) -> Self

Apply .colorEffect(_:) — recolours each pixel.

Source

pub fn color_invert(self) -> Self

Apply .colorInvert(_:).

Source

pub fn confirmation_message( self, title: &str, actions: View, message: View, presented: bool, ) -> Self

confirmationDialog(…actions:message:) with a fixed flag, which cannot be dismissed — see confirmation_dialog.

Source

pub fn container_value<T: KeyValue>( self, key: &CustomContainerKey<T>, value: impl IntoKeyValue<T>, ) -> Self

.containerValue(\.key, value) for a key defined here.

What the @_alwaysEmitIntoClient modifier’s body does, since the modifier itself exports no symbol: build a _ContainerValueWritingModifier and apply it with .modifier(_:).

Source

pub fn corner_radius(self, radius: f64) -> Self

Apply .cornerRadius(_:).

Examples found in repository?
examples/common/spec.rs (line 648)
632fn decorate(mut v: View, node: &Node) -> Result<View, String> {
633    if let Some(p) = node.f64_attr("pad") {
634        v = v.padding(p);
635    }
636    if let Some(size) = node.attr("frame") {
637        let (w, h) = parse_size(size, node.line)?;
638        v = v.frame(w, h);
639    }
640    if let Some(o) = node.f64_attr("opacity") {
641        v = v.opacity(o);
642    }
643    if let Some(c) = node.attr("bg") {
644        let c = parse_color(c, node.line)?;
645        v = v.bg(c);
646    }
647    if let Some(r) = node.f64_attr("corner") {
648        v = v.corner_radius(r);
649    }
650    Ok(v)
651}
Source

pub fn custom_animation(self, curve: &CustomAnimationCurve, value: i64) -> Self

.animation(Animation(curve), value:) with a curve written in Rust.

Source

pub fn custom_button_style(self, style: &CustomButtonStyle) -> Self

.buttonStyle(_:) with a style written in Rust.

Source

pub fn custom_label_style(self, style: &CustomLabelStyle) -> Self

.labelStyle(_:) with a style written in Rust.

Source

pub fn custom_modifier(self, modifier: &CustomModifier) -> Self

.modifier(_:) with a modifier written in Rust.

The result is ModifiedContent<Self, RustModifier> — a concrete type, not an opaque one, because modifier<T>(_:) says so. T is unconstrained there, so no witness table is passed at the call: SwiftUI finds the conformance by lookup when it renders, which is exactly why registering it matters.

Source

pub fn custom_transition(self, transition: &CustomTransition) -> Self

.transition(_:) with a transition written in Rust.

Wrapped in an AnyTransition on the way, because that is what transition<T: Transition>(_:) does: it is @_alwaysEmitIntoClient and exports no symbol, so the binding calls what its body calls.

Source

pub fn delete_disabled(self, value: bool) -> Self

Apply .deleteDisabled(_:).

Source

pub fn dialog_icon(self, system_name: Option<&str>) -> Self

Apply .dialogIcon(_:).

Source

pub fn dialog_prevents_app_termination(self, prevents: Option<bool>) -> Self

Apply .dialogPreventsAppTermination(_:).

Source

pub fn dialog_severity(self, value: DialogSeverity) -> Self

Source

pub fn dialog_suppression_toggle(self, state: &BoundState<bool>) -> Self

Apply .dialogSuppressionToggle(isSuppressed:).

Source

pub fn dialog_suppression_toggle_labelled( self, label: &str, state: &BoundState<bool>, ) -> Self

Apply .dialogSuppressionToggle(_:isSuppressed:) with a label.

Seven integer arguments — four for the key, three for the binding — so Self.Type and the witness table travel on the stack rather than in registers.

Source

pub fn disable_autocorrection(self, disable: Option<bool>) -> Self

Apply .disableAutocorrection(_:).

Source

pub fn distortion_effect(self, shader: &Shader, max_w: f64, max_h: f64) -> Self

Apply .distortionEffect(_:maxSampleOffset:) — warps geometry.

Source

pub fn drag_gesture(self, minimum_distance: f64) -> Self

Attach a DragGesture.

Source

pub fn draggable_text(self, text: &str) -> Self

Apply .draggable(_:) with a String payload.

The overload everything else calls draggable: drag this view and a piece of text comes out, droppable anywhere that takes one. The containerItemID: binding next door is a different modifier for a different job — reordering within a container.

String because it is the Transferable conformer that needs no bridging: its witness is exported from CoreTransferable, and its value is two loadable words. A Data or a URL payload would each need their own.

Source

pub fn environment_model(self, model: &Model) -> Self

.environment(model) — put the model where every view below can read it.

The Observable overload. A body that reads a property of the model through Model::get while SwiftUI is tracking it is re-run when that property changes; one that reads a different property is not.

Source

pub fn environment_value<T: KeyValue>( self, key: &CustomEnvKey<T>, value: impl IntoKeyValue<T>, ) -> Self

.environment(\.key, value) for a key defined here.

Source

pub fn equatable(self) -> Self

.equatable() — wrap a view in EquatableView, whatever its type.

equatable_text does this for a Text and nothing else, because the mangled name it resolves names Text. The constraint is Content: Equatable & View, and whether a given type satisfies it is a question the runtime can answer — so this asks, instead of the binding deciding in advance which one type is allowed.

The bound is genuine, not a limitation here: a view erased into AnyView is not Equatable and cannot be made so. That is what the panic says, and it is the same thing Swift’s type checker would say at the call site.

Wrapping is the whole of it — equatable() is @inlinable with the body EquatableView(content: self), and EquatableView stores only its content, so the value is the content’s own bytes copied through its value witness. A raw memcpy would work for a Text and leak a reference for anything holding one.

Source

pub fn file_dialog_browser_options( self, value: FileDialogBrowserOptions, ) -> Self

Source

pub fn file_dialog_confirmation_label(self, value: &str) -> Self

Apply .fileDialogConfirmationLabel(_:).

Source

pub fn file_dialog_customization_id(self, value: &str) -> Self

Apply .fileDialogCustomizationID(_:).

Source

pub fn file_dialog_default_directory(self, path: Option<&str>) -> Self

Apply .fileDialogDefaultDirectory(_:).

Source

pub fn file_dialog_imports_unresolved_aliases(self, value: bool) -> Self

Apply .fileDialogImportsUnresolvedAliases(_:).

Source

pub fn file_dialog_message(self, value: &str) -> Self

Apply .fileDialogMessage(_:).

Source

pub fn file_dialog_url_enabled(self, enabled: bool) -> Self

Apply .fileDialogURLEnabled(_:).

The argument is a Foundation.Predicate<Pack{URL}>, which the #Predicate macro normally builds from an expression tree at compile time. Predicate also exposes .true and .false as statics, and those are values rather than syntax — so they are reachable from here, where an arbitrary predicate is not.

The type is generic over a parameter pack, whose mangling closes with _QP rather than directly; see crate::mangle::pack.

Source

pub fn file_exporter_filename_label(self, value: &str) -> Self

Apply .fileExporterFilenameLabel(_:).

Source

pub fn find_disabled(self, value: bool) -> Self

Apply .findDisabled(_:).

Source

pub fn flips_for_right_to_left_layout_direction(self, value: bool) -> Self

Apply .flipsForRightToLeftLayoutDirection(_:).

Source

pub fn focus_effect_disabled(self, value: bool) -> Self

Apply .focusEffectDisabled(_:).

Source

pub fn focus_section(self) -> Self

Apply .focusSection(_:).

Source

pub fn focused_on(self, projection: [u64; 3]) -> Self

Apply .focused(_:) with a real, installed @FocusState.

focused applies the same modifier with a FocusState built on the spot, which is what SwiftUI stores either way but leaves nothing to read or move. This takes the projection of a property SwiftUI has installed, so crate::state::ComposedView::focus reports whether the field has focus and crate::state::ComposedView::set_focus puts it there.

Source

pub fn focused_scene_object(self) -> Self

Apply .focusedSceneObject(_:).

Source

pub fn focused_scene_value<T: KeyValue>( self, key: &FocusKey<T>, value: impl IntoKeyValue<T>, ) -> Self

.focusedSceneValue(keyPath, value) — publish a value for the whole scene.

What a window tells the menu bar about its selection. The scene form is the one commands read; focused_value_keyed is the same thing scoped to whatever currently has focus.

Examples found in repository?
examples/scenes.rs (line 68)
48fn main_window() -> ViewHandle {
49    vstack(&[
50        text("A SwiftUI app, no Swift source")
51            .font_size(20.0)
52            .padding(8.0),
53        divider(),
54        text(&format!("count: {}", counter().get()))
55            .font_size(34.0)
56            .padding(12.0),
57        hstack(&[
58            button("−", || counter().set(counter().get() - 1)),
59            button("+", || counter().set(counter().get() + 1)),
60        ]),
61        spacer(),
62        text("⌘, for Settings · the ★ in the menu bar has a menu")
63            .font_size(11.0)
64            .opacity(0.6),
65    ])
66    .padding(24.0)
67    .frame(420.0, 300.0)
68    .focused_scene_value(counter_focus_key(), counter().get())
69    .into_handle()
70}
Source

pub fn focused_value_keyed<T: KeyValue>( self, key: &FocusKey<T>, value: impl IntoKeyValue<T>, ) -> Self

.focusedValue(keyPath, value) — publish a value for the focused view.

Source

pub fn focused_value_model(self, model: &Model) -> Self

.focusedValue(model) — publish the model for the commands above it.

The object form of what crate::views::focused_scene_value does with a key path, and the one Apple now recommends: a key is a type, and an @Observable object already is one.

Source

pub fn font_apply(self, font: u64) -> Self

Apply an already-built raw Font value with .font(_:).

Source

pub fn font_custom(self, name: &str, size: f64) -> Self

Apply .font(.custom(_:size:)).

Source

pub fn font_system( self, size: f64, weight: Option<Weight>, design: Option<Design>, ) -> Self

Apply .font(.system(size:weight:design:)).

Source

pub fn font_text_style(self, style: TextStyle) -> Self

Apply .font(_:) with one of the built-in text styles.

Source

pub fn font_weight(self, weight: Weight) -> Self

Apply .fontWeight(_:).

Source

pub fn foreground_color(self, color: Option<Color>) -> Self

Apply .foregroundColor(_:).

Source

pub fn foreground_color_value(self, color: u64) -> Self

Apply .foregroundColor(_:), the deprecated environment-writing one.

Not foreground_style_color: this produces _EnvironmentKeyWritingModifier<Color?> and that produces _ForegroundStyleModifier<Color>. They render the same. Apply .foregroundColor(_:) to a Color that is already built.

For one of SwiftUI’s named colours, which no set of components can spell. See super::system_color.

Source

pub fn foreground_style_color(self, r: f64, g: f64, b: f64, a: f64) -> Self

Apply .foregroundStyle(_:) with a colour.

Named for what it does, not for .foregroundColor(_:) — which is deprecated and a different thing: it writes an environment key, producing _EnvironmentKeyWritingModifier<Color?> where this produces _ForegroundStyleModifier<Color>. The two render alike, so only a type-level comparison tells them apart. See foreground_color for the other one.

Source

pub fn foreground_style_hierarchical(self, level: Hierarchical) -> Self

Apply .foregroundStyle(.linearGradient(colors:startPoint:endPoint:)).

The shorthand in Swift source is a protocol-extension static marked @inlinable, so it has no symbol; the LinearGradient it builds does. Apply .foregroundStyle(_:) with one of the hierarchical levels — .secondary and friends.

Source

pub fn foreground_style_linear_gradient( self, colors: &[u64], start: (f64, f64), end: (f64, f64), ) -> Self

Source

pub fn foreground_style_pair(self, primary: u64, secondary: u64) -> Self

Apply .foregroundStyle(_:_:) — a primary and a secondary style.

What symbolRenderingMode(.palette) needs: a palette symbol takes its layers from successive styles, and with only one it renders as monochrome.

Source

pub fn foreground_style_triple( self, primary: u64, secondary: u64, tertiary: u64, ) -> Self

Apply .foregroundStyle(_:_:_:) — three styles.

A palette symbol takes its layers from successive styles. foreground_style_pair covers the two-layer symbols; the three-layer ones — and there are plenty in SF Symbols — rendered their third layer in the secondary colour, because there was no way to say what it should be.

Eleven words of arguments, so three spill: the three style addresses and Self.Type fill x0–x3, the three style types and the Self: View witness take x4–x7, and all three ShapeStyle witnesses go to the stack.

Spilling only two of them — which is easy to do, since the pair version next door fits in eight words exactly and spills none — left the callee reading a stale word as a witness table. It did not fault there: it faulted much later inside swift::MetadataCacheKey::operator==, recursing on a type built from the garbage, which is what an argument-count mistake looks like from the outside.

Source

pub fn foreground_style_value(self, color: u64) -> Self

Apply .foregroundStyle(_:) to a Color that is already built.

The components overload above cannot express Color.blue: SwiftUI’s named colours are semantic, not literal, and resolve per appearance — the aqua Color.blue is nowhere near (0, 0, 1). This takes the value a static getter handed back instead. See super::system_color.

Source

pub fn frame_max_infinity(self, alignment: Alignment) -> Self

Apply .frame(maxWidth:maxHeight:alignment:) with .infinity for both.

Six Optional<CGFloat>s — min, ideal and max for each axis — then an Alignment, then the two generic words. Each optional is payload and tag, so that is sixteen words in all: x0 through x7 carry the first four optionals and the remaining eight go on the stack. The generic arguments come after every formal parameter, which is what makes them spill; putting them in x6 and x7 builds a frame out of the metadata pointers.

Source

pub fn frame_max_width(self, alignment: Alignment) -> Self

Apply .frame(maxWidth: .infinity) — the width only.

Not frame_max_infinity, which sets both axes. Swift’s .frame(maxWidth: .infinity) leaves maxHeight nil, so the view keeps its content’s height; setting both stretched a card to fill its canvas and moved everything in it.

Six Optional<CGFloat>s — min, ideal and max for each axis — then an Alignment, then the two generic words. Each optional is payload and tag, so that is sixteen words in all: x0 through x7 carry the first four optionals and the remaining eight go on the stack. The generic arguments come after every formal parameter, which is what makes them spill; putting them in x6 and x7 builds a frame out of the metadata pointers.

Source

pub fn gesture<V: GestureData>( self, g: &GestureValue<V>, mask: GestureMask, ) -> Self

.gesture(_:including:).

Source

pub fn glass_effect(self) -> Self

Apply .glassEffect() — Liquid Glass, in its default shape.

The result type is a StaticIf<GlassEnabledPredicate, ...>: SwiftUI picks between the glass-modified view and the original at runtime depending on whether the platform has Liquid Glass enabled.

Source

pub fn glass_effect_id<'h>(self, id: Option<impl IntoHashable<'h>>) -> Self

Apply .glassEffectID(_:in:).

Source

pub fn glass_effect_kind(self, glass: Glass) -> Self

The same, with the variant named.

Identity is the no-op: it still builds the StaticIf, so the view’s type is the one a glass effect gives it, with nothing drawn. That is what makes it usable as the “off” end of a condition without the two branches disagreeing about their type.

Source

pub fn glass_effect_transition(self, value: GlassEffectTransition) -> Self

Source

pub fn glass_effect_union<'h>(self, id: Option<impl IntoHashable<'h>>) -> Self

Apply .glassEffectUnion(id:namespace:).

Source

pub fn grid_cell_columns(self, value: i64) -> Self

Apply .gridCellColumns(_:).

Source

pub fn help(self, value: &str) -> Self

Apply .help(_:).

Source

pub fn help_text(self, value: &str) -> Self

Apply .help(_:).

Source

pub fn high_priority_gesture_of<V: GestureData>( self, g: &GestureValue<V>, mask: GestureMask, ) -> Self

.highPriorityGesture(_:including:) — this gesture wins over the view’s own.

Source

pub fn horizontal_radio_group_layout(self) -> Self

Apply .horizontalRadioGroupLayout(_:).

Source

pub fn interaction_activity_tracking_tag(self, value: &str) -> Self

Apply .interactionActivityTrackingTag(_:).

Source

pub fn interactive_dismiss_disabled(self, value: bool) -> Self

Apply .interactiveDismissDisabled(_:).

Source

pub fn invalidatable_content(self, value: bool) -> Self

Apply .invalidatableContent(_:).

Source

pub fn label_icon_to_title_spacing(self, value: f64) -> Self

Apply .labelIconToTitleSpacing(_:).

Source

pub fn label_reserved_icon_width(self, value: f64) -> Self

Apply .labelReservedIconWidth(_:).

Source

pub fn labels_hidden(self) -> Self

Apply .labelsHidden(_:).

Source

pub fn layer_effect(self, shader: &Shader, max_w: f64, max_h: f64) -> Self

Apply .layerEffect(_:maxSampleOffset:) — can sample neighbouring pixels.

Source

pub fn layout_priority(self, value: f64) -> Self

Apply .layoutPriority(_:).

Source

pub fn layout_value_int(self, value: i64) -> Self

Apply .layoutValue(key:value:) with a runtime-synthesized key.

A second protocol through the same machinery as preference_int, to show nothing about it is specific to PreferenceKey.

Source

pub fn list_item_tint(self, tint: Option<ListItemTint>) -> Self

Apply .listItemTint(_:).

None clears the tint, which is the nil the modifier’s ListItemTint? parameter takes.

Source

pub fn long_press_gesture(self, duration: f64, max_distance: f64) -> Self

Attach a LongPressGesture with .gesture(_:including:).

Source

pub fn luminance_to_alpha(self) -> Self

Apply .luminanceToAlpha(_:).

Source

pub fn magnify_gesture(self, minimum_scale_delta: f64) -> Self

Attach a MagnifyGesture.

Source

pub fn minimum_scale_factor(self, value: f64) -> Self

Apply .minimumScaleFactor(_:).

Source

pub fn monospaced_digit(self) -> Self

Apply .monospacedDigit(_:).

Source

pub fn move_disabled(self, value: bool) -> Self

Apply .moveDisabled(_:).

Source

pub fn multiline_alignment(self, align: TextAlign) -> Self

Apply .multilineTextAlignment(_:).

Source

pub fn navigation_bar_back_button_hidden(self, value: bool) -> Self

Apply .navigationBarBackButtonHidden(_:).

Source

pub fn navigation_split_view_style(self, style: SplitViewStyle) -> Self

Apply .navigationSplitViewStyle(_:).

Source

pub fn navigation_subtitle(self, value: &str) -> Self

Apply .navigationSubtitle(_:).

Source

pub fn navigation_subtitle_text(self, value: &str) -> Self

Apply .navigationSubtitle(_:).

Source

pub fn navigation_view_style_columns(self) -> Self

.navigationViewStyle(.columns) — the two-column split.

The witness is looked up at run time rather than named: a NavigationViewStyle conformance mangles its substitutions against the words in its own type name, so ColumnNavigationViewStyle’s is not DefaultNavigationViewStyle’s with a letter changed. Copying one has produced a witness for the wrong protocol in this crate before.

Source

pub fn navigation_view_style_double_column(self) -> Self

.navigationViewStyle(.doubleColumn) — sidebar plus detail.

Source

pub fn on_continuous_hover( self, space: CoordinateSpace, perform: impl Fn(HoverPhase) + 'static, ) -> Self

Apply .onContinuousHover(coordinateSpace:perform:).

Source

pub fn on_drag_ended_value( self, minimum_distance: f64, action: impl Fn(DragValue) + 'static, ) -> Self

The same, with the value SwiftUI delivered.

on_drag_gesture’s handler is told only that a drag ended. This one is told where it started, where it finished and how fast it was going — see DragValue.

Source

pub fn on_drag_gesture( self, minimum_distance: f64, action: impl Fn() + 'static, ) -> Self

Attach a DragGesture with an onEnded handler.

drag_gesture attaches a bare DragGesture with nothing listening, which builds the same value Swift would but can never be seen to fire. This wires the action SwiftUI calls when the drag ends, so the gesture is observable.

The result type is taken from .gesture’s opaque-result-type descriptor rather than a hand-written mangling: the type is ModifiedContent<AnyView, AddGestureModifier<_EndedGesture<DragGesture>, _>>, and spelling that out by hand is how earlier bindings resolved to null.

Source

pub fn on_long_press_gesture( self, duration: f64, max_distance: f64, action: impl Fn() + 'static, ) -> Self

Apply .onLongPressGesture(minimumDuration:maximumDistance:pressing:perform:).

Unlike long_press_gesture, which attaches a bare LongPressGesture with nothing listening, this takes the action SwiftUI runs when the press completes — so the gesture can be observed rather than only built.

Source

pub fn on_magnify_ended( self, minimum_scale_delta: f64, action: impl Fn(MagnifyValue) + 'static, ) -> Self

Attach a MagnifyGesture with an onEnded handler.

Source

pub fn on_pencil_double_tap(self, action: impl Fn() + 'static) -> Self

Apply .onPencilDoubleTap(perform:).

Source

pub fn on_pencil_squeeze(self, action: impl Fn() + 'static) -> Self

Apply .onPencilSqueeze(perform:).

Source

pub fn on_preference_change_int(self) -> Self

Apply .onPreferenceChange(_:perform:), recording the value.

The value is read back through observed_preference. K.Value must also be Equatable here, so the call carries two witness tables for the one generic parameter.

Source

pub fn on_rotate_ended( self, minimum_degrees: f64, action: impl Fn(RotateValue) + 'static, ) -> Self

Attach a RotateGesture with an onEnded handler.

Source

pub fn on_tap_gesture(self, count: i64, action: impl Fn() + 'static) -> Self

Apply .onTapGesture(count:perform:). The action may capture, as super::button’s may — a tap handler that cannot know which row it is on is one every list has to route around.

Source

pub fn padding_insets(self, insets: EdgeInsets) -> Self

.padding(_: EdgeInsets) — a different inset per edge.

padding_set takes one length for a set of edges; this takes four. The insets go in d0–d3, being a homogeneous float aggregate.

Source

pub fn padding_set(self, edges: EdgeSet, length: Option<f64>) -> Self

Apply .padding(_:_:) — chosen edges, an explicit length.

edges is an Edge.Set bit pattern: 1 top, 2 leading, 4 bottom, 8 trailing, so .vertical is 5 and .all is 15. A None length means the system’s own inset, as in padding_default. .padding(_:_:) with the edges named rather than spelled as a bitmask.

padding_edges takes the raw option-set bits, which a caller has to know; this reads the member out of SwiftUI’s own Edge.Set instead.

Source

pub fn preference_int(self, value: i64) -> Self

Apply .preference(key:value:) with a runtime-synthesized key.

The key type carries a PreferenceKey conformance built by crate::conformance at run time, and its Value is Int. No Swift source declares it, which is the whole point: this is the one family of modifiers that expects the client to supply a conformance.

Source

pub fn preferred_color_scheme(self, scheme: ColorScheme) -> Self

Apply .preferredColorScheme(_:) — light or dark for this subtree.

Source

pub fn presented_window_style(self, style: WindowStyle) -> Self

Apply .presentedWindowStyle(_:).

Source

pub fn presented_window_toolbar_style(self, style: WindowToolbarStyle) -> Self

Apply .presentedWindowToolbarStyle(_:).

Source

pub fn preview_context(self) -> Self

Apply .previewContext(_:).

Source

pub fn preview_device(self, name: Option<&str>) -> Self

Apply .previewDevice(_:).

Source

pub fn preview_display_name(self, name: Option<&str>) -> Self

Apply .previewDisplayName(_:).

Source

pub fn preview_interface_orientation(self, value: InterfaceOrientation) -> Self

Source

pub fn preview_layout(self, layout: PreviewLayout) -> Self

Apply .previewLayout(_:).

Source

pub fn privacy_sensitive(self, value: bool) -> Self

Apply .privacySensitive(_:).

Source

pub fn progress_view_style(self, style: ProgressStyle) -> Self

Apply .progressViewStyle(_:).

Not missing after all. Searching the export table for progressViewStyle finds nothing because the mangling compresses ViewStyle to 08progressC5Style — C substitutes the View of the enclosing SwiftUI.View — so the spelled-out name never appears. The SIL for one line of Swift names it outright.

.linear and .automatic are @_alwaysEmitIntoClient statics with no symbol of their own; the structs they return have plain initialisers, which is what this needs.

Source

pub fn replace_disabled(self, value: bool) -> Self

Apply .replaceDisabled(_:).

Source

pub fn rotate_gesture(self, minimum_degrees: f64) -> Self

Attach a RotateGesture. The minimum delta is an Angle, i.e. radians.

Source

pub fn rotation(self, degrees: f64, anchor_x: f64, anchor_y: f64) -> Self

Apply .rotationEffect(.degrees(_), anchor:).

Source

pub fn rotation_3d(self, degrees: f64, ax: f64, ay: f64, az: f64) -> Self

Apply .rotation3DEffect(_:axis:).

Source

pub fn scaled_to_fill(self) -> Self

Apply .scaledToFill(_:).

Source

pub fn scaled_to_fit(self) -> Self

Apply .scaledToFit(_:).

Source

pub fn scene_padding(self, v0: ScenePadding, v1: EdgeSet) -> Self

Apply .scenePadding(_:).

Source

pub fn scroll_clip_disabled(self, value: bool) -> Self

Apply .scrollClipDisabled(_:).

Source

pub fn scroll_disabled(self, value: bool) -> Self

Apply .scrollDisabled(_:).

Source

pub fn scroll_position_edge(self, edge: Edge) -> Self

.scrollPosition(_:anchor:) — scroll to an edge, and stay bound to it.

scroll_position_id is the other overload, which scrolls to a row by its identity. This one takes a whole ScrollPosition, which is what “scrolled to the top” is: there is no row to name.

The position lives in the binding for the life of the view. SwiftUI writes back as the user scrolls, so it has to be somewhere that outlives the call that made it.

Source

pub fn search_completion(self, value: &str) -> Self

Apply .searchCompletion(_:).

Source

pub fn sign_in_with_apple_button_style(self, style: AppleButtonStyle) -> Self

.signInWithAppleButtonStyle(_:).

Declared on View in the overlay, so its mangled name says SwiftUI.View with the overlay as the extension’s module — which is why it resolves in the overlay’s image and not in SwiftUI’s.

Source

pub fn simultaneous_gesture_of<V: GestureData>( self, g: &GestureValue<V>, mask: GestureMask, ) -> Self

.simultaneousGesture(_:including:) — both this and the view’s own run.

Source

pub fn speech_adjusted_pitch(self, value: f64) -> Self

Apply .speechAdjustedPitch(_:).

Source

pub fn speech_always_includes_punctuation(self, value: bool) -> Self

Apply .speechAlwaysIncludesPunctuation(_:).

Source

pub fn speech_announcements_queued(self, value: bool) -> Self

Apply .speechAnnouncementsQueued(_:).

Source

pub fn speech_spells_out_characters(self, value: bool) -> Self

Apply .speechSpellsOutCharacters(_:).

Source

pub fn submit_scope(self, value: bool) -> Self

Apply .submitScope(_:).

Source

pub fn symbol_color_rendering_mode(self, mode: SymbolColorRendering) -> Self

Apply .symbolColorRenderingMode(_:).

Source

pub fn symbol_effect(self, effect: SymbolEffect) -> Self

.symbolEffect(_:) with any of the indefinite effects.

The case tag is read from the enum’s reflection rather than written down: SymbolEffectConfiguration.Effect numbers its cases in declaration order, which is not the order the documentation lists them — .variableColor is 2 and .scale is 3, where reading down the page would say otherwise. A wrong tag builds a valid value of the wrong case, which renders, and renders wrongly. See abi::enum_case_index.

Source

pub fn symbol_variable_value_mode(self, mode: SymbolVariableValue) -> Self

Apply .symbolVariableValueMode(_:).

Source

pub fn tab_view_customization(self) -> Self

.tabViewCustomization(_:) with a live customization, not nil.

tab_view_customization_none passes nil, which is the “do not persist anything” case and the only one that needed no value. This builds a real TabViewCustomization and hands SwiftUI a binding to it, so the user’s reordering and hiding of tabs is kept — the whole point of the modifier.

The value lives in the binding’s closures for the life of the process: a customization SwiftUI can write back to has to outlive the call that made it, and there is nowhere else to put it.

Source

pub fn tab_view_search_activation(self, activation: TabSearchActivation) -> Self

.tabViewSearchActivation(_:).

Source

pub fn tab_view_style(self, style: TabStyle) -> Self

Apply .tabViewStyle(_:).

Source

pub fn task_once( self, priority: TaskPriority, file: &str, line: i64, action: impl Fn() + Send + Sync + 'static, ) -> Self

Apply .task { … } — the spelling with no id:.

A different modifier from task, not a default-argument version of it: that one builds _TaskValueModifier2<ID> and re-runs when the id changes, this one builds _TaskModifier2 and runs once. _TaskModifier2 is not generic, so there are no generic words to spill.

The name carries the call site — SwiftUI records View.task @ file:line — so a value comparison against a reference only agrees if the caller passes the reference’s own file and line, which is why they are parameters.

Source

pub fn text_baseline_offset(self, amount: f64) -> Self

Text.baselineOffset(_:)

Source

pub fn text_bold(self) -> Self

Text.bold() — the one that returns Text.

Returns the View extension’s result if this is not a Text: that is what a caller wants there, and it is what every one of these used to do.

Source

pub fn text_font(self, font: Option<&Font>) -> Self

Text.font(_:) — the overload that returns Text.

Text("x").font(.body).bold() stays a Text all the way through in Swift precisely because this returns one; going through the View extension for the font is what made the rest of the chain fall back to the environment forms. None clears the font.

Source

pub fn text_font_weight(self, weight: Option<Weight>) -> Self

Text.fontWeight(_:) — the overload that returns Text.

Font.Weight? lowers to two words, a payload and a tag, which land ahead of self — so this is the one shape the single-word helper cannot serve. None clears the weight.

Source

pub fn text_foreground_color(self, color: Color) -> Self

Text.foregroundColor(_:) — the overload that returns Text.

Source

pub fn text_foreground_hierarchical(self, level: Hierarchical) -> Self

Text.foregroundStyle(_:) with one of the hierarchical styles.

Source

pub fn text_foreground_linear_gradient( self, colors: &[u64], start: (f64, f64), end: (f64, f64), ) -> Self

Text.foregroundStyle(LinearGradient(...)).

Source

pub fn text_input_completion(self, value: &str) -> Self

Apply .textInputCompletion(_:).

Source

pub fn text_italic(self) -> Self

Text.italic()

Source

pub fn text_kerning(self, amount: f64) -> Self

Text.kerning(_:) — space added between every pair of characters.

Source

pub fn text_monospaced(self) -> Self

Text.monospaced(_:)

Source

pub fn text_tracking(self, amount: f64) -> Self

Text.tracking(_:) — like kerning, but not suppressed between the pairs the font has a ligature for.

Source

pub fn tint_color(self, color: u64) -> Self

Apply .tint(_:) through the Color? overload.

View.tint has two: one generic over ShapeStyle, which tint calls and which yields _EnvironmentKeyWritingModifier<AnyShapeStyle?>, and one taking a plain Color?, which yields …<Color?>. Swift picks the second for .tint(.white), so a reference written that way disagrees with the first on both type and value.

Source

pub fn toolbar_customizable_placed( self, toolbar_id: &str, item_id: &str, placement: ToolbarItemPlacement, shows_by_default: bool, content: View, ) -> Self

The same, with the item placed somewhere other than .automatic.

Source

pub fn toolbar_item_hidden(self, value: bool) -> Self

Apply .toolbarItemHidden(_:).

Source

pub fn toolbar_placed( self, placement: ToolbarItemPlacement, content: View, ) -> Self

Apply .toolbar { ToolbarItem(placement:) { content } }.

toolbar above is this with .automatic, which is what the placement argument defaults to in Swift.

Source

pub fn touch_bar(self, content: View) -> Self

Apply .touchBar(content:).

Source

pub fn touch_bar_customization_label(self, value: &str) -> Self

Apply .touchBarCustomizationLabel(_:).

Source

pub fn touch_bar_item_presence( self, presence: TouchBarItemPresence, identifier: &str, ) -> Self

Apply .touchBarItemPresence(_:).

The enum holds a String, which makes it larger than four words and so address-only: the argument is a pointer to a buffer this builds, with the string’s two words written first and the tag injected by the enum’s own witness afterwards.

Source

pub fn touch_bar_item_principal(self, value: bool) -> Self

Apply .touchBarItemPrincipal(_:).

Source

pub fn transform_preference_double(self) -> Self

Apply .transformPreference(_:_:), doubling the value in place.

Source

pub fn transition_opacity(self) -> Self

Apply .transition(.opacity).

AnyTransition is eight bytes — a single class reference — so it is loadable: its static getters return it in x0 and it is passed by value. Reading it through an indirect (x8) return, as the larger resilient types like Material and Glass require, yields an uninitialised buffer whose contents are then released as if they were an object.

Source

pub fn transition_slide(self) -> Self

Apply .transition(.slide) — in from the leading edge, out to the trailing.

Source

pub fn typesetting_language(self, v0: TypesettingLanguage, v1: bool) -> Self

Apply .typesettingLanguage(_:).

Source

pub fn unredacted(self) -> Self

Apply .unredacted(_:).

Source

pub fn view_opacity(self, value: f64) -> Self

.opacity(_:), taking Color’s own overload when the receiver is a Color.

Color.opacity(_:) returns Color — the same shape as Text.bold() and Image.resizable(), and the reason Apple’s Color.primary.opacity(0.1) types as a plain Color where the View extension gives ModifiedContent<Color, _OpacityEffect>. Both render identically; only one is the type the listing has.

Source

pub fn window_dismiss_behavior(self, value: WindowInteractionBehavior) -> Self

Source

pub fn window_full_screen_behavior( self, value: WindowInteractionBehavior, ) -> Self

Source

pub fn window_minimize_behavior(self, value: WindowInteractionBehavior) -> Self

Source

pub fn window_resize_behavior(self, value: WindowInteractionBehavior) -> Self

Source

pub fn window_toolbar_full_screen_visibility( self, value: WindowToolbarFullScreenVisibility, ) -> Self

Source

pub fn writing_direction(self, strategy: WritingDirectionStrategy) -> Self

Apply .writingDirection(strategy:).

Source

pub fn writing_tools_affordance_visibility(self, value: Visibility) -> Self

Apply .writingToolsAffordanceVisibility(_:).

Source

pub fn writing_tools_behavior(self, value: WritingToolsBehavior) -> Self

Source§

impl View

Source

pub fn foreground_style<S: ShapeStyleArg>(self, style: S) -> Self

.foregroundStyle(_:) — one spelling for every style.

The argument’s type picks the binding, the way its conformance does in Swift. See ShapeStyleArg.

Source§

impl View

Source

pub fn background_style<S: BackgroundStyleArg>(self, style: S) -> Self

.backgroundStyle(_:) — one spelling for every style.

The style the views inside this one use for their backgrounds, which is a different question from what View::background draws behind this one. See BackgroundStyleArg.

Source§

impl View

Source

pub fn environment<V: EnvironmentArg>(self, value: V) -> Self

.environment(_:_:) — one spelling for every property.

See EnvironmentArg. The leading-dot caveat from ShapeStyleArg applies: name the value’s type rather than writing .environment(.large).

Source

pub fn navigation_view_style(self, style: NavigationViewStyle) -> Self

.navigationViewStyle(_:).

Source

pub unsafe fn modifier(self, modifier_meta: *const c_void, bytes: &[u8]) -> Self

.modifier(_:) — apply a ViewModifier this crate has no name for.

The escape hatch. Every bound modifier goes through this internally; exposing it means a SwiftUI modifier type the crate has never heard of can still be applied, given its metadata and the bytes of a value.

§Safety

modifier_meta must be metadata for a type conforming to ViewModifier, and bytes a live value of exactly that type. Neither is checked: a mismatch hands SwiftUI a value of the wrong shape and it writes through it.

Source

pub fn accessibility(self, what: Accessibility<'_>) -> Self

.accessibility(…) — the deprecated family, under its Swift name.

See Accessibility. New code should prefer the modern spellings, which are separate methods here as they are in Swift.

Source

pub fn draggable(self, payload: Draggable<'_>) -> Self

.draggable(_:) — what comes out when this view is dragged.

Source

pub fn scroll_position(self, target: ScrollTarget<'_>) -> Self

.scrollPosition(_:) — where the scroll view should sit.

Source

pub fn transform_environment<K: EnvKey>( self, action: impl Fn(K::Value) -> K::Value + 'static, ) -> Self

.transformEnvironment(_:transform:) — read a property, change it, write it back for everything below.

The key is the type parameter, the way the key path is the argument in Swift:

text("x").transform_environment::<ColorSchemeKey>(|_| ColorScheme::Dark);
Source

pub fn default_app_storage(self, store: AppStorageStore<'_>) -> Self

.defaultAppStorage(_:).

Panics on a suite name UserDefaults refuses — the app’s own bundle identifier, or the global domain. views::default_app_storage_suite returns the None instead, for a caller that wants to handle it.

Source§

impl View

Source

pub fn rotation_effect(self, degrees: f64) -> Self

.rotationEffect(_:) — View::rotation about the centre, which is the anchor SwiftUI defaults to.

Source

pub fn rotation_3d_effect(self, degrees: f64, ax: f64, ay: f64, az: f64) -> Self

.rotation3DEffect(_:axis:) — View::rotation_3d under SwiftUI’s name.

Source

pub fn scale_effect(self, sx: f64, sy: f64) -> Self

.scaleEffect(x:y:) — View::scale under SwiftUI’s name.

Source

pub fn multiline_text_alignment(self, align: TextAlign) -> Self

.multilineTextAlignment(_:) — View::multiline_alignment under SwiftUI’s name.

Source§

impl View

Source

pub fn clip_shape<S: ClipShapeArg>(self, shape: S) -> Self

.clipShape(_:) — one spelling for every shape.

v.clip_shape(ClipShape::Circle)
    .clip_shape(ClipShape::RoundedRect(8.0));
Source§

impl View

Source

pub fn bg(self, c: Color) -> Self

Apply .background(_:) with a color.

Examples found in repository?
examples/app.rs (line 14)
9fn main() {
10    run(|| {
11        vstack(&[
12            text("Hello from Rust! 🦀")
13                .padding(12.0)
14                .bg(Color::BLUE)
15                .rounded(8.0)
16                .opacity(0.95),
17            spacer(),
18            hstack(&[
19                image("star.fill"),
20                text("No Swift compiler needed"),
21            ]),
22            divider(),
23            text("Pure dlsym + arm64 asm → SwiftUI")
24                .padding(8.0),
25        ])
26        .padding(40.0)
27        .into_handle()
28    });
29}
More examples
Hide additional examples
examples/common/spec.rs (line 645)
632fn decorate(mut v: View, node: &Node) -> Result<View, String> {
633    if let Some(p) = node.f64_attr("pad") {
634        v = v.padding(p);
635    }
636    if let Some(size) = node.attr("frame") {
637        let (w, h) = parse_size(size, node.line)?;
638        v = v.frame(w, h);
639    }
640    if let Some(o) = node.f64_attr("opacity") {
641        v = v.opacity(o);
642    }
643    if let Some(c) = node.attr("bg") {
644        let c = parse_color(c, node.line)?;
645        v = v.bg(c);
646    }
647    if let Some(r) = node.f64_attr("corner") {
648        v = v.corner_radius(r);
649    }
650    Ok(v)
651}
Source

pub fn bg_view(self, content: View) -> Self

.background { … } — an arbitrary view behind this one, centred.

SwiftUI has two background overloads and they are different modifiers, not one with a convenience: View::bg reaches the one generic over ShapeStyle, this reaches the one generic over View. So the argument here can be a whole subtree, not only a colour.

Source

pub fn bg_view_aligned(self, content: View, alignment: Alignment) -> Self

.background(alignment:) { … }

Source

pub fn bg_material(self, kind: MaterialKind) -> Self

.background(.regularMaterial) and its neighbours — a blur of whatever is behind the view rather than a colour over it.

Source

pub fn bg_linear_gradient( self, colors: &[Color], start: (f64, f64), end: (f64, f64), ) -> Self

.background(LinearGradient(colors:startPoint:endPoint:))

The points are unit points: (0, 0) is top-leading and (1, 1) bottom-trailing, so a top-to-bottom gradient is (0.5, 0)→(0.5, 1).

Source

pub fn bg_radial_gradient( self, colors: &[Color], center: (f64, f64), start_radius: f64, end_radius: f64, ) -> Self

.background(RadialGradient(colors:center:startRadius:endRadius:))

Source

pub fn opacity(self, value: f64) -> Self

Apply .opacity(_:).

On a Color this is Color.opacity(_:), which returns Color — the same concrete-overload story as Text.bold().

Examples found in repository?
examples/app.rs (line 16)
9fn main() {
10    run(|| {
11        vstack(&[
12            text("Hello from Rust! 🦀")
13                .padding(12.0)
14                .bg(Color::BLUE)
15                .rounded(8.0)
16                .opacity(0.95),
17            spacer(),
18            hstack(&[
19                image("star.fill"),
20                text("No Swift compiler needed"),
21            ]),
22            divider(),
23            text("Pure dlsym + arm64 asm → SwiftUI")
24                .padding(8.0),
25        ])
26        .padding(40.0)
27        .into_handle()
28    });
29}
More examples
Hide additional examples
examples/common/spec.rs (line 641)
632fn decorate(mut v: View, node: &Node) -> Result<View, String> {
633    if let Some(p) = node.f64_attr("pad") {
634        v = v.padding(p);
635    }
636    if let Some(size) = node.attr("frame") {
637        let (w, h) = parse_size(size, node.line)?;
638        v = v.frame(w, h);
639    }
640    if let Some(o) = node.f64_attr("opacity") {
641        v = v.opacity(o);
642    }
643    if let Some(c) = node.attr("bg") {
644        let c = parse_color(c, node.line)?;
645        v = v.bg(c);
646    }
647    if let Some(r) = node.f64_attr("corner") {
648        v = v.corner_radius(r);
649    }
650    Ok(v)
651}
examples/scenes.rs (line 64)
48fn main_window() -> ViewHandle {
49    vstack(&[
50        text("A SwiftUI app, no Swift source")
51            .font_size(20.0)
52            .padding(8.0),
53        divider(),
54        text(&format!("count: {}", counter().get()))
55            .font_size(34.0)
56            .padding(12.0),
57        hstack(&[
58            button("−", || counter().set(counter().get() - 1)),
59            button("+", || counter().set(counter().get() + 1)),
60        ]),
61        spacer(),
62        text("⌘, for Settings · the ★ in the menu bar has a menu")
63            .font_size(11.0)
64            .opacity(0.6),
65    ])
66    .padding(24.0)
67    .frame(420.0, 300.0)
68    .focused_scene_value(counter_focus_key(), counter().get())
69    .into_handle()
70}
71
72/// The focused-value key the window publishes its count under.
73///
74/// `.focusedSceneValue(\.key, value)` is how a window tells the commands above
75/// it what is selected. Both halves are synthesised at run time: the
76/// `FocusedValueKey` conformance *and* the `WritableKeyPath<FocusedValues, Int?>`
77/// — `FocusedValues` exports no properties, so unlike `EnvironmentValues` there
78/// is no SwiftUI modifier holding a key path to borrow.
79///
80/// The menu cannot *read* it yet: that needs `@FocusedValue`, a `DynamicProperty`
81/// SwiftUI instantiates itself, which is a different mechanism from anything
82/// here. What this demonstrates is the publishing half, in a real app.
83fn counter_focus_key() -> &'static views::FocusKey {
84    static K: std::sync::OnceLock<views::FocusKey> = std::sync::OnceLock::new();
85    K.get_or_init(|| views::focus_key("sceneCounter"))
86}
87
88fn settings_pane() -> ViewHandle {
89    vstack(&[
90        text("Preferences").font_size(18.0),
91        divider(),
92        text("This pane is a `Settings` scene — the one ⌘, opens."),
93        text(&format!("It sees the same state: {}", counter().get()))
94            .opacity(0.7),
95    ])
96    .padding(24.0)
97    .frame(360.0, 200.0)
98    .into_handle()
99}
100
101fn utility_window() -> ViewHandle {
102    vstack(&[
103        text("Utility").font_size(16.0),
104        text("A `Window`, not a `WindowGroup`: one of it, addressed by id.")
105            .opacity(0.7),
106    ])
107    .padding(20.0)
108    .frame(320.0, 140.0)
109    .into_handle()
110}
examples/dashboard.rs (line 33)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
Source

pub fn rounded(self, radius: f64) -> Self

Apply .cornerRadius(_:).

Examples found in repository?
examples/app.rs (line 15)
9fn main() {
10    run(|| {
11        vstack(&[
12            text("Hello from Rust! 🦀")
13                .padding(12.0)
14                .bg(Color::BLUE)
15                .rounded(8.0)
16                .opacity(0.95),
17            spacer(),
18            hstack(&[
19                image("star.fill"),
20                text("No Swift compiler needed"),
21            ]),
22            divider(),
23            text("Pure dlsym + arm64 asm → SwiftUI")
24                .padding(8.0),
25        ])
26        .padding(40.0)
27        .into_handle()
28    });
29}
Source

pub fn border(self, c: Color, width: f64) -> Self

Apply .border(_:width:).

Through views::border_value rather than views::border, because the latter takes components and pins alpha to 1 — so a translucent border came out opaque and nothing said so.

Source

pub fn border_system(self, c: SystemColor, width: f64) -> Self

.border(_:width:) with one of SwiftUI’s own colours.

Source

pub fn when(self, condition: bool, f: impl FnOnce(Self) -> Self) -> Self

Apply f only when condition holds.

Modifier chains often need a branch, and an if in the middle of a builder chain otherwise forces a temporary binding.

ⓘ
text("hi").when(selected, |v| v.bold().fg(Color::RED))
Source

pub fn when_some<T>( self, value: Option<T>, f: impl FnOnce(Self, T) -> Self, ) -> Self

Apply f with the contained value when value is Some.

Source

pub fn either( self, condition: bool, yes: impl FnOnce(Self) -> Self, no: impl FnOnce(Self) -> Self, ) -> Self

Apply one of two branches.

Source

pub fn card(self, pad: f64, bg: Color, radius: f64) -> Self

Shorthand: padding + background + corner radius.

Source

pub fn shadow(self, c: Color, radius: f64, dx: f64, dy: f64) -> Self

.shadow(color:radius:x:y:)

Source

pub fn blur(self, radius: f64) -> Self

.blur(radius:)

Source

pub fn rotate(self, degrees: f64) -> Self

.rotationEffect(.degrees(_)) about the centre.

Examples found in repository?
examples/dashboard.rs (line 40)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
Source

pub fn rotate_anchored(self, degrees: f64, anchor: (f64, f64)) -> Self

.rotationEffect(.degrees(_), anchor:) — the point the view turns about, as a unit point: (0, 0) is top-leading, (0.5, 0.5) the centre.

Not a detail: a dial hand turns about its base and a card flips about an edge, and neither is expressible by rotating about the middle.

Source

pub fn scale(self, sx: f64, sy: f64) -> Self

.scaleEffect(_:) about the centre.

Source

pub fn scale_anchored(self, sx: f64, sy: f64, anchor: (f64, f64)) -> Self

.scaleEffect(_:anchor:) — grow from a unit point rather than the middle.

Source

pub fn offset(self, dx: f64, dy: f64) -> Self

.offset(x:y:)

Source

pub fn brightness(self, amount: f64) -> Self

.brightness(_:)

Source

pub fn saturation(self, amount: f64) -> Self

.saturation(_:)

Source

pub fn contrast(self, amount: f64) -> Self

.contrast(_:)

Source

pub fn grayscale(self, amount: f64) -> Self

.grayscale(_:)

Source

pub fn material(self, kind: MaterialKind) -> Self

.background(_: Material)

Source

pub fn glass(self) -> Self

.glassEffect() — Liquid Glass.

Source

pub fn gradient( self, colors: &[Color], start: (f64, f64), end: (f64, f64), ) -> Self

.background(LinearGradient(…))

Source

pub fn radial_gradient( self, colors: &[Color], center: (f64, f64), start_radius: f64, end_radius: f64, ) -> Self

.background(RadialGradient(…))

Source

pub fn tint(self, c: Color) -> Self

.tint(_:)

Source

pub fn color_scheme(self, scheme: ColorScheme) -> Self

.preferredColorScheme(_:)

Source

pub fn control_size(self, size: ControlSize) -> Self

.controlSize(_:)

Source

pub fn button_style(self, style: ButtonStyle) -> Self

.buttonStyle(_:)

Examples found in repository?
examples/settings.rs (line 101)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
More examples
Hide additional examples
examples/todo.rs (line 70)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
82
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
examples/swift_org_tutorial.rs (line 151)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
examples/dashboard.rs (line 73)
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
Source

pub fn background_shape_style(self, style: ShapeStyle) -> Self

.backgroundStyle(_:) with one of SwiftUI’s semantic styles.

Source

pub fn bg_auto_gradient(self, c: Color) -> Self

.background(_.gradient) — the automatic gradient derived from a colour.

Source

pub fn bg_in_circle(self) -> Self

.background(in: .circle)

Source

pub fn container_background( self, placement: ContainerBackgroundPlacement, alignment: Alignment, content: View, ) -> Self

.containerBackground(for:alignment:content:) — the background a container hands to its whole area, not just this view’s bounds.

See views::ContainerBackgroundPlacement: two of its cases trap on macOS, which is SwiftUI’s own availability rather than anything here.

Source

pub fn fg_value(self, color: u64) -> Self

.foregroundStyle(_:) with an already-built colour, which is how a system colour is passed — see views::system_color_value.

Source

pub fn fg_pair(self, primary: u64, secondary: u64) -> Self

.foregroundStyle(_:_:) — primary and secondary, for a symbol drawn in two tones.

Source

pub fn fg_triple(self, primary: u64, secondary: u64, tertiary: u64) -> Self

.foregroundStyle(_:_:_:) — three tones.

A palette symbol takes its layers from successive styles. fg_pair covers the two-layer symbols; the three-layer ones — and there are plenty in SF Symbols — drew their third layer in the secondary colour, because there was no way to say what it should be.

Source

pub fn tint_value(self, tint: u64) -> Self

.tint(_:) with an already-built colour.

Source

pub fn color_scheme_forced(self, value: ColorScheme) -> Self

.colorScheme(_:) — force light or dark for this subtree, as distinct from View::color_scheme’s preferred scheme, which asks the whole window.

Source

pub fn edges_ignoring_safe_area(self, edges: EdgeSet) -> Self

.edgesIgnoringSafeArea(_:) — the older spelling; see View::ignores_safe_area for the one that takes regions too.

Source

pub fn persistent_system_overlays(self, visibility: Visibility) -> Self

.persistentSystemOverlays(_:) — the home indicator and its neighbours.

Source

pub fn symbol_variant(self, variant: SymbolVariants) -> Self

.symbolVariant(_:) — .fill, .circle and so on, without renaming the symbol.

Source

pub fn symbol_rendering_mode(self, mode: Option<SymbolRenderingMode>) -> Self

.symbolRenderingMode(_:) — None restores the default.

Source

pub fn label_style(self, style: LabelStyle) -> Self

.labelStyle(_:) — icon only, title only, or both.

Source

pub fn menu_style(self, style: MenuStyle) -> Self

.menuStyle(_:)

Source

pub fn button_border_shape(self, shape: ButtonBorderShape) -> Self

.buttonBorderShape(_:)

Source

pub fn scroll_target_behavior(self, behavior: ScrollTargetBehavior) -> Self

.scrollTargetBehavior(_:) — .paging and friends.

Source

pub fn scroll_content_background(self, visibility: Visibility) -> Self

.scrollContentBackground(_:) — hiding it is how a List loses its grouped backdrop.

Source

pub fn symbol_effect_pulse(self) -> Self

.symbolEffect(.pulse)

Source

pub fn symbol_effects_removed(self, removed: bool) -> Self

.symbolEffectsRemoved(_:) — stop inherited effects at this view.

Source

pub fn symbol_color_rendering_mode_flat(self) -> Self

.symbolColorRenderingMode(.flat)

Source

pub fn symbol_variable_value_mode_color(self) -> Self

.symbolVariableValueMode(.color)

Source

pub fn keyframe_animator( self, initial: f64, to: f64, repeating: bool, content: View, ) -> Self

.keyframeAnimator(initialValue:repeating:content:) — drive a value through keyframes and rebuild the content from it.

Source

pub fn phase_animator( self, phases: &[i64], content: View, animated: bool, ) -> Self

.phaseAnimator(_:content:) — step through phases, rebuilding at each.

Source

pub fn transaction(self, action: impl Fn(TransactionRef) + 'static) -> Self

.transaction(_:) — reach the transaction driving the current change, which is how an animation is suppressed for one update.

Source

pub fn geometry_group(self) -> Self

.geometryGroup() — animate this subtree’s geometry as one, rather than letting each child interpolate independently and pull apart.

Source

pub fn transform_effect( self, a: f64, b: f64, c: f64, d: f64, tx: f64, ty: f64, ) -> Self

.transformEffect(_:) — an affine transform, as [a b c d tx ty].

Source

pub fn visual_effect(self) -> Self

.visualEffect(_:)

Source§

impl View

Source

pub fn toggle_style(self, style: ToggleStyle) -> Self

.toggleStyle(_:)

Source

pub fn picker_style(self, style: PickerStyle) -> Self

.pickerStyle(_:)

Examples found in repository?
examples/settings.rs (line 76)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
Source

pub fn date_picker_style(self, style: DatePickerStyle) -> Self

.datePickerStyle(_:)

Source

pub fn gauge_style(self, style: GaugeStyle) -> Self

.gaugeStyle(_:)

Examples found in repository?
examples/dashboard.rs (line 66)
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
Source

pub fn form_style(self, style: FormStyle) -> Self

.formStyle(_:)

Examples found in repository?
examples/settings.rs (line 83)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
Source

pub fn group_box_style(self, style: GroupBoxStyle) -> Self

.groupBoxStyle(_:)

Source

pub fn control_group_style(self, style: ControlGroupStyle) -> Self

.controlGroupStyle(_:)

Source

pub fn disclosure_group_style(self, style: DisclosureGroupStyle) -> Self

.disclosureGroupStyle(_:)

Source

pub fn table_style(self, style: TableStyle) -> Self

.tableStyle(_:)

Source

pub fn text_editor_style(self, style: TextEditorStyle) -> Self

.textEditorStyle(_:)

Source

pub fn labeled_content_style(self, style: LabeledContentStyle) -> Self

.labeledContentStyle(_:)

Source

pub fn text_selection(self, style: TextSelectability) -> Self

.textSelection(_:) — whether the user can select and copy the text.

Source

pub fn button_repeat_behavior(self, value: ButtonRepeatBehavior) -> Self

.buttonRepeatBehavior(_:) — whether holding repeats the action.

Source

pub fn button_sizing(self, value: ButtonSizing) -> Self

.buttonSizing(_:)

Source

pub fn menu_button_style(self, style: MenuButtonStyle) -> Self

.menuButtonStyle(_:)

Source

pub fn menu_action_dismiss_behavior( self, value: MenuActionDismissBehavior, ) -> Self

.menuActionDismissBehavior(_:) — whether choosing an item closes the menu.

Source

pub fn slider_thumb_visibility(self, value: Visibility) -> Self

.sliderThumbVisibility(_:)

Source

pub fn spring_loading_behavior(self, value: SpringLoadingBehavior) -> Self

.springLoadingBehavior(_:) — whether hovering a drag over this opens it.

Source

pub fn palette_selection_effect(self, value: PaletteSelectionEffect) -> Self

.paletteSelectionEffect(_:)

Source

pub fn material_active_appearance(self, value: MaterialActiveAppearance) -> Self

.materialActiveAppearance(_:)

Source

pub fn progress_view_style_circular(self) -> Self

.progressViewStyle(.circular)

Source

pub fn menu_indicator(self, visibility: Visibility) -> Self

.menuIndicator(_:) — the chevron that says a control opens a menu.

Source

pub fn menu_order(self, order: MenuOrder) -> Self

.menuOrder(_:)

Source

pub fn labels_visibility(self, visibility: Visibility) -> Self

.labelsVisibility(_:) — hiding a label keeps it for VoiceOver while taking it off the screen, which .hidden() does not.

Source

pub fn header_prominence(self, prominence: Prominence) -> Self

.headerProminence(_:)

Source

pub fn badge_prominence(self, prominence: BadgeProminence) -> Self

.badgeProminence(_:)

Source

pub fn list_style(self, style: ListStyle) -> Self

.listStyle(_:)

Examples found in repository?
examples/inbox.rs (line 115)
110fn body() -> View {
111    let i = inbox();
112    let rows = matching();
113    navigation_stack(
114        list(for_each_items(&rows, |&i| linked_row(i)))
115        .list_style(views::ListStyle::InsetListStyle)
116        .searchable(&i.query, &i.searching, SearchFieldPlacement::Automatic, "Search"),
117    )
118    .navigation_title("Inbox")
119    .toolbar(button("Compose", || {}).keyboard_shortcut(KeyboardShortcut::DefaultAction))
120}
More examples
Hide additional examples
examples/todo.rs (line 122)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn list_row_insets(self, insets: Option<[f64; 4]>) -> Self

.listRowInsets(_:) as [top, leading, bottom, trailing]; None restores the default inset.

Source

pub fn list_row_separator( self, visibility: Visibility, edges: VerticalEdgeSet, ) -> Self

.listRowSeparator(_:edges:)

Source

pub fn list_section_separator( self, visibility: Visibility, edges: VerticalEdgeSet, ) -> Self

.listSectionSeparator(_:edges:)

Source

pub fn selection_disabled(self, disabled: bool) -> Self

.selectionDisabled(_:) — a row that shows but cannot be picked.

Source

pub fn swipe_actions( self, edge: HorizontalEdge, allows_full_swipe: bool, content: View, ) -> Self

.swipeActions(edge:allowsFullSwipe:content:)

Examples found in repository?
examples/inbox.rs (line 107)
105fn linked_row(i: usize) -> View {
106    navigation_link_labelled(row(i), detail(i))
107        .swipe_actions(HorizontalEdge::Trailing, true, button("Delete", || {}))
108}
Source

pub fn refreshable(self, action: impl Fn() + Send + Sync + 'static) -> Self

.refreshable(action:) — pull to refresh.

Source

pub fn scroll_dismisses_keyboard( self, mode: ScrollDismissesKeyboardMode, ) -> Self

.scrollDismissesKeyboard(_:) — what scrolling does to an open keyboard.

Source

pub fn list_row_separator_tint( self, color: Option<Color>, edges: &[VerticalEdgeSet], ) -> Self

.listRowSeparatorTint(_:edges:) — None restores the default.

Source

pub fn list_section_separator_tint( self, color: Option<Color>, edges: &[VerticalEdgeSet], ) -> Self

.listSectionSeparatorTint(_:edges:)

Source

pub fn list_item_tint_monochrome(self, tinted: bool) -> Self

.listItemTint(.monochrome)

Source

pub fn alternating_row_backgrounds( self, value: AlternatingRowBackgroundBehavior, ) -> Self

.alternatingRowBackgrounds(_:)

Source

pub fn section_actions(self, content: View) -> Self

.sectionActions(content:) — controls in a section’s header area.

Source

pub fn section_index_label(self, label: &str) -> Self

.sectionIndexLabel(_:) — the letter this section shows in a scrubber.

Source

pub fn table_column_headers(self, visibility: Visibility) -> Self

.tableColumnHeaders(_:)

Source

pub fn tab_view_style_automatic(self) -> Self

.tabViewStyle(.automatic)

Source

pub fn tab_view_customization_none(self) -> Self

.tabViewCustomization(nil)

Source

pub fn tab_view_search_activation_automatic(self) -> Self

.tabViewSearchActivation(.automatic)

Source

pub fn tab_view_sidebar_header(self, content: View) -> Self

.tabViewSidebarHeader { … }

.tabViewSidebarFooter { … }

Source

pub fn tab_view_sidebar_bottom_bar(self, content: View) -> Self

.tabViewSidebarBottomBar { … }

Source

pub fn tab_bar_minimize_behavior(self, value: TabBarMinimizeBehavior) -> Self

.tabBarMinimizeBehavior(_:)

Source§

impl View

Source

pub fn drag_configuration( self, within_app: DragOperations, outside_app: DragOperations, ) -> Self

.dragConfiguration(within:outside:) — which operations a drag permits inside the app and outside it, which need not be the same.

Source

pub fn drag_container(self, items: &[&str]) -> Self

.dragContainer(for:) — the items a multi-item drag carries.

Source

pub fn drag_container_selection(self, selected: &[&str]) -> Self

.dragContainerSelection(_:) — which of them are selected, so dragging one drags the selection rather than just the item under the finger.

Source

pub fn draggable_container_item(self, id: HashableValue<'_>) -> Self

.draggableContainerItem(id:) — mark this view as one of the container’s items.

Source

pub fn drag_previews_formation(self, value: DragDropPreviewsFormation) -> Self

.dragPreviewsFormation(_:) — how several dragged previews stack up.

Source

pub fn drop_previews_formation(self, value: DragDropPreviewsFormation) -> Self

.dropPreviewsFormation(_:)

Source

pub fn drop_configuration( self, decide: impl Fn() -> DropOperation + 'static, ) -> Self

.dropConfiguration(_:) — decide what a drop over this view would do, which is what sets the cursor before anything is released.

Source

pub fn drop_destination( self, accept: impl Fn(&[String]) -> bool + 'static, targeted: impl Fn(bool) + 'static, ) -> Self

.dropDestination(for:action:isTargeted:) — accept returns whether the drop was taken; targeted fires as the drag enters and leaves.

Source

pub fn on_drag_session_updated(self, action: impl Fn() + 'static) -> Self

.onDragSessionUpdated(_:)

Source

pub fn on_drop_session_updated(self, action: impl Fn() + 'static) -> Self

.onDropSessionUpdated(_:)

Source

pub fn on_copy_command(self, items: &[&str]) -> Self

.onCopyCommand(perform:) — what Copy takes from this view.

Source

pub fn on_cut_command(self, items: &[&str]) -> Self

.onCutCommand(perform:)

Source

pub fn on_paste_command( self, kinds: &[ContentType], paste: impl Fn(&[ItemProvider]) + 'static, ) -> Self

.onPasteCommand(of:perform:)

Source

pub fn on_delete_command(self, action: impl Fn() + 'static) -> Self

.onDeleteCommand(perform:)

Source

pub fn on_move_command(self, action: impl Fn(i64) + 'static) -> Self

.onMoveCommand(perform:) — arrow keys, with the direction as an Int.

Source

pub fn on_exit_command(self, action: impl Fn() + 'static) -> Self

.onExitCommand(perform:) — escape.

Source

pub fn on_command( self, selector: &'static CStr, action: impl Fn() + 'static, ) -> Self

.onCommand(_:perform:) — any other selector by name, which is the way out when a command has no modifier of its own.

Source

pub fn cuttable(self, items: &[&str]) -> Self

.cuttable(for:action:) — what Cut takes, as distinct from View::copyable, which Copy takes.

Source

pub fn paste_destination(self, paste: impl Fn(&[String]) + 'static) -> Self

.pasteDestination(for:action:)

Source

pub fn rename_action(self, action: impl Fn() + 'static) -> Self

.renameAction(_:) — what the Rename command does, which a list row needs for in-place renaming to work at all.

Source

pub fn pointer_style(self, style: Option<PointerStyle>) -> Self

.pointerStyle(_:) — None restores the default cursor.

Source

pub fn pointer_visibility(self, value: Visibility) -> Self

.pointerVisibility(_:)

Source

pub fn on_modifier_keys_changed( self, mask: EventModifier, initial: bool, action: impl Fn(u64, u64) + 'static, ) -> Self

.onModifierKeysChanged(mask:initial:_:)

Source

pub fn modifier_key_alternate( self, modifiers: EventModifier, content: View, ) -> Self

.modifierKeyAlternate(_:_:) — a different view while a key is held.

Source

pub fn on_interactive_resize_change( self, action: impl Fn(bool) + 'static, ) -> Self

.onInteractiveResizeChange(_:)

Source

pub fn user_activity( self, kind: &str, active: bool, action: impl Fn() + 'static, ) -> Self

.userActivity(_:isActive:_:) — advertise what this view is doing, for Handoff and Spotlight.

Source

pub fn on_continue_user_activity( self, kind: &str, action: impl Fn() + 'static, ) -> Self

.onContinueUserActivity(_:perform:) — the other end of Handoff.

Source

pub fn handles_external_events( self, preferring: &[&str], allowing: &[&str], ) -> Self

.handlesExternalEvents(preferring:allowing:)

Source

pub fn allowed_dynamic_range_high(self) -> Self

.allowedDynamicRange(.high)

Source

pub fn tab_item(self, label: View) -> Self

.tabItem { … } — the label a TabView shows for this page.

Source

pub fn high_priority_gesture( self, minimum_distance: f64, action: impl Fn() + 'static, ) -> Self

.highPriorityGesture(_:) — take the gesture ahead of the children, where .gesture would lose to them.

Source

pub fn simultaneous_gesture( self, minimum_distance: f64, action: impl Fn() + 'static, ) -> Self

.simultaneousGesture(_:) — recognise alongside the children rather than instead of them.

Source

pub fn on_open_url(self, action: impl Fn(&str) + 'static) -> Self

.onOpenURL(perform:) — deep links.

Source

pub fn copyable(self, items: &[&str]) -> Self

.copyable(_:) — what a copy command takes from this view.

Source

pub fn scroll_position_id( self, state: &BoundState<String>, anchor: Option<(f64, f64)>, ) -> Self

.scrollPosition(id:anchor:) bound to Rust state — the id of the item at the anchor lands in state, and writing it scrolls there.

Source

pub fn default_scroll_anchor( self, anchor: Option<(f64, f64)>, role: ScrollAnchorRole, ) -> Self

.defaultScrollAnchor(_:for:) — None restores the default.

Source

pub fn scroll_target_layout(self, enabled: bool) -> Self

.scrollTargetLayout() — mark the stack whose children are the targets a paging scroll snaps to.

Source

pub fn scroll_bounce_behavior( self, behavior: ScrollBounceBehavior, axes: AxisSet, ) -> Self

.scrollBounceBehavior(_:axes:)

Source

pub fn scroll_indicators_flash(self, on_appear: bool) -> Self

.scrollIndicatorsFlash(onAppear:)

Source

pub fn scroll_edge_effect_hidden(self, hidden: bool, edges: EdgeSet) -> Self

.scrollEdgeEffectHidden(_:for:)

Source

pub fn scroll_edge_effect_style( self, style: Option<ScrollEdgeEffectStyle>, edges: &[EdgeSetMember], ) -> Self

.scrollEdgeEffectStyle(_:for:) — None restores the default.

Source

pub fn scroll_transition( self, config: ScrollTransitionConfiguration, axis: Option<Axis>, ) -> Self

.scrollTransition(_:axis:) — how a child changes as it crosses the viewport.

Source

pub fn scroll_transition_ends( self, top_leading: ScrollTransitionConfiguration, bottom_trailing: ScrollTransitionConfiguration, axis: Option<Axis>, ) -> Self

.scrollTransition(topLeading:bottomTrailing:axis:) — the two ends of the scroll configured separately.

The single-configuration scroll_transition applies the same one at both ends; this is what lets a view animate on the way in and do nothing on the way out.

Source

pub fn on_scroll_phase_change(self, action: impl Fn(i64, i64) + 'static) -> Self

.onScrollPhaseChange(_:) — the handler sees the old and new phase.

Source

pub fn on_scroll_visibility_change( self, threshold: f64, action: impl Fn(bool) + 'static, ) -> Self

.onScrollVisibilityChange(threshold:_:)

Source

pub fn default_focus(self, value: bool, priority: DefaultFocusPriority) -> Self

.defaultFocus(_:_:) — which control starts focused.

Source

pub fn prefers_default_focus(self, prefers: bool) -> Self

.prefersDefaultFocus(_:in:)

Source

pub fn focus_scope(self) -> Self

.focusScope(_:) — a boundary focus moves within.

Source

pub fn a11y_focused(self) -> Self

.accessibilityFocused(_:)

Source

pub fn a11y_default_focus(self, value: bool) -> Self

.accessibilityDefaultFocus(_:_:)

Source

pub fn focused(self) -> Self

.focused(_:)

Source

pub fn matched_geometry_effect( self, id: HashableValue<'_>, properties: &[GeometryProperties], anchor: (f64, f64), is_source: bool, ) -> Self

.matchedGeometryEffect(id:in:properties:anchor:isSource:) — the pair of views that share an id are interpolated between rather than crossfaded.

Source

pub fn matched_geometry_effect_in( self, id: HashableValue<'_>, namespace: Namespace, properties: &[GeometryProperties], anchor: (f64, f64), is_source: bool, ) -> Self

.matchedGeometryEffect(id:in:properties:anchor:isSource:) in a shared namespace.

The pairing spelling. matched_geometry_effect mints a namespace per call, so the views it makes cannot pair with anything.

Source

pub fn on_drag_item(self, item: &str, preview: View) -> Self

.onDrag { NSItemProvider(object: item) } with a custom preview.

Named apart from View::on_drag, which is the drag gesture — a finger moving on screen — where this is drag and drop, which hands an item to another view or another app.

Source

pub fn on_drop( self, kinds: &[ContentType], accept: impl Fn(&[ItemProvider]) -> bool + 'static, ) -> Self

.onDrop(of:isTargeted:perform:) — the handler returns whether it took the drop.

Source

pub fn on_key_press( self, characters: CharacterSetKind, phases: KeyPressPhases, action: impl Fn(KeyPress) -> KeyPressResult + 'static, ) -> Self

.onKeyPress(_:phases:action:)

The action is handed the views::KeyPress — what was typed, which modifiers were held, and which phase of the press it is — and answers whether it handled it. It used to receive nothing at all, which left a key handler unable to branch on the key.

let v = text("editor").on_key_press(
    CharacterSetKind::Alphanumerics,
    KeyPressPhases::Down,
    |press| {
        if press.characters == "s" && press.holding(EventModifier::Command) {
            KeyPressResult::Handled
        } else {
            KeyPressResult::Ignored
        }
    },
);
Source

pub fn on_key( self, key: Key, action: impl Fn() -> KeyPressResult + 'static, ) -> Self

.onKeyPress(_:action:) — one named key.

on_key_press watches a whole character set and hands the action the press; this watches one key, which is how a shortcut is usually written — “Escape closes this”. Only the character-set form was bound, so a view that cared about Escape had to accept every key and filter.

let sheet = text("editor").on_key(Key::Escape, || KeyPressResult::Handled);
Source

pub fn sensory_feedback( self, feedback: SensoryFeedback, trigger: i64, condition: impl Fn(i64, i64) -> bool + 'static, ) -> Self

.sensoryFeedback(_:trigger:condition:) — haptics, fired when the condition says the trigger’s change deserves one.

Source

pub fn on_hover(self, callback: impl Fn(bool) + 'static) -> Self

Apply .onHover(perform:) — fires callback on gaze enter/exit (visionOS) or mouse enter/exit (macOS).

Source§

impl View

Source

pub fn padding(self, amount: f64) -> Self

Apply .padding(_:).

Examples found in repository?
examples/inbox.rs (line 73)
60fn detail(i: usize) -> View {
61    let m = &MESSAGES[i];
62    vstack_aligned_spacing(
63        &[
64            text(m.subject).text_style(TextStyle::Title).bold(),
65            text!("From {}", m.from).fg_system(SystemColor::Gray),
66            divider(),
67            text("Body text would go here.").fg_system(SystemColor::Gray),
68            spacer(),
69        ],
70        HorizontalAlignment::Leading,
71        Some(12.0),
72    )
73    .padding(20.0)
74    .navigation_title(m.subject)
75}
More examples
Hide additional examples
examples/app.rs (line 13)
9fn main() {
10    run(|| {
11        vstack(&[
12            text("Hello from Rust! 🦀")
13                .padding(12.0)
14                .bg(Color::BLUE)
15                .rounded(8.0)
16                .opacity(0.95),
17            spacer(),
18            hstack(&[
19                image("star.fill"),
20                text("No Swift compiler needed"),
21            ]),
22            divider(),
23            text("Pure dlsym + arm64 asm → SwiftUI")
24                .padding(8.0),
25        ])
26        .padding(40.0)
27        .into_handle()
28    });
29}
examples/common/spec.rs (line 634)
632fn decorate(mut v: View, node: &Node) -> Result<View, String> {
633    if let Some(p) = node.f64_attr("pad") {
634        v = v.padding(p);
635    }
636    if let Some(size) = node.attr("frame") {
637        let (w, h) = parse_size(size, node.line)?;
638        v = v.frame(w, h);
639    }
640    if let Some(o) = node.f64_attr("opacity") {
641        v = v.opacity(o);
642    }
643    if let Some(c) = node.attr("bg") {
644        let c = parse_color(c, node.line)?;
645        v = v.bg(c);
646    }
647    if let Some(r) = node.f64_attr("corner") {
648        v = v.corner_radius(r);
649    }
650    Ok(v)
651}
examples/dynamic_ui.rs (line 78)
64pub fn body() -> View {
65    let text_src = current().lock().expect("spec").clone();
66    match spec::parse(&text_src).and_then(|nodes| spec::build(&nodes)) {
67        Ok(v) => v,
68        Err(e) => vstack_aligned_spacing(
69            &[
70                text("Could not build that screen")
71                    .text_style(TextStyle::Headline)
72                    .fg_system(SystemColor::Red),
73                text(&e).font_size(12.0).fg_system(SystemColor::Secondary),
74            ],
75            HorizontalAlignment::Leading,
76            Some(8.0),
77        )
78        .padding(20.0),
79    }
80}
examples/hot_reload.rs (line 107)
96fn body() -> View {
97    let (src, error, generation, micros) = {
98        let g = state_cell().lock().expect("state");
99        (g.last_good.clone(), g.error.clone(), g.generation, g.micros)
100    };
101
102    // The last version that parsed. It cannot fail — it parsed before — but a
103    // spec that builds views from slots could in principle, so the fallback is
104    // still handled rather than unwrapped.
105    let screen = spec::parse(&src)
106        .and_then(|nodes| spec::build(&nodes))
107        .unwrap_or_else(|e| text(&e).fg_system(SystemColor::Red).padding(20.0));
108
109    vstack_spacing(&[screen, status(error.as_deref(), generation, micros)], 0.0)
110}
111
112/// A strip along the bottom: which generation is on screen, how long the last
113/// reload took, what the slots hold, and the error if there is one.
114///
115/// In the window rather than the terminal because that is where you are
116/// looking. Watching a reloader work from a log means watching two things.
117fn status(error: Option<&str>, generation: u64, micros: u64) -> View {
118    let slots = spec::slot_summary();
119    let slot_line = if slots.is_empty() {
120        String::new()
121    } else {
122        slots
123            .iter()
124            .map(|(k, v)| format!("{k}={v}"))
125            .collect::<Vec<_>>()
126            .join("  ")
127    };
128
129    // The error row is *always* present, empty when there is nothing wrong.
130    // An error that appears and disappears would otherwise reflow the screen
131    // above it on every save — which looks exactly like the reloader having
132    // replaced the view, and makes "did the screen survive this?" impossible
133    // to answer by looking.
134    let rows = vec![
135        divider(),
136        hstack_spacing(
137            &[
138                circle_shape()
139                    .fill_system(if error.is_some() {
140                        SystemColor::Orange
141                    } else {
142                        SystemColor::Clear
143                    })
144                    .frame(8.0, 8.0),
145                text(error.unwrap_or(""))
146                    .font_size(11.0)
147                    .fg_system(SystemColor::Orange),
148                spacer(),
149            ],
150            6.0,
151        )
152        .padding(6.0)
153        .frame(348.0, 24.0),
154        hstack_spacing(
155            &[
156                circle_shape()
157                    .fill_system(if error.is_some() {
158                        SystemColor::Orange
159                    } else {
160                        SystemColor::Green
161                    })
162                    .frame(8.0, 8.0),
163                text(&format!("gen {generation}"))
164                    .font_size(11.0)
165                    .fg_system(SystemColor::Secondary),
166                // Microseconds below a millisecond: a reload of a short spec
167                // really is that fast, and "0.0 ms" reads as "not measured".
168                text(&if micros < 1000 {
169                    format!("{micros} \u{b5}s")
170                } else {
171                    format!("{:.1} ms", micros as f64 / 1000.0)
172                })
173                .font_size(11.0)
174                .fg_system(SystemColor::Secondary),
175                spacer(),
176                text(&slot_line).font_size(11.0).fg_system(SystemColor::Secondary),
177            ],
178            8.0,
179        )
180        .padding(6.0)
181        .frame(348.0, 24.0),
182    ];
183    vstack_spacing(&rows, 0.0)
184}
examples/scenes.rs (line 52)
48fn main_window() -> ViewHandle {
49    vstack(&[
50        text("A SwiftUI app, no Swift source")
51            .font_size(20.0)
52            .padding(8.0),
53        divider(),
54        text(&format!("count: {}", counter().get()))
55            .font_size(34.0)
56            .padding(12.0),
57        hstack(&[
58            button("−", || counter().set(counter().get() - 1)),
59            button("+", || counter().set(counter().get() + 1)),
60        ]),
61        spacer(),
62        text("⌘, for Settings · the ★ in the menu bar has a menu")
63            .font_size(11.0)
64            .opacity(0.6),
65    ])
66    .padding(24.0)
67    .frame(420.0, 300.0)
68    .focused_scene_value(counter_focus_key(), counter().get())
69    .into_handle()
70}
71
72/// The focused-value key the window publishes its count under.
73///
74/// `.focusedSceneValue(\.key, value)` is how a window tells the commands above
75/// it what is selected. Both halves are synthesised at run time: the
76/// `FocusedValueKey` conformance *and* the `WritableKeyPath<FocusedValues, Int?>`
77/// — `FocusedValues` exports no properties, so unlike `EnvironmentValues` there
78/// is no SwiftUI modifier holding a key path to borrow.
79///
80/// The menu cannot *read* it yet: that needs `@FocusedValue`, a `DynamicProperty`
81/// SwiftUI instantiates itself, which is a different mechanism from anything
82/// here. What this demonstrates is the publishing half, in a real app.
83fn counter_focus_key() -> &'static views::FocusKey {
84    static K: std::sync::OnceLock<views::FocusKey> = std::sync::OnceLock::new();
85    K.get_or_init(|| views::focus_key("sceneCounter"))
86}
87
88fn settings_pane() -> ViewHandle {
89    vstack(&[
90        text("Preferences").font_size(18.0),
91        divider(),
92        text("This pane is a `Settings` scene — the one ⌘, opens."),
93        text(&format!("It sees the same state: {}", counter().get()))
94            .opacity(0.7),
95    ])
96    .padding(24.0)
97    .frame(360.0, 200.0)
98    .into_handle()
99}
100
101fn utility_window() -> ViewHandle {
102    vstack(&[
103        text("Utility").font_size(16.0),
104        text("A `Window`, not a `WindowGroup`: one of it, addressed by id.")
105            .opacity(0.7),
106    ])
107    .padding(20.0)
108    .frame(320.0, 140.0)
109    .into_handle()
110}
111
112fn menu_bar_item() -> ViewHandle {
113    vstack(&[
114        text(&format!("count: {}", counter().get())),
115        button("Reset", || counter().set(0)),
116    ])
117    .padding(10.0)
118    .into_handle()
119}
Source

pub fn padding_edges(self, edges: EdgeSet, length: Option<f64>) -> Self

.padding(_:_:) on chosen edges — .padding(.horizontal, 8).

None asks for SwiftUI’s own default inset rather than a number.

Examples found in repository?
examples/inbox.rs (line 98)
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
More examples
Hide additional examples
examples/todo.rs (line 78)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
Source

pub fn padding_default(self) -> Self

.padding() — the system’s default inset on every edge.

Source

pub fn frame_optional( self, width: Option<f64>, height: Option<f64>, alignment: Alignment, ) -> Self

.frame(width:height:alignment:) with either dimension left out.

An omitted dimension is not zero: it means “take what the parent offers”, which is a different layout from asking for nothing.

Examples found in repository?
examples/todo.rs (line 116)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn expand(self, alignment: Alignment) -> Self

.frame(maxWidth: .infinity, maxHeight: .infinity) — fill the parent.

Source

pub fn expand_width(self, alignment: Alignment) -> Self

.frame(maxWidth: .infinity) — fill across, keep the natural height.

Source

pub fn frame_aligned(self, w: f64, h: f64, alignment: Alignment) -> Self

.frame(width:height:alignment:).

Source

pub fn frame(self, w: f64, h: f64) -> Self

Apply .frame(width:height:).

Examples found in repository?
examples/common/spec.rs (line 638)
632fn decorate(mut v: View, node: &Node) -> Result<View, String> {
633    if let Some(p) = node.f64_attr("pad") {
634        v = v.padding(p);
635    }
636    if let Some(size) = node.attr("frame") {
637        let (w, h) = parse_size(size, node.line)?;
638        v = v.frame(w, h);
639    }
640    if let Some(o) = node.f64_attr("opacity") {
641        v = v.opacity(o);
642    }
643    if let Some(c) = node.attr("bg") {
644        let c = parse_color(c, node.line)?;
645        v = v.bg(c);
646    }
647    if let Some(r) = node.f64_attr("corner") {
648        v = v.corner_radius(r);
649    }
650    Ok(v)
651}
More examples
Hide additional examples
examples/scenes.rs (line 67)
48fn main_window() -> ViewHandle {
49    vstack(&[
50        text("A SwiftUI app, no Swift source")
51            .font_size(20.0)
52            .padding(8.0),
53        divider(),
54        text(&format!("count: {}", counter().get()))
55            .font_size(34.0)
56            .padding(12.0),
57        hstack(&[
58            button("−", || counter().set(counter().get() - 1)),
59            button("+", || counter().set(counter().get() + 1)),
60        ]),
61        spacer(),
62        text("⌘, for Settings · the ★ in the menu bar has a menu")
63            .font_size(11.0)
64            .opacity(0.6),
65    ])
66    .padding(24.0)
67    .frame(420.0, 300.0)
68    .focused_scene_value(counter_focus_key(), counter().get())
69    .into_handle()
70}
71
72/// The focused-value key the window publishes its count under.
73///
74/// `.focusedSceneValue(\.key, value)` is how a window tells the commands above
75/// it what is selected. Both halves are synthesised at run time: the
76/// `FocusedValueKey` conformance *and* the `WritableKeyPath<FocusedValues, Int?>`
77/// — `FocusedValues` exports no properties, so unlike `EnvironmentValues` there
78/// is no SwiftUI modifier holding a key path to borrow.
79///
80/// The menu cannot *read* it yet: that needs `@FocusedValue`, a `DynamicProperty`
81/// SwiftUI instantiates itself, which is a different mechanism from anything
82/// here. What this demonstrates is the publishing half, in a real app.
83fn counter_focus_key() -> &'static views::FocusKey {
84    static K: std::sync::OnceLock<views::FocusKey> = std::sync::OnceLock::new();
85    K.get_or_init(|| views::focus_key("sceneCounter"))
86}
87
88fn settings_pane() -> ViewHandle {
89    vstack(&[
90        text("Preferences").font_size(18.0),
91        divider(),
92        text("This pane is a `Settings` scene — the one ⌘, opens."),
93        text(&format!("It sees the same state: {}", counter().get()))
94            .opacity(0.7),
95    ])
96    .padding(24.0)
97    .frame(360.0, 200.0)
98    .into_handle()
99}
100
101fn utility_window() -> ViewHandle {
102    vstack(&[
103        text("Utility").font_size(16.0),
104        text("A `Window`, not a `WindowGroup`: one of it, addressed by id.")
105            .opacity(0.7),
106    ])
107    .padding(20.0)
108    .frame(320.0, 140.0)
109    .into_handle()
110}
examples/inbox.rs (line 84)
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
examples/dashboard.rs (line 43)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
examples/hot_reload.rs (line 144)
117fn status(error: Option<&str>, generation: u64, micros: u64) -> View {
118    let slots = spec::slot_summary();
119    let slot_line = if slots.is_empty() {
120        String::new()
121    } else {
122        slots
123            .iter()
124            .map(|(k, v)| format!("{k}={v}"))
125            .collect::<Vec<_>>()
126            .join("  ")
127    };
128
129    // The error row is *always* present, empty when there is nothing wrong.
130    // An error that appears and disappears would otherwise reflow the screen
131    // above it on every save — which looks exactly like the reloader having
132    // replaced the view, and makes "did the screen survive this?" impossible
133    // to answer by looking.
134    let rows = vec![
135        divider(),
136        hstack_spacing(
137            &[
138                circle_shape()
139                    .fill_system(if error.is_some() {
140                        SystemColor::Orange
141                    } else {
142                        SystemColor::Clear
143                    })
144                    .frame(8.0, 8.0),
145                text(error.unwrap_or(""))
146                    .font_size(11.0)
147                    .fg_system(SystemColor::Orange),
148                spacer(),
149            ],
150            6.0,
151        )
152        .padding(6.0)
153        .frame(348.0, 24.0),
154        hstack_spacing(
155            &[
156                circle_shape()
157                    .fill_system(if error.is_some() {
158                        SystemColor::Orange
159                    } else {
160                        SystemColor::Green
161                    })
162                    .frame(8.0, 8.0),
163                text(&format!("gen {generation}"))
164                    .font_size(11.0)
165                    .fg_system(SystemColor::Secondary),
166                // Microseconds below a millisecond: a reload of a short spec
167                // really is that fast, and "0.0 ms" reads as "not measured".
168                text(&if micros < 1000 {
169                    format!("{micros} \u{b5}s")
170                } else {
171                    format!("{:.1} ms", micros as f64 / 1000.0)
172                })
173                .font_size(11.0)
174                .fg_system(SystemColor::Secondary),
175                spacer(),
176                text(&slot_line).font_size(11.0).fg_system(SystemColor::Secondary),
177            ],
178            8.0,
179        )
180        .padding(6.0)
181        .frame(348.0, 24.0),
182    ];
183    vstack_spacing(&rows, 0.0)
184}
Source

pub fn clip_circle(self) -> Self

.clipShape(Circle())

Source

pub fn clip_capsule(self) -> Self

.clipShape(Capsule())

Source

pub fn clip_capsule_styled(self, continuous: bool) -> Self

.clipShape(Capsule(style:)) — false gives the circular arc.

Source

pub fn clip_rounded_styled(self, radius: f64, continuous: bool) -> Self

.clipShape(RoundedRectangle(cornerRadius:style:)) — .continuous is the squircle Apple’s own UI uses, and it is visibly not a circular arc.

Source

pub fn clip_rounded(self, radius: f64) -> Self

.clipShape(RoundedRectangle(cornerRadius:))

Source

pub fn overlay(self, content: View) -> Self

.overlay(alignment: .center) { … }

Examples found in repository?
examples/swift_org_tutorial.rs (lines 137-143)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
Source

pub fn overlay_aligned(self, content: View, alignment: Alignment) -> Self

.overlay(alignment:content:) — the same modifier as View::overlay, which pins to the centre.

Source

pub fn mask(self, content: View) -> Self

.mask(alignment: .center) { … } — a _MaskAlignmentEffect.

Source

pub fn mask_aligned(self, content: View, alignment: Alignment) -> Self

.mask(alignment:_:) with an alignment other than the centre.

Source

pub fn mask_plain(self, content: View) -> Self

.mask(_:) — the older, alignment-free overload, which is a _MaskEffect. A different type from View::mask, not a shorthand for it.

Source

pub fn aspect_ratio(self, ratio: f64, fill: bool) -> Self

.aspectRatio(_:contentMode:)

Source

pub fn fixed_size(self, horizontal: bool, vertical: bool) -> Self

.fixedSize(horizontal:vertical:)

Source

pub fn z_index(self, value: f64) -> Self

.zIndex(_:)

Source

pub fn disabled(self, value: bool) -> Self

.disabled(_:)

Source

pub fn hidden(self) -> Self

.hidden()

Source

pub fn blend_mode(self, mode: u8) -> Self

.blendMode(_:)

Source

pub fn navigation_title(self, title: &str) -> Self

.navigationTitle(_:)

Examples found in repository?
examples/inbox.rs (line 74)
60fn detail(i: usize) -> View {
61    let m = &MESSAGES[i];
62    vstack_aligned_spacing(
63        &[
64            text(m.subject).text_style(TextStyle::Title).bold(),
65            text!("From {}", m.from).fg_system(SystemColor::Gray),
66            divider(),
67            text("Body text would go here.").fg_system(SystemColor::Gray),
68            spacer(),
69        ],
70        HorizontalAlignment::Leading,
71        Some(12.0),
72    )
73    .padding(20.0)
74    .navigation_title(m.subject)
75}
76
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
102
103/// The row as it appears in the list: a link to the detail, with the swipe
104/// action attached to the link rather than to its label.
105fn linked_row(i: usize) -> View {
106    navigation_link_labelled(row(i), detail(i))
107        .swipe_actions(HorizontalEdge::Trailing, true, button("Delete", || {}))
108}
109
110fn body() -> View {
111    let i = inbox();
112    let rows = matching();
113    navigation_stack(
114        list(for_each_items(&rows, |&i| linked_row(i)))
115        .list_style(views::ListStyle::InsetListStyle)
116        .searchable(&i.query, &i.searching, SearchFieldPlacement::Automatic, "Search"),
117    )
118    .navigation_title("Inbox")
119    .toolbar(button("Compose", || {}).keyboard_shortcut(KeyboardShortcut::DefaultAction))
120}
Source

pub fn navigation_title_bound(self, state: &BoundState<String>) -> Self

.navigationTitle(_:) with a binding — an editable title.

The title bar becomes a rename field: the user edits it in place and the new name is written back into Rust. Only the fixed-string overload was bound, so a document could be shown under a name but never renamed from where the name appears.

let name = BoundState::new(String::from("Untitled"));
let doc = text("body").navigation_title_bound(&name);
Source

pub fn navigation_destination_for<V: IntoView>( self, destination: impl Fn(i64) -> V + 'static, ) -> Self

.navigationDestination(for: Int.self) { value in … } — value-based routing.

This is how a NavigationStack is driven in modern SwiftUI: rows push a value, and the stack asks this modifier what view that value means. Only the isPresented: overload was bound, which is the older one-destination-per-flag shape — fine for a single detail sheet, and no use for a stack that pushes rows.

let stack = navigation_stack(
    list_identified(&[1, 2, 3], |id| text(&format!("row {id}")))
        .navigation_destination_for(|id| text(&format!("detail {id}"))),
);
Source

pub fn alert(self, title: &str, presented: bool, actions: View) -> Self

.alert(_:isPresented:actions:) with a fixed flag.

The flag becomes a Binding.constant, which SwiftUI treats as read-only, so this alert cannot be dismissed — there is nowhere to write false back to. View::alert_bound is the one a user can close.

Source

pub fn alert_bound( self, title: &str, state: &BoundState<bool>, actions: View, ) -> Self

.alert(_:isPresented:actions:) bound to Rust state.

Dismissing writes false into state, so Rust learns the alert closed without being told.

Source

pub fn alert_message_bound( self, title: &str, state: &BoundState<bool>, actions: View, message: View, ) -> Self

.alert(_:isPresented:actions:message:) — an alert that explains itself.

The message is the line under the title: what the buttons are about, and the difference between “Delete” and “Delete — this cannot be undone”. Only the title-and-buttons overload was bound, so an alert could ask but not say why.

let asking = BoundState::new(false);
let page = text("Notes").alert_message_bound(
    "Delete this?",
    &asking,
    button("Delete", || {}),
    text("This cannot be undone."),
);
Source

pub fn alert_message( self, title: &str, presented: bool, actions: View, message: View, ) -> Self

.alert(_:isPresented:actions:message:) with a fixed flag, which cannot be dismissed — see alert.

Source

pub fn confirmation_message_bound( self, title: &str, state: &BoundState<bool>, actions: View, message: View, ) -> Self

.confirmationDialog(_:isPresented:titleVisibility:actions:message:)

The message is the explanatory line under the title, and on a dialog it is often the only place the consequence is stated — “This deletes 12 items” under a bare “Delete”.

Source

pub fn sheet(self, presented: bool, content: View) -> Self

.sheet(isPresented:content:) with a fixed flag — undismissable, as View::alert is. See View::sheet_bound.

Source

pub fn sheet_bound(self, state: &BoundState<bool>, content: View) -> Self

.sheet(isPresented:content:) bound to Rust state, so a swipe down writes false back.

Examples found in repository?
examples/settings.rs (line 84)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
Source

pub fn sheet_bound_dismiss( self, state: &BoundState<bool>, content: View, on_dismiss: impl Fn() + 'static, ) -> Self

.sheet(isPresented:onDismiss:content:) — with a callback for the closing.

A sheet that saves what was edited has to know when it was dismissed, and onDismiss was hardwired to nil, so the sheet could be opened and closed and nothing on the Rust side would hear about it.

let editing = BoundState::new(false);
let page = text("Notes").sheet_bound_dismiss(
    &editing,
    text("editor"),
    || println!("saved"),
);
Source

pub fn confirmation_dialog( self, title: &str, presented: bool, actions: View, ) -> Self

.confirmationDialog(_:isPresented:actions:) with a fixed flag — undismissable. See View::confirmation_dialog_bound.

Source

pub fn confirmation_dialog_bound( self, title: &str, state: &BoundState<bool>, actions: View, ) -> Self

.confirmationDialog(_:isPresented:actions:) bound to Rust state.

Source

pub fn a11y_label(self, label: &str) -> Self

.accessibilityLabel(_:)

Examples found in repository?
examples/inbox.rs (line 99)
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
More examples
Hide additional examples
examples/dashboard.rs (line 50)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
examples/todo.rs (line 79)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
Source

pub fn a11y_hidden(self, hidden: bool) -> Self

.accessibilityHidden(_:)

Source

pub fn focusable(self, value: bool) -> Self

.focusable(_:)

Source

pub fn on_disappear(self, action: impl Fn() + 'static) -> Self

.onDisappear(perform:)

Source

pub fn on_long_press(self, duration: f64, max_distance: f64) -> Self

.gesture(LongPressGesture(...))

Source

pub fn on_long_press_perform( self, duration: f64, max_distance: f64, action: impl Fn() + 'static, ) -> Self

.onLongPressGesture(minimumDuration:maximumDistance:pressing:perform:)

Prefer this over on_long_press, which attaches the gesture with nothing listening.

Source

pub fn clipped(self) -> Self

.clipped()

Source

pub fn compositing_group(self) -> Self

.compositingGroup()

Source

pub fn drawing_group(self) -> Self

.drawingGroup() — flatten the subtree through Metal.

Source

pub fn rotate_3d(self, degrees: f64, axis: (f64, f64, f64)) -> Self

.rotation3DEffect(_:axis:)

Source

pub fn on_drag(self, minimum_distance: f64) -> Self

.gesture(DragGesture(...))

Source

pub fn on_drag_ended( self, minimum_distance: f64, action: impl Fn() + 'static, ) -> Self

.gesture(DragGesture(...).onEnded(_:))

Prefer this over on_drag, which attaches the gesture with nothing listening.

Source

pub fn on_drag_value( self, minimum_distance: f64, action: impl Fn(DragValue) + 'static, ) -> Self

.gesture(DragGesture(...).onEnded { value in … }), with the value.

on_drag_ended tells the handler only that a drag ended. This one hands over where it started, where it finished and how fast it was moving — see views::DragValue.

let card = text("drag me").on_drag_value(1.0, |v| {
    let (dx, dy) = v.translation();
    println!("moved {dx} x {dy}");
});
Source

pub fn on_magnify(self, minimum_scale_delta: f64) -> Self

.gesture(MagnifyGesture(...))

Source

pub fn on_magnify_value( self, minimum_scale_delta: f64, action: impl Fn(MagnifyValue) + 'static, ) -> Self

.gesture(MagnifyGesture(...).onEnded { value in … })

on_magnify attaches the gesture with nothing listening — it builds the value Swift would and can never be seen to fire. This one hands over the magnification, the velocity and where the pinch was centred; see views::MagnifyValue.

Source

pub fn on_rotate(self, minimum_degrees: f64) -> Self

.gesture(RotateGesture(...))

Source

pub fn on_rotate_value( self, minimum_degrees: f64, action: impl Fn(RotateValue) + 'static, ) -> Self

.gesture(RotateGesture(...).onEnded { value in … })

As on_rotate, but the handler is told how far. Angle stores radians, so views::RotateValue::degrees converts rather than reading a second field.

Source

pub fn popover(self, presented: bool, content: View) -> Self

.popover(isPresented:content:) with a fixed flag — undismissable. See View::popover_bound.

Source

pub fn popover_bound(self, state: &BoundState<bool>, content: View) -> Self

.popover(isPresented:content:) bound to Rust state, so tapping outside writes false back.

Source

pub fn on_change(self, value: i64, handler: impl Fn(i64, i64) + 'static) -> Self

.onChange(of:_:), watching an Int.

Source

pub fn on_change_str( self, value: &str, handler: impl Fn(String, String) + 'static, ) -> Self

.onChange(of:initial:_:) over a String.

onChange is one of the modifiers an application reaches for most, and it could only watch an Int — a search term, a selected identifier, a mode name all had to be turned into a number first. Swift constrains the watched value to Equatable and nothing else.

let v = text("results").on_change_str("query", |was, now| {
    println!("search went from {was:?} to {now:?}");
});
Source

pub fn on_change_bool( self, value: bool, handler: impl Fn(bool, bool) + 'static, ) -> Self

.onChange(of:initial:_:) over a Bool.

Source

pub fn on_change_f64( self, value: f64, handler: impl Fn(f64, f64) + 'static, ) -> Self

.onChange(of:initial:_:) over a Double.

Source

pub fn toolbar(self, content: View) -> Self

.toolbar { ToolbarItem { content } }

Examples found in repository?
examples/inbox.rs (line 119)
110fn body() -> View {
111    let i = inbox();
112    let rows = matching();
113    navigation_stack(
114        list(for_each_items(&rows, |&i| linked_row(i)))
115        .list_style(views::ListStyle::InsetListStyle)
116        .searchable(&i.query, &i.searching, SearchFieldPlacement::Automatic, "Search"),
117    )
118    .navigation_title("Inbox")
119    .toolbar(button("Compose", || {}).keyboard_shortcut(KeyboardShortcut::DefaultAction))
120}
Source

pub fn toolbar_customizable( self, toolbar_id: &str, item_id: &str, shows_by_default: bool, content: View, ) -> Self

.toolbar(id:) { ToolbarItem(id:showsByDefault:) { content } } — a toolbar the user can rearrange, remembered under toolbar_id.

shows_by_default is whether the item is there before any customization; false leaves it in the palette until it is dragged in.

Source

pub fn transition(self, kind: Transition) -> Self

.transition(.opacity)

Examples found in repository?
examples/swift_org_tutorial.rs (line 147)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
More examples
Hide additional examples
examples/todo.rs (line 117)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn id(self, value: i64) -> Self

.id(_) — the identity SwiftUI diffs against.

Changing it replaces the view rather than updating it, which is what makes a transition play: the old identity leaves, the new one arrives.

Examples found in repository?
examples/swift_org_tutorial.rs (line 148)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
Source

pub fn animation(self, value: i64) -> Self

.animation(.default, value:)

Examples found in repository?
examples/dashboard.rs (line 81)
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
Source

pub fn on_appear(self, action: impl Fn() + 'static) -> Self

.onAppear(perform:)

Source

pub fn on_tap(self, action: impl Fn() + 'static) -> Self

.onTapGesture(count:perform:)

Source

pub fn context_menu(self, items: View) -> Self

.contextMenu(menuItems:)

Source

pub fn context_menu_preview(self, items: View, preview: View) -> Self

.contextMenu(menuItems:preview:) — a menu with something to look at.

The preview is what a long press enlarges before the menu appears: the row blown up, a photo, a card. context_menu has no such slot, so the menu came up over the view as it already was.

let row = text("Photo").context_menu_preview(
    button("Delete", || {}),
    image("photo").frame(200.0, 200.0),
);
Source

pub fn scroll(self) -> Self

Wrap in a vertical ScrollView.

Examples found in repository?
examples/common/spec.rs (line 570)
487fn node_view(node: &Node) -> Result<View, String> {
488    let spacing = node.f64_attr("spacing").unwrap_or(8.0);
489    let base = match node.name.as_str() {
490        "vstack" => {
491            let kids = children(node)?;
492            match node.attr("align") {
493                Some(a) => vstack_aligned_spacing(&kids, h_align(a, node.line)?, Some(spacing)),
494                None => vstack_spacing(&kids, spacing),
495            }
496        }
497        "hstack" => {
498            let kids = children(node)?;
499            match node.attr("align") {
500                Some(a) => hstack_aligned_spacing(&kids, v_align(a, node.line)?, Some(spacing)),
501                None => hstack_spacing(&kids, spacing),
502            }
503        }
504        "zstack" => zstack_aligned(&children(node)?, align(node.attr("align").unwrap_or("center"), node.line)?),
505        "text" => {
506            let s = node.value.as_deref().unwrap_or("");
507            let mut v = text(s);
508            if let Some(style) = node.attr("style") {
509                v = v.text_style(text_style(style, node.line)?);
510            }
511            if let Some(size) = node.f64_attr("size") {
512                v = v.font_size(size);
513            }
514            if node.flag("bold") {
515                v = v.bold();
516            }
517            if node.flag("italic") {
518                v = v.italic();
519            }
520            if let Some(c) = node.attr("color") {
521                v = match tint(c, node.line)? {
522                    Tint::System(sc) => v.fg_system(sc),
523                    Tint::Literal(lc) => v.fg(lc),
524                };
525            }
526            v
527        }
528        "spacer" => spacer(),
529        "divider" => divider(),
530        // The action is a no-op on purpose: a spec read from a file has nowhere
531        // to put behaviour, and pretending otherwise would be worse than a
532        // button that visibly does nothing. `hot_reload.rs` is where a spec
533        // gains behaviour, by being reloaded.
534        "button" => button(node.value.as_deref().unwrap_or("Button"), || {}),
535        "color" => color(parse_color(node.value.as_deref().unwrap_or("#808080"), node.line)?),
536        "image" => system_image(node.value.as_deref().unwrap_or("star")).into_view(),
537        "rect" => match node.attr("color") {
538            Some(c) => match tint(c, node.line)? {
539                Tint::System(sc) => rectangle_shape().fill_system(sc),
540                Tint::Literal(lc) => rectangle_shape().fill(lc),
541            },
542            None => rectangle_shape().into_view(),
543        },
544        "circle" => match node.attr("color") {
545            Some(c) => match tint(c, node.line)? {
546                Tint::System(sc) => circle_shape().fill_system(sc),
547                Tint::Literal(lc) => circle_shape().fill(lc),
548            },
549            None => circle_shape().into_view(),
550        },
551        "capsule" => match node.attr("color") {
552            Some(c) => match tint(c, node.line)? {
553                Tint::System(sc) => capsule_shape().fill_system(sc),
554                Tint::Literal(lc) => capsule_shape().fill(lc),
555            },
556            None => capsule_shape().into_view(),
557        },
558        "progress" => progress(
559            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
560            node.f64_attr("total").unwrap_or(1.0),
561        ),
562        "gauge" => gauge(
563            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
564            node.f64_attr("min").unwrap_or(0.0),
565            node.f64_attr("max").unwrap_or(1.0),
566            text(node.attr("label").unwrap_or("")),
567        ),
568        "group_box" => group_box(stack_children(node)?),
569        "list" => list(stack_children(node)?),
570        "scroll" => stack_children(node)?.scroll(),
571        "form" => form(stack_children(node)?),
572        // Every bound control needs an explicit `@name`.
573        //
574        // Inventing one — from the line, or from position in the tree — looks
575        // friendlier and is a trap: adding a line above a `toggle` would
576        // change its derived name, and the control would silently reset on the
577        // next reload. A name the file states is a name that survives the file
578        // being edited, which is the entire point of the slots.
579        "toggle" => toggle_bound(
580            node.value.as_deref().unwrap_or("Toggle"),
581            &flag_slot(&require_slot(node)?, node.flag("on")),
582        ),
583        "slider" => {
584            let lo = node.f64_attr("min").unwrap_or(0.0);
585            let hi = node.f64_attr("max").unwrap_or(1.0);
586            slider_bound(
587                &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(lo)),
588                lo,
589                hi,
590            )
591        }
592        "stepper" => stepper_bound(
593            node.value.as_deref().unwrap_or("Stepper"),
594            &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(0.0)),
595            node.f64_attr("min").unwrap_or(0.0),
596            node.f64_attr("max").unwrap_or(100.0),
597            node.f64_attr("step").unwrap_or(1.0),
598        ),
599        "field" => textfield_bound(
600            node.value.as_deref().unwrap_or(""),
601            &string_slot(&require_slot(node)?, node.attr("text").unwrap_or("")),
602        ),
603        "label" => label(
604            node.value.as_deref().unwrap_or(""),
605            node.attr("icon").unwrap_or("star"),
606        ),
607        other => {
608            return Err(format!(
609                "line {}: no view called `{other}`; try one of {}",
610                node.line,
611                NAMES.join(", ")
612            ))
613        }
614    };
615    decorate(base, node)
616}
Source

pub fn position(self, x: f64, y: f64) -> Self

.position(x:y:) — place the view’s centre at a point in its parent, which is not the same as .offset(x:y:) moving it from where it was.

Source

pub fn hue_rotation(self, radians: f64) -> Self

.hueRotation(.radians(_))

Source

pub fn color_multiply(self, color: Color) -> Self

.colorMultiply(_:) — multiply every pixel by a colour, which tints without covering.

Source

pub fn content_transition(self, transition: ContentTransition) -> Self

.contentTransition(_:) — how a change to the content animates, as distinct from the view arriving or leaving.

Source

pub fn projection_effect(self, m: [f64; 9]) -> Self

.projectionEffect(_:) — a 3x3 projection, row-major.

Source

pub fn aspect_ratio_mode(self, fill: bool) -> Self

.aspectRatio(contentMode:) without pinning a ratio — true fills, false fits.

Source

pub fn safe_area_padding(self, length: f64) -> Self

.safeAreaPadding(_:) — padding measured from the safe area rather than from the view.

Source

pub fn content_margins( self, length: f64, placement: ContentMarginPlacement, ) -> Self

.contentMargins(_:for:)

Source

pub fn container_shape(self, shape: InsettableShape) -> Self

.containerShape(_:) — the shape descendants inherit for clipping.

Source

pub fn coordinate_space(self, name: HashableValue<'_>) -> Self

.coordinateSpace(_:) — name this view’s space so a GeometryProxy can report positions relative to it.

Source

pub fn grid_cell_unsized_axes(self, axes: AxisSet) -> Self

.gridCellUnsizedAxes(_:) — axes this cell should not stretch along.

Source

pub fn grid_column_alignment(self, alignment: HorizontalAlignment) -> Self

.gridColumnAlignment(_:)

Source

pub fn alignment_guide( self, alignment: HorizontalAlignment, compute: impl Fn(ViewDimensions) -> f64 + 'static, ) -> Self

.alignmentGuide(_:computeValue:) — move where this view lines up with its siblings without moving the view.

compute is handed the view’s views::ViewDimensions and answers in terms of them, which is what an alignment guide is for: returning d.width / 2.0 lines the view up by its centre, d.width by its far edge. It used to take no arguments, so the only guide it could express was a constant — the one kind that does not need the modifier.

let v = text("centred").alignment_guide(HorizontalAlignment::Leading, |d| d.width / 2.0);
Source

pub fn container_relative_frame( self, axes: &[AxisSet], alignment: Alignment, ) -> Self

.containerRelativeFrame(_:alignment:) — size against the container rather than the content, which is what makes a carousel page.

Source

pub fn container_relative_frame_thirds( self, axes: &[AxisSet], alignment: Alignment, ) -> Self

.containerRelativeFrame(_:count:span:spacing:alignment:) at thirds.

Source

pub fn on_geometry_change( self, measure: impl Fn(f64, f64) -> i64 + 'static, action: impl Fn(i64, i64) + 'static, ) -> Self

.onGeometryChange(for:of:action:) — observe the measured geometry.

measure is handed the view’s width and height and returns the value to watch; action is called with the old and the new one whenever that value changes. Both used to be blind — measure took no arguments, so it could not read the geometry the modifier exists to report, and action was told only that something had changed.

let v = text("wide?").on_geometry_change(
    |w, _h| (w > 400.0) as i64,
    |was, now| println!("wide: {was} -> {now}"),
);
Source

pub fn on_geometry_change_f64( self, measure: impl Fn(f64, f64) -> f64 + 'static, action: impl Fn(f64, f64) + 'static, ) -> Self

.onGeometryChange(for: Double.self, of:action:) — the same, watching a Double.

Which is usually what is wanted: the value being watched is nearly always a width or a height, and for: Int.self meant rounding it before it could be watched at all.

let v = text("wide?").on_geometry_change_f64(|w, _h| w, |was, now| {
    println!("width {was} -> {now}");
});
Source

pub fn clip_ellipse(self) -> Self

.clipShape(Ellipse())

Source

pub fn layout_direction_behavior(self, value: LayoutDirectionBehavior) -> Self

.layoutDirectionBehavior(_:) — whether this mirrors in a right-to-left language.

Source

pub fn layout_value(self, value: i64) -> Self

.layoutValue(key:value:)

Source

pub fn container_corner_offset(self, edges: EdgeSet, value: bool) -> Self

.containerCornerOffset(_:)

Source

pub fn safe_area_bar( self, edge: VerticalEdge, alignment: HorizontalAlignment, spacing: Option<f64>, content: View, ) -> Self

.safeAreaBar(edge:alignment:spacing:content:) — a bar that shrinks the safe area, as View::safe_area_inset does, but styled as a bar.

Source

pub fn ignores_safe_area(self) -> Self

.ignoresSafeArea() — let the view run under the notch, the home indicator and the keyboard, which is what a full-bleed background wants.

Source

pub fn ignores_safe_area_edges( self, regions: SafeAreaRegions, edges: EdgeSet, ) -> Self

.ignoresSafeArea(_:edges:) — the same, but only the regions and edges named. .ignoresSafeArea(.keyboard) alone is the common case.

Source

pub fn safe_area_inset( self, edge: VerticalEdge, alignment: HorizontalAlignment, spacing: Option<f64>, content: View, ) -> Self

.safeAreaInset(edge:alignment:spacing:) { … } — put a view against one edge and shrink this view’s safe area by however tall it turns out to be. A bottom bar that scrolling content stops above, without measuring.

Source

pub fn scroll_indicators( self, visibility: ScrollIndicatorVisibility, axes: AxisSet, ) -> Self

.scrollIndicators(_:axes:)

The axis is not optional here as it is in Swift: SwiftUI’s default is [.horizontal, .vertical], and Axis.Set has no .all static to name that pair with, so a no-axis convenience would have to quietly pick one.

Source

pub fn content_shape(self, shape: InsettableShape) -> Self

.contentShape(_:) — the region that takes hits, which is otherwise the view’s frame. A circular button in a square frame needs this or its corners stay tappable.

Source

pub fn tag(self, value: HashableValue<'_>) -> Self

.tag(_:) — the value a Picker or TabView selects when this is the chosen row.

Source

pub fn tag_int(self, value: i64) -> Self

.tag(_:) with an Int, which is what a Picker bound to views::BoundState<i64> selects by.

Examples found in repository?
examples/settings.rs (line 72)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
Source

pub fn tag_str(self, value: &str) -> Self

.tag(_:) with a String.

Source

pub fn task(self, action: impl Fn() + Send + Sync + 'static) -> Self

.task { … } — run the action once when the view appears, cancelled if it goes away first.

#[track_caller] so the task carries the call site’s file and line, which is what SwiftUI names it by in Instruments — taking file!() here would name every task after this file.

Source

pub fn task_id(self, id: i64, action: impl Fn() + Send + Sync + 'static) -> Self

.task(id:) { … } — as task, but restarted whenever the identity changes.

SwiftUI cancels the running task and starts a new one when id differs from the last body evaluation, which is how a detail view re-fetches when the selection moves. views::task has always built this; it had no chainable method, so the DSL could only ever start a task once.

Source

pub fn image_scale(self, scale: ImageScale) -> Self

.imageScale(_:) — how large an SF Symbol draws relative to its font.

Source

pub fn text_case(self, case: Option<TextCase>) -> Self

.textCase(_:) — None restores the text as written.

Source§

impl View

Source

pub fn navigation_destination( self, state: &BoundState<bool>, destination: View, ) -> Self

.navigationDestination(isPresented:destination:) bound to Rust state — pushing sets it, and the back button writes false back.

Source

pub fn inspector(self, state: &BoundState<bool>, content: View) -> Self

.inspector(isPresented:content:) bound to Rust state.

Source

pub fn inspector_column_width(self, width: f64) -> Self

.inspectorColumnWidth(_:) — one fixed width for the inspector column.

Source

pub fn inspector_column_width_range( self, min: Option<f64>, ideal: f64, max: Option<f64>, ) -> Self

.inspectorColumnWidth(min:ideal:max:) — a width the user can drag within.

None for a bound leaves the column unconstrained in that direction, which is not the same as pinning it to zero. .inspector_column_width above is the fixed spelling.

Source

pub fn toolbar_background( self, visibility: Visibility, placements: &[ToolbarPlacement], ) -> Self

.toolbarBackground(_:for:)

Source

pub fn toolbar_visibility( self, visibility: Visibility, placements: &[ToolbarPlacement], ) -> Self

.toolbarVisibility(_:for:) — whether the bar shows at all.

SwiftUI also spells this .toolbar(_:for:); this reaches the named one.

Source

pub fn toolbar_title_display_mode(self, mode: ToolbarTitleDisplayMode) -> Self

.toolbarTitleDisplayMode(_:) — large title or inline.

Source

pub fn toolbar_role(self, role: ToolbarRole) -> Self

.toolbarRole(_:)

Source

pub fn searchable( self, text: &BoundState<String>, presented: &BoundState<bool>, placement: SearchFieldPlacement, prompt: &str, ) -> Self

.searchable(text:isPresented:placement:prompt:), both bindings owned by Rust — the query text lands in text as it is typed.

Examples found in repository?
examples/inbox.rs (line 116)
110fn body() -> View {
111    let i = inbox();
112    let rows = matching();
113    navigation_stack(
114        list(for_each_items(&rows, |&i| linked_row(i)))
115        .list_style(views::ListStyle::InsetListStyle)
116        .searchable(&i.query, &i.searching, SearchFieldPlacement::Automatic, "Search"),
117    )
118    .navigation_title("Inbox")
119    .toolbar(button("Compose", || {}).keyboard_shortcut(KeyboardShortcut::DefaultAction))
120}
Source

pub fn navigation_split_view_style_automatic(self) -> Self

.navigationSplitViewStyle(.automatic)

Source

pub fn navigation_view_style_automatic(self) -> Self

.navigationViewStyle(.automatic)

Source

pub fn navigation_document(self, item: &str) -> Self

.navigationDocument(_:)

Source

pub fn navigation_document_url(self, spec: &str) -> Self

.navigationDocument(_:) with a URL.

Source

pub fn toolbar_background_visibility( self, visibility: Visibility, placements: &[ToolbarPlacement], ) -> Self

.toolbarBackgroundVisibility(_:for:) — distinct from View::toolbar_background, which sets what the background is.

Source

pub fn toolbar_color_scheme( self, scheme: Option<ColorScheme>, placements: &[ToolbarPlacement], ) -> Self

.toolbarColorScheme(_:in:) — None restores the inherited scheme.

Source

pub fn toolbar_title_menu(self, content: View) -> Self

.toolbarTitleMenu(content:) — the menu behind a tappable title.

Source

pub fn presentation_sizing(self) -> Self

.presentationSizing(_:)

Source

pub fn presentation_background_interaction( self, value: PresentationBackgroundInteraction, ) -> Self

.presentationBackgroundInteraction(_:) — whether what is behind a sheet still takes touches, which is what makes a half-sheet usable.

Source

pub fn presentation_compact_adaptation( self, value: PresentationAdaptation, ) -> Self

.presentationCompactAdaptation(_:) — what a popover becomes when the size class is compact, which on a phone is always.

Source

pub fn presentation_content_interaction( self, value: PresentationContentInteraction, ) -> Self

.presentationContentInteraction(_:) — whether a drag resizes the sheet or scrolls its content.

Source

pub fn navigation_transition(self) -> Self

.navigationTransition(_:)

Source

pub fn navigation_split_view_column_width(self, width: f64) -> Self

.navigationSplitViewColumnWidth(_:)

Source

pub fn matched_transition_source(self, id: HashableValue<'_>) -> Self

.matchedTransitionSource(id:in:) — the view a zoom transition grows from, paired with View::matched_geometry_effect’s destination.

Source

pub fn presentation_detents(self, detents: &[PresentationDetent]) -> Self

.presentationDetents(_:) — the heights a sheet can rest at, which is what makes it a half-sheet rather than a full one.

Examples found in repository?
examples/settings.rs (line 106)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
Source

pub fn presentation_drag_indicator(self, visibility: Visibility) -> Self

.presentationDragIndicator(_:)

Examples found in repository?
examples/settings.rs (line 107)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
Source

pub fn presentation_corner_radius(self, radius: Option<f64>) -> Self

.presentationCornerRadius(_:) — None restores the system radius.

Source

pub fn presentation_background( self, alignment: Alignment, content: View, ) -> Self

.presentationBackground(alignment:content:)

Source

pub fn tint_system(self, c: SystemColor) -> Self

.tint(_:) with one of SwiftUI’s own colours.

View::tint takes a literal Color; a named colour is not a fixed triple, so for an accent — which is what the system draws controls with — naming it is usually what is meant.

Examples found in repository?
examples/dashboard.rs (line 67)
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
Source

pub fn search_toolbar_behavior(self, value: SearchToolbarBehavior) -> Self

.searchToolbarBehavior(_:)

Source

pub fn search_presentation_toolbar_behavior( self, value: SearchPresentationToolbarBehavior, ) -> Self

.searchPresentationToolbarBehavior(_:)

Source

pub fn text_selection_affinity(self, value: TextSelectionAffinity) -> Self

.textSelectionAffinity(_:)

Source

pub fn type_select_equivalent(self, text: Option<&str>) -> Self

.typeSelectEquivalent(_:) — what typing in a list jumps to.

Source

pub fn search_scopes(self, scope: &BoundState<i64>, scopes: View) -> Self

.searchScopes(_:scopes:) bound to Rust state — the chosen scope lands in scope.

Source

pub fn search_suggestions( self, visibility: Visibility, placements: SearchSuggestionsPlacementSet, ) -> Self

.searchSuggestions(_:for:) — where suggestions may appear.

Source

pub fn search_selection(self, changed: impl Fn() + 'static) -> Self

.searchSelection(_:)

Source

pub fn search_focused(self) -> Self

.searchFocused(_:)

Source

pub fn text_input_suggestions(self, count: usize, content: View) -> Self

.textInputSuggestions { … } — completions offered under a field.

Source

pub fn find_navigator(self, state: &BoundState<bool>) -> Self

.findNavigator(isPresented:) bound to Rust state — the find bar.

Source§

impl View

Source

pub fn file_exporter( self, state: &BoundState<bool>, item: Option<&str>, kinds: &[ContentType], default_filename: Option<&str>, completion: impl Fn(FileOutcome) + 'static, cancellation: impl Fn() + 'static, ) -> Self

.fileExporter(isPresented:item:contentTypes:defaultFilename:onCompletion:onCancellation:)

Source

pub fn file_importer( self, state: &BoundState<bool>, kinds: &[ContentType], completion: impl Fn(FileOutcome) + 'static, ) -> Self

.fileImporter(isPresented:allowedContentTypes:onCompletion:)

Source

pub fn file_mover( self, state: &BoundState<bool>, file: Option<&str>, completion: impl Fn(FileOutcome) + 'static, ) -> Self

.fileMover(isPresented:file:onCompletion:)

Source

pub fn item_provider(self, item: Option<&str>) -> Self

.itemProvider(_:) — what this view offers to a drag or a service.

Source

pub fn exports_item_providers( self, kinds: &[ContentType], items: &[&str], edit: impl Fn(&[ItemProvider]) -> bool + 'static, ) -> Self

.exportsItemProviders(_:items:onEdit:)

Source

pub fn imports_item_providers( self, kinds: &[ContentType], accept: impl Fn(&[ItemProvider]) -> bool + 'static, ) -> Self

.importsItemProviders(_:onImport:)

Source

pub fn exportable_to_services(self, items: &[&str]) -> Self

.exportableToServices(_:) — what the Services menu may take.

Source

pub fn importable_from_services( self, accept: impl Fn(&[String]) -> bool + 'static, ) -> Self

.importableFromServices(for:action:)

Source

pub fn on_receive( self, complete_immediately: bool, perform: impl Fn(i64) + 'static, ) -> Self

.onReceive(_:perform:) — a publisher’s values, as Ints.

Source

pub fn on_scroll_geometry_change( self, measure: impl Fn(ScrollGeometry) -> i64 + 'static, action: impl Fn(i64, i64) + 'static, ) -> Self

.onScrollGeometryChange(for:of:action:) measure is handed the scroll view’s views::ScrollGeometry and returns the value to watch; action is called with the old and the new one. Both used to be blind, which left the modifier able to notice that something had scrolled and nothing more.

Source

pub fn on_scroll_geometry_change_f64( self, measure: impl Fn(ScrollGeometry) -> f64 + 'static, action: impl Fn(f64, f64) + 'static, ) -> Self

.onScrollGeometryChange(for: Double.self, …) — the same, watching a Double, which a scroll offset is.

Source

pub fn on_scroll_target_visibility_change( self, threshold: f64, visible: impl Fn(&[i64]) + 'static, ) -> Self

.onScrollTargetVisibilityChange(for:threshold:_:) — which targets are on screen, which is how a carousel knows what page it is on.

Source

pub fn dismissal_confirmation_dialog( self, title: &str, should_present: bool, actions: View, message: View, ) -> Self

.dismissalConfirmationDialog(_:shouldPresent:actions:message:) — ask before a sheet closes on unsaved work.

Source

pub fn presentation_prevents_app_termination( self, prevents: Option<bool>, ) -> Self

.presentationPreventsAppTermination(_:) — None restores the default.

Source

pub fn text_input_formatting_control_visibility( self, visibility: Visibility, placements: TextInputFormattingControlPlacementSet, ) -> Self

.textInputFormattingControlVisibility(_:for:)

Source

pub fn hand_gesture_shortcut( self, shortcut: HandGestureShortcut, enabled: bool, ) -> Self

.handGestureShortcut(_:isEnabled:) — the pinch that stands in for a tap on a watch.

Source

pub fn assistive_access_navigation_icon(self, name: &str) -> Self

.assistiveAccessNavigationIcon(_:)

Source

pub fn a11y_rotor(self, label: &str, text: &str) -> Self

.accessibilityRotor(_:textRanges:) — a custom rotor VoiceOver can spin through.

Source

pub fn a11y_rotor_entry(self, id: HashableValue<'_>) -> Self

.accessibilityRotorEntry(id:in:)

Source

pub fn a11y_chart_descriptor(self) -> Self

.accessibilityChartDescriptor(_:)

Source

pub fn environment_object(self) -> Self

.environmentObject(_:)

Source

pub fn focused_object(self) -> Self

.focusedObject(_:)

Source

pub fn default_app_storage_standard(self) -> Self

.defaultAppStorage(_:)

Source

pub fn text_renderer(self) -> Self

.textRenderer(_:)

Source

pub fn attributed_text_formatting_definition(self) -> Self

.attributedTextFormattingDefinition(_:)

Source

pub fn environment_image_scale(self, scale: ImageScale) -> Self

.environment(\.imageScale, _)

Source

pub fn environment_symbol_variants(self, value: SymbolVariants) -> Self

.environment(\.symbolVariants, _)

Source

pub fn transform_environment_image_scale( self, action: impl Fn(ImageScale) -> ImageScale + 'static, ) -> Self

.transformEnvironment(\.imageScale, _)

Source

pub fn focused_value(self, present: bool) -> Self

.focusedValue(_:)

Source

pub fn preference(self, value: i64) -> Self

.preference(key:value:) — write a value for an ancestor to collect.

Source

pub fn on_preference_change(self) -> Self

.onPreferenceChange(_:perform:) — observe what descendants wrote.

The value is read back with views::observed_preference rather than through a closure, because SwiftUI calls the handler on its own schedule and the last value is what a caller wants.

Source

pub fn transform_preference(self) -> Self

.transformPreference(_:_:) — rewrite what passes through.

Source

pub fn anchor_preference(self, transform: impl Fn() -> i64 + 'static) -> Self

.anchorPreference(key:value:transform:) — write a preference derived from this view’s geometry.

Source

pub fn transform_anchor_preference( self, transform: impl Fn(i64) -> i64 + 'static, ) -> Self

.transformAnchorPreference(key:value:transform:)

Source

pub fn overlay_preference_value( self, alignment: Alignment, content: View, ) -> Self

.overlayPreferenceValue(_:alignment:_:) — place content over this view using what a descendant reported, which is how a badge follows the thing it belongs to.

Source

pub fn background_preference_value( self, alignment: Alignment, content: View, ) -> Self

.backgroundPreferenceValue(_:alignment:_:)

Source

pub fn grid_cell_anchor(self, x: f64, y: f64) -> Self

.gridCellAnchor(_:) — where this cell sits in the space the grid gives it, as a unit point.

Source

pub fn popover_anchored( self, state: &BoundState<bool>, anchor: (f64, f64), arrow_edge: Edge, content: View, ) -> Self

.popover(isPresented:attachmentAnchor:arrowEdge:content:) bound to Rust state — the anchored form, where the arrow points at a chosen point rather than the view’s middle.

Source

pub fn window_resize_anchor(self, anchor: Option<(f64, f64)>) -> Self

.windowResizeAnchor(_:) — None restores the default.

Source§

impl View

Source

pub fn font_size(self, size: f64) -> Self

.font(.system(size:)) On a Text this is Text.font(_:), which returns Text, so a chain of text modifiers stays one type the way Swift’s does.

Examples found in repository?
examples/dynamic_ui.rs (line 73)
64pub fn body() -> View {
65    let text_src = current().lock().expect("spec").clone();
66    match spec::parse(&text_src).and_then(|nodes| spec::build(&nodes)) {
67        Ok(v) => v,
68        Err(e) => vstack_aligned_spacing(
69            &[
70                text("Could not build that screen")
71                    .text_style(TextStyle::Headline)
72                    .fg_system(SystemColor::Red),
73                text(&e).font_size(12.0).fg_system(SystemColor::Secondary),
74            ],
75            HorizontalAlignment::Leading,
76            Some(8.0),
77        )
78        .padding(20.0),
79    }
80}
More examples
Hide additional examples
examples/scenes.rs (line 51)
48fn main_window() -> ViewHandle {
49    vstack(&[
50        text("A SwiftUI app, no Swift source")
51            .font_size(20.0)
52            .padding(8.0),
53        divider(),
54        text(&format!("count: {}", counter().get()))
55            .font_size(34.0)
56            .padding(12.0),
57        hstack(&[
58            button("−", || counter().set(counter().get() - 1)),
59            button("+", || counter().set(counter().get() + 1)),
60        ]),
61        spacer(),
62        text("⌘, for Settings · the ★ in the menu bar has a menu")
63            .font_size(11.0)
64            .opacity(0.6),
65    ])
66    .padding(24.0)
67    .frame(420.0, 300.0)
68    .focused_scene_value(counter_focus_key(), counter().get())
69    .into_handle()
70}
71
72/// The focused-value key the window publishes its count under.
73///
74/// `.focusedSceneValue(\.key, value)` is how a window tells the commands above
75/// it what is selected. Both halves are synthesised at run time: the
76/// `FocusedValueKey` conformance *and* the `WritableKeyPath<FocusedValues, Int?>`
77/// — `FocusedValues` exports no properties, so unlike `EnvironmentValues` there
78/// is no SwiftUI modifier holding a key path to borrow.
79///
80/// The menu cannot *read* it yet: that needs `@FocusedValue`, a `DynamicProperty`
81/// SwiftUI instantiates itself, which is a different mechanism from anything
82/// here. What this demonstrates is the publishing half, in a real app.
83fn counter_focus_key() -> &'static views::FocusKey {
84    static K: std::sync::OnceLock<views::FocusKey> = std::sync::OnceLock::new();
85    K.get_or_init(|| views::focus_key("sceneCounter"))
86}
87
88fn settings_pane() -> ViewHandle {
89    vstack(&[
90        text("Preferences").font_size(18.0),
91        divider(),
92        text("This pane is a `Settings` scene — the one ⌘, opens."),
93        text(&format!("It sees the same state: {}", counter().get()))
94            .opacity(0.7),
95    ])
96    .padding(24.0)
97    .frame(360.0, 200.0)
98    .into_handle()
99}
100
101fn utility_window() -> ViewHandle {
102    vstack(&[
103        text("Utility").font_size(16.0),
104        text("A `Window`, not a `WindowGroup`: one of it, addressed by id.")
105            .opacity(0.7),
106    ])
107    .padding(20.0)
108    .frame(320.0, 140.0)
109    .into_handle()
110}
examples/settings.rs (line 96)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
examples/inbox.rs (line 90)
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
examples/dashboard.rs (line 44)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
53
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
examples/swift_org_tutorial.rs (line 141)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
Source

pub fn font( self, size: f64, weight: Option<Weight>, design: Option<Design>, ) -> Self

.font(.system(size:weight:design:)) — Text.font(_:) on a Text.

Source

pub fn text_style(self, style: TextStyle) -> Self

.font(_:) with a built-in text style. On a Text this is Text.font(_:), which returns Text — so a chain like .text_style(.body).bold() stays a Text the way Swift’s does, instead of each step wrapping the last in an environment modifier.

Examples found in repository?
examples/inbox.rs (line 64)
60fn detail(i: usize) -> View {
61    let m = &MESSAGES[i];
62    vstack_aligned_spacing(
63        &[
64            text(m.subject).text_style(TextStyle::Title).bold(),
65            text!("From {}", m.from).fg_system(SystemColor::Gray),
66            divider(),
67            text("Body text would go here.").fg_system(SystemColor::Gray),
68            spacer(),
69        ],
70        HorizontalAlignment::Leading,
71        Some(12.0),
72    )
73    .padding(20.0)
74    .navigation_title(m.subject)
75}
More examples
Hide additional examples
examples/dynamic_ui.rs (line 71)
64pub fn body() -> View {
65    let text_src = current().lock().expect("spec").clone();
66    match spec::parse(&text_src).and_then(|nodes| spec::build(&nodes)) {
67        Ok(v) => v,
68        Err(e) => vstack_aligned_spacing(
69            &[
70                text("Could not build that screen")
71                    .text_style(TextStyle::Headline)
72                    .fg_system(SystemColor::Red),
73                text(&e).font_size(12.0).fg_system(SystemColor::Secondary),
74            ],
75            HorizontalAlignment::Leading,
76            Some(8.0),
77        )
78        .padding(20.0),
79    }
80}
examples/settings.rs (line 98)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
examples/dashboard.rs (line 41)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
53
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
examples/sugar.rs (line 22)
4fn main() {
5    let show_detail = true;
6    let items = vec![String::from("alpha"), String::from("beta")];
7
8    let sugared = swiftui! {
9        VStack(spacing: 8.0) {
10            Text("Title").text_style(.large_title)
11            if show_detail {
12                Text("the details")
13            }
14            ForEach(items) { item in
15                Text(item)
16            }
17        }
18    };
19
20    let by_hand = vstack_spacing(
21        &[
22            text("Title").text_style(views::TextStyle::LargeTitle),
23            conditional(show_detail, text("the details"), empty()),
24            for_each_items(&items, |item| text(item)),
25        ],
26        8.0,
27    );
28
29    let a = views::dump_value_to_depth(&sugared.into_handle(), 6);
30    let b = views::dump_value_to_depth(&by_hand.into_handle(), 6);
31    eprintln!("macro == hand-written? {}", a == b);
32    if a != b {
33        for (x, y) in a.lines().zip(b.lines()) {
34            if x != y {
35                eprintln!("  macro: {}\n  hand : {}", x.trim(), y.trim());
36                break;
37            }
38        }
39    }
40}
examples/swift_org_tutorial.rs (line 134)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
Source

pub fn font_named(self, name: &str, size: f64) -> Self

.font(.custom(_:size:))

Source

pub fn font_ref(self, font: &Font) -> Self

.font(_:) with a prebuilt views::Font, which is far cheaper than rebuilding the font for every view.

Source

pub fn bold(self) -> Self

.bold()

On a Text this is Text.bold(), which returns Text — the same type Swift produces, and the reason the documentation corpus compares equal. On anything else it is the View extension, which writes the environment so the text below inherits it.

Examples found in repository?
examples/inbox.rs (line 64)
60fn detail(i: usize) -> View {
61    let m = &MESSAGES[i];
62    vstack_aligned_spacing(
63        &[
64            text(m.subject).text_style(TextStyle::Title).bold(),
65            text!("From {}", m.from).fg_system(SystemColor::Gray),
66            divider(),
67            text("Body text would go here.").fg_system(SystemColor::Gray),
68            spacer(),
69        ],
70        HorizontalAlignment::Leading,
71        Some(12.0),
72    )
73    .padding(20.0)
74    .navigation_title(m.subject)
75}
76
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
More examples
Hide additional examples
examples/settings.rs (line 98)
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
examples/dashboard.rs (line 41)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
53
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
examples/swift_org_tutorial.rs (line 134)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
examples/todo.rs (line 90)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
examples/common/spec.rs (line 515)
487fn node_view(node: &Node) -> Result<View, String> {
488    let spacing = node.f64_attr("spacing").unwrap_or(8.0);
489    let base = match node.name.as_str() {
490        "vstack" => {
491            let kids = children(node)?;
492            match node.attr("align") {
493                Some(a) => vstack_aligned_spacing(&kids, h_align(a, node.line)?, Some(spacing)),
494                None => vstack_spacing(&kids, spacing),
495            }
496        }
497        "hstack" => {
498            let kids = children(node)?;
499            match node.attr("align") {
500                Some(a) => hstack_aligned_spacing(&kids, v_align(a, node.line)?, Some(spacing)),
501                None => hstack_spacing(&kids, spacing),
502            }
503        }
504        "zstack" => zstack_aligned(&children(node)?, align(node.attr("align").unwrap_or("center"), node.line)?),
505        "text" => {
506            let s = node.value.as_deref().unwrap_or("");
507            let mut v = text(s);
508            if let Some(style) = node.attr("style") {
509                v = v.text_style(text_style(style, node.line)?);
510            }
511            if let Some(size) = node.f64_attr("size") {
512                v = v.font_size(size);
513            }
514            if node.flag("bold") {
515                v = v.bold();
516            }
517            if node.flag("italic") {
518                v = v.italic();
519            }
520            if let Some(c) = node.attr("color") {
521                v = match tint(c, node.line)? {
522                    Tint::System(sc) => v.fg_system(sc),
523                    Tint::Literal(lc) => v.fg(lc),
524                };
525            }
526            v
527        }
528        "spacer" => spacer(),
529        "divider" => divider(),
530        // The action is a no-op on purpose: a spec read from a file has nowhere
531        // to put behaviour, and pretending otherwise would be worse than a
532        // button that visibly does nothing. `hot_reload.rs` is where a spec
533        // gains behaviour, by being reloaded.
534        "button" => button(node.value.as_deref().unwrap_or("Button"), || {}),
535        "color" => color(parse_color(node.value.as_deref().unwrap_or("#808080"), node.line)?),
536        "image" => system_image(node.value.as_deref().unwrap_or("star")).into_view(),
537        "rect" => match node.attr("color") {
538            Some(c) => match tint(c, node.line)? {
539                Tint::System(sc) => rectangle_shape().fill_system(sc),
540                Tint::Literal(lc) => rectangle_shape().fill(lc),
541            },
542            None => rectangle_shape().into_view(),
543        },
544        "circle" => match node.attr("color") {
545            Some(c) => match tint(c, node.line)? {
546                Tint::System(sc) => circle_shape().fill_system(sc),
547                Tint::Literal(lc) => circle_shape().fill(lc),
548            },
549            None => circle_shape().into_view(),
550        },
551        "capsule" => match node.attr("color") {
552            Some(c) => match tint(c, node.line)? {
553                Tint::System(sc) => capsule_shape().fill_system(sc),
554                Tint::Literal(lc) => capsule_shape().fill(lc),
555            },
556            None => capsule_shape().into_view(),
557        },
558        "progress" => progress(
559            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
560            node.f64_attr("total").unwrap_or(1.0),
561        ),
562        "gauge" => gauge(
563            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
564            node.f64_attr("min").unwrap_or(0.0),
565            node.f64_attr("max").unwrap_or(1.0),
566            text(node.attr("label").unwrap_or("")),
567        ),
568        "group_box" => group_box(stack_children(node)?),
569        "list" => list(stack_children(node)?),
570        "scroll" => stack_children(node)?.scroll(),
571        "form" => form(stack_children(node)?),
572        // Every bound control needs an explicit `@name`.
573        //
574        // Inventing one — from the line, or from position in the tree — looks
575        // friendlier and is a trap: adding a line above a `toggle` would
576        // change its derived name, and the control would silently reset on the
577        // next reload. A name the file states is a name that survives the file
578        // being edited, which is the entire point of the slots.
579        "toggle" => toggle_bound(
580            node.value.as_deref().unwrap_or("Toggle"),
581            &flag_slot(&require_slot(node)?, node.flag("on")),
582        ),
583        "slider" => {
584            let lo = node.f64_attr("min").unwrap_or(0.0);
585            let hi = node.f64_attr("max").unwrap_or(1.0);
586            slider_bound(
587                &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(lo)),
588                lo,
589                hi,
590            )
591        }
592        "stepper" => stepper_bound(
593            node.value.as_deref().unwrap_or("Stepper"),
594            &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(0.0)),
595            node.f64_attr("min").unwrap_or(0.0),
596            node.f64_attr("max").unwrap_or(100.0),
597            node.f64_attr("step").unwrap_or(1.0),
598        ),
599        "field" => textfield_bound(
600            node.value.as_deref().unwrap_or(""),
601            &string_slot(&require_slot(node)?, node.attr("text").unwrap_or("")),
602        ),
603        "label" => label(
604            node.value.as_deref().unwrap_or(""),
605            node.attr("icon").unwrap_or("star"),
606        ),
607        other => {
608            return Err(format!(
609                "line {}: no view called `{other}`; try one of {}",
610                node.line,
611                NAMES.join(", ")
612            ))
613        }
614    };
615    decorate(base, node)
616}
Source

pub fn italic(self) -> Self

.italic() — Text.italic() on a Text, the View extension otherwise.

Examples found in repository?
examples/common/spec.rs (line 518)
487fn node_view(node: &Node) -> Result<View, String> {
488    let spacing = node.f64_attr("spacing").unwrap_or(8.0);
489    let base = match node.name.as_str() {
490        "vstack" => {
491            let kids = children(node)?;
492            match node.attr("align") {
493                Some(a) => vstack_aligned_spacing(&kids, h_align(a, node.line)?, Some(spacing)),
494                None => vstack_spacing(&kids, spacing),
495            }
496        }
497        "hstack" => {
498            let kids = children(node)?;
499            match node.attr("align") {
500                Some(a) => hstack_aligned_spacing(&kids, v_align(a, node.line)?, Some(spacing)),
501                None => hstack_spacing(&kids, spacing),
502            }
503        }
504        "zstack" => zstack_aligned(&children(node)?, align(node.attr("align").unwrap_or("center"), node.line)?),
505        "text" => {
506            let s = node.value.as_deref().unwrap_or("");
507            let mut v = text(s);
508            if let Some(style) = node.attr("style") {
509                v = v.text_style(text_style(style, node.line)?);
510            }
511            if let Some(size) = node.f64_attr("size") {
512                v = v.font_size(size);
513            }
514            if node.flag("bold") {
515                v = v.bold();
516            }
517            if node.flag("italic") {
518                v = v.italic();
519            }
520            if let Some(c) = node.attr("color") {
521                v = match tint(c, node.line)? {
522                    Tint::System(sc) => v.fg_system(sc),
523                    Tint::Literal(lc) => v.fg(lc),
524                };
525            }
526            v
527        }
528        "spacer" => spacer(),
529        "divider" => divider(),
530        // The action is a no-op on purpose: a spec read from a file has nowhere
531        // to put behaviour, and pretending otherwise would be worse than a
532        // button that visibly does nothing. `hot_reload.rs` is where a spec
533        // gains behaviour, by being reloaded.
534        "button" => button(node.value.as_deref().unwrap_or("Button"), || {}),
535        "color" => color(parse_color(node.value.as_deref().unwrap_or("#808080"), node.line)?),
536        "image" => system_image(node.value.as_deref().unwrap_or("star")).into_view(),
537        "rect" => match node.attr("color") {
538            Some(c) => match tint(c, node.line)? {
539                Tint::System(sc) => rectangle_shape().fill_system(sc),
540                Tint::Literal(lc) => rectangle_shape().fill(lc),
541            },
542            None => rectangle_shape().into_view(),
543        },
544        "circle" => match node.attr("color") {
545            Some(c) => match tint(c, node.line)? {
546                Tint::System(sc) => circle_shape().fill_system(sc),
547                Tint::Literal(lc) => circle_shape().fill(lc),
548            },
549            None => circle_shape().into_view(),
550        },
551        "capsule" => match node.attr("color") {
552            Some(c) => match tint(c, node.line)? {
553                Tint::System(sc) => capsule_shape().fill_system(sc),
554                Tint::Literal(lc) => capsule_shape().fill(lc),
555            },
556            None => capsule_shape().into_view(),
557        },
558        "progress" => progress(
559            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
560            node.f64_attr("total").unwrap_or(1.0),
561        ),
562        "gauge" => gauge(
563            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
564            node.f64_attr("min").unwrap_or(0.0),
565            node.f64_attr("max").unwrap_or(1.0),
566            text(node.attr("label").unwrap_or("")),
567        ),
568        "group_box" => group_box(stack_children(node)?),
569        "list" => list(stack_children(node)?),
570        "scroll" => stack_children(node)?.scroll(),
571        "form" => form(stack_children(node)?),
572        // Every bound control needs an explicit `@name`.
573        //
574        // Inventing one — from the line, or from position in the tree — looks
575        // friendlier and is a trap: adding a line above a `toggle` would
576        // change its derived name, and the control would silently reset on the
577        // next reload. A name the file states is a name that survives the file
578        // being edited, which is the entire point of the slots.
579        "toggle" => toggle_bound(
580            node.value.as_deref().unwrap_or("Toggle"),
581            &flag_slot(&require_slot(node)?, node.flag("on")),
582        ),
583        "slider" => {
584            let lo = node.f64_attr("min").unwrap_or(0.0);
585            let hi = node.f64_attr("max").unwrap_or(1.0);
586            slider_bound(
587                &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(lo)),
588                lo,
589                hi,
590            )
591        }
592        "stepper" => stepper_bound(
593            node.value.as_deref().unwrap_or("Stepper"),
594            &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(0.0)),
595            node.f64_attr("min").unwrap_or(0.0),
596            node.f64_attr("max").unwrap_or(100.0),
597            node.f64_attr("step").unwrap_or(1.0),
598        ),
599        "field" => textfield_bound(
600            node.value.as_deref().unwrap_or(""),
601            &string_slot(&require_slot(node)?, node.attr("text").unwrap_or("")),
602        ),
603        "label" => label(
604            node.value.as_deref().unwrap_or(""),
605            node.attr("icon").unwrap_or("star"),
606        ),
607        other => {
608            return Err(format!(
609                "line {}: no view called `{other}`; try one of {}",
610                node.line,
611                NAMES.join(", ")
612            ))
613        }
614    };
615    decorate(base, node)
616}
Source

pub fn monospaced(self) -> Self

.monospaced() — Text.monospaced() on a Text.

Source

pub fn weight(self, weight: Weight) -> Self

.fontWeight(_:) — Text.fontWeight(_:) on a Text, which returns Text, and the View extension otherwise.

Source

pub fn fg(self, c: Color) -> Self

.foregroundStyle(_:) On a Text this is Text.foregroundColor(_:), which returns Text.

Examples found in repository?
examples/swift_org_tutorial.rs (line 142)
129fn body() -> View {
130    let colour = COLORS[COLOR.load(Ordering::Relaxed) % COLORS.len()];
131
132    vstack![
133        // Text("Why not try…").font(.largeTitle.bold())
134        text("Why not try…").text_style(TextStyle::LargeTitle).bold(),
135        vstack![
136            // Circle().fill(colors.randomElement() ?? .blue).padding().overlay(…)
137            circle_shape().fill_system(colour).padding(16.0).overlay(
138                // Image(systemName: "figure.\(selected.lowercased())")
139                //     .font(.system(size: 144)).foregroundColor(.white)
140                image!("figure.{}", selected().to_lowercase())
141                    .font_size(144.0)
142                    .fg(Color::WHITE),
143            ),
144            // Text("\(selected)!").font(.title)
145            text!("{}!", selected()).text_style(TextStyle::Title),
146        ]
147        .transition(Transition::Slide)
148        .id(ID.load(Ordering::Relaxed)),
149        spacer(),
150        // Button("Try again") { … }.buttonStyle(.borderedProminent)
151        button("Try again", try_again).button_style(ButtonStyle::BorderedProminent),
152    ]
153}
More examples
Hide additional examples
examples/common/spec.rs (line 523)
487fn node_view(node: &Node) -> Result<View, String> {
488    let spacing = node.f64_attr("spacing").unwrap_or(8.0);
489    let base = match node.name.as_str() {
490        "vstack" => {
491            let kids = children(node)?;
492            match node.attr("align") {
493                Some(a) => vstack_aligned_spacing(&kids, h_align(a, node.line)?, Some(spacing)),
494                None => vstack_spacing(&kids, spacing),
495            }
496        }
497        "hstack" => {
498            let kids = children(node)?;
499            match node.attr("align") {
500                Some(a) => hstack_aligned_spacing(&kids, v_align(a, node.line)?, Some(spacing)),
501                None => hstack_spacing(&kids, spacing),
502            }
503        }
504        "zstack" => zstack_aligned(&children(node)?, align(node.attr("align").unwrap_or("center"), node.line)?),
505        "text" => {
506            let s = node.value.as_deref().unwrap_or("");
507            let mut v = text(s);
508            if let Some(style) = node.attr("style") {
509                v = v.text_style(text_style(style, node.line)?);
510            }
511            if let Some(size) = node.f64_attr("size") {
512                v = v.font_size(size);
513            }
514            if node.flag("bold") {
515                v = v.bold();
516            }
517            if node.flag("italic") {
518                v = v.italic();
519            }
520            if let Some(c) = node.attr("color") {
521                v = match tint(c, node.line)? {
522                    Tint::System(sc) => v.fg_system(sc),
523                    Tint::Literal(lc) => v.fg(lc),
524                };
525            }
526            v
527        }
528        "spacer" => spacer(),
529        "divider" => divider(),
530        // The action is a no-op on purpose: a spec read from a file has nowhere
531        // to put behaviour, and pretending otherwise would be worse than a
532        // button that visibly does nothing. `hot_reload.rs` is where a spec
533        // gains behaviour, by being reloaded.
534        "button" => button(node.value.as_deref().unwrap_or("Button"), || {}),
535        "color" => color(parse_color(node.value.as_deref().unwrap_or("#808080"), node.line)?),
536        "image" => system_image(node.value.as_deref().unwrap_or("star")).into_view(),
537        "rect" => match node.attr("color") {
538            Some(c) => match tint(c, node.line)? {
539                Tint::System(sc) => rectangle_shape().fill_system(sc),
540                Tint::Literal(lc) => rectangle_shape().fill(lc),
541            },
542            None => rectangle_shape().into_view(),
543        },
544        "circle" => match node.attr("color") {
545            Some(c) => match tint(c, node.line)? {
546                Tint::System(sc) => circle_shape().fill_system(sc),
547                Tint::Literal(lc) => circle_shape().fill(lc),
548            },
549            None => circle_shape().into_view(),
550        },
551        "capsule" => match node.attr("color") {
552            Some(c) => match tint(c, node.line)? {
553                Tint::System(sc) => capsule_shape().fill_system(sc),
554                Tint::Literal(lc) => capsule_shape().fill(lc),
555            },
556            None => capsule_shape().into_view(),
557        },
558        "progress" => progress(
559            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
560            node.f64_attr("total").unwrap_or(1.0),
561        ),
562        "gauge" => gauge(
563            node.value.as_deref().and_then(|v| v.parse().ok()).unwrap_or(0.5),
564            node.f64_attr("min").unwrap_or(0.0),
565            node.f64_attr("max").unwrap_or(1.0),
566            text(node.attr("label").unwrap_or("")),
567        ),
568        "group_box" => group_box(stack_children(node)?),
569        "list" => list(stack_children(node)?),
570        "scroll" => stack_children(node)?.scroll(),
571        "form" => form(stack_children(node)?),
572        // Every bound control needs an explicit `@name`.
573        //
574        // Inventing one — from the line, or from position in the tree — looks
575        // friendlier and is a trap: adding a line above a `toggle` would
576        // change its derived name, and the control would silently reset on the
577        // next reload. A name the file states is a name that survives the file
578        // being edited, which is the entire point of the slots.
579        "toggle" => toggle_bound(
580            node.value.as_deref().unwrap_or("Toggle"),
581            &flag_slot(&require_slot(node)?, node.flag("on")),
582        ),
583        "slider" => {
584            let lo = node.f64_attr("min").unwrap_or(0.0);
585            let hi = node.f64_attr("max").unwrap_or(1.0);
586            slider_bound(
587                &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(lo)),
588                lo,
589                hi,
590            )
591        }
592        "stepper" => stepper_bound(
593            node.value.as_deref().unwrap_or("Stepper"),
594            &number_slot(&require_slot(node)?, node.f64_attr("value").unwrap_or(0.0)),
595            node.f64_attr("min").unwrap_or(0.0),
596            node.f64_attr("max").unwrap_or(100.0),
597            node.f64_attr("step").unwrap_or(1.0),
598        ),
599        "field" => textfield_bound(
600            node.value.as_deref().unwrap_or(""),
601            &string_slot(&require_slot(node)?, node.attr("text").unwrap_or("")),
602        ),
603        "label" => label(
604            node.value.as_deref().unwrap_or(""),
605            node.attr("icon").unwrap_or("star"),
606        ),
607        other => {
608            return Err(format!(
609                "line {}: no view called `{other}`; try one of {}",
610                node.line,
611                NAMES.join(", ")
612            ))
613        }
614    };
615    decorate(base, node)
616}
Source

pub fn baseline_offset(self, amount: f64) -> Self

Text.baselineOffset(_:)

Source

pub fn fg_system(self, c: SystemColor) -> Self

.foregroundColor(_:) with one of SwiftUI’s named colours.

Not the same modifier as View::fg, and not a colour that components can spell: see views::system_color.

Examples found in repository?
examples/inbox.rs (line 65)
60fn detail(i: usize) -> View {
61    let m = &MESSAGES[i];
62    vstack_aligned_spacing(
63        &[
64            text(m.subject).text_style(TextStyle::Title).bold(),
65            text!("From {}", m.from).fg_system(SystemColor::Gray),
66            divider(),
67            text("Body text would go here.").fg_system(SystemColor::Gray),
68            spacer(),
69        ],
70        HorizontalAlignment::Leading,
71        Some(12.0),
72    )
73    .padding(20.0)
74    .navigation_title(m.subject)
75}
76
77fn row(i: usize) -> View {
78    let m = &MESSAGES[i];
79    hstack_spacing(
80        &[
81            // An unread dot, or the space where one would be.
82            view_if!(
83                m.unread,
84                circle_shape().fill_system(SystemColor::Blue).frame(8.0, 8.0),
85                empty().frame(8.0, 8.0)
86            ),
87            vstack_aligned(
88                &[
89                    text(m.from).bold(),
90                    text(m.subject).font_size(12.0).fg_system(SystemColor::Gray),
91                ],
92                HorizontalAlignment::Leading,
93            ),
94            spacer(),
95        ],
96        8.0,
97    )
98    .padding_edges(EdgeSet::Vertical, Some(4.0))
99    .a11y_label(&format!("{}, {}", m.from, m.subject))
100    .a11y_hint(if m.unread { "Unread" } else { "Read" })
101}
More examples
Hide additional examples
examples/dynamic_ui.rs (line 72)
64pub fn body() -> View {
65    let text_src = current().lock().expect("spec").clone();
66    match spec::parse(&text_src).and_then(|nodes| spec::build(&nodes)) {
67        Ok(v) => v,
68        Err(e) => vstack_aligned_spacing(
69            &[
70                text("Could not build that screen")
71                    .text_style(TextStyle::Headline)
72                    .fg_system(SystemColor::Red),
73                text(&e).font_size(12.0).fg_system(SystemColor::Secondary),
74            ],
75            HorizontalAlignment::Leading,
76            Some(8.0),
77        )
78        .padding(20.0),
79    }
80}
examples/hot_reload.rs (line 107)
96fn body() -> View {
97    let (src, error, generation, micros) = {
98        let g = state_cell().lock().expect("state");
99        (g.last_good.clone(), g.error.clone(), g.generation, g.micros)
100    };
101
102    // The last version that parsed. It cannot fail — it parsed before — but a
103    // spec that builds views from slots could in principle, so the fallback is
104    // still handled rather than unwrapped.
105    let screen = spec::parse(&src)
106        .and_then(|nodes| spec::build(&nodes))
107        .unwrap_or_else(|e| text(&e).fg_system(SystemColor::Red).padding(20.0));
108
109    vstack_spacing(&[screen, status(error.as_deref(), generation, micros)], 0.0)
110}
111
112/// A strip along the bottom: which generation is on screen, how long the last
113/// reload took, what the slots hold, and the error if there is one.
114///
115/// In the window rather than the terminal because that is where you are
116/// looking. Watching a reloader work from a log means watching two things.
117fn status(error: Option<&str>, generation: u64, micros: u64) -> View {
118    let slots = spec::slot_summary();
119    let slot_line = if slots.is_empty() {
120        String::new()
121    } else {
122        slots
123            .iter()
124            .map(|(k, v)| format!("{k}={v}"))
125            .collect::<Vec<_>>()
126            .join("  ")
127    };
128
129    // The error row is *always* present, empty when there is nothing wrong.
130    // An error that appears and disappears would otherwise reflow the screen
131    // above it on every save — which looks exactly like the reloader having
132    // replaced the view, and makes "did the screen survive this?" impossible
133    // to answer by looking.
134    let rows = vec![
135        divider(),
136        hstack_spacing(
137            &[
138                circle_shape()
139                    .fill_system(if error.is_some() {
140                        SystemColor::Orange
141                    } else {
142                        SystemColor::Clear
143                    })
144                    .frame(8.0, 8.0),
145                text(error.unwrap_or(""))
146                    .font_size(11.0)
147                    .fg_system(SystemColor::Orange),
148                spacer(),
149            ],
150            6.0,
151        )
152        .padding(6.0)
153        .frame(348.0, 24.0),
154        hstack_spacing(
155            &[
156                circle_shape()
157                    .fill_system(if error.is_some() {
158                        SystemColor::Orange
159                    } else {
160                        SystemColor::Green
161                    })
162                    .frame(8.0, 8.0),
163                text(&format!("gen {generation}"))
164                    .font_size(11.0)
165                    .fg_system(SystemColor::Secondary),
166                // Microseconds below a millisecond: a reload of a short spec
167                // really is that fast, and "0.0 ms" reads as "not measured".
168                text(&if micros < 1000 {
169                    format!("{micros} \u{b5}s")
170                } else {
171                    format!("{:.1} ms", micros as f64 / 1000.0)
172                })
173                .font_size(11.0)
174                .fg_system(SystemColor::Secondary),
175                spacer(),
176                text(&slot_line).font_size(11.0).fg_system(SystemColor::Secondary),
177            ],
178            8.0,
179        )
180        .padding(6.0)
181        .frame(348.0, 24.0),
182    ];
183    vstack_spacing(&rows, 0.0)
184}
examples/dashboard.rs (line 44)
28fn tile(i: usize) -> View {
29    let value = reading(i);
30    vstack_spacing(
31        &[
32            zstack![
33                circle_shape().stroke_system(SystemColor::Gray, 6.0).opacity(0.25),
34                // The filled part: the same circle trimmed to the fraction, and
35                // turned so the arc starts at the top rather than at three
36                // o'clock.
37                circle_shape()
38                    .trim(0.0, value)
39                    .stroke_system(TINTS[i], 6.0)
40                    .rotate(-90.0),
41                text!("{:.0}", value * 100.0).text_style(TextStyle::Title2).bold(),
42            ]
43            .frame(72.0, 72.0),
44            text(LABELS[i]).font_size(12.0).fg_system(SystemColor::Gray),
45        ],
46        8.0,
47    )
48    .padding(12.0)
49    .a11y_element(AccessibilityChildBehavior::Combine)
50    .a11y_label(LABELS[i])
51    .a11y_value(&format!("{:.0} percent", value * 100.0))
52}
53
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
examples/todo.rs (line 67)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
82
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
examples/settings.rs (line 62)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
86
87/// The sheet, which the user can dismiss — the flag is Rust's, so closing it
88/// writes `false` back rather than leaving the two sides disagreeing.
89fn about_panel() -> View {
90    let s = settings();
91    vstack_spacing(
92        &[
93            system_image("gearshape.fill")
94                .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
95                .view()
96                .font_size(48.0)
97                .fg_system(SystemColor::Blue),
98            text("Settings").text_style(TextStyle::Title).bold(),
99            text!("Signed in as {}", s.name.get()).fg_system(SystemColor::Gray),
100            spacer(),
101            button("Done", hide_about).button_style(views::ButtonStyle::BorderedProminent),
102        ],
103        16.0,
104    )
105    .padding(24.0)
106    .presentation_detents(&[views::PresentationDetent::Medium])
107    .presentation_drag_indicator(Visibility::Visible)
108}
Source

pub fn fg_linear_gradient( self, colors: &[Color], start: (f64, f64), end: (f64, f64), ) -> Self

.foregroundStyle(LinearGradient(colors:startPoint:endPoint:)) — text and symbols painted with a gradient instead of a flat colour.

Unit points, as in View::bg_linear_gradient. On a Text this is Text.foregroundStyle(_:), which returns Text.

Source

pub fn kerning(self, amount: f64) -> Self

.kerning(_:) — Text.kerning(_:) on a Text, which returns Text.

Source

pub fn tracking(self, amount: f64) -> Self

.tracking(_:) — like kerning, but not suppressed between the pairs the font has a ligature for.

Source

pub fn line_spacing(self, amount: f64) -> Self

.lineSpacing(_:)

Source

pub fn line_limit(self, limit: i64) -> Self

.lineLimit(_:)

Source

pub fn text_align(self, align: TextAlign) -> Self

.multilineTextAlignment(_:)

Source

pub fn autocorrection_disabled(self, disable: Option<bool>) -> Self

.disableAutocorrection(_:) — None restores the system default.

Named for the modern spelling because that is what a caller looks for, but autocorrectionDisabled(_:) is inlined and exports no symbol — this reaches disableAutocorrection(_:), which is the same modifier and the one SwiftUI still exports.

Source

pub fn text_scale(self, scale: TextScale, enabled: bool) -> Self

.textScale(_:isEnabled:)

Source

pub fn dynamic_type_size(self, size: DynamicTypeSize) -> Self

.dynamicTypeSize(_:) — pin the size class rather than following the system setting.

Source

pub fn accent_color(self, color: Option<Color>) -> Self

.accentColor(_:) — None restores the inherited accent.

Deprecated in SwiftUI in favour of View::tint, and kept because the documentation still shows it.

Source

pub fn underline(self) -> Self

.underline()

Source

pub fn underline_styled( self, active: bool, pattern: LinePattern, color: Option<Color>, ) -> Self

.underline(_:pattern:color:) — None keeps the text’s own colour.

active is not decoration: this writes the environment, so passing false is how a subtree turns off an underline it would otherwise inherit. There is no other way to say that.

Source

pub fn strikethrough(self) -> Self

.strikethrough()

Source

pub fn strikethrough_styled( self, active: bool, pattern: LinePattern, color: Option<Color>, ) -> Self

.strikethrough(_:pattern:color:) — active: false turns off an inherited strikethrough, as with View::underline_styled.

Examples found in repository?
examples/todo.rs (line 72)
59fn row(i: usize, it: &Item) -> View {
60    hstack_spacing(
61        &[
62            // The checkmark is the button, so the whole symbol is the target.
63            button_labelled(
64                system_image(if it.done { "checkmark.circle.fill" } else { "circle" })
65                    .symbol_rendering_mode(Some(views::SymbolRenderingMode::Hierarchical))
66                    .view()
67                    .fg_system(if it.done { SystemColor::Green } else { SystemColor::Gray }),
68                move || toggle(i),
69            )
70            .button_style(views::ButtonStyle::Bordered),
71            text(&it.title)
72                .strikethrough_styled(it.done, LinePattern::Solid, None)
73                .fg_system(if it.done { SystemColor::Gray } else { SystemColor::Primary }),
74            spacer(),
75        ],
76        10.0,
77    )
78    .padding_edges(EdgeSet::Vertical, Some(6.0))
79    .a11y_label(&it.title)
80    .a11y_value(if it.done { "Done" } else { "Not done" })
81}
Source

pub fn truncation_mode(self, mode: TruncationMode) -> Self

.truncationMode(_:) — which end of over-long text gets the ellipsis.

Source

pub fn line_height(self, height: Option<LineHeightKind>) -> Self

.lineHeight(_:) — None restores the font’s own leading.

Source

pub fn font_design(self, design: Design) -> Self

.fontDesign(_:) — .monospaced and friends, without restating the size.

Source

pub fn font_width(self, width: Option<FontWidth>) -> Self

.fontWidth(_:) — None restores the default width.

Source

pub fn redacted(self, reasons: RedactionReasons) -> Self

.redacted(reason:) — the placeholder treatment, for loading states.

Source

pub fn text_field_style(self, style: TextFieldStyle) -> Self

.textFieldStyle(_:) — .roundedBorder is the one that looks like a field rather than a line of text.

Examples found in repository?
examples/settings.rs (lines 51-53)
43fn body() -> View {
44    let s = settings();
45
46    form![
47        section![header: text("Account");
48            hstack![
49                text("Name"),
50                spacer(),
51                textfield_bound("Your name", &s.name).text_field_style(
52                    views::TextFieldStyle::RoundedBorderTextFieldStyle,
53                ),
54            ],
55            toggle_bound("Notifications", &s.notify),
56        ],
57        section![header: text("Playback");
58            vstack_aligned(&[
59                hstack![
60                    text("Volume"),
61                    spacer(),
62                    text!("{:.0}%", s.volume.get() * 100.0).fg_system(SystemColor::Gray),
63                ],
64                slider_bound(&s.volume, 0.0, 1.0),
65            ], HorizontalAlignment::Leading),
66            stepper_bound("Refresh every", &s.refresh, 1.0, 60.0, 1.0),
67        ],
68        section![header: text("Appearance");
69            picker_bound!(
70                "Theme",
71                &s.theme,
72                text(THEMES[0]).tag_int(0),
73                text(THEMES[1]).tag_int(1),
74                text(THEMES[2]).tag_int(2),
75            )
76            .picker_style(PickerStyle::InlinePickerStyle),
77        ],
78        section![
79            button("About", show_about)
80                .a11y_hint("Opens a panel describing this app"),
81        ],
82    ]
83    .form_style(FormStyle::GroupedFormStyle)
84    .sheet_bound(&s.about, about_panel())
85}
More examples
Hide additional examples
examples/todo.rs (line 97)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn submit_label(self, label: SubmitLabel) -> Self

.submitLabel(_:) — what the return key says.

Examples found in repository?
examples/todo.rs (line 99)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn on_submit( self, trigger: SubmitTrigger, action: impl Fn() + 'static, ) -> Self

.onSubmit(of:_:) — the return key, or a search field’s, or a collection’s, depending on the trigger.

Examples found in repository?
examples/todo.rs (line 98)
83fn body() -> View {
84    let todos = items().lock().unwrap().clone();
85    let remaining = todos.iter().filter(|i| !i.done).count();
86
87    vstack_aligned_spacing(
88        &[
89            hstack![
90                text("Todo").text_style(TextStyle::LargeTitle).bold(),
91                spacer(),
92                text!("{remaining} left").fg_system(SystemColor::Gray),
93            ],
94            hstack_spacing(
95                &[
96                    textfield_bound("What needs doing?", draft())
97                        .text_field_style(views::TextFieldStyle::RoundedBorderTextFieldStyle)
98                        .on_submit(SubmitTrigger::Text, add)
99                        .submit_label(SubmitLabel::Done),
100                    button("Add", add).button_style(views::ButtonStyle::BorderedProminent),
101                ],
102                8.0,
103            ),
104            // The empty state is a branch, so it arrives and leaves rather than
105            // appearing from nothing.
106            view_if!(
107                todos.is_empty(),
108                vstack_spacing(
109                    &[
110                        system_image("checkmark.seal").view().font_size(40.0)
111                            .fg_system(SystemColor::Green),
112                        text("Nothing left to do").fg_system(SystemColor::Gray),
113                    ],
114                    8.0,
115                )
116                .frame_optional(None, Some(160.0), Alignment::Center)
117                .transition(Transition::ScaleWithOpacity { scale: 0.8, anchor: (0.5, 0.5) }),
118                list(for_each_items(
119                    &todos.iter().cloned().enumerate().collect::<Vec<_>>(),
120                    |(i, it)| row(*i, it),
121                ))
122                .list_style(views::ListStyle::PlainListStyle)
123            ),
124        ],
125        HorizontalAlignment::Leading,
126        Some(14.0),
127    )
128    .padding(20.0)
129}
Source

pub fn text_content_type(self, kind: Option<TextContentKind>) -> Self

.textContentType(_:) — what the field holds, which is what lets the system offer a saved password or a one-time code. None clears it.

Source

pub fn keyboard_shortcut(self, shortcut: KeyboardShortcut) -> Self

.keyboardShortcut(_:) — .defaultAction is return, .cancelAction is escape, which is what makes a button the one a sheet’s return key hits.

Examples found in repository?
examples/inbox.rs (line 119)
110fn body() -> View {
111    let i = inbox();
112    let rows = matching();
113    navigation_stack(
114        list(for_each_items(&rows, |&i| linked_row(i)))
115        .list_style(views::ListStyle::InsetListStyle)
116        .searchable(&i.query, &i.searching, SearchFieldPlacement::Automatic, "Search"),
117    )
118    .navigation_title("Inbox")
119    .toolbar(button("Compose", || {}).keyboard_shortcut(KeyboardShortcut::DefaultAction))
120}
More examples
Hide additional examples
examples/dashboard.rs (line 74)
54fn body() -> View {
55    vstack_aligned_spacing(
56        &[
57            text("System").text_style(TextStyle::LargeTitle).bold(),
58            grid(&[grid_row(&[tile(0), tile(1), tile(2)])]),
59            divider(),
60            // A gauge over the busiest reading, which is a different control
61            // from the rings and reads the same state.
62            vstack_aligned(
63                &[
64                    text("Busiest").font_size(12.0).fg_system(SystemColor::Gray),
65                    gauge(reading(1), 0.0, 1.0, text("Memory"))
66                        .gauge_style(views::GaugeStyle::AccessoryLinearCapacityGaugeStyle)
67                        .tint_system(SystemColor::Orange),
68                ],
69                HorizontalAlignment::Leading,
70            ),
71            spacer(),
72            button("Refresh", refresh)
73                .button_style(views::ButtonStyle::BorderedProminent)
74                .keyboard_shortcut(KeyboardShortcut::DefaultAction),
75        ],
76        HorizontalAlignment::Leading,
77        Some(16.0),
78    )
79    .padding(20.0)
80    // Animate whatever changed, rather than snapping to the new reading.
81    .animation(LOAD[0].load(Ordering::Relaxed) as i64)
82}
Source

pub fn list_row_background(self, background: Option<View>) -> Self

.listRowBackground(_:) — None restores the default.

Source§

impl View

Source

pub fn new(handle: ViewHandle) -> Self

Wrap a handle so the chainable modifiers can be used on it.

Source

pub fn handle(&self) -> &ViewHandle

Get the underlying handle.

Source

pub fn into_handle(self) -> ViewHandle

Consume and return the handle.

Examples found in repository?
examples/dashboard.rs (line 99)
98fn content_view() -> swiftui_native::ViewHandle {
99    state::root_view(|_| body().into_handle())
100}
More examples
Hide additional examples
examples/inbox.rs (line 123)
122fn content_view() -> swiftui_native::ViewHandle {
123    state::root_view(|_| body().into_handle())
124}
examples/settings.rs (line 121)
120fn content_view() -> swiftui_native::ViewHandle {
121    state::root_view(|_| body().into_handle())
122}
examples/todo.rs (line 132)
131fn content_view() -> swiftui_native::ViewHandle {
132    state::root_view(|_| body().into_handle())
133}
examples/swift_org_tutorial.rs (line 176)
175fn content_view() -> swiftui_native::ViewHandle {
176    state::root_view(|_generation| body().into_handle())
177}
examples/dynamic_ui.rs (line 83)
82fn content_view() -> swiftui_native::ViewHandle {
83    swiftui_native::state::root_view(|_| body().into_handle())
84}
85
86/// Screens written here as *data*, not as Rust.
87///
88/// Each is a string this file could have read from disk instead; they are
89/// inline so the example runs with no arguments and so the renders are
90/// reproducible. Between them they reach stacks, shapes, controls, text
91/// styling and nesting — the same span the hand-written examples cover, with
92/// nothing about them in the compiled code.
93const DEMOS: &[(&str, &str)] = &[
94    (
95        "readout",
96        r#"
97// A status readout. Nothing here is a Rust type.
98vstack spacing=14 pad=20 align=leading {
99  text "Deployment" style=large_title bold
100  text "3 of 4 regions healthy" color=secondary size=13
101
102  divider
103
104  hstack spacing=12 {
105    circle color=green frame=14x14
106    text "us-east" size=14
107    spacer
108    text "ok" color=green size=13
109  }
110  hstack spacing=12 {
111    circle color=green frame=14x14
112    text "us-west" size=14
113    spacer
114    text "ok" color=green size=13
115  }
116  hstack spacing=12 {
117    circle color=orange frame=14x14
118    text "eu-central" size=14
119    spacer
120    text "degraded" color=orange size=13
121  }
122  hstack spacing=12 {
123    circle color=gray frame=14x14
124    text "ap-south" size=14
125    spacer
126    text "draining" color=gray size=13
127  }
128
129  divider
130  text "Rollout" size=12 color=secondary
131  progress 0.62
132  spacer
133  button "Promote"
134}
135"#,
136    ),
137    (
138        "card",
139        r#"
140// A card, to show layering and a hex colour.
141zstack align=center frame=320x200 {
142  color #1d2b53 frame=300x180 corner=16
143  vstack spacing=10 pad=24 align=leading {
144    text "Boarding pass" style=title2 bold color=white
145    text "LHR to SFO" color=white size=14 opacity=0.8
146    spacer
147    hstack spacing=16 {
148      vstack spacing=2 align=leading {
149        text "GATE" size=10 color=white opacity=0.6
150        text "B14" style=title3 bold color=white
151      }
152      vstack spacing=2 align=leading {
153        text "SEAT" size=10 color=white opacity=0.6
154        text "22A" style=title3 bold color=white
155      }
156      spacer
157      image "airplane"
158    }
159  }
160}
161"#,
162    ),
163    (
164        "gauges",
165        r#"
166// Three gauges and a grouped block, from data alone.
167vstack spacing=16 pad=20 align=leading {
168  text "Capacity" style=title bold
169  gauge 0.34 label="CPU"
170  gauge 0.71 label="Memory"
171  gauge 0.12 label="Disk"
172  divider
173  group_box {
174    vstack spacing=6 align=leading {
175      text "Notes" style=headline
176      text "Every view on this screen was named by a string." size=12 color=secondary
177      text "The binary has no VStack<...> type baked in for it." size=12 color=secondary
178    }
179  }
180  spacer
181}
182"#,
183    ),
184];
185
186fn demo(name: &str) -> Option<&'static str> {
187    DEMOS.iter().find(|(n, _)| *n == name).map(|(_, s)| *s)
188}
189
190/// Read a spec from a path, a demo name, or stdin for `-`.
191fn load(arg: &str) -> Result<String, String> {
192    if arg == "-" {
193        use std::io::Read;
194        let mut s = String::new();
195        std::io::stdin().read_to_string(&mut s).map_err(|e| e.to_string())?;
196        return Ok(s);
197    }
198    if let Some(d) = demo(arg) {
199        return Ok(d.to_string());
200    }
201    std::fs::read_to_string(arg).map_err(|e| format!("{arg}: {e}"))
202}
203
204/// Read specs from stdin and render each as it arrives.
205///
206/// A blank line submits. This is the shortest demonstration there is: the same
207/// process, still running, drawing a screen typed a moment ago.
208fn repl() {
209    use std::io::{BufRead, Write};
210    eprintln!("Type a screen. Blank line renders it; Ctrl-D quits.");
211    eprintln!("Names: {}", spec::NAMES.join(" "));
212    let stdin = std::io::stdin();
213    let mut buf = String::new();
214    let mut n = 0usize;
215    loop {
216        eprint!("> ");
217        let _ = std::io::stderr().flush();
218        let mut line = String::new();
219        match stdin.lock().read_line(&mut line) {
220            Ok(0) => break,
221            Ok(_) => {}
222            Err(e) => {
223                eprintln!("{e}");
224                break;
225            }
226        }
227        if line.trim().is_empty() {
228            if buf.trim().is_empty() {
229                continue;
230            }
231            match spec::parse(&buf).and_then(|nodes| spec::build(&nodes)) {
232                Ok(v) => {
233                    n += 1;
234                    let out = format!(
235                        "{}/../../target/dynamic_ui_repl_{n}.png",
236                        env!("CARGO_MANIFEST_DIR")
237                    );
238                    let handle = v.into_handle();
239                    eprintln!("  {}", swiftui_native::diag::type_name(
240                        swiftui_native::views::meta_of(&handle)
241                    ));
242                    if swiftui_native::render::render(&handle, 420, 420).write_png(&out) {
243                        eprintln!("  wrote {out}");
244                    }
245                }
246                Err(e) => eprintln!("  {e}"),
247            }
248            buf.clear();
249        } else {
250            buf.push_str(&line);
251        }
252    }
253}
254
255/// Print the Swift type a spec builds.
256///
257/// The strongest short proof that this is real SwiftUI and not a lookalike: the
258/// name comes from the Swift runtime's own metadata, and it is a different name
259/// for every different spec.
260fn print_type(arg: &str) -> i32 {
261    match load(arg).and_then(|s| {
262        spec::parse(&s).and_then(|nodes| spec::build(&nodes)).map(|v| v.into_handle())
263    }) {
264        Ok(h) => {
265            println!(
266                "{}",
267                swiftui_native::diag::type_name(swiftui_native::views::meta_of(&h))
268            );
269            0
270        }
271        Err(e) => {
272            eprintln!("{e}");
273            1
274        }
275    }
276}
277
278#[cfg(target_os = "macos")]
279fn main() {
280    let args: Vec<String> = std::env::args().skip(1).collect();
281    let flag = |f: &str| args.iter().any(|a| a == f);
282
283    if flag("--names") {
284        println!("{}", spec::NAMES.join("\n"));
285        return;
286    }
287    if flag("--repl") {
288        return repl();
289    }
290    if let Some(i) = args.iter().position(|a| a == "--type") {
291        let Some(arg) = args.get(i + 1) else {
292            eprintln!("--type wants a spec: a path, `-`, or a demo name");
293            std::process::exit(2);
294        };
295        std::process::exit(print_type(arg));
296    }
297    if flag("--render") {
298        // One PNG per built-in spec. Different text, different Swift type,
299        // different picture — from one binary, in one process.
300        for (name, src) in DEMOS {
301            set_spec(src);
302            // The spec's own view, for the type name: `content_view` wraps it
303            // in the runtime-synthesised `RustView` that carries `@State`, and
304            // that wrapper is the same whatever the spec says. What differs —
305            // and what makes the point — is the type underneath it.
306            let built = body().into_handle();
307            let out = format!("{}/../../target/dynamic_ui_{name}.png", env!("CARGO_MANIFEST_DIR"));
308            let ok = swiftui_native::render::render(&content_view(), 380, 420).write_png(&out);
309            println!(
310                "{name:10} {}\n           {}",
311                swiftui_native::diag::type_name(swiftui_native::views::meta_of(&built)),
312                if ok { out } else { "render failed".to_string() }
313            );
314        }
315        return;
316    }
317    if flag("--sim") {
318        return simulator::main(&simulator::Bundle {
319            example: "dynamic_ui",
320            bundle_id: "dev.rswift.DynamicUI",
321            executable: "DynamicUI",
322            display_name: "Dynamic UI",
323            launch_args: &[],
324        });
325    }
326
327    // A path or a demo name, else the first demo.
328    if let Some(arg) = args.iter().find(|a| !a.starts_with("--")) {
329        match load(arg) {
330            Ok(s) => set_spec(&s),
331            Err(e) => {
332                eprintln!("{e}");
333                std::process::exit(1);
334            }
335        }
336    }
337    show_window(&content_view(), "Dynamic UI", 380.0, 460.0);
338}

Trait Implementations§

Source§

impl Debug for View

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl IntoView for View

Auto Trait Implementations§

§

impl !Sync for View

§

impl Freeze for View

§

impl RefUnwindSafe for View

§

impl Send for View

§

impl Unpin for View

§

impl UnsafeUnpin for View

§

impl UnwindSafe for View

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.