rust_widgets 2.0.0

Pure Rust cross-platform native GUI library with hardware-adaptive rendering, 60+ widgets, touch/gesture support, i18n, and SVG-pipeline-accurate output
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 Mike Li/Mikewolfli/Wei Li(mikewolfli@163.com) -->
<!-- SPDX-License-Identifier: MIT -->

# iOS Backend Status

## Current Status

The iOS backend (`src/platform/ios/`) is a **state-driven** backend. It
implements the `Platform` contract — widget creation, geometry, text,
visibility, enablement, menu tree, list/combo data, clipboard, drag/drop, IME
and accessibility metadata — through `BackendState<IosHandleKind>`.

The one thing the host owes the library is a **window** to paint into. That is
the single UIKit object this backend creates (`native::create_ui_window` in
`src/platform/ios/native.rs`), and it is gated behind
`#[cfg(all(target_os = "ios", feature = "ios-uikit-ffi"))]`. Elsewhere the
backend runs in pure state mode.

## BLUE15: no per-kind UIKit controls

The backend used to instantiate a real `UIView` per logical widget —
`UIButton`, `UILabel`, `UISwitch`, `UITextField`, `UIPickerView`,
`UITableView`, `UIProgressView`, `UISlider`, `UIScrollView`,
`UIAlertController`, `UIStackView`, `UIActivityIndicatorView` — and mirror every
state mutation into it through `native::*` helpers (`store_native_view`,
`add_as_subview`, `wire_button_action`, `set_native_text`, `set_native_frame`,
`set_native_hidden`, `set_native_enabled`).

Under the self-drawn strategy (BLUE15 #55/#56) the library paints every
`WidgetKind`, so the host supplies a **window plus a drawing surface** and
nothing per-kind. The control creators, the view registry, the `ButtonTarget`
Objective-C class and its event queue existed only to serve that path and have
been **deleted** (#59: delete means delete). The drawing surface is mounted
through `MobilePlatformExtension::attach_to_native_view`.

## What is implemented

| Area | Status | Notes |
|---|---|---|
| `Platform` contract (`create_window` + full window contract) | ✅ Implemented | state-backed, with parent/kind validation |
| `UIWindow` creation | ✅ Implemented | real `UIWindow` with a root view controller, visible |
| Per-kind UIKit controls (`UIButton` / `UILabel` / …) | ⛔ Deleted | BLUE15 #59 — the library paints them |
| Menu tree (MenuBar/Menu/MenuItem) | ✅ Implemented | in-process tree + injectable trigger queue |
| ComboBox / ListBox data paths | ✅ Implemented | shared list-data tables |
| Show / hide / geometry / text / enabled | ✅ Implemented | logical state round-trips |
| Clipboard | ✅ Implemented | in-process store |
| Drag & drop | ✅ Implemented | injectable drop-event queue |
| IME + accessibility metadata | ✅ Implemented | modelled state |
| Print facts | ✅ Implemented | honest error: `UIPrintInteractionController` is not bound |

## Capabilities (honest contract)

`IosMobilePlatform::capabilities()` declares the flags explicitly rather than
inheriting desktop defaults:

- `dpi_scaling: true`, `ime: true`, `accessibility: true` — the state model
  tracks these.
- `native_menu: false` — the menu is an in-process tree served through an
  injectable queue, **not** an OS menu. This is asserted by
  `ios_platform_reports_explicit_mobile_capabilities`.

## Build and test

```bash
# Host (feature-gated preview backend; UIKit code is compiled out)
cargo test --lib --no-default-features --features "mobile-api" platform::ios

# iOS target cross-compile (installs: rustup target add aarch64-apple-ios-sim)
cargo check --target aarch64-apple-ios-sim --no-default-features \
  --features "ios ios-uikit-ffi"
```

## Honest boundaries

Client-verified facts for this revision:

- The **host** test suite runs the state backend and is green on every host
  (`cargo test --no-default-features --features desktop --lib`).
- The iOS-target compile checks and the Simulator probe outputs that earlier
  revisions of this file recorded (`tools/run_ios_testapp.sh`) were taken
  **before** the BLUE15 control deletion and have **not** been re-run: the
  development host is macOS with no iOS SDK/toolchain in this workspace, so the
  `ios-uikit-ffi` build and the Simulator probe are **unverified** for this
  revision. Re-running `tools/run_ios_testapp.sh` on a Mac with Xcode is the
  required next step.
- `create_ui_window` uses `initWithFrame:` (scene-less) because the library has
  no access to a `UIWindowScene` instance; `initWithWindowScene:` would be the
  modern path once a scene is threaded through by the host app.
- The library ships no AndroidX-equivalent framework dependency; UIKit is the
  system framework, so no bundling is required.