Как удалить строки разделителя списков в SwiftUI 2.0 в iOS 14

Итак, вопрос довольно простой, и он находится в заголовке. Я хочу удалить разделитель строк в SwiftUI iOS 14. Раньше я использовал UITableView().appearance().separatorStyle = .none, который выполнял эту работу в iOS 13. Однако теперь это не работает. Любое обновление или идея о том, как заставить его работать. Спасибо:)


person Osama Naeem    schedule 26.06.2020    source источник
comment
Ну нет больше UITableView под ним ... больше никаких хакеров))   -  person Asperi    schedule 26.06.2020
comment
@SchmidtyApps опубликовал решение, которое, как я подтвердил, работает! Но ответ был удален модератором, и я не могу его восстановить. См. github.com/SchmidtyApps/SwiftUIListSeparator.   -  person Jordan H    schedule 21.09.2020


Ответы (11)


Вот демонстрация возможного решения. Протестировано с Xcode 12b.

демо

List {
    ForEach(0..<3) { _ in
        VStack {
            Text("Hello, World!").padding(.leading)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        .listRowInsets(EdgeInsets())
        .background(Color.white)
    }
}
person Asperi    schedule 26.06.2020
comment
Использовать Color(UIColor.systemBackground)) вместо Color.white? - person akmin; 27.06.2020
comment
Кроме того, в некоторых случаях вы можете захотеть применить вставки с отрицательными краями. .listRowInsets(EdgeInsets(.init(top: -1, leading: -1, bottom: -1, trailing: -1))). - person zrfrank; 16.08.2020
comment
Как это сделать, не изменяя вставки? Если удалить все отступы, список будет выглядеть плохо. - person Jordan H; 23.08.2020
comment
@JordanH Вы можете установить стиль списка на .listStyle(InsetListStyle()) - person pawello2222; 21.10.2020
comment
мне нравится это решение, и оно прекрасно работает на симуляторе (XCode 12, под управлением iOS 13 и 14), однако оно не работает на моем реальном устройстве (iPhone XS, iOS 14.2). Разделители списков появляются по какой-то странной причине. Кто-нибудь еще сталкивался с таким же? - person Qingwan Kuah; 08.01.2021
comment
Я использую кнопку в ячейке списка. После добавления этого выделенный цвет у моих кнопок исчез. - person Tulon; 05.07.2021

Как я сделал список, который работает как на iOS 14, так и на iOS 13, в нем нет разделителей и дополнительных полей

struct NoButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
    }
}

struct ListWithoutSepatorsAndMargins<Content: View>: View {
        let content: () -> Content
    
        var body: some View {
            if #available(iOS 14.0, *) {
                ScrollView {
                    LazyVStack(spacing: 0) {
                        self.content()
                    }
                    .buttonStyle(NoButtonStyle())
                }
            } else {
                List {
                    self.content()
                }
                .listStyle(PlainListStyle())
                .buttonStyle(NoButtonStyle())
            }
        }
    }

Пример использования -

ListWithoutSepatorsAndMargins {
    ForEach(0..<5) { _ in
      Text("Content")
    }
}

если в списке больше компонентов, оберните их в группу

                ListWithoutSepatorsAndMargins {
                    Group {
                            self.groupSearchResults()
                            self.myGroups()
                            self.exploreGroups()
                        }
                    }
                }

    

Надеюсь, это кому-то поможет, я потратил много времени на такие мелочи, Apple пытается сильно подтолкнуть нас к использованию LazyVStack, кажется

person Harish saini    schedule 23.09.2020
comment
это решение вредно, потому что LazyVStack работает с ячейками совершенно иначе, чем List. Вы можете проверить загрузку процессора при прокрутке этих ячеек. Если ячейка представляет собой нечто большее, чем текст («привет, тест»), вы увидите пиковую нагрузку при прокрутке. - person Lonkly; 05.10.2020
comment
Использование ЦП немного увеличивается при прокрутке, но мгновенно снижается по мере стабилизации, что раньше происходило и в UITableView, у меня довольно тяжелые ячейки в моем приложении и очень большие списки, это никогда не вызывало задержек при прокрутке или сбоев для мы пока не обнаружили проблем, но используйте на свой страх и риск! - person Harish saini; 07.10.2020
comment
@Lonkly, почему ты думаешь, что это может быть проблемой? - person Zapko; 09.10.2020
comment
@Zapko, как вы думаете, в чем основное отличие StackView от TableView в UIKit? То же, что у List и LazyVStack. TableView повторно использует ячейки, LazyVStack - нет. Поэтому, когда у вас есть больше элементов, которые умещаются на экране, а макет более сложный, чем текст (контент), вы получите крайнюю медлительность и лаги. Поэтому предоставление решения под названием ListWithoutSeparators {} и превращение его в LazyVStack внутри очень вредно. - person Lonkly; 09.10.2020
comment
при использовании ленивого vstack вы теряете другие преимущества списка, такие как состояние редактирования, жест для удаления и т. д. - person Shengchalover; 09.04.2021
comment
Я решил это с помощью List здесь stackoverflow.com/a/64028051/14327378, проверьте это, если вы хотите List: ) - person Harish saini; 12.04.2021

Объединили ответы @asperi, @akmin и @zrfrank в одно целое. По моему опыту, List более надежен и эффективен, чем LazyVStack, поэтому я все еще использую List для всего сложного, требующего надежности.

extension View {
    func listRow() -> some View {
        self.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            .listRowInsets(EdgeInsets(top: -1, leading: -1, bottom: -1, trailing: -1))
            .background(Color(.systemBackground))
    }
}

