SwiftUI: лучший способ изменения метки TabbedView на основе NavigationBarTitle - PullRequest
1 голос
/ 12 июня 2019

Я наконец смог выяснить, как изменить заголовок моего NavigationView на основе текущей вкладки в TabbedView, используя onAppear(), но я уверен, что это не такдля этого:

struct SomeTabbedView : View {
  @State private var selection = 0
  @State private var title = "First"
  var body: some View {
    NavigationView {
      TabbedView(selection: $selection) {
        ContentView()
          .tabItemLabel(
            Text("First")
          ).tag(0).onAppear{
            self.title = "First"
        }

        OtherView()
          .tabItemLabel(
            Text("Second")
          ).tag(1).onAppear{
            self.title = "Second"
          }
        }.navigationBarTitle(Text(title))
      }
    }
}

Короче говоря, это довольно сильно нарушает принцип СУХОГО.Если мы решим изменить первое представление, например, строку «First», текущая реализация потребует повторить это в трех разных местах.

Я думал об инициализации массива словарей и циклической обработке над View: Label пары, но не только я не уверен, что это правильный путь, я не уверен, как приступить к его реализации.Также возможно иметь массив с метками, но это создает другое нарушение в случае, если мы хотим изменить порядок представлений.

Ответы [ 2 ]

4 голосов
/ 12 июня 2019

Ваш вид верхнего уровня должен быть TabbedView, и каждая вкладка должна иметь свой собственный NavigationView. Это не относится к тому факту, что «Первый» используется как для .navigationBarTitle, так и для .tabItemLabel, но на самом деле это две разные вещи, которые могут отличаться.

struct SomeTabbedView : View {
    @State private var selection = 0

    var body: some View {

        TabbedView(selection: $selection) {
            NavigationView {
                ContentView()
                    .navigationBarTitle(Text("First"))
            }
            .tabItemLabel(Text("First"))
            .tag(0)

            NavigationView {
                OtherView()
                    .navigationBarTitle(Text("Second"))
            }
            .tabItemLabel(Text("Second"))
            .tag(1)
        }.edgesIgnoringSafeArea(.top)
    }
}
0 голосов
/ 23 июня 2019

У меня была похожая проблема, и я решил ее, создав оболочку вида, похожую на ту, что делается в SwiftUI. Это просто добавление СУХОСТИ к ответу vacawama :

struct NavigationTab<Title, Content>: View where Title: StringProtocol, Content: View {
    var title: Title
    var content: () -> Content

    var body: some View {
        NavigationView {
            content()
                .navigationBarTitle(Text(title))
        }
        .tabItemLabel(Text(title))
    }
}

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

struct SomeTabbedView: View {
    @State private var selection = 0

    var body: some View {
        TabbedView(selection: $selection) {
            NavigationTab(title: "First") {
                ContentView()
            }
            .tag(0)

            NavigationTab(title: "Second") {
                OtherView()
            }
            .tag(1)
        }
    }
}

Это, очевидно, усложняется, если вы хотите, чтобы дополнительные детали, такие как изображение над ярлыком вкладки, поскольку .navigationBarTitle() требует экземпляр Text.

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