This tutorial follows the previous tutorial.
We use the same Page trait and MyApp struct.
use iced::{
Task,
widget::{button, column, text, text_input},
};
fn main() -> iced::Result {
iced::application("My App", MyApp::update, MyApp::view).run_with(MyApp::new)
}
#[derive(Debug, Clone)]
enum Message {
PageA(PageAMessage),
PageB(PageBMessage),
}
trait Page {
fn update(&mut self, message: Message) -> Option<Box<dyn Page>>;
fn view(&self) -> iced::Element<Message>;
}
struct MyApp {
page: Box<dyn Page>,
}
impl MyApp {
fn new() -> (Self, Task<Message>) {
(
Self {
page: Box::new(PageA::new()),
},
Task::none(),
)
}
fn update(&mut self, message: Message) {
let page = self.page.update(message);
if let Some(p) = page {
self.page = p;
}
}
fn view(&self) -> iced::Element<Message> {
self.page.view()
}
}For PageA (the login form), we have a TextInput for names and a submit Button.
We pass name field of PageA to new function of PageB when we press the submit button.
#[derive(Debug, Clone)]
enum PageAMessage {
TextChanged(String),
ButtonPressed,
}
type Ma = PageAMessage;
struct PageA {
name: String,
}
impl PageA {
fn new() -> Self {
Self {
name: String::new(),
}
}
}
impl Page for PageA {
fn update(&mut self, message: Message) -> Option<Box<dyn Page>> {
if let Message::PageA(msg) = message {
match msg {
PageAMessage::TextChanged(s) => self.name = s,
PageAMessage::ButtonPressed => {
return Some(Box::new(PageB::new(self.name.clone())));
}
}
}
None
}
fn view(&self) -> iced::Element<Message> {
column![
text_input("Name", &self.name).on_input(|s| Message::PageA(Ma::TextChanged(s))),
button("Log in").on_press(Message::PageA(Ma::ButtonPressed)),
]
.into()
}
}In PageB, we receive the name from new function and display the name in view.
#[derive(Debug, Clone)]
enum PageBMessage {
ButtonPressed,
}
type Mb = PageBMessage;
struct PageB {
name: String,
}
impl PageB {
fn new(name: String) -> Self {
Self { name }
}
}
impl Page for PageB {
fn update(&mut self, message: Message) -> Option<Box<dyn Page>> {
if let Message::PageB(msg) = message {
match msg {
PageBMessage::ButtonPressed => return Some(Box::new(PageA::new())),
}
}
None
}
fn view(&self) -> iced::Element<Message> {
column![
text(format!("Hello {}!", self.name)),
button("Log out").on_press(Message::PageB(Mb::ButtonPressed)),
]
.into()
}
}➡️ Next: Navigation History
📘 Back: Table of contents

