pub struct StatefulView {
pub metadata: *const c_void,
pub witness_table: *const c_void,
pub id: i64,
/* private fields */
}Expand description
A runtime-built Swift view type with a real @State.
SwiftUI installs the storage itself: it walks the type’s reflection field
records looking for a stored property whose type conforms to
DynamicProperty, finds the State<Int>, and attaches a location box. That
is what makes set invalidate the view and re-run the body,
and what lets set_animated interpolate — a @State
change is a change to a view SwiftUI already knows, unlike a root swap.
The catch is how quietly that walk fails. If the field’s mangled type name
does not demangle, the runtime reports the field as an empty tuple, SwiftUI
finds no DynamicProperty, and everything still works — the body runs
once, writes report success — except nothing ever updates. See the layout
assertions in build_type.
§Several at once
The body witness is one extern "C" function with no room for an instance
parameter, so the struct carries a second stored field holding an id. The
witness reads it and looks the right builder up, which is what lets more
than one StatefulView be live at a time.
Fields§
§metadata: *const c_voidMetadata for the synthesised struct.
witness_table: *const c_voidIts View witness table.
id: i64Identifies this instance to the shared body witness.
Implementations§
Source§impl StatefulView
impl StatefulView
Sourcepub fn new(
initial: i64,
builder: impl Fn(i64) -> ViewHandle + Send + 'static,
) -> Self
pub fn new( initial: i64, builder: impl Fn(i64) -> ViewHandle + Send + 'static, ) -> Self
Build the type and one instance of it.
builder receives the current state value every time SwiftUI evaluates
the body.
Hosting the result works: examples/parity’s state_rebuild check
hosts one, writes to it three times, and asserts the body saw each new
value. An earlier note here said it faulted in a value witness — that was
true of the first attempt, which borrowed State<Int>’s witness table;
the module docs explain why that cannot work and what replaced it.
Examples found in repository?
54fn root_view() -> views::ViewHandle {
55 thread_local! {
56 static ROOT: std::cell::OnceCell<swiftui_native::state::StatefulView> =
57 const { std::cell::OnceCell::new() };
58 }
59 ROOT.with(|cell| {
60 let sv = cell.get_or_init(|| {
61 let sv = swiftui_native::state::StatefulView::new(0, |_generation| ui());
62 ROOT_ID.store(sv.id, std::sync::atomic::Ordering::Release);
63 sv
64 });
65 sv.as_view()
66 })
67}Sourcepub fn set_animated(&self, value: i64)
pub fn set_animated(&self, value: i64)
Write a new value inside withAnimation, so SwiftUI interpolates.
Sourcepub fn set_animated_with(&self, value: i64, animation: u64)
pub fn set_animated_with(&self, value: i64, animation: u64)
As set_animated, with the animation spelled out —
withAnimation(.easeInOut(duration: 1)) { ... } and the like.
Sourcepub fn as_view(&self) -> ViewHandle
pub fn as_view(&self) -> ViewHandle
Wrap the instance in an AnyView so it can be hosted like any other view.
Examples found in repository?
54fn root_view() -> views::ViewHandle {
55 thread_local! {
56 static ROOT: std::cell::OnceCell<swiftui_native::state::StatefulView> =
57 const { std::cell::OnceCell::new() };
58 }
59 ROOT.with(|cell| {
60 let sv = cell.get_or_init(|| {
61 let sv = swiftui_native::state::StatefulView::new(0, |_generation| ui());
62 ROOT_ID.store(sv.id, std::sync::atomic::Ordering::Release);
63 sv
64 });
65 sv.as_view()
66 })
67}