2017-08-11 26 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

FAIL :(セクションが作成されますが、行は良いもの

ない瞬間のために私のコードがありますです

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

新しい行セクションを作成することはどういう意味ですか?行|セクションを動的に作成していますか? –

+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"]!)) 

しかし、これは各セクションは一列のみを持っている場合にのみ動作します。それ以外の場合は、現在の行が割り当てられているセクションを検出し、次に行の数を取得するためにセクションの番号を最初に取得する必要があります。あなたはこのようになります。各セクションの行の配列を持つセクションの配列、持っている場合

は:

を、] [セクション#1の値、] arraySection = [[セクション#0の値をしましょう。 .. ]

次にあなたがこれを使用することにより、各行の値を取得することができます。

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

======== EDIT =========== Bもっと良い方法があるユタ - だから、オブジェクトまたは構造体

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

私はこの問題が製品のcellForRowAtの製品アレイにあると思います。あなたはおそらく、あなたがindexPath.sectionを処理するためにモデルを調整する必要が

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

で各セクションの最初のオブジェクトの同じ配列要素にアクセスしています。

+0

あなたの答えをありがとう。しかし、私は12のセクションを持っています、私は12の配列を作成するつもりはありません:/ – pierreafranck

+0

各値のキーを提供する必要がある辞書オブジェクトの配列を使用する代わりに、私は[[Int ]]()。このようにして、セクションごとにオブジェクトの配列を持つことができます。例えば、[1,2,3]、[9,8,7]]では、最初のセクション行には1,2,3が、2番目のセクションには9,8,7がそれぞれ格納されます。つまり、rowメソッドのセルは、商品[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] 
} 

は、その後、私はを追加右buttoでUITableViewControllerを使用する予定n新しいセクション/行をUITableViewに挿入するには、新しいセクション/行を追加します。UITextFieldの内部に簡潔さのためにUIAlertControllerを使用します。セクションの名前と行の名前を入れる必要があります。最後には、以下の画像のようになります。

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に追加してください。

私はこれがあなたを助けてくれることを願っています。

関連する問題