Как открыть новый ViewController строки ячейки и передать данные программно без раскадровки

#ios #uitableview #autolayout

Вопрос:

Я хочу открыть DetailViewController, щелкнув строку в UITableView, передать данные, чтобы отобразить их в DetailViewController, и иметь возможность вернуться стрелкой назад. Я знаю, как это сделать с помощью раскадровки и навигационной ссылки, но в данном случае я понятия не имею. Как это сделать программно без раскадровки? Вот мой код:

ListViewController:

 import UIKit

class ListViewController: UIViewController {

var collection: UICollectionView!
var tableView = UITableView()
private let viewModel = ListViewModel()
let detailViewController = DetailViewController() //I want to open this one

var users = [DataModel]()

struct Cells {
    static let listCellTablewViewCell = "ListCellTableViewCell"
}

override func viewDidLoad() {
    super.viewDidLoad()
   
    self.viewModel.bindPageViewModelToController = {
        self.fetchData()
    }
    setupUI()
    configureTableView()
}

func fetchData() {
    users  = self.viewModel.pageData.data
    tableView.reloadData()
}

fileprivate func setupUI() {
    collection = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
    collection.backgroundColor = .red
    collection.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(collection)
    
    collection.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
    collection.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    collection.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    collection.heightAnchor.constraint(equalToConstant: 400).isActive = true
}

func configureTableView() {
    view.addSubview(tableView)
    setTableViewDelegates()
    tableView.rowHeight = 100
    tableView.register(ListCellTableViewCell.self, forCellReuseIdentifier: "ListCellTableViewCell")
    tableView.pin(to: view)
}

func setTableViewDelegates() {
    tableView.delegate = self
    tableView.dataSource = self
}

}

extension ListViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return users.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: Cells.listCellTablewViewCell) as! ListCellTableViewCell
    let data = users[indexPath.row]
    cell.set(data: data)
    
    return cell
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let row = indexPath.row
   
}
}
}
 

ListCellTableViewCell:

 import UIKit

class ListCellTableViewCell: UITableViewCell {

var firstNameLabel = UILabel()
var lastNameLabel = UILabel()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    addSubview(firstNameLabel)
    addSubview(lastNameLabel)
    
    configureFirstNameLabel()
    configureFirstNameLabel()
    setFirstnameLabel()
    setLastNameLabel()
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func set(data: DataModel) {
    firstNameLabel.text = data.firstName
    lastNameLabel.text = data.lastName
}

func configureFirstNameLabel() {
    firstNameLabel.numberOfLines = 0
    firstNameLabel.backgroundColor = .red
}

func configureLastNameLabel() {
    lastNameLabel.numberOfLines = 0
    lastNameLabel.adjustsFontSizeToFitWidth = true
    lastNameLabel.backgroundColor = .blue
}

func setFirstnameLabel() {
    firstNameLabel.translatesAutoresizingMaskIntoConstraints = false
    firstNameLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    firstNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12).isActive = true
    firstNameLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true

}

func setLastNameLabel() {
    lastNameLabel.translatesAutoresizingMaskIntoConstraints = false
    lastNameLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    lastNameLabel.leadingAnchor.constraint(equalTo: lastNameLabel.trailingAnchor, constant: 20).isActive = true
    lastNameLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
    lastNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12).isActive = true
}
}
 

Комментарии:

1. Вы используете навигационный контроллер или хотите отобразить детали модально?

2. Раскадровки нет. Я не знаю, как открыть новый вид, когда нет раскадровки или SwiftUI. Я хочу щелкнуть строку, а затем открыть представление, в котором отображаются данные ячейки. Надеюсь, я написал это понятно.

3. Вы можете создать экземпляр контроллера вида с помощью инициализатора — let newVC = DetailViewController() и задать свойство для передачи выбранного элемента, но есть ли у вас навигационный контроллер на текущем контроллере вида, который вы хотите использовать, или вы хотите показать новый контроллер вида модально?

4. Модально — это хорошая идея.

5. Я сделал, как вы упомянули, и это работает. Спасибо!