Как в приложении MacOS с использованием SwiftUI изменить синий фон по умолчанию для выбранной ссылки NavigationLink, вложенной в список?

Доброго времени суток всем. Как в приложении MacOS с использованием SwiftUI изменить синий фон по умолчанию для выбранной ссылки NavigationLink, вложенной в список? Список находится внутри NavigationView. Я не нашел здесь решения. Каким будет код, который нужно добавить к следующему базовому примеру: Два TextView перечислены, и если мы щелкнем по TextView, мы отобразим соответствующий View.

ContentView.swift:

import SwiftUI

struct ContentView: View {

  @State var selection: Int?

  var body: some View {

    HStack() {
      NavigationView {
        List () {
          NavigationLink(destination: FirstView(), tag: 0, selection: self.$selection) {
            Text("Click Me To Display The First View")
          } // End Navigation Link

          NavigationLink(destination: SecondView(), tag: 1, selection: self.$selection) {
            Text("Click Me To Display The Second View")
          } // End Navigation Link

        } // End list
        .frame(minWidth: 350, maxWidth: 350)
        .onAppear {
            self.selection = 0
        }

      } // End NavigationView
        .listStyle(SidebarListStyle())
        .frame(maxWidth: .infinity, maxHeight: .infinity)

    } // End HStack
  } // End some View
} // End ContentView

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

FirstView.swift:

import SwiftUI

struct FirstView: View {

  var body: some View {
    Text("(1) Hello, I am the first view")
      .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct FirstView_Previews: PreviewProvider {
  static var previews: some View {
    FirstView()
  }
}

SecondView.swift:

import SwiftUI

struct SecondView: View {
  var body: some View {
    Text("(2) Hello, I am the second View")
      .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct SecondView_Previews: PreviewProvider {
  static var previews: some View {
    SecondView()
  }
}

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

введите здесь описание изображения


person Wild8x    schedule 18.04.2020    source источник


Ответы (1)


следующий код - один из вариантов достижения желаемого:

struct ContentView: View {

@State var selection: Int? = 0
@State var pressed: Int? = 0

init() {
    UITableViewCell.appearance().selectionStyle = .none
    UITableView.appearance().backgroundColor = UIColor.clear
}

var body: some View {

    var theBinding = Binding(
        get: { self.selection },
        set: {
            self.selection = $0
            self.pressed = $0 == nil ? self.pressed : $0!
    })

    return HStack() {
        NavigationView {
            List {
                NavigationLink(destination: FirstView(), tag: 0, selection: theBinding) {
                    Text("Click Me To Display The First View")
                }.listRowBackground(self.pressed == 0 ? Color.red : Color.green)

                NavigationLink(destination: SecondView(), tag: 1, selection: theBinding) {
                    Text("Click Me To Display The Second View")
                }.listRowBackground(self.pressed == 1 ? Color.red : Color.green)

            }.frame(minWidth: 350, maxWidth: 350)
                .onAppear { self.pressed = 0 }

        }.listStyle(SidebarListStyle())
         .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
}
person workingdog    schedule 19.04.2020
comment
Привет, workingdog, спасибо за ответ, но я не могу протестировать ваш код, потому что, когда я импортирую UIKit в свой файл MacOS ContentView.swift ... появляется следующее всплывающее сообщение Нет такого модуля UIKIt - person Wild8x; 19.04.2020
comment
ха, да, я использую катализатор, чтобы все работало на macos (10.15.4). - person workingdog; 19.04.2020
comment
Я смотрю, как заменить UITableViewCell.appearance (). SelectionStyle = .none UITableView.appearance (). BackgroundColor = UIColor.clear на эквивалент NS ... - person workingdog; 19.04.2020
comment
У меня такое чувство, что мне придется запустить новый проект iOS и выбрать опцию Mac в главе: Информация о развертывании - ›Целевое устройство. А потом я добавлю Mac Target и попробую ваш код. - person Wild8x; 19.04.2020
comment
Что ж, я только что это сделал, и в файле ContentView.swift есть следующие две ошибки для строки import UIKit: (1) Нет такого модуля 'UIKit' + (2) UIKit недоступен при сборке для macOS. Рассмотрите возможность использования #if !os(macOS) для условного импорта этой структуры. - person Wild8x; 19.04.2020
comment
Я импортирую SwiftUI только в ContentView, но он автоматически импортируется в AppDelegate и SceneDelegate. Я снова проверил, создав новый проект ios, скопировал и вставил приведенный выше код, и у меня все работает хорошо. - person workingdog; 20.04.2020
comment
Как вы сказали, 3 файла (ContentView, FirstView и SecondView) отлично работают на iOS Target, а UIKIt импортируется в файл AppDelegate один раз, но не в файл Content или FirstView или SecondView. Когда я запускаю iOS Target на симуляторе iPad Pro, мы видим разделенный экран и выбранный другой цвет фона. Но когда в том же проекте я создаю MacOS Target и создаю 3 файла в этом новом Target и запускаю на симуляторе MyMac: 3 ошибки появились, потому что структура UIKIt не находится на MacOS Target! Использование неразрешенного идентификатора UITableViewCell + UITableView + UIColor - person Wild8x; 20.04.2020
comment
просто чтобы прояснить, есть только одна цель. Просто установите флажок Mac в разделе Общие - ›Информация о развертывании -› Целевое устройство. Вы не создаете отдельную цель MacOS. Вы запускаете эту единственную цель как на ios, так и на macos (Catalina). - person workingdog; 22.04.2020
comment
Теперь он работает на Mac. Но единственная оставшаяся проблема заключается в том, что я должен раскомментировать модификатор «.listStyle (SidebarListStyle ())» в файле ContentView, иначе появится следующее сообщение об ошибке: «'SidebarListStyle' недоступен в iOS». Жаль, потому что я хочу запускать это приложение только на Mac. Мы не можем убрать отметку с цели iOS и iPad и оставить только цель MacOS. Я открою новый вопрос, чтобы узнать, как добавить модификатор только для конкретной цели. Поэтому я отмечу ваш ответ «ок», но надеюсь, что решение будет предложено для одинокой цели MacOS. Еще раз спасибо за вашу помощь. - person Wild8x; 23.04.2020
comment
просто замените .listStyle (SidebarListStyle ()) на .navigationViewStyle (DefaultNavigationViewStyle ()) - person workingdog; 23.04.2020
comment
Спасибо, но, наконец, я использовал это решение, которое использует #if os (macOS) ... по этой ссылке: stackoverflow.com/questions/61386877 / - person Wild8x; 23.04.2020
comment
Спасибо Workingdog. Я только что попробовал, и все в порядке! Наконец-то! - person Wild8x; 23.04.2020