SwiftUI预览报错:无法在PreviewProvider类型使用Binding实例成员
SwiftUI预览中使用@Binding类型Bool变量的崩溃解决方法
问题场景
在SwiftUI视图中声明了@Binding类型的Bool变量,但生成预览时程序崩溃,无法正常使用该变量。
视图代码
struct MapPinSheetSectionOneView: View { // Safari View - Binding @Binding var isBrowsingWebsite: Bool // Variables let item: Place // Main body var body: some View { HStack(alignment: .top, spacing: 0) { // Type/Title/Excerpt showSectionOne .border(.blue) // Spacers Spacer() Spacer() Spacer() // Link & Close Button showSheetLinkAndCloseButton .border(.red) } .border(.red) // Divider Divider() } // MARK: Category, Title & Excerpt private var showSectionOne: some View { VStack(alignment: .leading, spacing: 0) { Group { if item.category != "" { Text(verbatim: item.category) .padding(8) .background( RoundedRectangle(cornerRadius: 8) .fill(Color.accentColor) ) } if item.title != "" { Text(item.title) .font(.title2.weight(.semibold)) } if item.excerpt != "" { HStack(alignment: .top, spacing: 3) { Text(item.excerpt) .font(.footnote) .foregroundColor(.secondary) .lineLimit(2) Spacer() } } } .lineLimit(1) } } // MARK: Link & Close Button private var showSheetLinkAndCloseButton: some View { Group { if item.website != "" { Button(action: { self.isBrowsingWebsite = true }) { Image(systemName: "link.circle.fill") } .sheet(isPresented: $isBrowsingWebsite) { SafariViewWrapper(url: URL(string: item.website)!) } } Image(systemName: "xmark.circle.fill") } .imageScale(.large) .foregroundColor(.accentColor) } }
尝试的预览代码
struct MapPinSheetSectionOneView_Previews: PreviewProvider { @Binding var isBrowsingWebsite: Bool static var previews: some View { MapPinSheetSectionOneView( isBrowsingWebsite: $isBrowsingWebsite, item: Place( id: 0, title: "Title", category: "Category", type: "Type", description: "Description", excerpt: "Excerpt", address: "Address", city: "City", state: "State", zipcode: 0, country: "Country", lat: 39.828194, long: -98.569611, altitude: 0, amenity: ("Amenities"), admission: "Free", website: "Website" ) ) } }
崩溃错误信息
Instance member '$isBrowsingWebsite' cannot be used on type 'MapPinSheetSectionOneView_Previews'
解决方法
错误原因
预览的previews是静态方法,你在预览结构体里声明的@Binding var isBrowsingWebsite: Bool是实例成员,静态方法无法直接访问实例成员,这就是报错的核心原因。
方案1:使用@State创建本地可交互的Binding
如果需要在预览中测试按钮点击切换状态的功能,可以用@State包装一个本地变量,再通过$符号转为Binding传递给视图:
struct MapPinSheetSectionOneView_Previews: PreviewProvider { static var previews: some View { @State private var isPreviewBrowsing = false return MapPinSheetSectionOneView( isBrowsingWebsite: $isPreviewBrowsing, item: Place( id: 0, title: "Title", category: "Category", type: "Type", description: "Description", excerpt: "Excerpt", address: "Address", city: "City", state: "State", zipcode: 0, country: "Country", lat: 39.828194, long: -98.569611, altitude: 0, amenity: "Amenities", admission: "Free", website: "https://example.com" // 传入合法URL,避免强制解包崩溃 ) ) } }
方案2:使用.constant创建只读Binding
如果预览只需要展示视图样式,不需要测试交互功能,可以直接用Binding.constant(_:)创建一个只读的Binding实例传递:
struct MapPinSheetSectionOneView_Previews: PreviewProvider { static var previews: some View { MapPinSheetSectionOneView( isBrowsingWebsite: .constant(false), item: Place( id: 0, title: "Title", category: "Category", type: "Type", description: "Description", excerpt: "Excerpt", address: "Address", city: "City", state: "State", zipcode: 0, country: "Country", lat: 39.828194, long: -98.569611, altitude: 0, amenity: "Amenities", admission: "Free", website: "https://example.com" ) ) } }
额外提示
视图中URL(string: item.website)!使用了强制解包,建议在预览中传入合法的URL字符串(比如"https://example.com"),避免因为URL为nil导致预览崩溃。
内容的提问来源于stack exchange,提问作者SLE
相关产品推荐
相关产品推荐

