A
A
Andrew2021-03-04 12:41:47
Swift
Andrew, 2021-03-04 12:41:47

How to make a form in UITableView?

Friends, I'm trying to make a form in UItableview. Several questions arose during the process. I'm not sure that I basically approached the issue from the right side.

There is a simple custom cell:

class CreateUpdateCell: UITableViewCell {
    
    static let reuseID = "CreateUpdateCell"
    
    let imageField = UIImageView()
    let textField = UITextField()

 ...
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configure()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func set(image: UIImage, text: String) {
        imageField.image = image
        textField.placeholder = text
    }
    
    func configure() { ... }
}


In TableView I do this:

extension ToolCreateVC: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: CreateUpdateCell.reuseID, for: indexPath) as! CreateUpdateCell
        cell.textField.tag = indexPath.row
        switch indexPath.row {
        case 0:
            cell.set(image: UIImage(systemName: "pencil")!, text: "Наименование")
            cell.textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged)
        case 1:
            cell.set(image: UIImage(systemName: "tray")!, text: "Инвентарный номер")
            cell.textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged)
        case 2:
            cell.set(image: UIImage(systemName: "calendar")!, text: "Дата приобретения")
            cell.textField.inputView = buyDateDatePicker
            buyDateDatePicker.textField = cell.textField
            cell.textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged)
        case 3:
            cell.set(image: UIImage(systemName: "pencil")!, text: "Комментарий")
            cell.textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged)
        default:
            break
        }
        return cell
    }
    
    @objc func textFieldValueChanged(sender: UITextField) {
        guard let value = sender.text else { return }
        switch sender.tag {
        case 0:
            tool.name = value
        case 1:
            tool.codeNumber = value
        case 2:
            tool.buyDate = value.convertToyyyyMMddFormat()
        case 3:
            tool.comment = value
        default:
            break
        }
    }
}


There will be several questions, because they are similar to each other and to produce topics to ask each individual does not see the point.

Question 1: in order to save the value in the structure being created, each textField has to be assigned a tag with the number indexPath.row, so that in the textFieldValueChanged handler we can understand which field has actually changed + every time the button is pressed, I write a new value to the structure. I don't like this solution. Tell me, is this a norm solution or a crooked one and is there a better one?

Question 2: It is necessary to save data from buyDateDatePicker with .valueChanged in textField and structure. The only option that came to mind is to create a child class for datePicker:

class customUIDatePicker: UIDatePicker {
    var textField = UITextField()
}


And do something like this:
buyDateDatePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged)

cell.textField.inputView = buyDateDatePicker
buyDateDatePicker.textField = cell.textField
@objc func dateChanged() {
        buyDateDatePicker.textField.text = buyDateDatePicker.date.convertToddMMyy()
        tool.buyDate = buyDateDatePicker.textField.text?.convertToyyyyMMddFormat()
    }

But again, I'm not sure that this is not a crooked solution.

Question 3: If I initialize the tool, I can then change each variable separately without any problems. If I do force unwrap, then the object seems to be nil and cannot be assigned separately. Again, the question of the correctness of the decision arises. What is the best way to save all values ​​into an array during editing and then create an object based on it at once or create an empty object (I don’t like it, because if an object has many variables, then it looks somehow miserable) and change each variable separately?

class ToolCreateVC: UIViewController {
    
    //1:
    var tool: Tool = Tool(id: 0, name: "", codeNumber: nil, buyDate: nil, comment: nil, toolmove: nil)
    //2:
    var tool2: Tool!
// Но тогда не могу обратиться к переменным, например: tool2.name
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Golovin, 2021-03-26
@dadduUrsa

Good afternoon!
It's not entirely clear what you want to achieve. I so understand it what type of the table in which it is possible to change the data?
Then why dance with switch case? Make a model, in a cell through didSet processing and so on.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question