2016-09-14 10 views
0

小さなコンテキスト - 私はと呼ばれる領域モデルオブジェクトの配列によって設定されたTableViewを持つSelectedListItemsViewControllerという1つのViewControllerを持っています。 allListItemsと呼ばれるレルムモデルオブジェクトの配列によって作成されたTableViewを持ち、各セルにUISwitchが含まれている、AllListItemsViewControllerという別のViewControllerにナビゲートするAdd barボタンアイテムがあります。UISwitchを使用して配列からオブジェクトを削除する

上記の配列は両方とも、同じクラスに基づいています。これは、isSelectedというブール値プロパティを持ちます。私のコードでは、私は現在、AllListItemsViewControllerのセルでUISwitchを切り替えるときに、「オン」になるとisSelectedというプロパティーがindexPath.rowallListItemsからtrueに変更され、オブジェクトがselectedListItemsに追加されますアレイ。この部分はうまくいくようです。 「オフ」にスイッチを切り替える

falseに変更するallListItemsindexPath.rowisSelected性を引き起こし、オブジェクトがselectedListItemsからそのインデックスで除去されます。これはほとんどの場合に機能しますが、セルのUISwitchを間違った順序で切り替える場合があります(インデックス0、1、2でオンになっている場合はインデックス1にします) off ')、おそらくインデックスが範囲外であるためにシミュレーションがクラッシュします。

私は非常に素人ですので、以下のコードは賢明ではないと私は確信しています。

// The following arrays are for use with UISegmentedControl (other three removed for brevity) 
// This is an array of 'Appearance' list items created from allListItems 
let appearanceArray = allListItems.filter{ 
    $0.category.rangeOfString("Appearance") != nil 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: 
    NSIndexPath) -> UITableViewCell { 
    let cellIdentifier = "Cell" 
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AllListItemsTableViewCell 

    // This is a string value for the cell at indexPath.row 
    var listItemInCell = "" 

    // This is an array of all listItems in allListItems, and used with indexOf to check boolean status of isSelected inside of allListItems array 
    let arrayAll = allListItems.map{($0.listItem)} 

    // This is an array of all listItems in selectedListItems, and used to track remove indexes 
    let arraySelected = selectedListItems.map{($0.listItem)} 


    switch(segmentedControl.selectedSegmentIndex) 
    { 

    case 0: // Case 0 of 4, the others removed for brevity of this question 

     listItemInCell = appearanceArray[indexPath.row].listItem 

     // Index of listItemInCell inside of the array of allListItems' listItems 
     let indexOf = arrayAll.indexOf(listItemInCell)! 

     cell.listItemLabel.text = listItemInCell 

     // Tracks UISwitch activity 
     cell.callback = { (tableViewCell, switchState) in 
      if self.tableView.indexPathForCell(tableViewCell) != nil { 

       // do something with index path and switch state 
       if switchState == true { 
        allListItems[indexOf].isSelected = true 
        selectedListItems.append(self.appearanceArray[indexPath.row]) 
       } else { 
        allListItems[indexOf].isSelected = false 
        let indexInSelected = arraySelected.indexOf(listItemInCell)! 
        selectedListItems.removeAtIndex(indexInSelected) 
       } 
      } 
     } 

     if appearanceArray[indexPath.row].isSelected { 
      cell.toggleIsSelected.on = true 
     } else { 
      cell.toggleIsSelected.on = false 
     } 

     break 

これは、実行時エラーの原因となるエッジケースがないよりよい方法ですか?私が持っていた1つの考えは、selectedListItemsのインデックスを記録することは、グローバル変数であり、遅れて計算されているので最善のルートではないかもしれないということでした。もう一つの考えは、オブジェクトの配列自体の中の特定のスポットのインデックスを見つけるのではなく、インデックスを追跡するためにオブジェクトのプロパティの配列を作成するときに、翻訳で何かが失われるということです。

答えて

0

最後の3時間は、それを周りに揺れて、私はそれを考え出した。私の他にswitchStateの場合、代わりに使用して

    let indexInSelected = arraySelected.indexOf(listItemInCell)! 
        selectedListItems.removeAtIndex(indexInSelected) 

では私の代わりに、完全に私はいくつかの削除例を持っていた私のインデックスの範囲外の問題を修正しているようだ

    let objectToRemove = self.appearanceArray[indexPath.row] 

        for object in selectedListItems { 
         if object == objectToRemove { 
          selectedListItems.removeAtIndex(selectedListItems.indexOf(objectToRemove)!) 
         } 
        } 

を使用しました。また、元の2行をサポートしていた不必要なコードを無駄に取り除くことができるようにも見えます。

関連する問題