为何返回EmptyView会使SwiftUI的AsyncImage无法正常工作?
问题原因分析
这是因为SwiftUI中EmptyView的布局特性和AsyncImage在Xcode 13.3.1中的实现逻辑共同导致的:
EmptyView的尺寸特性:EmptyView是一个没有任何视觉元素、也没有固有尺寸的视图——它的宽高都会被计算为0。当AsyncImage处于加载中(.loading)或加载失败(.failure)状态时,如果返回EmptyView,整个AsyncImage的布局尺寸会被压缩为0×0。AsyncImage的布局更新逻辑:在Xcode 13的AsyncImage实现里,当视图初始尺寸为0时,即使后续图片加载成功(进入.success分支),布局系统可能无法正确触发重新计算,或者图片没有足够的空间来渲染展示。
而使用Text("empty")的情况完全不同:Text有自己的固有尺寸(基于文本内容和默认字体),这会让AsyncImage在加载阶段就拥有一个非零的布局空间。当图片加载完成后,替换为带.frame(width:140, height:140)的图片视图时,布局系统能正常识别尺寸变化并渲染图片。
解决方法
如果你想使用EmptyView作为占位,只需要给它指定固定尺寸,让AsyncImage在加载阶段也拥有明确的布局空间即可:
AsyncImage(url: URL(string: "https://ychef.files.bbci.co.uk/976x549/p01j3jyb.jpg")) { phase in switch phase { case .success(let image): image .resizable() .frame(width: 140, height: 140) default: EmptyView() .frame(width: 140, height: 140) // 添加固定尺寸 } }
这样修改后,图片就能正常加载显示了。
内容的提问来源于stack exchange,提问作者Marty
相关产品推荐
相关产品推荐

