如何获取位于collectionviewcell内的TextField的文本?

时间:2018-08-23 00:59:06

标签: swift textfield collectionview

我是Swift的新手,我想做的是让用户在位于集合视图单元格内的TextField中键入文本。我有一个名为“PestañaCero”的CollectionViewCell,在其中创建了TextField,这是一个:

import Foundation
import UIKit

class PestañaCero: UICollectionViewCell
{


    let NombreUsuarioTextField: UITextField =
    {
       let nombre = UITextField()
        nombre.borderStyle = UITextBorderStyle.roundedRect
        nombre.placeholder = "Nombre de Usuario"
        nombre.textAlignment = .center
        return nombre
    }()

    let NumerodeContactoTextField: UITextField =
    {
        let nombre = UITextField()
        nombre.borderStyle = UITextBorderStyle.roundedRect
        nombre.placeholder = "Numero de Contacto"
        nombre.textAlignment = .center
        return nombre
    }()

    let DireccionOrigenTextField: UITextField =
    {
        let nombre = UITextField()
        nombre.borderStyle = UITextBorderStyle.roundedRect
        nombre.placeholder = "Direccion de Origen"
        nombre.textAlignment = .center
        return nombre
    }()

    let DireccionDestinoTextField: UITextField =
    {
        let nombre = UITextField()
        nombre.borderStyle = UITextBorderStyle.roundedRect
        nombre.placeholder = "Direccion de Destino"
        nombre.textAlignment = .center
        return nombre
    }()

    func setupViews()
    {
        addSubview(NombreUsuarioTextField)
        addSubview(NumerodeContactoTextField)
        addSubview(DireccionOrigenTextField)
        addSubview(DireccionDestinoTextField)


        //VERTICAL CONSTRAINT

        addConstraintsWithFormat("H:|-16-[v0]-16-|", views: NombreUsuarioTextField)
        addConstraintsWithFormat("H:|-16-[v0]-16-|", views: NumerodeContactoTextField)
        addConstraintsWithFormat("H:|-16-[v0]-16-|", views: DireccionOrigenTextField)
        addConstraintsWithFormat("H:|-16-[v0]-16-|", views: DireccionDestinoTextField)

        addConstraintsWithFormat("V:|-100-[v0(30)]-12-[v1(30)]-12-[v2(30)]-12-[v3(30)]", views:
        NombreUsuarioTextField,NumerodeContactoTextField, DireccionOrigenTextField ,DireccionDestinoTextField)
    }

}

我试图触摸在cellCollectionItemAt中创建的按钮时打印文本,该代码位于UICollectionViewController类中

