Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.0k views
in Technique[技术] by (71.8m points)

uitableview - How to save UITextField text and update UIButton title in a custom XIB Cell?

Here, I have a Table View that contains custom XIB cells. My goal is to update the custom XIB cell content by: (1) saving the "Task Name" UITextField text + (2) updating "Set Time" UIButton title to show, for example "1:30", after the time is set in the pop-up View Controller.

However, I got a "Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift" message at "cell.timeButton.setTitle("(savedTaskTime[indexPath.row].hour + ":" + savedTaskTime[indexPath.row].minute[0])", for: .normal) when trying to update the "Set Time" UIButton title to show time.

1 -press set time-> 2

Firstly, I have two public custom class types:

// Custom class type to set hour/min for task time
public class TimerData {
    var hour: String
    var minute: [String]
    
    init(hour: String, minute: [String]) {
        self.hour = hour
        self.minute = minute
    }
}

// Custom class type to set task name/time in UITableView
public class TaskData {
    var name: String
    var time: [String]
    
    init(name: String, time: [String]) {
        self.name = name
        self.time = time
    }
}

This is my code for the View Controller that contains the Table View with the custom XIB cells:

class TaskListViewController: UIViewController {
    
    // MARK: - Outlet Variables
    @IBOutlet weak var taskList: SelfSizedTableView!
    ...
    
    // MARK: - Instance Variables
    var taskData = [TaskData]()
    var savedTaskName = [String]()
    var savedTaskTime = [TimerData]()
    ...
    
    // MARK: - View Controller Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Register TaskListCell.xib file
        let taskCellNib = UINib(nibName: "TaskCell", bundle: nil)
        taskList.register(taskCellNib, forCellReuseIdentifier: "taskCell")
        ...
    }
    
    // MARK: - Methods

    // Segues to selectTime screen pop-up when "set time button" is pressed
    @objc func showSelectTime(_ sender: UIButton) {
        performSegue(withIdentifier: "selectTime", sender: nil)
    }
    
}

extension TaskListViewController: UITableViewDataSource, UITableViewDelegate {
    
    // Return the number of rows in table view
    func tableView(_ tableView: UITableView,
                   numberOfRowsInSection section: Int) -> Int {
        return taskCount
    }
    
    // Return the configured cell that is inserted in table view
    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as! TaskListCell
        
        // Configure nameField in cell
        cell.nameField.tag = indexPath.row
        cell.nameField.delegate = self
        cell.nameField.text = savedTaskName[indexPath.row]
        
        // Configure timeButton in cell
        cell.timeButton.tag = indexPath.row
        cell.timeButton.addTarget(self, action: #selector(showSelectTime(_:)), for: .touchUpInside)
        cell.timeButton.setTitle("(savedTaskTime[indexPath.row].hour + ":" + savedTaskTime[indexPath.row].minute[0])", for: .normal)
        
        return cell
    }
}

extension TaskListViewController: UITextFieldDelegate {
    
    // Saves textField text input
    func textFieldDidEndEditing(_ textField: UITextField) {
        if let savedText = textField.text {
            savedTaskName.append(savedText)
        } else {
            savedTaskName.append("")
        }
    }
    
    // Resigns text field in focus + dismisses upon pressing return
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

This is my code for the View Controller that pops-up when the "set time button" is pressed:

class SelectTimeViewController: UIViewController {
    
    // MARK: - Instance Variables
    var timeFloat: Float = 0
    var hour: String = "0"
    var min: String = "00"
    var savedTime = [TimerData]()
    
    // MARK: - Outlet Variables
    @IBOutlet weak var setTimeLabel: UILabel!
    @IBOutlet weak var setTimeSlider: UISlider!
    
    // MARK: - Action Methods
    
    // Updates UISlider and setTimeLabel value
    @IBAction func adjustTimeSlider(_ sender: UISlider) {
        timeFloat = sender.value
        updateTimeLabel()
    }
    
    // Save set time + returns to TaskList screen
    @IBAction func saveTimeButton(_ sender: UIButton) {
        let timeCheck = (hour, min)
        if timeCheck != ("0", "00") {
            savedTime.append(TimerData(hour: hour, minute: [min]))
            dismiss(animated: true, completion: nil)
        } else {
            ...
            present(alert, animated: true, completion: nil)
        }
    }
    
    // MARK: - View Controller Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        
        updateTimeLabel()
        setTimeSlider.value = timeFloat
        
        setTimeSlider.addTarget(self, action: #selector(adjustTimeSlider(_:)), for: .valueChanged)

    }
    
    // MARK: - Methods
    
    // Update Time Label with Slider Value
    func updateTimeLabel() {
        
        let timeInt = Int(timeFloat)
        let timeSet = "(hour + ":" + min)"

        // Set hour value
        hour = "(timeInt / 60)"
        
        // Check min conditions + set min value
        let minCheck = timeInt % 60
        
        switch minCheck {
        case 0:
            min = "00"
        case 1...9:
            min = "0" + "(minCheck)"
        default:
            min = "(minCheck)"
        }
        
        // Update setTimeLabel
        setTimeLabel.text = timeSet
    }
    
    // MARK: - Navigation

    // Pass savedTime to savedTaskTime in TaskListViewController
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "savedTime" {
            let controller = segue.destination as! TaskListViewController
            controller.savedTaskTime = savedTime
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...