我想拥有一个自定义按钮结构,该结构将视图作为参数接收,单击该按钮后将显示为模式。但是,view参数始终为空,并且找不到我正在执行的错误。我的按钮结构如下所示:
struct InfoButton<Content:View>: View {
@State private var showingInfoPage: Bool
private var infoPage: Content
init(infoPage: Content, showingInfoPage: Bool) {
self.infoPage = infoPage
_showingInfoPage = State(initialValue: showingInfoPage)
}
var body: some View {
return
Button(action: {
self.showingInfoPage.toggle()
}) {
Image(systemName: "info.circle")
.resizable()
.frame(width: 25, height: 25)
.foregroundColor(.white)
.padding()
}.sheet(isPresented: self.$showingInfoPage) {
self.infoPage
}.frame(minWidth: 0, maxWidth: .infinity, alignment: .topTrailing)
}
}
此按钮位于我正在为其他多个视图创建的模板的导航栏中。我认为该模板最相关的部分是:
protocol TrainingView {
var title: String { get }
var subheadline: String { get }
var asAnyView: AnyView { get }
var hasInfoPage: Bool { get }
var infoPage: AnyView { get }
}
extension TrainingView where Self: View {
var asAnyView: AnyView {
AnyView(self)
}
var hasInfoPage: Bool {
false
}
var infoPage: AnyView {
AnyView(EmptyView())
}
}
struct TrainingViewTemplate: View {
@State var showInfoPage: Bool = false
@State var viewIndex: Int = 0
var body: some View {
//the views that conform to the template
let views: [TrainingView] = [
ExerciseView(),
TrainingSessionSummaryView()
]
return NavigationView {
ViewIterator(views, self.$viewIndex) { exerciseView in
VStack {
VStack {
Text(exerciseView.title)
.font(.title)
.fontWeight(.semibold).zIndex(1)
Text(exerciseView.subheadline)
.font(.subheadline)
Spacer()
exerciseView.asAnyView.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}.navigationBarItems(trailing: (exerciseView.hasInfoPage == true ? InfoButton(infoPage: exerciseView.infoPage, showingInfoPage: self.showInfoPage) : nil))
}
}
}
我调试到了要初始化navigationBarItems的地步。此时,练习视图具有“ hasInfoPage”和“ infoPage”本身的内容。
一个示例性锻炼视图具有这样的标题:
struct ExerciseView: View, TrainingView {
var title: String = "Strength Session"
var subheadline: String = "Pushups"
var numberOfExercise: Int = 1
@State var ratingValue: Double = 0
@Environment(\.presentationMode) var presentationMode
var hasInfoPage: Bool = true
var infoPage = ExerciseDetailView()
因此,在此视图中,infoPage用我在TemplateView中收到的ExercieDetailView()进行了初始化,但是,一旦单击InfoButton,调试器就会显示一个空的infoPage,即使“ showingInfoPage”变量包含正确的值也是如此。 。
谢谢您的提示!
您未确认协议,因此显示了infoPage
中的默认extension TrainingView
。
解决方法是
struct ExerciseView: View, TrainingView {
// .. other code here
var infoPage = AnyView(ExerciseDetailView()) // << here !!
``