@objc func confirmarbutton()
    {
        print("123")
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {

        var myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "PestañaCero", for: indexPath)
        myCell.backgroundColor = UIColor.black

        let nombre = UIButton(frame: CGRect(x: myCell.frame.width/2-100, y: 400, width: 200, height: 25))
        nombre.setTitle("Pedir Domicilio", for: .normal)
        nombre.backgroundColor = UIColor.orange
        nombre.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
        nombre.addTarget(self, action: #selector(confirmarbutton) , for: .touchUpInside)
        myCell.addSubview(nombre)



    }  

非常感谢任何帮助,谢谢大家

3 个答案:

答案 0 :(得分:1)

您可以在创建单元格cell.NumerodeContactoTextField.delegate = self时将单元格内textField的委托设置为控制器,然后在控制器中使用该委托。但是,这种方法的问题在于您将必须对所有textField执行此操作,因此更好的解决方案是在单元格中创建自己的委托,如下所示:

protocol CollectionCellTextFieldDelegate: class {
    func textDidChanged(_ textField: UITextField)
}

然后将其添加到您的单元格中:

class PestañaCero: UICollectionViewCell {
    weak var textFieldDelegate: CollectionCellTextFieldDelegate?
}

现在在控制器中创建单元格:

cell.textFieldDelegate = self

在控制器中符合并实现委托:

func textDidChanged(_ textField: UITextField) {
    //Here you will get the textField, and you can extract the textFields text
}

这只是您如何处理这种情况的一个示例。您应该能够根据需要进行修改。

有关如何使用上述方法进行操作的小样本

My Cell Class

import UIKit

    protocol CollectionCellTextFieldDelegate: class {
            func cellTextFields(_ fields: [UITextField])
    }

    class Cell: UICollectionViewCell {

        @IBOutlet weak var fieldOne: UITextField!
        @IBOutlet weak var fieldTwo: UITextField!
        @IBOutlet weak var button: UIButton!

        weak var textFieldDelegate: CollectionCellTextFieldDelegate?

        @IBAction func buttonClicked(_ sender: UIButton) {
            guard let textFieldDelegate = textFieldDelegate else { return } //we don't have do anything if not conformed to delegate
    //otherwise pass all textFields
            textFieldDelegate.cellTextFields([fieldOne, fieldTwo])
        }
     }

My Controller Class

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, CollectionCellTextFieldDelegate {


    @IBOutlet weak var collectionView: UICollectionView!


    override func viewDidLoad() {
        super.viewDidLoad()

    //register the cell xib
        collectionView.register(UINib(nibName: "Cell", bundle: nil), forCellWithReuseIdentifier: "Cell")
    }

    //MARK:- CollectionView
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
        cell.textFieldDelegate = self
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.bounds.width - 20.0, height: 175.0)
    }

    //you could write this delegate anyway you want, its just for a sample
    func cellTextFields(_ fields: [UITextField]) {

        //loop over each fields and get the text value
        fields.forEach {
            debugPrint($0.text ?? "Empty Field")
        }
    }

}

您可能还必须处理单元的出队,但是现在测试此代码并进行相应的修改。

答案 1 :(得分:1)

@objc func confirmarbutton(sender:UIButton)
{

    let indexPath = self.collView.indexPathForItem(at: sender.convert(CGPoint.zero, to: self.collView))
    let cell = self.collView.cellForItem(at: indexPath!) as! PestañaCero

    print(cell.NombreUsuarioTextField.text) // use textfield value like this

    print("123")
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{

    var myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "PestañaCero", for: indexPath)
    myCell.backgroundColor = UIColor.black

    let nombre = UIButton(frame: CGRect(x: myCell.frame.width/2-100, y: 400, width: 200, height: 25))
    nombre.setTitle("Pedir Domicilio", for: .normal)
    nombre.backgroundColor = UIColor.orange
    nombre.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
    nombre.addTarget(self, action: #selector(confirmarbutton(sender:)) , for: .touchUpInside)
    myCell.addSubview(nombre)

}

您可以使用indexpath访问任何行,您只需要在cellForItem方法中传递特定的indexpath即可获取该行,因此我只需传递我的发件人并找到该行以获取该文本字段值,只需将代码替换为您的代码即可工作:)

答案 2 :(得分:0)

这是我个人遵循的简单解决方案:

首先,我们应该能够弄清楚索引/行的按钮用户单击了哪个位置,以便知道我们将像下面的 * cellForItemAt * 中那样将“ indexPath”设置为按钮层方法:

nombre.layer.setValue(indexPath, forKey: "indexPath")

然后,我们需要如下所述的 confirmarbutton 方法的签名(如@Mahesh Dangar的回答所示):

@objc func confirmarbutton(sender:UIButton)

然后我们需要在 confirmarbutton 方法中使用indexPath,以便我们可以首先获取单元格,然后获取文本字段以访问该文本字段的值:

@objc func confirmarbutton(sender:UIButton){

    let indexPath = sender.layer.value(forKey: "indexPath") as! IndexPath
    let cell = collectionView.cellForItem(at: indexPath) as! PestañaCero

    let number = cell.NombreUsuarioTextField.text! // make sure you have value in textfield else you will get runTime error

   //below is safer alternative to above line...write one of them

    if let isNumberEntered = cell.NombreUsuarioTextField.text{
          //condition will be true if text field contains value
    }else{
         //This block will be executed if text field does not contain value/it is empty. you can show alert something like please enter the number etc.
    }
}