diff --git a/.agents/skills/mpx2rn/references/rn-template-reference.md b/.agents/skills/mpx2rn/references/rn-template-reference.md index b3dacffc47..5ac170fe4d 100644 --- a/.agents/skills/mpx2rn/references/rn-template-reference.md +++ b/.agents/skills/mpx2rn/references/rn-template-reference.md @@ -1431,6 +1431,24 @@ level 有效值: | 属性名 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | src | string | | webview 指向网页的链接,如果需要对跳转的 URL 设定白名单可跳转,需要在业务跳转之前处理该逻辑 | +| show-navigation-bar | boolean | `undefined` | 仅 RN:`true` 显示导航,`false` 隐藏;未传入时沿用页面导航配置,支持动态更新 | + +RN 下 `web-view` 默认沿用页面导航配置,页面设置 `navigationStyle: 'custom'` 时导航保持隐藏。H5 可通过 `@mpxjs/webview-bridge` 的 `invoke('hideNavigationBar')` / `invoke('showNavigationBar')` 主动覆盖页面配置,隐藏或显示导航,无需在 `apiImplementations` 中注册。调用支持可选的 `success`、`fail`、`complete` 回调,成功返回 `{ errMsg: 'hideNavigationBar:ok' }` 或 `{ errMsg: 'showNavigationBar:ok' }`。这两个内建调用仅在 RN 容器中生效。 + +`show-navigation-bar` 属性变化和 H5 bridge 调用以最近一次操作为准;属性值不变时,不会覆盖 H5 后续调用,属性改为 `undefined` 时恢复页面原配置。改变 `src`、H5 跳转或路由切换不会自动重置显隐状态,URL 参数不控制导航;需要随 H5 路由变化时,由业务在路由切换后主动调用。卸载时清除显隐覆盖并恢复页面原配置,重新挂载时按当前属性初始化,未传属性则沿用页面配置。系统状态栏仍保留。WebView 随页面容器自动铺满,宿主 API 的窗口尺寸与坐标数据仍按原页面配置计算。一个页面同时使用一个 `web-view`。 + +```html + + +``` + +```js +// 在被打开的 H5 中调用 +import webviewBridge from '@mpxjs/webview-bridge' + +webviewBridge.invoke('hideNavigationBar') // 隐藏 +webviewBridge.invoke('showNavigationBar') // 显示,按需调用其中一个 +``` #### 事件 diff --git a/docs-vitepress/guide/rn/component.md b/docs-vitepress/guide/rn/component.md index 1914d7bd03..93e4d6b56b 100644 --- a/docs-vitepress/guide/rn/component.md +++ b/docs-vitepress/guide/rn/component.md @@ -714,6 +714,24 @@ API | 属性名 | 类型 | 默认值 | 说明 | | ----------------------- | ------- | ------------- | ---------------------------------------------------------- | | src | string | | webview 指向网页的链接,如果需要对跳转的URL设定白名单可跳转,需要在业务跳转之前处理该逻辑 +| show-navigation-bar | boolean | `undefined` | 仅 RN:`true` 显示导航,`false` 隐藏;未传入时沿用页面导航配置,支持动态更新 | + +RN 下 `web-view` 默认沿用页面导航配置,页面设置 `navigationStyle: 'custom'` 时导航保持隐藏。H5 可通过 `@mpxjs/webview-bridge` 的 `invoke('hideNavigationBar')` / `invoke('showNavigationBar')` 主动覆盖页面配置,隐藏或显示导航,无需在 `apiImplementations` 中注册。调用支持可选的 `success`、`fail`、`complete` 回调,成功返回 `{ errMsg: 'hideNavigationBar:ok' }` 或 `{ errMsg: 'showNavigationBar:ok' }`。这两个内建调用仅在 RN 容器中生效。 + +`show-navigation-bar` 属性变化和 H5 bridge 调用以最近一次操作为准;属性值不变时,不会覆盖 H5 后续调用,属性改为 `undefined` 时恢复页面原配置。改变 `src`、H5 跳转或路由切换不会自动重置显隐状态,URL 参数不控制导航;需要随 H5 路由变化时,由业务在路由切换后主动调用。卸载时清除显隐覆盖并恢复页面原配置,重新挂载时按当前属性初始化,未传属性则沿用页面配置。系统状态栏仍保留。WebView 随页面容器自动铺满,宿主 API 的窗口尺寸与坐标数据仍按原页面配置计算。一个页面同时使用一个 `web-view`。 + +```html + + +``` + +```js +// 在被打开的 H5 中调用 +import webviewBridge from '@mpxjs/webview-bridge' + +webviewBridge.invoke('hideNavigationBar') // 隐藏 +webviewBridge.invoke('showNavigationBar') // 显示,按需调用其中一个 +``` 事件 diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index 8ac02fb4c1..47c486af58 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -572,6 +572,11 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) { error('Using pageWrapper requires passing navigation and route') return null } + navigation.setWebViewShowNav = (showNav) => { + navigation.setPageConfig({ + navigationStyle: showNav === undefined ? currentPageConfig.navigationStyle : (showNav ? undefined : 'custom') + }) + } const headerHeight = useInnerHeaderHeight(currentPageConfig) navigation.layout = getLayoutData(headerHeight) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx index 3606994845..5557d77c77 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useRef, useContext, useMemo, useState } from 'react' +import { forwardRef, useRef, useContext, useMemo, useState, useLayoutEffect } from 'react' import { warn, isFunction } from '@mpxjs/utils' import Portal from './mpx-portal/index' import { usePreventRemove, PreventRemoveEvent } from '@react-navigation/native' @@ -30,6 +30,7 @@ type CommonCallbackEvent = { interface WebViewProps { src?: string + 'show-navigation-bar'?: boolean bindmessage?: (event: OnMessageCallbackEvent) => void bindload?: (event: CommonCallbackEvent) => void binderror?: (event: CommonCallbackEvent) => void @@ -84,7 +85,7 @@ const styles = StyleSheet.create({ }) const _WebView = forwardRef, WebViewProps>((props, ref): JSX.Element | null => { - const { src, bindmessage, bindload, binderror } = props + const { src, 'show-navigation-bar': showNavigationBar, bindmessage, bindload, binderror } = props const mpx = global.__mpx const errorText: ErrorTextMap = { 'zh-CN': { @@ -103,6 +104,7 @@ const _WebView = forwardRef, WebViewPr } const { pageId } = useContext(RouteContext) || {} const [pageLoadErr, setPageLoadErr] = useState(false) + const [showNav, setShowNav] = useState(showNavigationBar) const currentPage = useMemo(() => getCurrentPage(pageId), [pageId]) const webViewRef = useRef(null) const fristLoaded = useRef(false) @@ -153,6 +155,20 @@ const _WebView = forwardRef, WebViewPr } } + useLayoutEffect(() => { + setShowNav(showNavigationBar) + }, [showNavigationBar]) + + useLayoutEffect(() => { + // 属性和 H5 均未指定显隐时,沿用页面导航配置。 + if (showNav === undefined) return + const applyShowNav = navigation?.setWebViewShowNav + if (!applyShowNav) return + applyShowNav(showNav) + // 卸载或显隐变化时清除旧覆盖,恢复页面配置。 + return () => applyShowNav(undefined) + }, [navigation, showNav]) + if (!src) { return null } @@ -231,6 +247,11 @@ const _WebView = forwardRef, WebViewPr const params = Array.isArray(args) ? args : [postData] const type = data.type switch (type) { + case 'hideNavigationBar': + case 'showNavigationBar': + setShowNav(type === 'showNavigationBar') + asyncCallback = Promise.resolve({ errMsg: `${type}:ok` }) + break case 'setTitle': { // case下不允许直接声明,包个块解决该问题 const title = postData._documentTitle?.trim()