List {
    Color.red
         .listRow()


    Color.green
         .listRow()
}
person average Joe    schedule 14.10.2020
comment
LazyVStack не подходит, если вы хотите иметь разделы списка. - person Yiming Dong; 02.11.2020
comment
У меня это работает. Список + некоторый вид (не LazyVStack) - person Brownsoo Han; 27.11.2020

Я нашел это простое решение на форумах разработчиков Apple. У меня работает 14.4:

List {
   ...
}.listStyle(SidebarListStyle())

Кажется, это добавляет немного отступов по краям. Если для вас это проблема, вы можете попробовать использовать отрицательный отступ.

person Mark Phillips    schedule 12.02.2021
comment
Я думаю, что это лучшее решение прямо сейчас, очень элегантно! - person phuongzzz; 01.03.2021
comment
У меня не работает - person Karanveer Singh; 20.06.2021

На основе среднего показателя Джо answer У меня получился следующий модификатор:

struct ListSeparatorNone: ViewModifier {

    var backgroundColor: Color = Color(.systemBackground)
    
    func body(content: Content) -> some View {
        content
            .listRowInsets(EdgeInsets(top: -1, leading: 0, bottom: 0, trailing: 0))
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            .background(backgroundColor)
    }
}

Расширение просмотра:

extension View {
    func listSeparatorNone(backgroundColor: Color = Color(.systemBackground)) -> some View {
        self.modifier(ListSeparatorNone(backgroundColor: backgroundColor))
    }
}

Пример использования:

List {
    ForEach(viewModel.countries, id: \.self) { country in
        Text(country)
            .padding(.leading, 10)
    }
    .listSeparatorNone()
}
person Tzegenos    schedule 12.04.2021

Если у вас не так много ячеек и, следовательно, вам не нужно полагаться на LazyVStack для повышения производительности, вы можете вернуться к ScrollView + VStack:

ScrollView {
  VStack {
    Row1()
    Row2()
    Row3()
  }
}
person Senseful    schedule 04.11.2020

Вы также можете вызвать эту функцию в конце вашего VStack (то есть внутри списка).

Это будет наложение на List Seperator в iOS 14 :)

private func hideDefaultListSeperator() -> some View {
    Rectangle()
        .fill(colorScheme == .light ? Color.white : Color.black)
        .frame(maxHeight: 1)
}
person Ehsan Askari    schedule 08.11.2020

Обновлять:

Я нашел решение, которое работает как на iOS 13, так и на iOS 14, дает простой список и использует List как на iOS.

struct ListWithoutSepatorsAndMargins<Content>: View where Content: View {
    let content: () -> Content

    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }

    var body: some View {
        List {
            self.content()
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
                .listRowInsets(EdgeInsets())
                .background(Color.white)
        }
        .listStyle(PlainListStyle())
        .buttonStyle(NoButtonStyle())
    }
}

struct NoButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
    }

и сделайте следующее в SceneDelegate.swift, чтобы удалить серый выбор ячеек по умолчанию

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    UITableView.appearance().separatorStyle = .none
    UITableView.appearance().allowsSelection = false
   .......

и мы можем использовать его следующим образом

ListWithoutSepatorsAndMargins {
    ForEach(0..<5) { _ in
      Text("Content")
    }
}

ListWithoutSepatorsAndMargins {
     Group {
        self.groupSearchResults()
        self.myGroups()
        self.exploreGroups()
     }
  }
}
person Harish saini    schedule 23.12.2020
comment
И где нам найти SceneDelegate? - person Ovi Trif; 24.03.2021
comment
добавьте его при запуске вашего приложения, первый фрагмент кода, который запускается - person Harish saini; 24.03.2021
comment
в более поздних версиях ios я получаю интервал между ячейками по умолчанию, который можно удалить, выполнив следующие действия - person Harish saini; 24.03.2021
comment
дополнительный .environment(\.defaultMinListRowHeight, 1) из предыдущего решения - person Harish saini; 24.03.2021

Вот мое решение для iOS 14:

struct MyRowView: View {
  var body: some View {
    ZStack(alignment: .leading) {
      // Background color of the Row. It will spread under the entire row.
      Color(.systemBackground)
      NavigationLink(destination: Text("Details")) {
        EmptyView()
      }
      .opacity(0) // Hide the Disclosure Indicator

      Text("Go to Details").padding(.leading)
    }
    // These 2 lines hide the row separators
    .padding(.horizontal, -16) // Removes default horizontal padding
    .padding(.vertical, -6)    // Removes default vertical padding
  }
}

В включающем списке должен быть этот модификатор

.listStyle (PlainListStyle ()).

Преимущество этого решения перед использованием LazyVStack заключается в том, что вы по-прежнему можете использовать возможности редактирования списка.

К сожалению, это решение полагается на жестко запрограммированные значения для удаления системных отступов по умолчанию для каждой строки. Надеюсь, SwiftUI 3.0 предоставит простые модификаторы .separatorStyle (.none) и .accessoryType (.none).

Код для удаления индикаторов раскрытия информации находится по адресу: https://www.appcoda.com/hide-disclosure-indicator-swiftui-list/.

person Joss    schedule 03.06.2021

iOS 15:

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

List(items, id:\.self) {
    Text("Row \($0)")
        .listRowSeparator(.hidden)
}

???? Также вы можете установить для каждого разделителя любой цвет с помощью настроек listRowSeparatorTintColor, как я уже упоминал здесь, в этом ответе:

Демо

person Mojtaba Hosseini    schedule 08.06.2021

Приведенный выше ответ работает для меня, вы должны установить только ниже обе функции:

.listRowInsets(EdgeInsets())

.background(Color.white)

person Yi.Lin    schedule 09.07.2020