使用单独的控制器将自定义单元格中的标签设置为数组中的名称

Set labels in a custom cell to names from an array using a separate controller

我有一个带有 table 的视图控制器。视图控制器有一个按钮,可以连接到另一个带有 4 个文本字段的控制器。有一个名称文本字段和其他三个可以输入数字的文本字段。当用户按下添加时,将附加一个数组,并在更新前一个视图控制器中的 table 时关闭视图控制器。然后向用户显示添加了新单元格的 table。该单元格有 4 个标签。

我想弄清楚如何将单元格中的每个标签设置为创建新单元格的视图控制器中的 4 个文本字段。这是创建了单元格的视图控制器的图片:

这是按下加号按钮时通过更新数组创建单元格的视图控制器:

我希望能够设置最左边的标签来代表每次添加到数组中的名称。用户第一次单击加号按钮时,文本字段视图控制器将弹出,用户可以将名称放入文本字​​段中。当按下添加按钮时,左侧的标签将显示附加数组的控制器中的名称。通过视图控制器添加的下一个名称将位于先前输入的名称下方的单元格中,依此类推。我需要获取数组才能正确显示文本。我最初希望单元格具有文本字段,用户可以将信息放在那里,但单元格数据没有正确发送到 firebase 数据库。

这是第一个视图控制器的代码:

import UIKit
import Firebase

class ConsiderationsTestViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var tableView: UITableView!

static var numberOfPeople: [String] = []

var AddPersonCell = "AddPersonCell"

@IBOutlet weak var CompanyImage: UIImageView!

@IBOutlet weak var companyNameTextFieldConsiderations: UITextField!

@IBOutlet weak var companyDescriptionTextFieldConsiderations: UITextField!

@IBOutlet weak var startDateTextFieldConsiderations: UITextField!

@IBOutlet weak var endDateTextFieldConsiderations: UITextField!

