从 SpreadsheetView 检索 TextField 用户条目

Posted

技术标签:

【中文标题】从 SpreadsheetView 检索 TextField 用户条目【英文标题】:Retrieve TextField User Entries from SpreadsheetView 【发布时间】:2020-07-02 10:36:37 【问题描述】:

早安,

我已经设法让我的电子表格视图工作,但没有从电子表格视图中检索用户输入数据的功能,只有一个填充单元格的功能,如下所示。有人可以帮我解决这个问题。电子表格视图中的第一列是使用填充到标签中的数组自动填充的,效果很好。然后第二列由 TextFields 组成,允许用户输入自己的数据,现在我想在按下下一个选项卡时将该数据保存到一个数组中并显示一个图表。我试图填充数组

            func spreadsheetView(_ spreadsheetView: SpreadsheetView, cellForItemAt indexPath: IndexPath) -> Cell? 
        if case (0, 0) = (indexPath.column, indexPath.row) 
            let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: CellInfo.identifier, for: indexPath) as! CellInfo
            cell.label.text = "STATION"
            cell.backgroundColor = .systemGray
            return cell
            
         else if case (1, 0) = (indexPath.column, indexPath.row) 
            let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: CellInfo.identifier, for: indexPath) as! CellInfo
            cell.Rlabel.text = "MAG READING"
            cell.backgroundColor = .systemGray

        return cell
            
         else if case (0, 1...(GlobalVariable.sharedInstance.numberOfStations)) = (indexPath.column, indexPath.row) 
            let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: MyLabelCell.identifier, for: indexPath) as! MyLabelCell
            cell.setup(with: GlobalVariable.sharedInstance.arrayProfileStations[indexPath.row-1])
            //print(GlobalVariable.sharedInstance.arrayProfileStations[indexPath.row-1])
            cell.backgroundColor = .systemGray6
            return cell
            
         else if case (1, 1...(GlobalVariable.sharedInstance.numberOfStations)) = (indexPath.column, indexPath.row) 
            let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: CellInfo.identifier, for: indexPath) as! CellInfo
            var array = [String]()
            cell.TextField.text = "-"
//            if GlobalVariable.sharedInstance.MagDataEntries 
//                cell.TextField.text = GlobalVariable.sharedInstance.MagDataEntries[indexPath.row-1]
//            else
                //Populate the array with user data
                
                //
            
                array.append(cell.TextField.text ?? "0")
                //GlobalVariable.sharedInstance.MagDataEntries.append(contentsOf: array)
                //print(indexPath.row-1)
                print(array)
                
          //
           
            return cell
//         else if case (1, 1...(GlobalVariable.sharedInstance.numberOfStations)) = (indexPath.column, indexPath.row) 
//
//            let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: MyLabelCell.identifier, for: indexPath) as! MyLabelCell
//            cell.setup(with: GlobalVariable.sharedInstance.arrayProfileStations[indexPath.row-1])
//            spreadsheetView.
//            return cell
    
        return nil
    

以下是标签文本字段的创建方式:

     class MyLabelCell:Cell
    
    static let identifier = "MyLabelCell"
    
    public let label = UILabel()
    public func setup(with text:String)
        label.text = text
        label.textAlignment = .center
        //label.isUserInteractionEnabled = true
        
        contentView.addSubview(label)
        
    
    
    override func layoutSubviews() 
        
            super.layoutSubviews()
            label.frame = contentView.bounds
        
    

     class CellInfo: Cell 
    let label = UILabel()
    let Rlabel = UILabel()
    let TextField = UITextField()
    static let identifier = "CellID"
    
    override init(frame: CGRect) 
        super.init(frame: frame)

        label.frame = bounds
        label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        label.font = UIFont.boldSystemFont(ofSize: 14)
        label.textAlignment = .center
        //label.backgroundColor = .darkGray

        contentView.addSubview(label)
        
        Rlabel.frame = bounds
        Rlabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        Rlabel.font = UIFont.boldSystemFont(ofSize: 14)
        Rlabel.textAlignment = .center
        //Rlabel.backgroundColor = .darkGray

        contentView.addSubview(Rlabel)
        
        TextField.frame = bounds
        TextField.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        TextField.font = UIFont.boldSystemFont(ofSize: 16)
        TextField.textAlignment = .center
        
        contentView.addSubview(TextField)
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

【问题讨论】:

【参考方案1】:

首先,注意几点:

开始简单一点。更容易学习基础知识。 对类使用UpperCase,对变量/属性使用lowerCase

你可以通过使用“回调”闭包来完成你想做的事情。

将这样的属性添加到您的单元格类中:

// closure to send data back to controller
var callback: ((String) -> ())?

在您的控制器类中,当您将单元格出列时,您还设置了它的关闭:

cell.callback =  [weak self] (fieldText) in
    // handle the text

回到你的单元类,使用UITextFieldDelegate,当文本字段被编辑后,将文本发送回控制器类:

func textFieldDidEndEditing(_ textField: UITextField) 
    guard let s = textField.text else 
        return
    
    // send the field's text to the controller
    callback?(s)

这是一个完整的例子。要对其进行测试(并从中学习),请添加一个新的UICollectionViewController 并将其自定义类分配给FieldsCollectionViewController。您不需要配置原型单元格——只需像这样设置集合视图的单元格大小:

这将为您提供一个“列”单元格,每个单元格都有一个 UITextField。每次文本字段结束编辑(例如点击另一个单元格)时,都会触发回调并更新数据源。

class CellInfo: UICollectionViewCell, UITextFieldDelegate 
    
    let textField = UITextField()
    static let identifier = "CellInfoID"

    // closure to send data back to controller
    var callback: ((String) -> ())?
    
    override init(frame: CGRect) 
        super.init(frame: frame)
        commonInit()
    
    required init?(coder: NSCoder) 
        super.init(coder: coder)
        commonInit()
    
    func commonInit() -> Void 
        
        textField.frame = bounds
        textField.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        textField.font = UIFont.boldSystemFont(ofSize: 16)
        textField.textAlignment = .center
        textField.borderStyle = .line
    
        textField.delegate = self
        
        contentView.addSubview(textField)

    
    
    func textFieldDidEndEditing(_ textField: UITextField) 
        guard let s = textField.text else 
            return
        
        // send the field's text to the controller
        callback?(s)
    
    


class FieldsCollectionViewController: UICollectionViewController 
    
    var myData: [String] = []
    
    override func viewDidLoad() 
        super.viewDidLoad()
        
        // just for example,
        //  fill data array with strings from "1" to "20"
        myData = (1...20).map( String($0) )
        
        collectionView.register(CellInfo.self, forCellWithReuseIdentifier: CellInfo.identifier)
    
    
    override func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return myData.count
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CellInfo.identifier, for: indexPath) as! CellInfo

        cell.textField.text = myData[indexPath.item]

        cell.callback =  [weak self] (fieldText) in
            print("editing ended for cell: \(indexPath) with text: \(fieldText)")
            // update data source with text from edited field
            self?.myData[indexPath.item] = fieldText
        

        return cell
    

【讨论】:

非常感谢我今天学到了很多,您对示例的解释再次感谢。我犯的唯一错误是忘记实现 textField Delegate,这让我有点摸不着头脑。 :)

以上是关于从 SpreadsheetView 检索 TextField 用户条目的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Integration Mail 从“text/html; charset=us-ascii”检索电子邮件内容正文

无法从SharedPreferences检索数据?

如何使用jQuery从数组中的元素中检索值?

从文本对象中检索文本值

如何使用 plist 在 UITextView 中检索短信?

从访问数据库中检索图像到图片框