Last active
February 27, 2020 14:56
-
-
Save Rep0se/97d7a97cfd05f42aa597904e6a2cfd3d to your computer and use it in GitHub Desktop.
UIKit TableViewController fix for SwiftUI List navigation bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment