Swift UIViewControllerサブクラス内でUITableViewDataSourceおよびUITableViewDelegateに準拠しようとしています。
class GameList: UIViewController {
var aTableView:UITableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
aTableView.delegate = self
aTableView.dataSource = self
self.view.addSubview(aTableView)
//errors on both lines for not conforming
}
}
ドキュメントでは、:
の後のclass
行に準拠する必要があると書かれていますが、通常はスーパークラスがそこに行きます。別の:
は機能しません。スーパークラスの後にコンマ区切りリストを使用しても機能しません
答えは以下にあります。 class GameList: UIViewController, UITableViewDataSource, UITableViewDelegate {
また、各プロトコルに必要なすべてのメソッドを採用する必要がありますが、最初は実行していませんでした。
コンマを使用します:
class GameList: UIViewController, UITableViewDelegate, UITableViewDataSource {
// ...
}
ただし、スーパークラスはコンマ区切りリストの最初の項目でなければならないことに注意してください。
プロトコルに必要なすべてのメソッドを採用しないと、コンパイラエラーが発生します。必要なすべてのメソッドを取得する必要があります!
XCode6-Beta7がリリースされると、
UITableViewDataSourceのプロトコルメソッドが少し変更され、ベータ6で正常に機能したプロトコルエラーに適合していることに気付きました。
これらは、 ITableViewDataSourceプロトコル に従って実装される必要なメソッドです。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // insert code}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // insert code
}
違いを再確認するか、実装したと思われるデリゲートメソッドを再実装することができます。
ここで2つのrequireメソッドを実装する必要があります。
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int {
return 10
}
func tableView(tableView:UITableView!, cellForRowAtIndexPath indexPath:NSIndexPath!) -> UITableViewCell! {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
cell.text = "Row #\(indexPath.row)"
cell.detailTextLabel.text = "Subtitle #\(indexPath.row)"
return cell
}
また、Delegateクラスからすべての非オプション関数をコピーすることも重要です。 Cmd + UITableViewDatasourceをクリックして、これら2つの定義をそのままコピーします。
Beta7の私にとって、UITableViewDatasourceには
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
私の実装:
var items = ["Apple", "Pear", "Banana"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Default")
cell.textLabel?.text = items[indexPath.row]
cell.detailTextLabel?.text = "Test"
return cell
}
次のメソッドを使用します。データソースメソッドに変更があります。
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
protocol UITableViewDataSource : NSObjectProtocol {
****func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell****
optional func numberOfSectionsInTableView(tableView: UITableView) -> Int // Default is 1 if not implemented
optional func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different
optional func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String?
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
optional func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
optional func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Index
optional func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! // return list of section titles to display in section index view (e.g. "ABCD...Z#")
optional func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
optional func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
// Data manipulation - reorder / moving support
optional func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
}
あなたのコードは動作します!!
この質問は既に回答されていますが、もう少しSwiftyにしたいだけです。
UITableViewDelegate, UITableViewDataSource
でプロトコルを記述する代わりに、extensionsを使用してそれらを分割できます。これはコードの編成に役立ちます。プロトコルの適合性の追加については、こちらで説明します page
上記の質問の場合、これは拡張機能を使用してプロトコルに対して確認できます。
class GameList: UIViewController {
var aTableView:UITableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
aTableView.delegate = self
aTableView.dataSource = self
self.view.addSubview(aTableView)
}
}
extension GameList: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
return cell
}
}
extension GameList: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row Clicked at \(indexPath.row)")
}
}