在尝试从Swift中的表格单元格中读取时发现为nil

时间:2016-04-14 19:10:01

标签: iphone swift uitableview

我有一个问题,我不明白,因为我是iPhone应用程序编程和Swift的新手。

我在Swift中有一个TableView,我用它来显示一些结果。我已经为每个单元格添加了一个按钮,以便用户可以选择不同的单元格,然后按删除键以删除单元格中显示的结果。

只有少数结果可以正常工作,但现在我已经开始获得nil-exception。

当我尝试获取特定行的单元格时,程序在函数getIndexToDelete中崩溃。

以下是我处理表格的代码:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Linq;

namespace App15
{
[Activity(Label = "App15", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);

// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var doc = XDocument.Load("map.svg");
}
}
}

这是ResultTableCell:

import UIKit

class DailyResultTable: UIViewController, UITableViewDataSource,      UITableViewDelegate {
var results = Results()
var yearShownIndex = 0
var monthShownIndex = 0
var dayShownIndex = 0
@IBOutlet weak var tableView: UITableView!

@IBOutlet weak var DeleteButton: UIButton!


override func viewDidLoad() {
    super.viewDidLoad()
 //   self.view.backgroundColor = UIColor(patternImage: UIImage(named: "StatisticBackground")!)

}

// DataSource
func numberOfSectionsInTableView(tableview: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   // return (self.results?.getDayList(yearShownIndex, posMonth: monthShownIndex).count)!
    print("return number of rows")
    if (results.getYearList().count > 0 ){
        if (results.getMonthList(yearShownIndex).count > 0){
            if (results.getDayList(yearShownIndex, posMonth: monthShownIndex).count > dayShownIndex){
            return (results.getDayList(yearShownIndex, posMonth: monthShownIndex)[dayShownIndex].results.count)
            }
        }
    }
    print("No numbers to show return 0")
    return 0;
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("DayResultCell", forIndexPath: indexPath) as! ResultTableCell
    let row = indexPath.row
    //cell.ResultField.text =  String((results?.getDayList(yearShownIndex, posMonth: monthShownIndex)[row].day)!) + "/" + String((results?.getMonthList(yearShownIndex)[monthShownIndex].month)!)
    let res = results.getDayList(yearShownIndex, posMonth: monthShownIndex)[dayShownIndex].results[row].result
    let maxRes = results.getDayList(yearShownIndex, posMonth: monthShownIndex)[dayShownIndex].results[row].maxresult
    let discipline = results.getDayList(yearShownIndex, posMonth: monthShownIndex)[dayShownIndex].results[row].discipline
    let text1 = String(res) + "/"
    let text2 =  String(maxRes)
    let text3 = " - " + discipline
    let text = text1 + text2 + text3
    print(text)
    cell.ResultField.text = text
    return cell
}


// Delegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
@IBAction func CheckBox(sender: UIButton) {
    let image = UIImage(named: "Selected") as UIImage!
    let selected = sender.selected
    sender.selected = !selected
    sender.setImage(image, forState: .Selected)
}

func getIndexToDelete()->[Int]{
    var indices = [Int]()

    for i in 0..<tableView.numberOfRowsInSection(0){
        let indexPath = NSIndexPath(forRow: i, inSection: 0)
         // Here does the program crash
        let cell = tableView.cellForRowAtIndexPath(indexPath) as! ResultTableCell
        if (cell.CheckBoxButton.selected){
            indices += [i]

    }
    }
    return indices
}

@IBAction func DeletePressed(sender: UIButton) {
    let deleteIndices = getIndexToDelete()
    var goback = false;
    var count = 0;
    for index in deleteIndices{
        print("Count: " + String(count))
        results.ListResults[yearShownIndex].months[monthShownIndex].day[dayShownIndex].results.removeAtIndex(index-count)
        count += 1
        print(String((results.getDayList(yearShownIndex, posMonth: monthShownIndex)[dayShownIndex].results.count)));

    }
    loadView()
    results.recreatePlainResult()
    results.saveResults()

    if (results.ListResults[yearShownIndex].months[monthShownIndex].day[dayShownIndex].results.count == 0){
        print(String(results.ListResults[yearShownIndex].months[monthShownIndex].day.count))
        results.ListResults[yearShownIndex].months[monthShownIndex].day.removeAtIndex(dayShownIndex)
        results.recreatePlainResult()
        results.saveResults()
        print(String(results.ListResults[yearShownIndex].months[monthShownIndex].day.count))
        goback = true
    }
    if (results.ListResults[yearShownIndex].months[monthShownIndex].day.count == 0){
        results.ListResults[yearShownIndex].months.removeAtIndex(monthShownIndex)
        results.recreatePlainResult()
        results.saveResults()
        goback = true
    }
    if (results.ListResults[yearShownIndex].months.count == 0){
        results.ListResults.removeAtIndex(monthShownIndex)
        results.recreatePlainResult()
        results.saveResults()
        goback = true
    }
    if (goback){
       // return;
        navigationController?.popViewControllerAnimated(true)
    }
}

}

我当然可以将import UIKit class ResultTableCell: UITableViewCell { @IBOutlet weak var ResultField: UITextField! @IBOutlet weak var CheckBoxButton: UIButton! } 放在if子句中,但其他奇怪的事情会发生。

2 个答案:

答案 0 :(得分:3)

请勿使用!

cellForRowAtIndexPath会返回UITableViewCell?,如果您拨打电话时该行不可见,则可以为零。

在将其转换为预期的对象类型之前,使用if let检查是否确实有一个单元格。

答案 1 :(得分:0)

这里有一些事情,让我们一次拿一个:

  1. 崩溃是强迫nil值通过!该部分应该是显而易见的。

  2. for循环从0开始到行数,但UITableViewCell个实例会被回收,因此无法正常工作。

  3. 复选框选择不是标准的iOS表格单元格选择,而是更自定义的

  4. 如果您使用UITableView的内置选择行为,则可以使用this方法。

    如果您想继续使用自定义复选框选项,那么最简单的方法就是听取选择更改并在选择内容时构建NSIndexPath

    然后当按下 delete 按钮时,您将有一个可以删除的预建索引,并且您不必循环搜索所选内容。