40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
import { useCallback, useEffect } from 'react'
|
|
import Taro, { useDidShow } from '@tarojs/taro'
|
|
import { applyPageBackground } from '../utils/themeBackground'
|
|
|
|
export interface UseStatusBarOptions {
|
|
/** 顶部系统状态栏(iOS 时间/电量)文字颜色模式:
|
|
* - 'auto'(默认):跟随当前 App 主题,浅色黑字、深色白字
|
|
* - 'light':强制白字(顶部是深色图片/背景的页面用)
|
|
* - 'dark':强制黑字
|
|
*/
|
|
mode?: 'auto' | 'light' | 'dark'
|
|
}
|
|
|
|
/**
|
|
* 同步当前页面的 iOS 系统状态栏(时间、电量)文字颜色。
|
|
* 每个页面只调用一次,避免全局 Provider 与页面生命周期竞争写入。
|
|
*/
|
|
export function useStatusBar(resolvedTheme: 'light' | 'dark', options: UseStatusBarOptions = {}) {
|
|
const { mode = 'auto' } = options
|
|
|
|
const apply = useCallback(() => {
|
|
const isDarkText = mode === 'dark' || (mode === 'auto' && resolvedTheme === 'light')
|
|
const frontColor = isDarkText ? '#000000' : '#ffffff'
|
|
const bgColor = isDarkText ? '#ffffff' : '#191919'
|
|
|
|
Taro.setNavigationBarColor({ frontColor, backgroundColor: bgColor })
|
|
// 同步页面背景色,确保自定义导航区(状态栏下方、胶囊按钮区域)跟随主题,
|
|
// 避免深色模式下顶部残留白色条带。
|
|
// 注意:iOS 上顶部/底部窗口背景需分别用 backgroundColorTop / Bottom 指定,
|
|
// 仅设置 backgroundColor 在 iOS 上无法覆盖顶部导航区。
|
|
applyPageBackground(resolvedTheme, bgColor)
|
|
}, [mode, resolvedTheme])
|
|
|
|
// 主题切换后立即更新当前页面。
|
|
useEffect(apply, [apply])
|
|
|
|
// 导航返回、切换 Tab 或从后台恢复后,以当前页面主题重新覆盖原生默认值。
|
|
useDidShow(apply)
|
|
}
|