安卓ios开发问题-安全边距

js 复制代码
  override func viewDidLayoutSubviews() {
    webView.frame = self.view.bounds
  }

关键发现 :iOS项目中WebView使用的是 self.view.bounds ,这意味着WebView占据了整个视图控制器的边界, 包括安全区域 。

H5项目中的安全区域处理

js 复制代码
.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

.bottom {
  flex: 0;
  border-top: solid 1px var(--adm-color-border);
  background-color: #fff;
  position: relative;
  z-index: 1;
  
  /* 添加底部安全区域适配 */
  padding-bottom: env(safe-area-inset-bottom);
  padding-bottom: constant(safe-area-inset-bottom);
}

问题根源

底部留有距离的原因是 双重安全区域处理 :

  1. iOS层面 :WebView已经占据了包含安全区域的完整视图边界
  2. H5层面 :CSS又额外添加了安全区域的padding 这导致在有Home Indicator的iPhone设备上,底部会有双倍的安全区域间距。

iPhone Safe Area 安全区域适配解决方案

问题描述

iPhone X 系列及更新设备引入了"刘海"和底部"Home Indicator",导致网页内容可能被遮挡或与底部留有过大间距。

解决方案概述

1. iOS 原生项目修改

文件 : t-ios/t/ViewController.swift

修改内容:

  • 使用 Auto Layout 约束替代手动设置 frame
  • WebView 顶部适配到 safeAreaLayoutGuide
  • 底部延伸到屏幕底部,由 H5 页面处理安全区域
swift 复制代码
// 设置 WebView 约束,确保适配安全区域
webView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
  webView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
  webView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
  webView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
  webView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])

2. H5 项目全局配置

文件 : t1-h5/.umirc.ts

Viewport 配置:

javascript 复制代码
metas: [
  {
    name: 'viewport',
    content: 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover',
  },
]

关键 : viewport-fit=cover 确保页面延伸到屏幕边缘。

3. CSS 安全区域变量

文件 : t1-h5/src/less/index.less

css 复制代码
:root {
  --safe-area-inset-top: constant(safe-area-inset-top);
  --safe-area-inset-right: constant(safe-area-inset-right);
  --safe-area-inset-bottom: constant(safe-area-inset-bottom);
  --safe-area-inset-left: constant(safe-area-inset-left);
  
  // 支持新语法
  --safe-area-inset-top: env(safe-area-inset-top);
  --safe-area-inset-right: env(safe-area-inset-right);
  --safe-area-inset-bottom: env(safe-area-inset-bottom);
  --safe-area-inset-left: env(safe-area-inset-left);
}

4. 布局组件适配

文件 : t1-h5/src/layouts/layout.less

css 复制代码
.bottom {
  // 为底部 TabBar 添加安全区域适配
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

5. 固定定位元素适配

对于使用 position: fixed 的底部元素,统一添加安全区域适配:

css 复制代码
.fixedBottomElement {
  position: fixed;
  bottom: 0;
  padding-bottom: calc(16px + constant(safe-area-inset-bottom));
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
}

工具类使用

文件 : t1-h5/src/utils/safeArea.ts

typescript 复制代码
import { useSafeArea } from '@/utils/safeArea';

// 在组件中使用
const { hasBottomInset, safeAreaInsets } = useSafeArea();

// 动态应用安全区域样式
const elementRef = useRef<HTMLDivElement>(null);
useEffect(() => {
  if (elementRef.current) {
    applySafeAreaStyles(elementRef.current, { bottom: true });
  }
}, []);

适配原则

  1. iOS 原生层面: WebView 顶部适配安全区域,底部延伸到屏幕底部
  2. H5 全局层面: 使用 CSS 环境变量定义安全区域
  3. 组件层面: 固定定位的底部元素添加安全区域 padding
  4. 通用性: 提供工具类便于新组件快速适配

测试验证

在以下设备上验证效果:

  • iPhone X/XS/XR 系列
  • iPhone 11 系列
  • iPhone 12/13/14/15 系列
  • iPad Pro (Face ID)

注意事项

  1. 使用 constant()env() 双重声明确保兼容性
  2. 对于固定定位元素,使用 calc() 函数叠加原有 padding
  3. 避免在全局容器上直接添加安全区域 padding,应在具体组件上处理
  4. 横屏模式下左右安全区域也需要考虑适配

影响范围

✅ 已适配的页面/组件:

  • 底部导航栏 (TabBar)
  • 拍照结果页面 (PicResult)
  • 分析结果页面 (AnalysisResult)
  • 订正详情页面 (CorrectionDetail)
  • 关于页面 (About)
  • 评分页面 (Grading)
  • 作业批改页面 (HomeworkGrading)

📝 需要继续关注的页面:

  • 其他包含固定定位元素的页面
  • 弹窗组件的安全区域适配
  • 横屏页面的左右安全区域适配
相关推荐
用户新2 小时前
V8引擎 精品漫游指南--Ignition篇(下 一) 动态执行前的事情
前端·javascript
@PHARAOH4 小时前
WHAT - GitLens vs Fork
前端
yqcoder4 小时前
前端性能优化:如何减少重绘与重排?
前端·性能优化
洋子5 小时前
Yank Note 系列 13 - 让 AI Agent 进入笔记工作流
前端·人工智能
wenzhangli77 小时前
Ooder A2UI 核心架构深度解析:WEB 拦截层的设计与实现
前端·架构
前端百草阁7 小时前
【前端性能优化全链路指南】从开发编写到构建运行的多维度实践
前端·性能优化
女生也可以敲代码8 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
ZhengEnCi8 小时前
M5-markconv自定义CSS样式指南 📝
前端·css·python
IT_陈寒8 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip8 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua