Post

Replies

Boosts

Views

Activity

How to connect SwiftUI state with UITable?
I use @Binding to sync data between SwiftUI component state and UITable state. my observations: while reordering @State variable of the TestView is updating, it can be checked by taping the button inside the table the data is not updating. 'log2' is always the same on reorder and which is more important the app crashes when I try to remove item. What to I missing? import SwiftUI import UIKit struct TestView: View { @State var items = ["item 1", "item 2", "item 3", "item 4", "item 5"] var body: some View { VStack { Button("Print Items") { print("log1", items) } ReorderableListView( items: $items ) { item in Text(item) } } } } private struct ReorderableListView<Content: View>: UIViewControllerRepresentable { @Binding var items: [String] let content: (String) -> Content class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate { var parent: ReorderableListView init(parent: ReorderableListView) { self.parent = parent } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { print("log2", parent.items) return parent.items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) let hostingController = UIHostingController(rootView: parent.content(parent.items[indexPath.row])) hostingController.view.backgroundColor = .clear cell.contentView.subviews.forEach { $0.removeFromSuperview() } cell.contentView.addSubview(hostingController.view) cell.separatorInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15) if indexPath.row == self.parent.items.count - 1 { cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude) } hostingController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: cell.contentView.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor), hostingController.view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor) ]) return cell } func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { let movedObject = parent.items.remove(at: sourceIndexPath.row) parent.items.insert(movedObject, at: destinationIndexPath.row) } func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { return true } func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { parent.items.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .automatic) } } } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } func makeUIViewController(context: Context) -> UITableViewController { let tableViewController = UITableViewController() tableViewController.tableView.dataSource = context.coordinator tableViewController.tableView.delegate = context.coordinator tableViewController.tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "Cell") tableViewController.tableView.isEditing = true return tableViewController } func updateUIViewController(_ uiViewController: UITableViewController, context: Context) { uiViewController.tableView.reloadData() } } private class CustomTableViewCell: UITableViewCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) } override func layoutSubviews() { super.layoutSubviews() superview?.subviews.filter({ "\(type(of: $0))" == "UIShadowView" }).forEach { (sv: UIView) in sv.removeFromSuperview() } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } #Preview { TestView() }
1
0
199
Oct ’24
what's wrong with `ToolbarItemGroup(placement: .keyboard)` inside `TavView`?
Why is there inconstancy of appearing the keyboard tool bar Item with tab view? Try to go to second tab and focus the field. Sometimes it does not appear (in my more complex project it does not appear >90% times). import SwiftUI struct MainTabView: View { var body: some View { TabView { FirstTabView() .tabItem { Label("Tab 1", systemImage: "house") } SecondTabView() .tabItem { Label("Tab 2", systemImage: "star") } } } } struct FirstTabView: View { @State private var text = "" var body: some View { NavigationStack { VStack { TextField("Enter something 1", text: $text) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("Done") { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } } } } } } struct SecondTabView: View { @State private var text = "" var body: some View { NavigationStack { VStack { TextField("Enter something 2", text: $text) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("Done") { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } } } } } } #Preview { MainTabView() }
0
1
169
Sep ’24
why ToolbarItemGroup appears only on the first tab?
// just check the below code. it's about simplest possible to // looks the same with simulator and real device with iOS 17.1+ import SwiftUI struct MainTabView: View { @FocusState private var focusedField: Bool var body: some View { TabView { TextField("test 1", text: .constant("test 1")) .focused($focusedField) .tabItem { Label("tab 1", systemImage: "number") } .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("Done") { focusedField = false } } } Text("test 2") .tabItem { Label("Home", systemImage: "house") } TextField("test 3", text: .constant("test 3")) .focused($focusedField) .tabItem { Label("tab 3", systemImage: "number") } .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("Done") { focusedField = false } } } } .tint(.primary) } } @main struct MainApp: App { var body: some Scene { WindowGroup { MainTabView() } } }
1
0
325
Aug ’24