The update and view functions form the heart of every Iced application. Together, they create a reactive loop where state changes trigger UI updates, and user interactions trigger state changes.
The update function can optionally return a Task to perform asynchronous work:
use iced::Task;struct State { weather: Option<Weather>,}#[derive(Clone)]enum Message { FetchWeather, WeatherFetched(Weather),}fn update(state: &mut State, message: Message) -> Task<Message> { match message { Message::FetchWeather => { Task::perform(fetch_weather(), Message::WeatherFetched) } Message::WeatherFetched(weather) => { state.weather = Some(weather); Task::none() } }}async fn fetch_weather() -> Weather { // Fetch data from an API... unimplemented!()}
Tasks allow you to run async code, interact with the runtime (focus widgets, change window settings), and more. They’re essential for real-world applications.
Task::none()
Task::perform()
Task::batch()
Message::ButtonPressed => { state.count += 1; Task::none() // No async work needed}
column![ text(counter.value).size(20), // Method chaining button("Increment").on_press(Message::Increment),].spacing(10) // Applied to the column.into() // Convert to Element
Widgets produce messages that your update function handles:
Button
Text Input
Checkbox
// View: Button produces Message::Increment when pressedbutton("Increment").on_press(Message::Increment)// Update: Handle the messagematch message { Message::Increment => counter.value += 1,}
// View: Input produces Message::InputChanged with the new texttext_input("Placeholder", &state.input) .on_input(Message::InputChanged)// Update: Store the new valuematch message { Message::InputChanged(value) => state.input = value,}
// View: Checkbox produces Message::ToggleComplete with boolcheckbox(task.completed) .on_toggle(Message::ToggleComplete)// Update: Update the completed statusmatch message { Message::ToggleComplete(completed) => task.completed = completed,}