ShadCN抽屉组件在iOS Safari中键盘弹出时高度异常问题
解决iOS Safari中ShadCN抽屉键盘弹出时高度收缩的问题
问题根源
iOS Safari在键盘弹出时会压缩视口可用高度,你当前给抽屉设置的h-5/6是基于初始视口高度的相对值,视口高度变化后抽屉会随之收缩;另外原生autoFocus的触发时机可能和抽屉渲染生命周期冲突,进一步放大了这个问题。
解决方案
1. 替换相对高度为固定视口单位
把抽屉的h-5/6改为基于屏幕高度的固定单位(如vh),避免受视口变化影响:
<DrawerContent className="h-[80vh]"> {/* 抽屉内容 */} </DrawerContent>
2. 固定抽屉布局并优化滚动区域
给抽屉内容添加弹性布局,确保ScrollArea占据剩余空间,防止内容被键盘挤压:
<DrawerContent className="h-[80vh] flex flex-col"> <ScrollArea className="flex-1"> <div className="p-4"> <form> <input type="text" autoFocus className="w-full p-2 border rounded" /> </form> {/* 可添加更多测试内容验证滚动 */} {Array.from({length:20}).map((_,i)=><p key={i} className="py-2">测试内容 {i+1}</p>)} </div> </ScrollArea> </DrawerContent>
3. 延迟触发输入框焦点
放弃原生autoFocus,改用useEffect在抽屉完全渲染后再唤起焦点,确保布局稳定:
import { useRef, useEffect, useState } from 'react'; import { Button } from "@/components/ui/button"; import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer"; import { ScrollArea } from "@/components/ui/scroll-area"; export default function Home() { const inputRef = useRef(null); const [isDrawerOpen, setIsDrawerOpen] = useState(false); useEffect(() => { if (isDrawerOpen && inputRef.current) { const timer = setTimeout(() => inputRef.current.focus(), 100); return () => clearTimeout(timer); } }, [isDrawerOpen]); return ( <div className="flex items-center justify-center min-h-screen"> <Drawer open={isDrawerOpen} onOpenChange={setIsDrawerOpen}> <DrawerTrigger> <Button variant={"destructive"}>Click</Button> </DrawerTrigger> <DrawerContent className="h-[80vh] flex flex-col"> <ScrollArea className="flex-1"> <div className="p-4"> <form> <input ref={inputRef} type="text" className="w-full p-2 border rounded" /> </form> {Array.from({length:20}).map((_,i)=><p key={i} className="py-2">测试内容 {i+1}</p>)} </div> </ScrollArea> </DrawerContent> </Drawer> </div> ); }
4. 添加iOS专属视口修复
在项目的index.html头部添加meta标签,优化iOS视口行为:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
验证效果
修改后,iOS Safari中打开抽屉唤起键盘时,抽屉高度会保持稳定,滚动区域也能正常工作,和Android端表现一致。
内容的提问来源于stack exchange,提问作者Mohan Raj
相关产品推荐
相关产品推荐

