2016-11-29 3 views
0

Я новичок в разработке iOS, и я пытаюсь создать пользовательские tableViewCells, но у меня есть проблема. У меня есть 3 раздела для моего TableViewCell и Array. Когда я пытаюсь назначить значения ячейкам по адресу UITableView, cellForRowAt, он запускает массив сверху с каждого раздела. Вот мой код:Custom tableViewCell

import Foundation 
import UIKit 

struct cellData { 

let cell : Int! 
let text : String! 
} 

class SettingsTableViewCell : UITableViewController{ 

var arrayOfCellData = [cellData]() 

override func viewDidLoad() { 

    arrayOfCellData = [cellData(cell : 1, text : "تغییر رنگ دکمه تنظیمات"), 
         cellData(cell : 2, text : "تغییر تصویر پشت زمینه"), 
         cellData(cell : 1, text : "تغییر رنگ قلم"), 
         cellData(cell : 2, text : "اعلانات"), 
         cellData(cell : 2, text : "صداها"), 
         cellData(cell : 2, text : "زبان"), 
         cellData(cell : 2, text : "بازگشت به حالت پیش فرض"), 
         cellData(cell : 2, text : "سوالات متداول")] 


} 

override func numberOfSections(in tableView: UITableView) -> Int { 
    return 3 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    if section == 0{ 
     return 3 
    } 
    else if section == 1{ 
     return 4 
    } 
    else if section == 2{ 

     return 1 
    } 


    return arrayOfCellData.count 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    if arrayOfCellData[indexPath.row].cell == 1{ 


     let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1 

     cell.cellName_1.text = arrayOfCellData[indexPath.row].text 

     return cell 

    } 
    else if arrayOfCellData[indexPath.row].cell == 2{ 

     let cell = Bundle.main.loadNibNamed("TableViewCell_Type2", owner: self, options: nil)?.first as! TableViewCell_Type2 

     cell.cellName_2.text = arrayOfCellData[indexPath.row].text 

     return cell 


    } 
    else{ 

     let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1 

     cell.cellName_1.text = arrayOfCellData[indexPath.row].text 

     return cell 


    } 



} 

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 



    if section == 0{ 
     return "تنظیمات رنگ\n" 
    } 
    else if section == 1{ 
     return "تنظیمات سیستم\n" 
    } 
    else if section == 2{ 

     return "پشتیبانی\n" 
    } 

    return "" 
    } 
} 
+1

Не используйте старые способы кодирования, такие как «Bundle.main.loadNibNamed», вместо этого используйте «registerNib», которые помогут вам в создании ячеек. Кроме того, можете ли вы опубликовать снимок экрана о своей проблеме? – Satyam

+0

В 'cellForRowAtIndexPath' вы рассматриваете только строку указательного пути. Поэтому каждый раздел отображает те же объекты из верхней части массива. Кроме того, вы можете создавать несколько настраиваемых ячеек в Interface Builder (я думаю, начиная с Xcode 6), нет необходимости в дополнительных наконечниках. И, наконец, не перекодируйте 'numberOfRows'. Создайте подходящую модель с вложенными массивами или чем-то еще, чтобы всегда использовать свойство count. – vadian

+0

Вы не можете просто рассмотреть 'indexPath.row', вычислить индекс массива на основе' indexPath.section' и 'indexPath.row'. Затем вы получите точный элемент из массива. –

ответ

0

Я изменил код таким образом, и это сработало!

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    var offset = 0 

    if indexPath.section == 0 { 

     offset = 0 

    } else if indexPath.section == 1 { 

     offset = 3 

    } else if indexPath.section == 2 { 

     offset = 7 

    } 


    if arrayOfCellData[indexPath.row + offset].cell == 1 { 


     let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1 

     cell.cellName_1.text = arrayOfCellData[indexPath.row + offset].text 

     return cell 

    } 
    else if arrayOfCellData[indexPath.row + offset].cell == 2 { 

     let cell = Bundle.main.loadNibNamed("TableViewCell_Type2", owner: self, options: nil)?.first as! TableViewCell_Type2 

     cell.cellName_2.text = arrayOfCellData[indexPath.row + offset].text 

     return cell 


    } 
    else { 

     let cell = Bundle.main.loadNibNamed("TableViewCell_Type1", owner: self, options: nil)?.first as! TableViewCell_Type1 

     cell.cellName_1.text = arrayOfCellData[indexPath.row + offset].text 

     return cell 

     } 
