2016-06-22 3 views
2

を試作UITableViewCellsに同じビューのインスタンスを区別し、tableViewに4つの異なるPickerViewで4つの異なるセルにそのプロトタイプを使用する方法。次のコードを使用して、テーブルビュー(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)にセルを供給し、後でピッカーを区別するために各ピッカーを別のインスタンス変数に設定します(同じUITableViewControllerインスタンスはすべてのデリゲート/データソースです)。私は<code>UIPickerView</code>が含まれている<code>UITableViewCell</code>プロトタイプを使用してい

しかし、コードを実行すると、4つのインスタンス変数がすべて同じUIPickerViewを指しています。代わりに4つの異なるUIPickerViewsを確実に使用することはできますか?この質問はObjective Cでタグ付けされたよう

func PickerCell(tableView: UITableView, indexPath: NSIndexPath, inout picker: UIPickerView?) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("PickerCell") 
    if let pickerFromCell = cell?.contentView.viewWithTag(1) as? UIPickerView { 
     pickerFromCell.reloadAllComponents() 
     pickerFromCell.dataSource = self 
     pickerFromCell.delegate = self 
     picker = pickerFromCell 
    } 
    return cell! 
} 
+0

[いいえ、 'tag'は本当に悪い識別目的 –

+1

ごとに異なるタグを設定する必要が

たとえば、このUITableViewCellサブクラスを考えます細胞を追跡する方法とAppleは今日その習慣を失望させている。あなたは 'UITableViewCell'をサブクラス化し、ビューコントローラではなく、セルにプロパティを持たなければなりません。 – Rob

+0

プロトタイプのセルは、その再利用識別子でデキューされたすべてのセルで同じUIPickerViewを再利用するという問題があるようです。これはAppleのドキュメンテーションと矛盾しているようですので、私はそれがバグだと仮定しなければなりません。ストーリーボードに4つのプロトタイプのセルを作成し、それぞれが異なる再利用された識別子を持つようにしてから、それぞれのセルを別の再利用識別子からデキューし、各ピッカーに異なるタグ付けを行いました。 (別の方法でタグを付けても同じ理由で動作しませんでした) –

答えて

0
var dict: [Int, UIPickerView] 

... 

if dict[indexPath.row] == nil { 
    // Create UIPickerView and assign it to dict[indexPath.row]. 
} 
0

、私はにObjCであなたの答えを与えています。ここで

は、when you have controls in UICollectionViewCell or UITableViewCell, give tag to your controls depending upon your indexPathをこのような問題を解決するための

ヒント、再利用可能なセル内のコントロールに対処するために、あなたは何ができるかです。

あなたはtableViewCell ケース1でそれを行うことができますcollectionViewCellで例を与える:CollectionViewが断面であれば、あなたのタグが[0] [0]、[1] [0] ...このような場合には何かをのようになります、このような

collectionViewCell.picker.tag = [[NSString stringWithFormat:@"%ld%ld",(long)indexPath.section,(long)indexPath.item] intValue]; // If it is sectional collection view 

ケース2:コレクションビューが非断面である場合には、このような何かを、これはあなたの問題を解決したり、それに応じて管理するために、あなたのアイデアを与えるだろう

collectionViewCell.picker.tag = [[NSString stringWithFormat:@"%ld",(long)indexPath.item] intValue]; // If it is non-sectional collection view 

ホープ。 セルに複数のコントロールがある場合、indexPath.item + 1 + 2のようなタグを指定してください。

1

tagの代わりに、次のように試してみてください。この

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    let cell = imageView.superview?.superview as! UITableViewCell //You have to use as may super as your UITableViewCell hierarchy 
    let indexPath = self.tabelView.indexPathForCell(cell) 
    self.pickerSelectedIndexArr[indexpath.row] = row 
} 

ようPickerViewDelegateのごdidSelectRowを変更しても、あなたが簡単にあなたが望む任意の時間をすべてピッカーを取得、選択した値ができさて

var pickerSelectedIndexArr: [Int] = [Int]() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.pickerSelectedIndexArr = [0, 0, 0 ,0] 
} 

方法

を次のように viewDidLoadであなたのファイルに pickerSelectedIndexArr配列を追加し、それを割り当てます
これがあなたを助けてくれることを願っています。

0

私はNiravに同意し、問題のセルのNSIndexPathを判定するためにセルを使用することに同意します。

個人的には、セルをデータソースのサブクラスにして、ピッカーの委任を行い、ピッカーの責任を負わせたいと思います。これにより、どのピッカーがどのセルに関連付けられているかについての混乱が完全に排除されます。しかし、ユーザーがピッカーから値を選択し、ビューコントローラがモデルを更新できるときに、セルがビューコントローラに通知できるプロトコルがあります。

// CustomCell.swift 

import UIKit 

/// Protocol that the view controller will conform to in order to receive updates 
/// from the cell regarding which row in the picker was picked. 
/// 
/// - note: This is a `class` protocol so that I can use `weak` reference. 

protocol CustomCellDelegate: class { 
    func cell(customCell: CustomCell, pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
} 

/// Custom cell subclass, which is the picker's data source and delegate 

class CustomCell: UITableViewCell, UIPickerViewDataSource, UIPickerViewDelegate { 

    /// The delegate who we will inform of any picker changes. 
    /// 
    /// This is weak to avoid strong reference cycle. 

    weak var delegate: CustomCellDelegate? 

    /// The array of values to be shown in the picker. 
    /// 
    /// If the `values` changes, this reloads the picker view. 

    var values: [String]? { 
     didSet { 
      pickerView.reloadComponent(0) 
     } 
    } 

    /// The outlet to the picker in the cell. 

    @IBOutlet weak var pickerView: UIPickerView! 

    // MARK: UIPickerViewDataSource 

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return values?.count ?? 0 
    } 

    // MARK: UIPickerViewDelegate 

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
     return values?[row] ?? "" 
    } 

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     delegate?.cell(self, pickerView: pickerView, didSelectRow: row, inComponent: component) 
    } 
} 

そしてビューコントローラ:

// ViewController.swift 

import UIKit 

class ViewController: UITableViewController, CustomCellDelegate { 

    // an array of arrays of acceptable values 

    let troupes = [ 
     ["Mo", "Larry", "Curly"], 
     ["Abbott", "Costello"], 
     ["Groucho", "Harpo", "Zeppo", "Chico", "Gummo"], 
     ["Laurel", "Hardy"], 
     ["Graham Chapman", "John Cleese", "Terry Gilliam", "Eric Idle", "Terry Jones", "Michael Palin"] 
    ] 

    /// An array that indicates which is item is selected for each table view cell 

    var selectedItemForRow: [Int]! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     selectedItemForRow = troupes.map { _ in return 0 } // initialize the `selectedItemForRow` array with zeros 

     // Whatever further initialization of the view controller goes here. 
    } 

    // MARK: UITableViewDataSource 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return troupes.count 
    } 

    // Populate cell, setting delegate, list of acceptable values, and currently selected value. 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell 
     cell.delegate = self 
     cell.values = troupes[indexPath.row] 
     cell.pickerView.selectRow(selectedItemForRow[indexPath.row], inComponent: 0, animated: false) 
     return cell 
    } 

    // MARK: CustomCellDelegate 

    // When the cell tells us that the user changed the selected row, let's update our model accordingly. 

    func cell(customCell: CustomCell, pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
     if let indexPath = tableView.indexPathForCell(customCell) { 
      selectedItemForRow[indexPath.row] = row 
     } 
    } 

} 
関連する問題