UITableView意外地发现Nil不一致发生

时间:2017-03-05 05:16:26

标签: ios swift uitableview

我已经在这个问题上被困了几个小时了,非常感谢任何帮助。我试图在按钮单击时遍历表格视图中的每个单元格,并从这些单元格中的文本字段中获取信息。我使用以下代码循环遍历单元格:

for i in 0...tableView.numberOfRows(inSection: 0)-1 {
        let index = IndexPath(row: i, section: 0)
        let cell: TextInputTableViewCell = self.tableView.cellForRow(at: index) as! TextInputTableViewCell
        if let name = cell.NameTF.text, let playerHandicap = Int(cell.HandicapTF.text!), name != "" {
            result = true
            handicaps[name] = playerHandicap
       } else {
            let alertController = UIAlertController(title: "Enter all values", message: "Please enter a name (text) and handicap (number) for each player", preferredStyle: .alert)

            let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            alertController.addAction(defaultAction)

            self.present(alertController, animated: true, completion: nil)
        }
    }

我面临的问题是,即使对于i = 0的情况,不同的行数也会产生不同的结果。例如,有4行,这可以很好地工作,但有12行我得到一个"意外发现nil在展开一个Optional值时#34;当i = 0时,单元初始化线上出错("让单元")。

提前致谢

编辑:

我现在正在尝试在编辑文本后保存每个文本字段值,而不是在单击按钮时迭代每个单元格。

我的细胞类:

protocol CustomDelegate: class {
    func nameEntered(tag: Int, text: String)
    func handicapEntered(tag: Int, text: String)

}

class TextInputTableViewCell: UITableViewCell {
    @IBOutlet weak var NameTF: UITextField!
    @IBOutlet weak var HandicapTF: UITextField!

    weak var delegate: CustomDelegate?

    @IBAction func NameTextEntered(_ sender: UITextField) {
        delegate?.nameEntered(tag: sender.tag, text: sender.text!)
    }

    @IBAction func HandicapTextEntered(_ sender: UITextField) {
        delegate?.handicapEntered(tag: sender.tag, text: sender.text!)
    }

}

在我的视图控制器中:

class HandicapViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomDelegate {

// .....

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextInputCell") as! TextInputTableViewCell
        cell.NameTF.tag = cellCount
        cell.HandicapTF.tag = cellCount
        cellCount += 1

        return cell
    }

// .....

func nameEntered(tag: Int, text: String) {
        if var cellInfo = cellInputs[tag] {
            cellInfo[0] = text
            cellInputs[tag] = cellInfo
        } else  {
            let cellInfo = [text, ""]
            cellInputs[tag] = cellInfo
        }
    }

 func handicapEntered(tag: Int, text: String) {
        if let handicapInt = Int(text) {
            if var cellInfo = cellInputs[tag] {
                cellInfo[1] = text
                cellInputs[tag] = cellInfo
            } else  {
                let cellInfo = ["", text]
                cellInputs[tag] = cellInfo
            }
        } else {
            let alertController = UIAlertController(title: "Invalid Value", message: "Please enter only whole numbers as your handicap.", preferredStyle: .alert)

            let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
            alertController.addAction(defaultAction)

            self.present(alertController, animated: true, completion: nil)
        }
    }

我发现动作函数在单元格类中被命中,但是对nameEntered和handicapEntered函数的调用并没有进入视图控制器。

1 个答案:

答案 0 :(得分:0)

UITableView

这是因为你试图循环遍历细胞。 protocol不会创建您要求的单元格数。它将只创建可以在屏幕中显示的尽可能多的单元格。滚动时,这些单元格将重新使用新值。

protocol CustomDelegate: class { func buttonClicked(cell: CustomCell) func textEntered(tag: Int, text: String) } class CustomCell { weak var delegate: CustomDelegate? @IBAction btnAction(_ sender: Any) { delegate?.buttonClicked(cell: self) } } extension CustomCell: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let text: NSString = textField.text as NSString? ?? "" let finalString: NSString = text.replacingCharacters(in: range, with: string) as NSString delegate?.textEntered(tag: textField.tag, text: finalString) return true } } 委托用于这些目的。

var name: String!
var mobile: String!
var country: String!
var age: String!

let nameTag = 25
let mobileTag = 26
let countryTag = 27
let ageTag = 28

在ViewController中,有很多方法可以保存这些值,基本方法是

let cell = .....
cell.delegate = self

// Set respective `tag`s for `UITextField` here
cell.inputFieldOne.tag = // here
cell.inputFieldTwo.tag = // another here

cellForRow数据源方法,

CustomDelegate

符合extension ViewController: CustomDelegate { func buttonClicked(cell: CustomCell) { // get your data here, let indexPath = tableView.indexPathForCell(cell) } } func textEntered(tag: Int, text: String) { if tag == nameTag { name = text } else if tag == mobileTag { mobile = text } else if tag == countryTag { country = text } else if tag == ageTag { age = text } } 方法,

import Foundation
import CoreLocation
import MapKit
import UIKit

class TrackLocationManagerDelegate: NSObject, CLLocationManagerDelegate {
      lazy var locationManager: CLLocationManager = {
             var locationManager            = CLLocationManager()
        locationManager.delegate        = LocationManagerDelegate.sharedInstance
        locationManager.desiredAccuracy = kCLLocationAccuracyBest

        // ERROR - activityType unavailable
        locationManager.activityType    = CLActivityType.fitness 

        locationManager.distanceFilter  = 10.0

        return locationManager
      }()

     // ERROR - Use of undeclared type MKPolyline
    fileprivate lazy var polyline = MKPolyline() 

    // ERROR -  Use of Undeclared type UIViewController
    func startUpdatingLocationIfAuthorized( inViewController vc: UIViewController) {  
        guard CLLocationManager.authorizationStatus() == .authorizedWhenInUse else {
            TrackLocationManagerDelegate.sharedInstance.locationManager.requestWhenInUseAuthorization()
            return
        }

        TrackLocationManagerDelegate.sharedInstance.locationManager.startUpdatingLocation()
    }
}

有很多方法可以从单元格中保存数据,这只是一种基本方法。