Swiftui List Row Cells setzen die Auffüllung, nachdem View angezeigt wird


8

Ich habe eine Standardliste mit nur einem Text und auf der rechten Seite den Pfeil zur Navigation. Aber nachdem die Liste geladen und auf dem Bildschirm angezeigt wurde, fügt die Liste die Zellen hinzu, von denen ich denke, dass sie links und rechts Auffüllungen hinzufügen. Aber das sieht nicht gut aus, also sieht es so aus, als ob die Liste hinterherhinkt!

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)

Geben Sie hier die Bildbeschreibung ein


1
Dies ist mit ziemlicher Sicherheit ein Fehler. SwiftUI ist noch neu, und ich habe einige kleine Dinge wie diese mit Liste, Formular usw. bemerkt. Die beste Wette ist das Datei-Feedback mit Apple: feedbackassistant.apple.com
John M.

Ich denke, das hat etwas mit der Verwendung von ForEach in einer Liste zu tun. Wenn ich eine statische Liste erstelle, geschieht dies nicht, aber wenn ich ForEach verwende, um Daten zu durchlaufen.
Radicalappdev

Hoffentlich wird es bald behoben. Ich habe versucht, das Auffüllen zu deaktivieren, und alles andere scheint immer noch zu bestehen. Ich werde hier wieder einchecken.
Ruhe

Antworten:


1

Ich habe das gleiche Problem, aber nur auf dem Simulator. Wenn ich die App auf einem beliebigen Telefon ausführe, egal wie alt, funktioniert sie einwandfrei, wie man es erwarten würde. Das solltest du versuchen.

Edit: ah jetzt sehe ich die mobilen Daten, du bist auf deinem Handy. In diesem Fall können Sie einen Fehlerbericht an Apple senden und warten und immer die neueste Software verwenden.


0

Es gibt eine mögliche Lösung dafür, die andere Komplikationen hervorruft: Animationen. Dieser seltsame Fehler ist von Animationen betroffen. Geben Sie ihm einfach eine Animation wie

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)

Macht den Fehler zumindest unsichtbar, aber seien Sie gewarnt, dass alle Unteransichten diese Animation erben, sodass Sie sie manuell erneut überschreiben müssen. Wenn Sie eine professionelle App schreiben, verwenden Sie lieber den TableView-Fix aus der Antwort von Repose.

Seltsame Sache: Wir haben herausgefunden, dass es auf iPhone XR und 11 (Simulator und reales Gerät) passiert, aber nicht auf iPhone 11 Pro, also möglicherweise nur auf LCD-Geräten ???

Ich hoffe, dies hilft zukünftigen Besuchern dieses Threads, die über diesen Thread stolpern, wie ich es getan habe, als ich diesen Fehler erlebt habe


0

Ich habe eine Problemumgehung gefunden, um dieses Problem zu beheben. Eine Einschränkung: Während die Verschiebung in der Tabelle behoben wird, wird die Animation des Titels der Navigationsleiste verzögert, sodass Sie gewarnt werden.

Sie können den TableViewController von UIKit in der Zwischenzeit verwenden, bis Apple das ListUI-Objekt von SwiftUI repariert.

Zusammenfassend müssen Sie einen TableViewController erstellen und in UIViewControllerRepresentable einschließen, um ihn dann in Ihre SwiftUI-Ansicht einzufügen. Die Navigationsaktion erfolgt am besten über die delegate-Methode didSelectRowAt.

Update: Anscheinend wurde das Problem im neuesten XCode 11.4 behoben (es sind jedoch jetzt mehr Probleme in der Simulatorumgebung vorhanden).

Ich habe hier einen vollständigen Code: 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()
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.