2017-08-11 33 views
-2

我想創建一個應用程序的部分在我的TableView。如何管理UITableView的部分

但實際上,我不知道如何管理部分。

我創建的部分,它工作正常,但當我嘗試在我的部分添加一個新行時,我得到了一個問題。

例子:

我創建我的第一個部分的新項目。

enter image description here

的節名是 「Aucun」 和行標籤將設置爲 「測試1」

它的工作原理!

enter image description here

所以,現在我想添加別的東西

enter image description here

的節名是 「PRODUITS Laitiers」 和行拉貝l爲 「Test2的」

enter image description here

不合格:(一節是創建,但行不是很好的一個

有我的代碼的時刻

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

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return arraySection[section] 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return numberOfRowsInSection[section] 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") 
    cell?.textLabel?.text = "\(String(describing: products[indexPath.row]["Name"]!))" 
    cell?.textLabel?.adjustsFontSizeToFitWidth = true 
    cell?.textLabel?.font = UIFont(name: "Arial", size: 14) 
    return cell! 
} 

numberOfRowsInSection是一個int數組,其中存儲了本節中必須包含的產品數量。

+0

你是什麼意思創建一個新的行|部分?你是否動態創建row |部分? –

+0

是的,就是這樣。當用戶在屏幕上輸入內容時,我會動態添加分節/行 – pierreafranck

+0

您應該查看此https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html ? –

回答

1

你得到「測試1」每一次,因爲你有節,但你總是試圖通過使用行的索引,而不檢查部分的索引得到一個值:

\(String(describing: products[indexPath.row]["Name"]!)) 

如果細胞所有的值在單個陣列中的存儲,那麼你應該使用部分數得到一個數組的值:

\(String(describing: products[indexPath.section]["Name"]!)) 

但是,這將只工作如果每個部分將有隻有一行。否則,您將必須先獲取節的編號,以檢測當前行分配的節,然後獲取行數。

如果你有行的每個部分的陣列部分的陣列,將看起來像這樣:

讓arraySection = [[段#0的值],[第#1的值]。 .. ]

然後,您可以使用此得到每一行的值:

let value = arraySection[indexPath.section][indexPath.row] 

========編輯=========== B UT有一個更好的方法 - 使用對象或結構

struct Row { 
    var value: String = "" 
} 

struct Section { 
    var name: String = "" 
    var values: [Row] = [] 
} 

因此,使用這種結構,你的代碼將被改變:

//your array of sections will contain objects 
let arraySection: [Section] = [] 

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

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    //get the name of the section 
    return arraySection[section].name 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    //check the count of rows for each section 
    return arraySection[section].values.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") 
    // now we can get the value for current row by checking sections and then rows 
    cell?.textLabel?.text = arraySection[indexPath.section].values[indexPath.row].value 
    cell?.textLabel?.adjustsFontSizeToFitWidth = true 
    cell?.textLabel?.font = UIFont(name: "Arial", size: 14) 
    return cell! 
} 
+0

謝謝兄弟。 arraySection已經是我存儲我的段名稱的數組。 你可以編輯你的答案與所有​​的代碼PLZ?我很困難:( – pierreafranck

+0

檢查它,我想給你另一種方式來處理所有值 – Woof

+0

嗯,我不明白行結構的,因爲你不使用它除了在cellForRowAt方法,因此我可以使用我的實際詞典?因爲我不只有[「姓名」]存儲在其中,我有3或4個信息,我將在以後使用 – pierreafranck

2

我認爲問題出在UITableViewDataSource方法cellForRowAt中的產品數組中。您正在訪問的每個部分中的第一個對象相同的數組元素與

products[indexPath.row]["Name"]! 

也許你需要調整你的模型來處理indexPath.section

+0

感謝您的回答。但我有12個可能的部分,我不打算創建12個數組:/ – pierreafranck

+0

而不是使用字典對象的數組,你必須爲每個值提供一個鍵,我會有一個2D Int數組,像[[Int ]]()。這樣你可以爲每個部分設置一個對象數組。例如[[1,2,3],[9,8,7]],第一部分的行可以用1,2,3來填充,第二部分用9,8,7來填充。即行方法的單元格可以使用產品[indexPath.section] [indexPath.row]。 –

+0

你可以用一個例子plz編輯你的答案嗎? :D – pierreafranck

0

我要創建一個Section模型保持的第一件事軌道段,如下所示:

/// Defines a section in data source 
struct Section { 

    // MARK: - Properties 

    /// The title of the section 
    let title: String 

    /// The items in the section 
    var items: [String] 
} 

然後,我將使用一個UITableViewController添加權butto n將新的部分/行插入UITableView,添加新的部分/行爲了簡潔起見,我將使用UIAlertController,其中兩個UITextField的內部需要放置部分的名稱和行的名稱。在結束看起來應該像下面的圖片:

enter image description here

在部分已經存在將要新行添加到該部分的情況下,否則,將創建新的部分和動態行。

DynamicTableViewController

class DynamicTableViewController: UITableViewController { 

    // MARK: - Properties 

    /// The data source for the table view 
    var dataSource = [Section(title: "Section 1", items: ["Row 1"])] 

    // MARK: - UIViewController 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    // MARK: - Table view data source 

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

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return dataSource[section].items.count 
    } 


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
     cell.textLabel?.text = dataSource[indexPath.section].items[indexPath.row] 
     return cell 
    } 

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
     return dataSource[section].title 
    } 

    @IBAction func didTapAddButton(_ sender: Any) { 
     presentAlerController() 
    } 
} 

extension DynamicTableViewController { 

    func add(_ sectionName: String?, _ row: String?) { 

     guard let name = sectionName, let rowName = row, 
     !name.isEmpty, !rowName.isEmpty else { 
     return 
     } 

     if let index = dataSource.index(where: { $0.title == name }) { 
      dataSource[index].items.append(rowName) 
     } else { 
     dataSource.append(Section(title: name, items: [rowName])) 
     } 

     tableView.reloadData() 
    } 

    func presentAlerController() { 

     let alertController = UIAlertController(title: "Add", message: "Add new Section/Row", preferredStyle: .alert) 

     let addAction = UIAlertAction(title: "Add", style: .default) { [weak self] _ in 
      let sectionTextField = alertController.textFields![0] as UITextField 
      let rowTextField = alertController.textFields![1] as UITextField 
      self?.add(sectionTextField.text, rowTextField.text) 
     } 

     let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in } 

     alertController.addTextField { textField in 
      textField.placeholder = "Add a new section name" 
     } 

     alertController.addTextField { textField in 
      textField.placeholder = "Add a new row" 
     } 

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

在上面的例子中,我不檢查重複行的存在,你可以做到這一點是很容易的。另外,我使用的是reloadData(),但如果你願意,你可以使用太:

// insert the new section with row of the row in the existent section 

tableView.beginUpdates() 
// insert new section in case of any 
insertSections(_ sections: IndexSet, with animation: UITableViewRowAnimation) 
// insert new row in section using: 
// insertRows(at: [IndexPath], with: UITableViewRowAnimation) 
tableView.endUpdates() 

還需要創建一個新的UIBarButtonItem並將其連接到我創造它能夠呈現UIAlertController@IBAction和將新的部分/行添加到UITableView

我希望這可以幫助你。