Danh sách Swiftui Row Cells đặt phần đệm sau khi View xuất hiện


8

Tôi có một Danh sách tiêu chuẩn chỉ với một Văn bản và ở bên phải mũi tên để điều hướng. Nhưng sau khi danh sách đang tải và xuất hiện trên Màn hình, danh sách sẽ thêm các ô mà tôi nghĩ rằng chúng thêm phần đệm ở bên trái và bên phải. Nhưng điều này có vẻ không tốt, vì vậy nó trông giống như danh sách bị trễ!

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)

nhập mô tả hình ảnh ở đây


1
Đây gần như chắc chắn là một lỗi. SwiftUI vẫn còn mới và tôi đã nhận thấy một vài điều nhỏ như thế này với Danh sách, Biểu mẫu, v.v. Đặt cược tốt nhất là phản hồi tệp với Apple: feedbackassistant.apple.com
John M.

Tôi nghĩ rằng điều này có liên quan đến việc sử dụng ForEach trong danh sách. Khi tôi tạo một danh sách tĩnh, điều này không xảy ra, nhưng nó xảy ra khi tôi sử dụng ForEach để lặp lại dữ liệu.
triệt để

Hi vọng nó sẽ được sửa sớm. Tôi đã thử vô hiệu hóa phần đệm và mọi thứ khác, dường như vẫn còn tồn tại. Tôi sẽ kiểm tra lại ở đây một lần nữa.
Nghỉ ngơi

Câu trả lời:


1

Tôi có cùng một vấn đề nhưng chỉ trên trình giả lập. Khi tôi chạy ứng dụng trên bất kỳ điện thoại nào, cho dù bao nhiêu tuổi, nó vẫn hoạt động hoàn toàn tốt như mọi người mong đợi. Bạn nên thử nó.

Chỉnh sửa: ah bây giờ tôi thấy dữ liệu di động, bạn đang ở trên điện thoại của bạn. Trong trường hợp đó, bạn có thể gửi báo cáo lỗi cho Apple và chờ và luôn sử dụng phần mềm mới nhất.


0

Có một cách khắc phục tiềm năng cho việc này tạo ra các biến chứng khác: Ảnh động. Lỗi kỳ lạ này bị ảnh hưởng bởi hình ảnh động, vì vậy chỉ cần cung cấp cho nó một hình ảnh động như

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)

Sẽ làm cho lỗi ít nhất là vô hình, nhưng được cảnh báo rằng tất cả các cuộc phỏng vấn sẽ kế thừa hoạt hình đó, vì vậy bạn cần phải ghi đè lại nó một cách thủ công cho chúng. Nếu bạn đang viết một ứng dụng chuyên nghiệp, thay vào đó hãy sử dụng bản sửa lỗi TableView từ câu trả lời của Repose.

Điều kỳ lạ: Chúng tôi phát hiện ra điều đó xảy ra trên iPhone XR và 11 (Trình mô phỏng và thiết bị thực) nhưng không phải trên iPhone 11 Pro, vì vậy nó chỉ có thể xảy ra trên các thiết bị LCD ???

Tôi hy vọng điều này sẽ giúp khách truy cập tương lai của chủ đề này, người vấp phải chủ đề này giống như tôi đã làm trong khi gặp lỗi đó


0

Tôi đã đưa ra một cách giải quyết để khắc phục vấn đề này. Một cảnh báo, trong khi nó sửa sự thay đổi trong bảng, nó đưa ra một độ trễ trong hoạt hình Tiêu đề Thanh điều hướng, vì vậy bạn được cảnh báo.

Bạn có thể sử dụng TableViewControll của UIKit trong thời gian này cho đến khi Apple sửa đối tượng Danh sách của SwiftUI.

Tóm lại, bạn cần tạo TableViewControll và bọc nó trong UIViewControllRepftimeable để sau đó đưa nó vào chế độ xem SwiftUI của bạn. Hành động điều hướng được thực hiện tốt nhất thông qua phương thức ủy nhiệm didSelectRowAt.

Cập nhật: có vẻ như sự cố đã được giải quyết trong XCode 11.4 mới nhất (tuy nhiên hiện tại có nhiều vấn đề hơn trong môi trường giả lập)

Tôi có một mã đầy đủ ở đây: 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()
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.