pub fn render(view: &ViewHandle, width: u32, height: u32) -> RenderedExpand description
Render a view offscreen at exactly width x height pixels.
Examples found in repository?
examples/todo.rs (line 152)
140fn main() {
141 if std::env::args().any(|a| a == "--sim" || a == "device") {
142 return simulator::main(&simulator::Bundle {
143 example: "todo",
144 bundle_id: "dev.rswift.Todo",
145 executable: "Todo",
146 display_name: "Todo",
147 launch_args: &[],
148 });
149 }
150 if std::env::args().any(|a| a == "--render") {
151 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/todo.png");
152 swiftui_native::render::render(&content_view(), 420, 460).write_png(out);
153 eprintln!("wrote {out}");
154 return;
155 }
156 show_window(&content_view(), "Todo", 420.0, 460.0);
157}More examples
examples/inbox.rs (line 143)
131fn main() {
132 if std::env::args().any(|a| a == "--sim" || a == "device") {
133 return simulator::main(&simulator::Bundle {
134 example: "inbox",
135 bundle_id: "dev.rswift.Inbox",
136 executable: "Inbox",
137 display_name: "Inbox",
138 launch_args: &[],
139 });
140 }
141 if std::env::args().any(|a| a == "--render") {
142 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/inbox.png");
143 swiftui_native::render::render(&content_view(), 420, 520).write_png(out);
144 eprintln!("wrote {out}");
145 return;
146 }
147 show_window(&content_view(), "Inbox", 420.0, 520.0);
148}examples/settings.rs (line 141)
129fn main() {
130 if std::env::args().any(|a| a == "--sim" || a == "device") {
131 return simulator::main(&simulator::Bundle {
132 example: "settings",
133 bundle_id: "dev.rswift.Settings",
134 executable: "Settings",
135 display_name: "Settings",
136 launch_args: &[],
137 });
138 }
139 if std::env::args().any(|a| a == "--render") {
140 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/settings.png");
141 swiftui_native::render::render(&content_view(), 420, 640).write_png(out);
142 eprintln!("wrote {out}");
143 return;
144 }
145 show_window(&content_view(), "Settings", 420.0, 640.0);
146}examples/dashboard.rs (line 119)
107fn main() {
108 if std::env::args().any(|a| a == "--sim" || a == "device") {
109 return simulator::main(&simulator::Bundle {
110 example: "dashboard",
111 bundle_id: "dev.rswift.Dashboard",
112 executable: "Dashboard",
113 display_name: "Dashboard",
114 launch_args: &[],
115 });
116 }
117 if std::env::args().any(|a| a == "--render") {
118 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/dashboard.png");
119 swiftui_native::render::render(&content_view(), 420, 480).write_png(out);
120 eprintln!("wrote {out}");
121 return;
122 }
123 show_window(&content_view(), "Dashboard", 420.0, 480.0);
124}examples/swift_org_tutorial.rs (line 200)
185fn main() {
186 // `--sim` and `--device` build for iOS and run it there; see `common/simulator.rs`.
187 if std::env::args().any(|a| a == "--sim" || a == "device" || a == "ipa") {
188 return simulator::main(&simulator::Bundle {
189 example: "swift_org_tutorial",
190 bundle_id: "dev.rswift.WhyNotTry",
191 executable: "WhyNotTry",
192 display_name: "Why not try…",
193 launch_args: &[],
194 });
195 }
196 // `--render` draws one frame to a PNG instead of opening a window, so the
197 // result can be looked at without a display.
198 if std::env::args().any(|a| a == "--render") {
199 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tutorial.png");
200 let frame = swiftui_native::render::render(&content_view(), 420, 640);
201 frame.write_png(out);
202 eprintln!("wrote {out} ({} colours)", frame.distinct());
203 return;
204 }
205 // `WindowGroup { ContentView() }` — the same tree the tutorial's `App` hosts.
206 show_window(&content_view(), "Why not try…", 420.0, 640.0);
207}examples/dynamic_ui.rs (line 242)
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}Additional examples can be found in: