在出现视图后,Swiftui列表行单元格设置填充

时间:2019-10-21 12:22:16

标签: ios swift swiftui ios13 swiftui-list

我有一个标准列表,仅包含一个文本,右侧是用于导航的箭头。但是在加载列表并显示在屏幕上之后,该列表添加了我认为它们在左侧和右侧添加填充的单元格。但这看起来不太好,所以列表似乎滞后了!

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)

enter image description here

4 个答案:

答案 0 :(得分:1)

我有相同的问题,但仅在模拟器上。当我在任何手机上运行该应用程序时,无论它有多旧,它都可以像人们期望的那样完美运行。 您应该尝试一下。

编辑:啊,现在我看到了移动数据,您在手机上。在这种情况下,您可以向Apple提交错误报告,然后等待并始终使用最新软件。

答案 1 :(得分:0)

我想出了一种解决方法来解决此问题。一个警告,虽然它固定了表格中的偏移,但它在“导航栏标题”动画中引入了延迟,因此警告您。

在苹果修复SwiftUI的List对象之前,您可以同时使用UIKit的TableViewController。

总而言之,您需要创建一个TableViewController并将其包装在UIViewControllerRepresentable中,然后将其注入到SwiftUI视图中。导航动作最好通过didSelectRowAt委托方法完成。

更新:似乎该问题已在最新的XCode 11.4中解决(但是现在模拟器环境中存在更多问题)

我在这里有完整的代码: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()
    }
}

答案 2 :(得分:0)

编辑:iOS 13.6解决了该问题,我从后面开始的解决方案现在会产生故障而不是解决!

对此有一个潜在的解决方法,它可能会导致其他并发症:

动画。 这个怪异的错误会受到动画的影响,所以只需给它一个动画

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)

将使该bug至少不可见,但要警告所有子视图都将继承该动画,因此您需要手动对其进行重写。如果您要编写专业的应用程序,请使用Repose的答案中的TableView修复程序。

奇怪的事情:我们发现它发生在iPhone XR和11(模拟器和真实设备)上,但没有发生在iPhone 11 Pro上,因此它可能只发生在LCD设备上?

我希望这可以帮助该线程的未来访问者像我在遇到该错误时一样偶然发现该线程

答案 3 :(得分:0)

List
{
   ForEach(items)
   {(item) in
      NavigationLink(destination:Destination())
      {
       Text("example")
      }
   }
}.listStyle(InsetListStyle())

.listStyle(InsetListStyle())帮助我解决了XCode12中的问题。