Как скрыть / показать дочерние представления от родительского представления - PullRequest
1 голос
/ 08 марта 2020

Я создал пользовательский вид, который показывает контент и 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. Я что-то здесь упускаю?

Спасибо!

1 Ответ

0 голосов
/ 08 марта 2020

Я добился того, что вы просили, используя @Binding. Вот как я это сделал

struct PageNavigator<Content: View>: View {
var prevAction: () -> Void
var nextAction: () -> Void
private let content: () -> Content

@Binding var showNext : Bool

init(showNext : Binding<Bool> , prevAction: @escaping () -> Void, nextAction: @escaping () -> Void, @ViewBuilder content: @escaping () -> Content) {
    self.prevAction = prevAction
    self.nextAction = nextAction
    self.content = content

    self._showNext = showNext
}

 var body: some View {
    VStack {
        ...

            if self.showNext {
                Button(action: { self.nextAction() }) {
                    HStack{
                        Text("Next")
                            .multilineTextAlignment(.trailing)
                        Image(systemName: "chevron.right.circle.fill")
                    }
                }
            }

        ...
    }
}

Теперь от родителя:

@State var showNext : Bool = true
...
PageNavigator( showNext : self.$showNext, prevAction: {
        if (self.pageToDisplay > 0){
            --->
            self.showNext.toggle() // = false , true
        }else{
            self.pageToDisplay = 0
        }
    }, nextAction: {
        self.pageToDisplay = self.pageToDisplay + 1

    },content: {
        ...
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...