SwiftUI:无法使用参数将View传递到CustomView中

huangapple go评论106阅读模式
英文:

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:

  1. //
  2. // ProductsTabButton.swift
  3. // RM Product Guide
  4. //
  5. // Created by Matthew Hardiman on 04/07/2023.
  6. //
  7. import SwiftUI
  8. struct ProductsTabButton: View {
  9. @State var sheetActiveBool: Bool = false
  10. var dismissFunction: () -> Void
  11. var buttonColor: String = "rmWhite"
  12. var buttonText: String = "Button Text"
  13. var buttonIcon: String = "list.dash"
  14. var buttonView: some View = BackgroundView()
  15. var body: some View {
  16. // BUTTON STYLING
  17. Button(action: {
  18. sheetActiveBool.toggle()
  19. },label:{
  20. VStack(spacing: 0){
  21. Image(systemName: buttonIcon).productLinkBlockImage()
  22. Text(buttonText).productLinkBlockText()
  23. }
  24. .frame(maxWidth: .infinity, maxHeight: .infinity)
  25. .background(Color(buttonColor))
  26. })
  27. .sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction) {
  28. fetchView()
  29. }
  30. }
  31. @ViewBuilder
  32. func fetchView() -> some View {
  33. buttonView
  34. }
  35. }
  36. struct ProductsTabButton_Previews: PreviewProvider {
  37. static var previews: some View {
  38. ProductsTabButton(
  39. dismissFunction: {
  40. print("Test")
  41. },
  42. buttonColor: "rmYellow",
  43. buttonText: "Yellow",
  44. buttonIcon: "list.star",
  45. //buttonView: SearchView()
  46. buttonView: Text("Test")
  47. )
  48. }
  49. }

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:

  1. //
  2. // ProductsTabButton.swift
  3. // RM Product Guide
  4. //
  5. // Created by Matthew Hardiman on 04/07/2023.
  6. //
  7. import SwiftUI
  8. struct ProductsTabButton: View {
  9. @State var sheetActiveBool: Bool = false
  10. var dismissFunction: () -> Void
  11. var buttonColor: String = "rmWhite"
  12. var buttonText: String = "Button Text"
  13. var buttonIcon: String = "list.dash"
  14. var buttonView: some View = BackgroundView()
  15. var body: some View {
  16. // BUTTON STYLING
  17. Button(action: {
  18. sheetActiveBool.toggle()
  19. },label:{
  20. VStack(spacing: 0){
  21. Image(systemName: buttonIcon).productLinkBlockImage()
  22. Text(buttonText).productLinkBlockText()
  23. }
  24. .frame(maxWidth: .infinity, maxHeight: .infinity)
  25. .background(Color(buttonColor))
  26. })
  27. .sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction) {
  28. fetchView()
  29. }
  30. }
  31. @ViewBuilder
  32. func fetchView() -> some View {
  33. buttonView
  34. }
  35. }
  36. struct ProductsTabButton_Previews: PreviewProvider {
  37. static var previews: some View {
  38. ProductsTabButton(
  39. dismissFunction: {
  40. print("Test")
  41. },
  42. buttonColor: "rmYellow",
  43. buttonText: "Yellow",
  44. buttonIcon: "list.star",
  45. //buttonView: SearchView()
  46. buttonView: Text("Test")
  47. )
  48. }
  49. }

Any help with this would be greatly appreciated.

Thank you!

答案1

得分: 1

不应该将View作为View的属性。如果它是更大视图的可定制部分,请存储一个返回视图的闭包。

  1. struct ProductsTabButton<ButtonView: View>: View {
  2. @State var sheetActiveBool: Bool = false
  3. var dismissFunction: () -> Void
  4. var buttonColor: String
  5. var buttonText: String
  6. var buttonIcon: String
  7. var buttonView: () -> ButtonView
  8. // ...
  9. }

您可以直接将此闭包传递给sheet

  1. .sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction, content: buttonView)

如果要为此属性设置默认值,请在扩展中编写初始化程序:

  1. struct ProductsTabButton<ButtonView: View>: View {
  2. // ...
  3. init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", @ViewBuilder buttonView: @escaping () -> ButtonView, dismiss: @escaping () -> Void) {
  4. self.buttonColor = buttonColor
  5. self.buttonIcon = buttonIcon
  6. self.dismissFunction = dismiss
  7. self.buttonText = buttonText
  8. self.buttonView = buttonView
  9. }
  10. // ...
  11. }
  12. extension ProductsTabButton where ButtonView == BackgroundView {
  13. init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", dismiss: @escaping () -> Void) {
  14. self.init(buttonColor: buttonColor, buttonText: buttonText, buttonIcon: buttonIcon, buttonView: { BackgroundView() }, dismiss: dismiss)
  15. }
  16. }
英文:

You should not have Views as properties of Views. If it's a customisable part of a bigger view, store a closure that returns a view instead.

  1. struct ProductsTabButton<ButtonView: View>: View {
  2. @State var sheetActiveBool: Bool = false
  3. var dismissFunction: () -> Void
  4. var buttonColor: String
  5. var buttonText: String
  6. var buttonIcon: String
  7. var buttonView: () -> ButtonView
  8. // ...
  9. }

You can pass this closure to sheet directly:

  1. .sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction, content: buttonView)

If you want a default value for this property, write an initialiser in an extension:

  1. struct ProductsTabButton<ButtonView: View>: View {
  2. // ...
  3. init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", @ViewBuilder buttonView: @escaping () -> ButtonView, dismiss: @escaping () -> Void) {
  4. self.buttonColor = buttonColor
  5. self.buttonIcon = buttonIcon
  6. self.dismissFunction = dismiss
  7. self.buttonText = buttonText
  8. self.buttonView = buttonView
  9. }
  10. // ...
  11. }
  12. extension ProductsTabButton where ButtonView == BackgroundView {
  13. init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", dismiss: @escaping () -> Void) {
  14. self.init(buttonColor: buttonColor, buttonText: buttonText, buttonIcon: buttonIcon, buttonView: { BackgroundView() }, dismiss: dismiss)
  15. }
  16. }

huangapple
  • 本文由 发表于 2023年7月4日 21:27:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定