如何在iOS 26新WebPage/WebView中实现Safari式文本缩放
iOS WebView 实现 Safari 式文本缩放功能
核心思路
放弃旧版pageZoom的整体缩放方案,通过注入JavaScript调整根元素字体大小实现仅文本缩放,同时为表格添加横向滚动容器,避免不必要的页面水平滚动,完全匹配Safari的文本缩放体验。
实现步骤
1. WebView 基础配置
先配置WKWebView,禁用用户双指缩放(避免和自定义按钮冲突),确保JavaScript可用:
import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() // 禁用用户双指缩放 config.preferences.setValue(false, forKey: "userScalable") // 启用JavaScript config.defaultWebpagePreferences.allowsContentJavaScript = true webView = WKWebView(frame: view.bounds, configuration: config) webView.navigationDelegate = self view.addSubview(webView) // 加载目标网页 if let url = URL(string: "https://your-target-url.com") { webView.load(URLRequest(url: url)) } // 添加缩放按钮(示例,可根据UI需求自定义位置样式) let decreaseBtn = UIButton(type: .system) decreaseBtn.setTitle("A⁻", for: .normal) decreaseBtn.addTarget(self, action: #selector(decreaseTextSize), for: .touchUpInside) decreaseBtn.frame = CGRect(x: 20, y: view.safeAreaInsets.top + 20, width: 44, height: 44) view.addSubview(decreaseBtn) let increaseBtn = UIButton(type: .system) increaseBtn.setTitle("A⁺", for: .normal) increaseBtn.addTarget(self, action: #selector(increaseTextSize), for: .touchUpInside) increaseBtn.frame = CGRect(x: 70, y: view.safeAreaInsets.top + 20, width: 44, height: 44) view.addSubview(increaseBtn) } // 网页加载完成后注入JavaScript func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { let jsCode = """ let textScale = 1.0; const minScale = 0.8; // 最小缩放比例 const maxScale = 1.5; // 最大缩放比例 const step = 0.1; // 每次缩放步长 function adjustTextSize(isIncrease) { // 调整缩放级别,限制在最小/最大值内 if (isIncrease) { textScale = Math.min(textScale + step, maxScale); } else { textScale = Math.max(textScale - step, minScale); } // 修改根元素字体大小,所有使用相对单位(rem/em)的文本会自动缩放 document.documentElement.style.fontSize = `${textScale * 100}%`; // 处理表格:为表格添加横向滚动容器,避免页面整体水平滚动 document.querySelectorAll('table').forEach(table => { if (!table.parentElement.classList.contains('table-scroll-container')) { const container = document.createElement('div'); container.style.overflowX = 'auto'; container.style.width = '100%'; container.classList.add('table-scroll-container'); table.parentNode.insertBefore(container, table); container.appendChild(table); } }); } """ webView.evaluateJavaScript(jsCode) } // 缩小文本按钮点击事件 @objc func decreaseTextSize() { webView.evaluateJavaScript("adjustTextSize(false)") } // 放大文本按钮点击事件 @objc func increaseTextSize() { webView.evaluateJavaScript("adjustTextSize(true)") } }
2. 关键逻辑说明
- 文本缩放核心:通过修改
document.documentElement(HTML根元素)的font-size百分比,让所有使用rem、em等相对单位的文本元素自动缩放,完全模拟Safari的文本缩放逻辑。 - 表格处理:为每个表格包裹一个横向滚动容器,当文本放大导致表格宽度超出页面时,仅表格自身可横向滚动,不会触发整个页面的水平滚动。
- 缩放边界控制:设置最小/最大缩放比例,避免缩放过度导致页面布局错乱。
额外优化建议
- 可将缩放级别保存到
UserDefaults,下次打开App时自动恢复用户上次的缩放设置。 - 对于使用固定像素字体的老旧网站,可在JS中额外遍历文本元素调整
font-size,示例代码:// 针对固定像素字体的元素补充缩放 document.querySelectorAll('p, span, td, th').forEach(el => { if (el.style.fontSize && el.style.fontSize.includes('px')) { const originalSize = parseFloat(el.style.fontSize); el.style.fontSize = `${originalSize * textScale}px`; } });
内容的提问来源于stack exchange,提问作者Seeker
相关产品推荐
相关产品推荐