let datePickerS = UIDatePicker()
let datePickerE = UIDatePicker()

    var database: Database!
    var storage: Storage!
    var selectedImage: UIImage?
    
    var ref:DatabaseReference?
    var databaseHandle:DatabaseHandle = 0
    
    let dbref = Database.database().reference()
    let uid = Auth.auth().currentUser?.uid
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        self.companyNameTextFieldConsiderations.delegate = self
        self.companyDescriptionTextFieldConsiderations.delegate = self
        
        // Set the Firebase reference
        ref = Database.database().reference()
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ConsiderationsTestViewController.handleSelectCompanyImageView))
         CompanyImage.addGestureRecognizer(tapGesture)
         CompanyImage.isUserInteractionEnabled = true

        self.navigationController!.navigationBar.isTranslucent = false
        
        navigationItem.backBarButtonItem = UIBarButtonItem(
        title: "", style: .plain, target: nil, action: nil)
        
        createDatePickerForStart()
        
        createDatePickerForEnd()
        
        NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
    }

  @objc func loadList(){
    //load data here
    self.tableView.reloadData()
}

    @objc func handleSelectCompanyImageView() {

        let pickerController = UIImagePickerController()
        pickerController.delegate = self
        pickerController.allowsEditing = true
        present(pickerController, animated: true, completion: nil)
                    }
    
    @IBAction func AddPersonTapped(_ sender: Any) {
  
       }

    @IBAction func sendButtonTapped(_ sender: Any) {
    
    let companyNameC = companyNameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let companyDescriptionC = companyDescriptionTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    
    let today = Date()
    let formatter1 = DateFormatter()
    formatter1.dateFormat = "MMM d y"
    print(formatter1.string(from: today))
    let todaysDate = formatter1.string(from: today)
            
    let storageRef = Storage.storage().reference(forURL: "STORAGE URL HERE")
    let imageName = companyNameTextFieldConsiderations.text!
    let storageCompanyRef = storageRef.child("Company_Image_Considerations").child("\(todaysDate)").child(imageName)
    let companyDescriptionTextFieldText = companyDescriptionTextFieldConsiderations.text
    let dateToStart = startDateTextFieldConsiderations.text
    let dateToDecide = endDateTextFieldConsiderations.text
    let companyRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName)

    let considerationInfluencerRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName).child("Users")
    
     //let values = ["Feed_Quantity": "feedTFC", "Story_Quantity": "storyTFC", "Compensation": "compensationTFC"]
    
        guard let imageSelected = self.CompanyImage.image else {
            print ("Avatar is nil")
            return
                }
                   
                var dict: Dictionary<String, Any> = [
                    "Company Image": "",
                    "Company Description": companyDescriptionTextFieldText!,
                    "Start Date": dateToStart!,
                    "Decision Date": dateToDecide! ]
    
                   
        guard let imageData = imageSelected.jpegData(compressionQuality: 0.5) else {
            return
                }
    
                let metadata = StorageMetadata()
                metadata.contentType = "image/jpeg"
                storageCompanyRef.putData(imageData, metadata: metadata, completion:
                { (StorageMetadata, error) in
                if (error != nil) {
                return
                    }
                            
                storageCompanyRef.downloadURL { (url, error) in
                if let metadateImage = url?.absoluteString {
                dict["Company Image"] = metadateImage
                   
                companyRef.updateChildValues(dict, withCompletionBlock:  {
                (error, ref) in
                if error == nil {
                print("Done")
                return
                    }
                  }
                )
               }
             }
                            
                                   storageRef.updateMetadata(metadata) { metadata, error in
                                    if error != nil {
                                    //Uh-oh, an error occurred!
                                    } else {
                                    // Updated metadata for 'images/forest.jpg' is returned
                                }
                            }
                        })
    
      //        considerationInfluencerRef.updateChildValues(values as [AnyHashable : Any]) { (error, ref) in
      //        if error != nil {
      //        print(error ?? "")
      //        return
      //                           }
    
      self.navigationController?.popViewController(animated: true)
      //           }
       }


    func createDatePickerForStart() {
    // center text in field
    startDateTextFieldConsiderations.textAlignment = .center
    
    // toolbar
    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    
    // barbutton
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedStart))
    toolbar.setItems([doneButton], animated: true)
    
    // assign toolbar to textfield
    
    startDateTextFieldConsiderations.inputAccessoryView = toolbar
    
    // assign datePicker to text field
    startDateTextFieldConsiderations.inputView = datePickerS
    
    // date picker mode
    datePickerS.datePickerMode = .date
    
     }
 
    func createDatePickerForEnd() {
    // center text in field
    endDateTextFieldConsiderations.textAlignment = .center
    
    // toolbar
    let toolbar = UIToolbar()
    toolbar.sizeToFit()
    
    // barbutton
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedEnd))
    toolbar.setItems([doneButton], animated: true)
    
    // assign toolbar to textfield
    endDateTextFieldConsiderations.inputAccessoryView = toolbar
    
    // assign datePicker to text field
    endDateTextFieldConsiderations.inputView = datePickerE
    
    // date picker mode
    datePickerE.datePickerMode = .dateAndTime
       }

    @objc func donePressedStart() {
    // formatter
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .none
    
    startDateTextFieldConsiderations.text = formatter.string(from: datePickerS.date)
    self.view.endEditing(true)
     }

    @objc func donePressedEnd() {
    // formatter
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .medium
    
    endDateTextFieldConsiderations.text = formatter.string(from: datePickerE.date)
    self.view.endEditing(true)
            }

    @IBAction func testTapped(_ sender: Any) {
    print(ConsiderationsTestViewController.numberOfPeople)
           }
        }
    
    extension ConsiderationsTestViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
               func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
                   //print("did Finish Picking Media")
                   if let image = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerEditedImage")] as? UIImage{
                       selectedImage = image
                       CompanyImage.image = image
                   }
                   dismiss(animated: true, completion: nil)
               }
           }

      extension ConsiderationsTestViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return ConsiderationsTestViewController.numberOfPeople.count
         }

    func numberOfSections(in tableView: UITableView) -> Int {
    return 1
         }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: AddPersonCell, for: indexPath) as! ConsiderationsCell
    
    return cell
       }

     }

这是第二个视图控制器的代码:

import UIKit
import Firebase

class DropDownCellViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UITextFieldDelegate {

var numberOfPeople = [String]()

var users = [User]()

var userName = [String]()

var filteredNames: [String]!

let dropDownCell = "dropDownCell"

var emptyField = [String]()

override func viewDidLoad() {
super.viewDidLoad()

updateDataArray()

tableView.register(UserCell.self, forCellReuseIdentifier: dropDownCell)

filteredNames = userName

    tableView.delegate = self
    tableView.dataSource = self
    nameTextField.delegate = self
       
    tableView.isHidden = true
       
       // Manage tableView visibility via TouchDown in textField
nameTextField.addTarget(self, action: #selector(textFieldActive), for: UIControl.Event.touchDown)
   }

@IBOutlet weak var nameTextField: NoCopyPasteUITextField!

@IBOutlet weak var tableView: UITableView!

@IBOutlet weak var gridTextField: UITextField!

@IBOutlet weak var storyTextField: UITextField!

@IBOutlet weak var compensationTextField: UITextField!

@IBAction func textFieldChanged(_ sender: AnyObject) {
    tableView.isHidden = true
}

@IBAction func cancelButtonTapped(_ sender: Any) {
    self.navigationController?.popViewController(animated: true)
}

@IBAction func addButtonTapped(_ sender: Any) {
    
    ConsiderationsTestViewController.numberOfPeople.append("\(nameTextField.text!)")
    
    self.navigationController?.popViewController(animated: true)
    
    print(ConsiderationsTestViewController.numberOfPeople)
    
    DispatchQueue.main.async {
       NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
            }
    }

  let searchController = UISearchController(searchResultsController: nil)

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
    {
      guard let touch:UITouch = touches.first else
      {
          return;
      }
      if touch.view != tableView
      {
          nameTextField.endEditing(true)
          tableView.isHidden = true
      }
    }

   @objc func textFieldActive() {
       tableView.isHidden = !tableView.isHidden
   }

  // MARK: UITextFieldDelegate
   func textFieldDidEndEditing(_ textField: UITextField) {
       // TODO: Your app can do something when textField finishes editing
       print("The textField ended editing. Do something based on app requirements.")
   }
   
   func textFieldShouldReturn(_ textField: UITextField) -> Bool {
       textField.resignFirstResponder()
       return true
   }


  func numberOfSections(in tableView: UITableView) -> Int {
      // #warning Incomplete implementation, return the number of sections
    return 1
   }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    
    return filteredNames.count
    }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: dropDownCell, for: indexPath) as!
    UserCell
    
    let user = users[indexPath.row]
    cell.textLabel?.text = user.name
    
    if let profileImageUrl = user.profileImageUrl {
    
    cell.profileImageView.loadImageUsingCacheWithUrlString(urlString: profileImageUrl)
        
    }
    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Row selected, so set textField to relevant value, hide tableView
           // endEditing can trigger some other action according to requirements
           nameTextField.text = userName[indexPath.row]
           tableView.isHidden = true
           nameTextField.endEditing(true)
       }

//Mark: Search Bar Config
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    
    filteredNames = []
    
    if searchText == "" {
        filteredNames = userName
        
    }
    else {
        for names in userName {
            
            if names.lowercased().contains(searchText.lowercased()) {
                
                filteredNames.append(names)
            }
        }
    }
    self.tableView.reloadData()
}

func updateDataArray() {
    
    Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.name = dictionary["name"] as? String
            user.email = dictionary["email"] as? String
            user.facebookUrl = dictionary["facebookUrl"] as? String
            user.instagramUrl = dictionary["instagramUrl"] as? String
            user.linkedInUrl = dictionary["linkedInUrl"] as? String
            user.profileImageUrl = dictionary["profileImageUrl"] as? String
            user.twitterUrl = dictionary["twitterUrl"] as? String
            user.id = dictionary["id"] as? String
            user.userType = dictionary["userType"] as? String
            
            self.users.append(user)
            self.userName.append(user.name!)
            self.filteredNames.append(user.name!)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
            }
        }
        
    }, withCancel: nil)
    
    
  }
 }

我正在尝试为标签附加一个函数,该函数在名为 renameLabel 的 addButton 函数中调用。这是 func 重命名标签代码:

func renameLabel() {
let cell = ConsiderationsTestViewController.init().tableView.dequeueReusableCell(withIdentifier: AddPersonCell) as! ConsiderationsCell
    
cell.nameLabelC.text = ("\(ConsiderationsTestViewController.numberOfPeople)")
}

我现在收到错误消息:

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

任何帮助都会很棒!

首先在第二个VC之上创建一个协议。

protocol UpdatingArrayDelegate: class {
    func updateArray(newArray: [String])
}

在第二个 VC 中创建:

var updatingArrayDelegate: UpdatingArrayDelegate!

然后在推送到第二个 VC 之前,将委托设置为 self:

@objc func pushToSecondVCButtonTapped() {
    let destVC = secondVC()
    updatingArrayDelegate = self
    self.navigationController?.pushViewController(destVC, animated: true)
    // if you don't have self.navigationController use:
    // present(destVC(), animated: true, completion: nil)
}

现在,在第二个 VC 完成编辑时,按下您的添加按钮,执行以下操作:

@objc func doneButtonTapped() {
    updatingArrayDelegate?.updateArray(newArray: myNewArrayCreatedOnThisSecondVC)
    self.navigationController?.popViewController(animated: true)
}

然后在first上添加delegate函数

extension FirstVC: UpdatingArrayDelegate {
    func updateArray(newArray: [String]) {
        print("updateArray")
        let myCell = myTableView.cellForRow(at: IndexPath(row: x, section: y)) as! MyCell
        myCell.textLabel1.text = newArray[0]
        myCell.textLabel2.text = newArray[1]
        myCell.textLabel3.text = newArray[2]
        myCell.textLabel4.text = newArray[3]
    }
}

你可以这样考虑委托: 老板 (secondVC) 给工人 (firstVC) 一个做什么的协议。 Worker 阅读协议并按照协议中给出的功能执行工作。在工人跑到老板面前之前,他必须确定他可以完成下一个任务(写在他将要拥有的协议上。)