Células de linha da lista Swiftui definem o preenchimento após a exibição de exibição

8

Eu tenho uma lista padrão apenas com um texto e no lado direito a seta para navegação. Mas, depois que a lista é carregada e exibida na Tela, a lista adota as células, acho que adicionam preenchimento à esquerda e à direita. Mas isso não parece bom, então parece que a lista está atrasada!

List {
                       ForEach(0..<book.chapters) { index in
                           NavigationLink(destination: ReadingView(book: self.book, chapter: index)){
                               Text("Kapitel \(index + 1)")
                           }
                       }
        }


           .navigationBarTitle(Text(book.long_name), displayMode: .inline)

insira a descrição da imagem aqui

prumo
fonte
1
Isso é quase certamente um bug. SwiftUI ainda é novo, e tenho notado várias pequenas coisas como esta com a lista, Form, etc. Melhor aposta é o feedback arquivo com Apple: feedbackassistant.apple.com
John M.
Eu acho que isso tem algo a ver com o uso do ForEach em uma lista. Quando faço uma lista estática, isso não acontece, mas acontece quando uso o ForEach para fazer um loop sobre os dados.
radicalappdev
Esperamos que esteja consertado em breve. Eu tentei desativar o preenchimento e tudo mais, parece que ainda persiste. Vou verificar aqui novamente.
Repose

Respostas:

1

Eu tenho o mesmo problema, mas apenas no simulador. Quando estou executando o aplicativo em qualquer telefone, não importa quantos anos, ele funciona perfeitamente como seria de esperar. Você deveria tentar isso.

Edit: ah agora eu vejo os dados móveis, você está no seu telefone. Nesse caso, você pode registrar um relatório de bug na Apple, aguardar e sempre usar o software mais recente.

Lilfaen
fonte
0

Existe uma possível correção para isso, que produz outras complicações: Animações. Esse bug estranho é afetado por animações, então dê uma animação como

List {
                   ForEach(0..<book.chapters) { index in
                       NavigationLink(destination: ReadingView(book: self.book, chapter: index)){
                           Text("Kapitel \(index + 1)")
                       }
                   }
    }.animation(.easeInOut(duration: 500))


       .navigationBarTitle(Text(book.long_name), displayMode: .inline)

Tornará o bug pelo menos invisível, mas esteja avisado de que todas as subvisões herdarão essa animação; portanto, você precisará substituí-lo manualmente novamente por elas. Se você estiver escrevendo um aplicativo profissional, use a correção do TableView da resposta de Repose.

Estranho: descobrimos que isso acontece no iPhone XR e 11 (simulador e dispositivo real), mas não no iPhone 11 Pro, por isso pode ocorrer apenas em dispositivos LCD ???

Espero que isso ajude os futuros visitantes deste tópico que tropeçam nesse tópico, como eu fiz ao experimentar esse bug

hustenbonbon
fonte
0

Eu vim com uma solução alternativa para corrigir esse problema. Uma ressalva, enquanto corrige a mudança na tabela, introduz um atraso na animação do título da barra de navegação, para que você seja avisado.

Você pode usar o TableViewController do UIKit enquanto isso a Apple corrige o objeto List do SwiftUI.

Em resumo, você precisa criar um TableViewController e envolvê-lo em UIViewControllerRepresentable para injetá-lo na visualização SwiftUI. A melhor ação de navegação é feita pelo método delegado didSelectRowAt.

Atualização: parece que o problema foi resolvido no XCode 11.4 mais recente (no entanto, mais problemas estão presentes no ambiente do simulador agora)

Eu tenho um código completo aqui: https://gist.github.com/Rep0se/97d7a97cfd05f42aa597904e6a2cfd3d

//
//  UIKitSwiftUITableView.swift
//  Table Test
//
//  Created on 2020-02-19.
//  Note: While this solution fixes Table shifting bug, it introduces Navigation Bar Title bug for a Large Title. Beware.
//  LBTATools can be downloaded using Swift Package Manager from: https://github.com/bhlvoong/LBTATools
//

import SwiftUI
import LBTATools

struct UIKitSwiftUITableView: View {
    var body: some View {
        NavigationView {
            UIKitSwiftUIContainer()
        }
    }
}

struct Restaurante: Hashable {
    let name: String
    let image: String
}

struct UIKitSwiftUIContainer: View {
    let restaurants = [
        Restaurante(name: "Joe's Original", image: "house"),
        Restaurante(name: "Pheasant Plucker", image: "house.fill"),
        Restaurante(name: "Radius", image: "music.house"),
        Restaurante(name: "The Ship", image: "music.house.fill")
    ]
    var body: some View {
        UIKitTableViewRepresentable(restaurants: restaurants)
            .navigationBarTitle("Select a restaurant") // <- UI bug exests for Navigation Bar Title
            .edgesIgnoringSafeArea(.all)
    }
}

struct UIKitTableViewRepresentable: UIViewControllerRepresentable {
    typealias UIViewControllerType = UIViewController

    let restaurants: [Restaurante]
    init(restaurants: [Restaurante]) {
        self.restaurants = restaurants
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<UIKitTableViewRepresentable>) -> UIViewController {
        UIKitComboTableViewController(restaurants: restaurants)
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<UIKitTableViewRepresentable>) {

    }
}

class UIKitComboTableViewController: UITableViewController {

    let reuseIdentifier = "reuseIdentifier"
    var restaurants: [Restaurante]
    init(restaurants: [Restaurante]) {
        self.restaurants = restaurants
        super.init(style: .insetGrouped)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(TableCell.self, forCellReuseIdentifier: reuseIdentifier)
    }

    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return restaurants.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as? TableCell {
            cell.viewModel.name = restaurants[indexPath.row].name
            cell.viewModel.image = restaurants[indexPath.row].image
            cell.accessoryType = .disclosureIndicator
            return cell
        } else {
            return UITableViewCell()
        }
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let hostingController = UIHostingController(rootView: UIKitSwiftUIContainer())
        show(hostingController, sender: self)
    }
}

class TableCell: UITableViewCell {
    let viewModel = RestaurantViewModel()
    lazy var row = ListRowView(viewModel: viewModel)
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let hostingController = UIHostingController(rootView: row)
        addSubview(hostingController.view)
        hostingController.view.fillSuperview()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

struct ListRowView: View {
    @ObservedObject var viewModel: RestaurantViewModel
    var body: some View {
        HStack{
            Image("Avatar").renderingMode(.original).padding()
            Text(viewModel.name)
                .foregroundColor(.black)
            Spacer()
        }.frame(minHeight: 44)
    }
}

class RestaurantViewModel: ObservableObject {
    @Published var name = ""
    @Published var image = ""
}

struct UIKitSwiftUITableView_Previews: PreviewProvider {
    static var previews: some View {
        UIKitSwiftUITableView()
    }
}
Repouso
fonte