0

Вместо arrayOfCellData [indexPath.row], попробуйте это рассчитать правильный индекс в массиве:

var idx = indexPath.row 
    if indexPath.section == 1 { idx += 3 } 
    else if indexPath.section == 2 { idx += 7 } 

    // and then you can use: 
    arrayOfCellData[idx] 
+0

После использования вашего решения у меня возникла ошибка компилятора. Он жалуется на эту ошибку: бинарный оператор «==» не может применяться к операндам типа «section.Type» и «Int» – fatemeh

+0

@fatemeh, когда вы хотите использовать '==', вы должны использовать его по 2 значениям, которые имеют тот же тип. Я не знаю, что такое 'section.Type', но' Int', очевидно, является целым числом. Поэтому убедитесь, что вы сравниваете один и тот же тип. Вы всегда можете «Ctrl + щелкнуть» на переменной, чтобы увидеть ее тип. fahmidin? – Honey

+0

раздел @fatemeh - indexPath.section. Я думал, это очевидно. Я редактировал код. – Gabriel

1

Это предложение с более удобным источником данных

  • Создать перечисление для типов клеток

    enum CellType { 
        case one, two 
    } 
    
  • Структура содержит заголовок для разделов, массив для типов ячеек и массив для текстовых строк.

    struct CellData { 
        let title : String 
        let typeArray : [CellType] 
        let textArray : [String] 
    } 
    
  • Объявите массив источника данных

    var arrayOfCellData = [CellData]() 
    
  • В viewDidLoad создать 3 секции. Приносим извинения за использование западного текста для textArray элементов, потому что я слишком смутился о поведении текста справа налево).

    override func viewDidLoad() { 
        super.viewDidLoad() 
        let section0 = CellData(title: "تنظیمات رنگ\n", typeArray: [.one, .two, .one], textArray: ["Text 1", "Text 2", "Text 3"]) 
        let section1 = CellData(title: "تنظیمات سیستم\n", typeArray: [.two, .two, .two, .two], textArray: ["Text 4", "Text 5", "Text 6", "Text 7"]) 
        let section2 = CellData(title: "پشتیبانی\n", typeArray: [.two], textArray: ["Text 8"]) 
    
        arrayOfCellData = [section0, section1, section2] 
    } 
    

Теперь источник данных и методы делегата гораздо проще для заполнения.
Следующий код предполагает, что обе ячейки предназначены непосредственно в Interface Builder с пользовательскими классами имени TableViewCell_Type1 и TableViewCell_Type2 и соответствующие идентификаторы Type1 и Type2:

override func numberOfSections(in tableView: UITableView) -> Int { 
     return arrayOfCellData.count 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     let section = arrayOfCellData[section] 
     return section.textArray.count 
    } 


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let section = arrayOfCellData[indexPath.section] 
     let text = section.textArray[indexPath.row] 
     let cellType = section.typeArray[indexPath.row] 


     switch cellType { 
     case .one: 
      let cell = tableView.dequeueReusableCell(withIdentifier: "Type1", for: indexPath) as! TableViewCell_Type1 
      cell.cellName_1.text = text 
      return cell 

     case .two: 
      let cell = tableView.dequeueReusableCell(withIdentifier: "Type2", for: indexPath) as! TableViewCell_Type2 
      cell.cellName_2.text = text 
      return cell 

     } 
    } 


    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 

     let section = arrayOfCellData[section] 
     return section.title 
    } 
+0

Ваш ответ имеет 'dequeueReusableCellWithIdentifier'. Ее нет! Есть ли способ, которым он может даже работать без такого ?! – Honey

+1

Я сознательно написал код для повторно используемых ячеек, потому что его намного проще реализовать. К сожалению, многие из многих руководств предлагают более громоздкий (и древний) способ. – vadian

Смежные вопросы