ios - 如何使用动态单元格获取 UITableView 中多个文本字段的值?

标签 ios swift uitableview

在 UIViewController 中,我有一个 UITableView,其中包含 1 个类型为 TextInputTableViewCell 的动态原型(prototype)单元格。
在原型(prototype)单元格的内容 View 中,我添加了一个文本字段。

  1. 如何使用 userInfo 中的数据填充文本字段?
  2. 一旦用户编辑了每个文本字段,我如何获取它们的数据?

我在 SO 上读到我应该使用标签,但其他人说这种方法容易出现错误和脆弱。无论如何,我不知道如何使用标签或其他方法从字段中获取数据。请指教。

import Foundation
import UIKit
import Firebase

 class TextInputTableViewCell: UITableViewCell, UITextFieldDelegate{ 
      @IBOutlet weak var textField: UITextField!

     //closure when the text changes
     var textChangedCallBack: ((_ cell: TextInputTableViewCell, _ text:String) -> ())?
      //Delegate method called when the text field loses focus
     func textFieldDidEndEditing(_ textField: UITextField) {
    textChangedCallBack?(self,textField.text!)
  }
}//end of class TextInputTableViewCell



class EditProfile: UIViewController, UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate {

 var dbRef:FIRDatabaseReference! //create a reference to Firebase
 var userInfo = [FireBaseData]() //this array will hold all data under userType in Firebase



@IBOutlet weak var tableView: UITableView!
@IBAction func saveToFirebase(_ sender: Any) {  

 //will post data from text fields  to firebase
}


struct Item {
    var name:String
    var editable:Bool
}

let placeHolderItems = [
    Item(name: "Name", editable: false),
    Item(name: "Phone Number", editable: true),
    Item(name: "Email", editable: true),
    Item(name: "Flat Number", editable: true),
    Item(name: "Street Address", editable: true),
    Item(name: "Postcode", editable: true)
]


override func viewDidLoad() {
    super.viewDidLoad()

   self.dbRef = FIRDatabase.database().reference().child("Cleaners")
    self.tableView.delegate = self
    self.tableView.dataSource = self
}

   override func viewWillAppear(_ animated: Bool) {
     super.viewWillAppear(true)

   //get user's profile from firebase
    self.startObservingDB { (userProfile) in

        if userProfile.count > 0 {
            self.userInfo = userProfile
             self.tableView.reloadData()
        }
    }

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


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



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TextInputCell") as! TextInputTableViewCell

    cell.textField.isEnabled = placeHolderItems[indexPath.row].editable
    cell.textField.placeholder = placeHolderItems[indexPath.row].name

 //After viewWillAppear finishes, self.userInfo will have the profile of
 //the user. How can I get here each textField  of the tableView so I can
   //populate each one of them with data from  self.userInfo?



         if !self.userInfo.isEmpty{

switch indexPath.row{
    case 0:
         cell.textField.text = self.userInfo[0].FirstName + " " + self.userInfo[indexPath.row].LastName
    case 1:
        cell.textField.text = self.userInfo[0].PhoneNumber

    case 2: cell.textField.text = self.userInfo[0].EmailAddress

    case 3: cell.textField.text = self.userInfo[0].FlatNumber

    case 4: cell.textField.text = self.userInfo[0].StreetAddress

    case 5: cell.textField.text = self.userInfo[0].PostCode

    default:
        break
     }
 }


    cell.textChangedCallBack = {(cell, text) in

        //get the cell's current index path 
        if let path = tableView.indexPath(for: cell) {

            //get the item at that row
            var item = self.placeHolderItems[path.row]

            //update the item with the new name  
        }  
    }

    return cell
  }
 }//end of EditProfileclass





extension EditProfile {


  //get user's profile in order to populate it in tableView
   func startObservingDB(callback:@escaping ((_ snapShot: [FireBaseData]) -> Void)) {

    //check if user is singed in
    guard let uid = FIRAuth.auth()?.currentUser?.uid  else {
        return
    }  

    dbRef.child(uid).child("profile").observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in
        var profileData = [FireBaseData]()

        for keyVal in snapshot.children{

            let userData = FireBaseData(snapshot: keyVal as! FIRDataSnapshot)
            profileData.append(userData)
                       }
        callback(profileData)

    }, withCancel: { (Error:Any) in 
        print("error is \(Error as! String)")

    })
    dbRef.removeAllObservers()

}//end of startObserving

}//end of EditProfile Class


enter image description here

enter image description here

最佳答案

通常要解决的问题是:用户在表格 View 单元格中编辑了一个文本字段,现在我们要相应地更新数据模型。但是哪个单元格包含这个文本字段?

“哪个”这个概念的真正意思是:包含单元格表示的索引路径是什么?如果我们知道这一点,我们就可以很容易地更新模型,因为如果我们的 TableView 数据源设计正确,我们已经知道如何通过索引路径访问模型。

所以我所做的只是简单地沿着 View 层次结构从文本字段向上移动到单元格,然后询问 TableView 这个单元格代表什么索引路径。这是我的应用程序中常用的模式:

func textFieldDidEndEditing(_ textField: UITextField) {
    var v : UIView = textField
    repeat { v = v.superview! } while !(v is UITableViewCell)
    let cell = v as! MyCell // or UITableViewCell or whatever
    let ip = self.tableView.indexPath(for:cell)!
    // and now we have the index path! update the model
}

关于ios - 如何使用动态单元格获取 UITableView 中多个文本字段的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47355585/

相关文章:

objective-c - 在 UITableView 初始化中设置选定的单元格

iphone - UITableViewCell 独有的 UISwitch

ios - iOS 如何存储用户数据

ios - 在iOS App中下载多个图像

c++ - xcode 4.5 中出现“iostream”文件未找到错误?

ios - 通过您自己的 iOS 应用程序将照片上传到 Instagram

swift - viewForAnnotation 未被调用(使用 Alamofire 解析 JSON)

iphone - 如何将字符串数组发送到 UIActionSheet varargs init 方法中?

ios - 如何自动滑动/滑动单元格tableviewcell swift 3

ios - 如何在模糊效果之上有一个 UIPageView?