Swiftuiリストの行セルは、ビューが表示された後にパディングを設定しました


8

テキストが1つだけの標準リストがあり、右側にナビゲーション用の矢印があります。しかし、リストがロードされてScreenに表示された後、リストはセルを適応させます。セルは左と右にパディングを追加すると思います。しかし、これは見栄えが良くないので、リストが遅れているように見えます!

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)

ここに画像の説明を入力してください


1
これはほぼ間違いなくバグです。:SwiftUIはまだ新しいです、と私は等のリスト、フォーム、とこのようないくつかの小さな事に気づいたの最善の策は、Appleとのファイルのフィードバックであるfeedbackassistant.apple.com
ジョンM.

これはリストでForEachを使用することと関係があると思います。静的なリストを作成する場合、これは発生しませんが、ForEachを使用してデータをループする場合は発生します。
radicalappdev '10 / 11/19

うまくいけば、すぐに修正されるでしょう。私はパディングや他のすべてを無効にしてみましたが、それでもまだ持続するようです。またチェックインします。
休息

回答:


1

私は同じ問題を抱えていますが、シミュレータのみです。私がどの電話でアプリを実行しているときでも、何歳になっても、期待どおりに問題なく動作します。あなたはそれを試すべきです。

編集:ああ、モバイルデータが表示されました。あなたはあなたの携帯電話にいます。その場合は、アップルにバグレポートを提出して、最新のソフトウェアを使用してください。


0

これには他の複雑な問題を引き起こす可能性のある修正があります:アニメーション。この奇妙なバグはアニメーションの影響を受けるため、次のようなアニメーションを提供してください

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)

少なくともバグを非表示にしますが、すべてのサブビューがそのアニメーションを継承することを警告されるため、手動で再度オーバーライドする必要があります。プロのアプリを作成している場合は、Reposeの回答にあるTableViewの修正を使用してください。

奇妙なこと:iPhone XRおよび11(シミュレーターおよび実際のデバイス)で発生するが、iPhone 11 Proでは発生しないため、LCDデバイスでのみ発生する可能性があることがわかりました。

これがバグを経験しているときに私がしたようにこのスレッドにつまずくこのスレッドの将来の訪問者に役立つことを願っています


0

この問題を修正するための回避策を考え出しました。注意点の1つは、テーブルのシフトは修正されますが、ナビゲーションバーのタイトルアニメーションに遅延が発生するため、警告が表示されます。

Appleが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()
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.