API
nsh/device
设备 API 向应用提供设备及其环境的信息。Rust 代码调用 nsh_core::ui::prelude 中的函数(window()、dark()、font_scale()、locale()、os()、idiom()、pixel_ratio()、set_color_scheme() 等);TSX 导入 nsh/device。窗口尺寸、配色方案、字体缩放、像素密度和区域设置是响应式的:在绑定(Rust 中传给元素的闭包,TSX 中的 JSX)、computed 或 effect 中读取它们,平台报告变化(旋转、窗口缩放、切换深色模式、修改文字大小或语言、移到另一种像素密度的屏幕)时,读取它们的地方会随之更新。
use nsh_core::{
platform::{Appearance, Idiom, Os},
ui::prelude::*, // window、dark、font_scale、locale、os、idiom、pixel_ratio、set_color_scheme……
};import { colorScheme, fontScale, locale, pixelRatio, platform, setColorScheme, windowSize } from "nsh/device";教程见设备与环境。
#windowSize
const windowSize: Accessor<Size>;
界面的尺寸(点):窗口,或嵌入时的 NshAppView / NshView。响应式。Rust:window() -> Size<Points>。
let wide = move || window().width >= px(600.0);
view().style_when(wide, |s| s.flex_row())const wide = () => windowSize().width >= 600;
<View style={{ flexDirection: wide() ? "row" : "column" }}>{/* ... */}</View>#colorScheme
const colorScheme: Accessor<"light" | "dark">;
显示的外观:系统的外观,除非应用设置了自己的(nsh.json 的 "appearance"、setColorScheme)。响应式。Rust:dark() -> bool;主题颜色(AdaptiveColor)和 .dark(…) 样式变体无需读取它就会跟随。Tailwind 的 dark: 变体也跟随它(见 Tailwind)。
view().flex_1().bg(move || if dark() { black() } else { white() })const dark = () => colorScheme() === "dark";
<View style={{ flex: 1, backgroundColor: dark() ? "#000" : "#fff" }} />#fontScale
const fontScale: Accessor<number>;
用户偏好的文字大小相对于默认大小的比例(1 为默认;iOS 上是动态字体,Android 上是字体大小设置),或嵌入它的应用设置的文字大小。响应式。Rust:font_scale() -> f32。除非设置了 allowFontScaling={false},文本本身已经会随之缩放;当其他尺寸(例如文字旁边的图标)也需要跟随时再读取它。
#locale
const locale: Accessor<string>;
用户的区域设置,BCP 47 标签("en-US"、"zh-Hans-CN"),或嵌入它的应用设置的区域设置。响应式。Rust:locale() -> Locale(locale().as_str() 即标签)。Intl 默认按它格式化;读取它来选择你自己的翻译文案(设备与环境)。
#setColorScheme
function setColorScheme(scheme: "light" | "dark" | "system"): void;
无论系统外观如何,立即以 scheme 显示应用:colorScheme()、dark: 类、组件的主题和平台控件(警告框、状态栏的默认样式)都随之变化;"system" 重新跟随系统。nsh.json 的 "appearance" 从启动时就设置它。Rust:set_color_scheme(Appearance::Dark)(Appearance::Light、Appearance::System)。
#platform
const platform: Platform;
interface Platform {
readonly os: "ios" | "android" | "macos" | "windows" | "linux" | "web";
readonly version: string;
readonly idiom: "phone" | "pad" | "mac" | "tv" | "desktop";
readonly catalyst: boolean;
select<T>(spec: PlatformSelectSpec<T>): T | undefined;
}
应用所运行的平台,运行期间不变。
| 成员 | Rust | 说明 |
|---|---|---|
os | os() -> Os(os().name() 即 TS 的字符串) | 操作系统。iOS、iOS 模拟器和 Mac Catalyst 都报告 "ios",浏览器报告 "web"。 |
version | os_version() -> (u16, u16) | iOS 和桌面系统:系统版本("17.5");Android:API 级别("35");Web:"0.0"。Rust 给出主版本和次版本号,在 Android 上是 API 级别和 0。 |
idiom | idiom() -> Idiom;"desktop" 用 is_desktop() | 设备类型:"phone"、"pad"(iPad、Android 平板)、"mac"(以 Mac 形态运行的 Mac Catalyst)、"tv"(Apple TV、Android TV)或 "desktop",即适用桌面行为:macOS、Windows、Linux,以及有鼠标且窗口较宽的浏览器。 |
catalyst | idiom() == Idiom::Mac | 以 Mac 形态运行的 Mac Catalyst。 |
select(spec) | match os() { … } | 当前平台对应的值(见下文)。 |
let columns = if is_desktop() { 3 } else { 1 };const columns = platform.idiom === "desktop" ? 3 : 1;#platform.select
interface PlatformSelectSpec<T> {
ios?: T;
android?: T;
macos?: T;
windows?: T;
linux?: T;
web?: T;
mobile?: T; // iOS、Android,以及手机和平板上的浏览器
desktop?: T; // macOS、Windows、Linux,以及桌面浏览器
native?: T; // 除 Web 外的所有平台
default?: T;
}
依次返回当前操作系统(ios、android、web 等)对应的值,否则 mobile / desktop,否则 native(除 Web 外的所有平台),否则 default,都没有则返回 undefined。在浏览器中,mobile 还是 desktop 由设备类型决定。Rust 代码对 os() 做 match(mobile / desktop 用 is_desktop())。
use nsh_core::platform::Os;
let card = view().p_4();
let card = match os() {
Os::Ios => card.shadow_color(black()).shadow_opacity(0.15).shadow_radius(px(8.0)),
Os::Android => card.elevation(px(4.0)),
_ => card,
};const shadow = platform.select({
ios: { shadowColor: "#000", shadowOpacity: 0.15, shadowRadius: 8 },
android: { elevation: 4 },
});#pixelRatio
const pixelRatio: Accessor<number>;
每个点对应的设备像素数(大多数 iPhone 上为 3)。响应式:窗口移动到另一种像素密度的屏幕上时(Mac Catalyst、桌面系统或外接显示器)它会变化。Rust:pixel_ratio() -> f32,取整到设备像素的长度用 round_to_nearest_pixel(points);在 TSX 中这个长度是 Math.round(x * pixelRatio()) / pixelRatio()。
let hairline = move || px(1.0 / pixel_ratio());const hairline = () => 1 / pixelRatio();#布局方向
布局方向跟随用户的语言:在从右到左书写的语言(阿拉伯语、希伯来语等)中,应用从右到左布局,行从右侧开始排列,left / right 样式属性(marginLeft、paddingRight 等)表示起始端和结束端。修改即时生效,无需重启。
视图的 direction 样式("ltr"、"rtl" 或默认的 "inherit")设置其自身子树的方向;Rust 中为 .direction(LayoutDirection::..)。
view().direction(LayoutDirection::Rtl).flex_row().gap_2().child(text("First")).child(text("Second"))<View style={{ direction: "rtl", flexDirection: "row", gap: 8 }}>
<Text>First</Text>
<Text>Second</Text>
</View>#相关内容
- 安全区域(Rust 的
safe_area();TSX 的safeArea()、safeAreaInsets())和软键盘(Rust 的keyboard_height();TSX 的keyboardFrame())属于nsh/base。 - 屏幕阅读器和减弱动态效果的设置在
nsh/accessibility中。