Swiftui List Row Cells establece el relleno después de que aparece Ver

8

Tengo una lista estándar solo con un texto y en el lado derecho la flecha para la navegación. Pero después de que la lista se carga y aparece en la pantalla, la lista se adapta a las celdas, creo que agregan relleno a la izquierda y a la derecha. Pero esto no se ve bien, ¡así que parece que la lista está retrasada!

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)

ingrese la descripción de la imagen aquí

Beto
fuente
1
Esto es casi seguro que es un error. SwiftUI es todavía nuevo, y me he dado cuenta de varias pequeñas cosas como esta con la lista, forma, etc. La mejor opción es la retroalimentación de archivos con Apple: feedbackassistant.apple.com
John M.
Creo que esto tiene algo que ver con el uso de ForEach en una lista. Cuando hago una lista estática, esto no sucede, pero sucede cuando uso ForEach para recorrer los datos.
radicalappdev
Con suerte, se solucionará pronto. He intentado deshabilitar el relleno y todo lo demás, parece que aún persiste. Me registraré aquí de nuevo.
Reposar el

Respuestas:

1

Tengo el mismo problema pero solo en el simulador. Cuando estoy ejecutando la aplicación en cualquier teléfono, no importa la antigüedad, funciona perfectamente como cabría esperar. Deberías intentar eso.

Editar: ah ahora veo los datos móviles, estás en tu teléfono. En ese caso, puede presentar un informe de error a Apple y esperar y utilizar siempre el software más reciente.

Lilfaen
fuente
0

Hay una posible solución para esto que produce otras complicaciones: animaciones. Este extraño error se ve afectado por las animaciones, así que solo dale una animación 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)

Hará que el error sea al menos invisible, pero tenga en cuenta que todas las subvistas heredarán esa animación, por lo que debe anularla manualmente de nuevo. Si está escribiendo una aplicación profesional, use la solución TableView de la respuesta de Repose.

Lo extraño: descubrimos que sucede en el iPhone XR y 11 (simulador y dispositivo real) pero no en el iPhone 11 Pro, por lo que solo puede ocurrir en dispositivos LCD.

Espero que esto ayude a los futuros visitantes de este hilo que tropiecen con este hilo como lo hice mientras experimentaba ese error

hustenbonbon
fuente
0

Se me ocurrió una solución para solucionar este problema. Una advertencia, mientras soluciona el cambio en la tabla, introduce un retraso en la animación del título de la barra de navegación, por lo que está advertido.

Mientras tanto, puede usar TableViewController de UIKit hasta que Apple arregle el objeto Lista de SwiftUI.

En resumen, debe crear un TableViewController y envolverlo en UIViewControllerRepresentable para luego inyectarlo en su vista SwiftUI. La acción de navegación se realiza mejor a través del método delegado didSelectRowAt.

Actualización: parece que el problema se ha resuelto en el nuevo XCode 11.4 (sin embargo, ahora hay más problemas en el entorno del simulador)

Tengo un código completo aquí: 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()
    }
}
Reposo
fuente