英文:
SwiftUI: Unable to pass View into CustomView using Parameters
问题
I'm currently having issues with sending a custom view through into another view as a parameter. All the other parameters work perfectly, it's just the view.
I've set up everything within a single Swift file to encapsulate the environment to troubleshoot, but I just get:
Cannot convert value of type 'Text' to expected argument type 'some View'
I'm most likely just missing something obvious, but I've tried with both any/some View, as well as variants with and without the @ViewBuilder but can't seem to find a solution.
Here's my code:
//
// ProductsTabButton.swift
// RM Product Guide
//
// Created by Matthew Hardiman on 04/07/2023.
//
import SwiftUI
struct ProductsTabButton: View {
@State var sheetActiveBool: Bool = false
var dismissFunction: () -> Void
var buttonColor: String = "rmWhite"
var buttonText: String = "Button Text"
var buttonIcon: String = "list.dash"
var buttonView: some View = BackgroundView()
var body: some View {
// BUTTON STYLING
Button(action: {
sheetActiveBool.toggle()
},label:{
VStack(spacing: 0){
Image(systemName: buttonIcon).productLinkBlockImage()
Text(buttonText).productLinkBlockText()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(buttonColor))
})
.sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction) {
fetchView()
}
}
@ViewBuilder
func fetchView() -> some View {
buttonView
}
}
struct ProductsTabButton_Previews: PreviewProvider {
static var previews: some View {
ProductsTabButton(
dismissFunction: {
print("Test")
},
buttonColor: "rmYellow",
buttonText: "Yellow",
buttonIcon: "list.star",
//buttonView: SearchView()
buttonView: Text("Test")
)
}
}
Any help with this would be greatly appreciated.
Thank you!
英文:
i'm currently having issues with sending a custom view through into another view as a parameter. All the other parameters work perfectly, it's just the view.
I've setup everything within a single swift file to encapsulate the enviroment to trouble shoot but i just get:
Cannot convert value of type 'Text' to expected argument type 'some View'
I'm most likely just missing something obvious, but i've tried with both any/some View, as well as variants with and without the @ViewBuilder but can't seem to find a solution.
Here's my code:
//
// ProductsTabButton.swift
// RM Product Guide
//
// Created by Matthew Hardiman on 04/07/2023.
//
import SwiftUI
struct ProductsTabButton: View {
@State var sheetActiveBool: Bool = false
var dismissFunction: () -> Void
var buttonColor: String = "rmWhite"
var buttonText: String = "Button Text"
var buttonIcon: String = "list.dash"
var buttonView: some View = BackgroundView()
var body: some View {
// BUTTON STYLING
Button(action: {
sheetActiveBool.toggle()
},label:{
VStack(spacing: 0){
Image(systemName: buttonIcon).productLinkBlockImage()
Text(buttonText).productLinkBlockText()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(buttonColor))
})
.sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction) {
fetchView()
}
}
@ViewBuilder
func fetchView() -> some View {
buttonView
}
}
struct ProductsTabButton_Previews: PreviewProvider {
static var previews: some View {
ProductsTabButton(
dismissFunction: {
print("Test")
},
buttonColor: "rmYellow",
buttonText: "Yellow",
buttonIcon: "list.star",
//buttonView: SearchView()
buttonView: Text("Test")
)
}
}
Any help with this would be greatly appreciated.
Thank you!
答案1
得分: 1
不应该将View
作为View
的属性。如果它是更大视图的可定制部分,请存储一个返回视图的闭包。
struct ProductsTabButton<ButtonView: View>: View {
@State var sheetActiveBool: Bool = false
var dismissFunction: () -> Void
var buttonColor: String
var buttonText: String
var buttonIcon: String
var buttonView: () -> ButtonView
// ...
}
您可以直接将此闭包传递给sheet
:
.sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction, content: buttonView)
如果要为此属性设置默认值,请在扩展中编写初始化程序:
struct ProductsTabButton<ButtonView: View>: View {
// ...
init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", @ViewBuilder buttonView: @escaping () -> ButtonView, dismiss: @escaping () -> Void) {
self.buttonColor = buttonColor
self.buttonIcon = buttonIcon
self.dismissFunction = dismiss
self.buttonText = buttonText
self.buttonView = buttonView
}
// ...
}
extension ProductsTabButton where ButtonView == BackgroundView {
init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", dismiss: @escaping () -> Void) {
self.init(buttonColor: buttonColor, buttonText: buttonText, buttonIcon: buttonIcon, buttonView: { BackgroundView() }, dismiss: dismiss)
}
}
英文:
You should not have View
s as properties of View
s. If it's a customisable part of a bigger view, store a closure that returns a view instead.
struct ProductsTabButton<ButtonView: View>: View {
@State var sheetActiveBool: Bool = false
var dismissFunction: () -> Void
var buttonColor: String
var buttonText: String
var buttonIcon: String
var buttonView: () -> ButtonView
// ...
}
You can pass this closure to sheet
directly:
.sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction, content: buttonView)
If you want a default value for this property, write an initialiser in an extension:
struct ProductsTabButton<ButtonView: View>: View {
// ...
init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", @ViewBuilder buttonView: @escaping () -> ButtonView, dismiss: @escaping () -> Void) {
self.buttonColor = buttonColor
self.buttonIcon = buttonIcon
self.dismissFunction = dismiss
self.buttonText = buttonText
self.buttonView = buttonView
}
// ...
}
extension ProductsTabButton where ButtonView == BackgroundView {
init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", dismiss: @escaping () -> Void) {
self.init(buttonColor: buttonColor, buttonText: buttonText, buttonIcon: buttonIcon, buttonView: { BackgroundView() }, dismiss: dismiss)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论