Как запустить дочернюю функцию от родителя?

0

Вопрос

Я хочу вызвать childFunction() demo childView, нажав кнопку в родительском представлении.

import SwiftUI

struct ChildView: View {
    
    func childFunction() {
        print("I am the child")
    }

    var body: some View {
      Text("I am the child")
    }
}

struct ContentView: View {
    var function: (() -> Void)?

    var body: some View {
        ChildView()
        
        Button(action: {
            self.function!()
        }, label: {
            Text("Button")
        })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Обновить: Спасибо @RajaKishan, это работает, но мне нужно, чтобы он работал также рекурсивно

import SwiftUI

struct ContentView: View {
    @State var text: String = "Parent"
    var isNavigationViewAvailable = true
    
    func function() {
        print("This view is \(text)")
    }
    
    var body: some View {
        
        VStack {
            if isNavigationViewAvailable  {
                Button(action: {
                    function()
                }, label: {
                    Text("Button")
                })
            }
           
            
            if isNavigationViewAvailable {
                NavigationView {
                    List {
                        NavigationLink("Child1") {
                            ContentView(text: "Child1", isNavigationViewAvailable: false)
                        }
                        NavigationLink("Child2") {
                            ContentView(text: "Child2", isNavigationViewAvailable: false)
                        }
                        NavigationLink("Child3") {
                            ContentView(text: "Child3", isNavigationViewAvailable: false)
                        }
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Возможно, это не самый красивый пример, но вопрос в том, как заставить кнопку запустить функцию ее дочернего элемента после того, как пользователь посетил соответствующего ребенка.

Например, при запуске, когда пользователь нажимает кнопку, он печатает "Это представление является родительским". После того, как пользователь перейдет к child1, нажатие кнопки должно вывести "Это представление является Child1", как и так далее. Таким образом, на функцию, которую запускает кнопка, следует ссылаться с последнего дочернего элемента.

Обновить: В конце концов я написал это решение.

Обновить: Я получил обратную связь, в которой меня просили дать разъяснения. Без проблем. Я надеюсь, что это кому-нибудь поможет.:)

Осветление: Я не включал весь код целиком, просто использовал простой пример. Но мне это было нужно при реализации древовидного сгенерированного меню: когда у каждого элемента в меню есть или нет своих дочерних элементов. При нажатии на родительский объект пользователь переходит в дочерние объекты. И здесь мне нужно было иметь возможность вернуться от дочернего объекта к родительскому, но вызвать эту функцию отклонения от родительского объекта. Для этого я использовал следующий код и ссылался на эту функцию для каждого родительского объекта:

@Environment(\.presentationMode) var presentationMode
 presentationMode.wrappedValue.dismiss()
ios swift swiftui
2021-11-24 05:44:05
1

Лучший ответ

1

Вы можете создать объект для дочернего представления.

struct ChildView: View {
 
    func childFunction() {
        print("I am the child")
    }
    
    var body: some View {
        Text("I am the child")
    }
}

struct ContentView: View {
    
    let childView = ChildView()
    
    var body: some View {
        childView
        Button(action: {
            childView.childFunction()
        }, label: {
            Text("Button")
        })
    }
}


ИЗМЕНИТЬ : Для списка можно использовать массив модели и вызывать целевую функцию по индексу.

Вот простой пример "ребенок-родитель".

struct ChildView: View {
    var text: String
    
    func childFunction() {
        print("This view is \(text)")
    }
    
    var body: some View {
        Text("I am the child")
    }
}



struct ContentView55: View {
    
    @State private var arrData = [Model(title: "Child1", destination: ChildView(text: "Child1")),
                                           Model(title: "Child2", destination: ChildView(text: "Child2")),
                                           Model(title: "Child3", destination: ChildView(text: "Child3"))]
    
    var body: some View {
        
        VStack {
            Button(action: {
                arrData[1].destination.childFunction()
            }, label: {
                Text("Button")
            })
            
            NavigationView {
                SwiftUI.List(arrData) {
                    NavigationLink($0.title, destination: $0.destination)
                }
            }
        }
    }
    
}
struct Model: Identifiable {
    var id = UUID()
    var title: String
    var destination: ChildView
}

Примечание: Вам нужно проиндексировать строку, чтобы вызвать дочернюю функцию.

2021-11-24 07:34:52

Привет. Спасибо за ответ. Это работает. Но в случае рекурсивной структуры представления, когда в contentView есть дочерние элементы contentView, созданные с помощью ссылок навигации, как это можно решить, поскольку тип значения не может иметь сохраненное свойство, которое рекурсивно содержит его ?
Degtiarev Aleksei

@DegtiarevAleksei не могли бы вы, пожалуйста, добавить один пример к вашему вопросу?
Raja Kishan

Обновил вопрос
Degtiarev Aleksei

@DegtiarevAleksei Я добавил часть редактирования. Это может быть полезно.
Raja Kishan

Спасибо за ответ, но после того, как я скомпилировал кнопку, она всегда возвращает "Это представление является дочерним 2".
Degtiarev Aleksei

@DegtiarevAleksei Это потому, что я установил индекс 1 (arrData[1]) в действии кнопки. прочти мою записку.
Raja Kishan

Это может сработать не так, как ожидалось, поскольку представления в SwiftUI являются структурами, что означает, что они передаются по значению и, таким образом, копируются каждый раз при их распространении. В конце концов, вы получаете несколько различных ChildView экземпляры, поэтому вы можете в конечном итоге вызвать дочернюю функцию в другом представлении, чем то, которое вы ожидаете.
Cristik

@Cristik да, я думаю, что правильно создавать несколько экземпляров для каждого вызова дочернего представления. Потому что он ведет себя по-разному для каждого случая.
Raja Kishan

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

Популярное в этой категории

Популярные вопросы в этой категории