横屏模式UISheet设medium detent仍全屏,求解决方案及代码优化
问题解答
1. 横屏模式下实现半高UISheet的方案
你的代码里根本没生效detents设置,因为memoryLogViewController.presentationController在调用present之前是不存在的——这个对象是系统在present操作时才会创建的,所以第二个if let永远走不进去,自然还是默认的全屏样式。
要实现横屏半高Sheet,按以下步骤修改:
方法一:present前配置Sheet样式
先给目标VC设置modalPresentationStyle为.pageSheet(这是启用UISheetPresentationController的前提),然后直接通过sheetPresentationController属性配置detents(这个属性是系统提供的便捷访问,不需要强转):
@IBAction func openMemoryLog(_ sender: UIButton) { guard let memoryLogVC = storyboard?.instantiateViewController(withIdentifier: "memoryLogViewController") else { return } // 必须先设置modal样式,才能启用Sheet控制器 memoryLogVC.modalPresentationStyle = .pageSheet // 直接配置detents,横屏时.medium()会对应半高 memoryLogVC.sheetPresentationController?.detents = [.medium()] present(memoryLogVC, animated: true) }
方法二:在目标VC内部配置
也可以把Sheet的配置逻辑放到MemoryLogViewController里,让职责更清晰:
class MemoryLogViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 这里设置也可以,因为此时presentationController已经存在 modalPresentationStyle = .pageSheet if let sheetPC = presentationController as? UISheetPresentationController { sheetPC.detents = [.medium()] } } }
此时触发present的代码可以简化,不需要再处理配置:
@IBAction func openMemoryLog(_ sender: UIButton) { guard let memoryLogVC = storyboard?.instantiateViewController(withIdentifier: "memoryLogViewController") else { return } present(memoryLogVC, animated: true) }
横屏模式下,.medium() detent的高度就是屏幕高度的一半,完全可以实现你的需求。
2. 嵌套if let的优化方案
你的代码里两层嵌套的if let可以用以下两种方式优化:
方式一:使用guard let提前退出
适合需要在条件不满足时直接返回的场景,代码结构更扁平:
@IBAction func openMemoryLog(_ sender: UIButton) { guard let memoryLogVC = storyboard?.instantiateViewController(withIdentifier: "memoryLogViewController") else { // 实例化失败时直接返回,避免嵌套 return } memoryLogVC.modalPresentationStyle = .pageSheet memoryLogVC.sheetPresentationController?.detents = [.medium()] present(memoryLogVC, animated: true) }
方式二:合并多个if let为一行
如果需要同时判断多个可选值,可以把它们写在同一个if let里:
@IBAction func openMemoryLog(_ sender: UIButton) { if let memoryLogVC = storyboard?.instantiateViewController(withIdentifier: "memoryLogViewController"), let sheetPC = memoryLogVC.sheetPresentationController { // 注意:这里需要先设置modalPresentationStyle,否则sheetPC会是nil memoryLogVC.modalPresentationStyle = .pageSheet sheetPC.detents = [.medium()] present(memoryLogVC, animated: true) } }
不过这种方式不如guard let直观,推荐优先用guard let来优化嵌套结构。
内容的提问来源于stack exchange,提问作者SmallGrammer
相关产品推荐
相关产品推荐

