Я создал пользовательский вид, который показывает контент и 2 кнопки (предыдущая и следующая). Пожалуйста, найдите код для структуры ниже:
struct PageNavigator<Content: View>: View {
var prevAction: () -> Void
var nextAction: () -> Void
private let content: () -> Content
init(prevAction: @escaping () -> Void, nextAction: @escaping () -> Void, @ViewBuilder content: @escaping () -> Content) {
self.prevAction = prevAction
self.nextAction = nextAction
self.content = content
}
var body: some View {
VStack {
content()
HStack {
Button(action: { self.prevAction() }) {
HStack{
Image(systemName: "chevron.left.circle.fill")
Text("Prev")
.multilineTextAlignment(.leading)
}
}
Spacer()
Button(action: { self.nextAction() }) {
HStack{
Text("Next")
.multilineTextAlignment(.trailing)
Image(systemName: "chevron.right.circle.fill")
}
}
}
.padding()
}.padding()
}
И вот как он используется из родительского представления
PageNavigator(prevAction: {
if (self.pageToDisplay > 0){
self.pageToDisplay = self.pageToDisplay - 1
}else{
self.pageToDisplay = 0
}
}, nextAction: {
self.pageToDisplay = self.pageToDisplay + 1
}){
//content to display
Spacer()
if(self.pageToDisplay < self.messages.count){
//show walkthrough
MessageView(title: self.messages[self.pageToDisplay].title , content: self.messages[self.pageToDisplay].message)
}else{
if(self.pageToDisplay == self.messages.count){
TermsAgreementView(pageToDisplay: self.$pageToDisplay)
}else if(self.pageToDisplay == self.messages.count + 1){
SetBaseCurrencyView()
}else if(self.pageToDisplay == self.messages.count + 2){
SmartRemindersView()
}else if(self.pageToDisplay == self.messages.count + 3){
GetStartedView()
}
else{
MessageView(title: "Test page \(self.messages.count)", content: "Test")
}
}
Spacer()
}
Теперь я хотел добавить свойство, которое позволит мне показать или скрыть кнопку «предыдущий» или «следующий» в родительском представлении. Какой эффективный способ сделать это? Я попытался добавить @Binding showNextButton: Bool и @Binding showPrevButton: Bool. Но он работает не так, как ожидалось.
Заранее спасибо!
СЛЕДОВАТЬ UP / UPDATE
Итак, предложенное ниже решение сработало, но у меня есть следующее вверх. Поэтому я создал 2 свойства showNextBtn и showPrevBtn, чтобы показать / скрыть 2 кнопки навигации. Но я бы хотел сделать их необязательными, чтобы не указывать эти 2 параметра. Поэтому, если 2 параметра не указаны, 2 кнопки должны быть скрыты. Я обновил код, как показано ниже:
struct PageNavigator<Content: View>: View {
var prevAction: () -> Void
var nextAction: () -> Void
private let content: () -> Content
@Binding var showNextBtn: Bool?
@Binding var showPrevBtn: Bool?
init(showNextBtn: Binding<Bool?>?, showPrevBtn: Binding<Bool?>?, prevAction: @escaping () -> Void, nextAction: @escaping () -> Void, @ViewBuilder content: @escaping () -> Content) {
self.prevAction = prevAction
self.nextAction = nextAction
self.content = content
if showNextBtn != nil{
self._showNextBtn = showNextBtn!
}else{
self._showNextBtn = Binding.constant(false)
}
if showPrevBtn != nil{
self._showPrevBtn = showPrevBtn!
}else{
self._showPrevBtn = Binding.constant(false)
}
}
var body: some View {
VStack {
content()
HStack {
if self.showPrevBtn!{
Button(action: { self.prevAction() }) {
HStack{
Image(systemName: "chevron.left.circle.fill")
Text("Prev")
.multilineTextAlignment(.leading)
}
}
}
Spacer()
if self.showNextBtn!{
Button(action: { self.nextAction() }) {
HStack{
Text("Next")
.multilineTextAlignment(.trailing)
Image(systemName: "chevron.right.circle.fill")
}
}
}
}
.padding()
}.padding()
}
И я использую вышеприведенное представление для родительского представления следующим образом:
PageNavigator(showNextBtn: $showNextBtn, showPrevBtn: $showPrevBtn, prevAction: {
if (self.pageToDisplay > 0){
self.pageToDisplay = self.pageToDisplay - 1
}else{
self.pageToDisplay = 0
}
}, nextAction: {
self.pageToDisplay = self.pageToDisplay + 1...
Но я получаю ошибку: «Не удается преобразовать значение типа «Связывание» с ожидаемым типом аргумента «Связывание?» Для параметров $ showNextBtn и $ showPrevBtn. Я что-то здесь упускаю?
Спасибо!