SwiftでNSIndexPathを使う

このエントリーをはてなブックマークに追加

本業の方が鬼のように眼を酷使している為、最近はSwiftの勉強も滞っていますが久しぶりにちょっといじりました。

今回はObjective-Cの

[NSIndexPath indexPathForItem:index inSection:0];

と等価になるSwiftのメソッドを探すのに手間をかけてしまったのでメモ。
まず、ドキュメントを見るとObjective-Cのサンプルしか載っていない為手がかりがつかめません。ここのブリッジがまだ甘いので正式版リリースの頃にはもっとドキュメントが充実することを期待。

とりあえずはNSIndexPathの定義自体を覗いてみると

class NSIndexPath : NSObject, NSCopying, NSSecureCoding, NSCoding {
    
    init() /* designated initializer */
    init(indexes: CConstPointer<Int>, length: Int) /* designated initializer */
    
    convenience init(index: Int)
    
    func indexPathByAddingIndex(index: Int) -> NSIndexPath!
    func indexPathByRemovingLastIndex() -> NSIndexPath!
    
    func indexAtPosition(position: Int) -> Int
    var length: Int { get }
    
    func getIndexes(indexes: CMutablePointer<Int>)
    
    // comparison support
    func compare(otherObject: NSIndexPath!) -> NSComparisonResult // sorting an array of indexPaths using this comparison results in an array representing nodes in depth-first traversal order
}

たったのこんだけです。
そしてObjective-Cと等価に見えるメソッドが見当たらなかったので、とりあえずコンストラクタinit(index: Int)に突っ込んで実行してみたら見事に実行時エラー。

2014-07-06 22:24:58.914 MyStuff[13317:942088] * Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid index path for use with UITableView.  Index paths passed to table view must contain exactly two indices specifying the section and row.  Please use the category on NSIndexPath in UITableView.h if possible.’**

「カテゴリ使えよ」と。あれ?ということはSwiftでいうextensionってことですよね。なるほど、ってなことでUIKit>UITableViewの中身を観てみるとちゃんとありました。

extension NSIndexPath {
    
    init(forRow row: Int, inSection section: Int) -> NSIndexPath
    
    var section: Int { get }
    var row: Int { get }
}

これを使って以下のように書けば思った通り動作。Objective-Cの知識がそもそも無いので初歩的なところで結構つまづきますねー。

NSIndexPath(forRow: index, inSection: 0)

 

Written on July 6, 2014
このエントリーをはてなブックマークに追加