import UIKit
import ObjectiveC
var SubRowObjectKey: String = "subRow"
extension IndexPath {
var subRow: Int {
get {
let subRowObj = objc_getAssociatedObject(self, &SubRowObjectKey)
if subRowObj != nil {
return (subRowObj as! Int)
}
return 0
}
set {
let subRowObj = (newValue as NSInteger)
objc_setAssociatedObject(self, &SubRowObjectKey, subRowObj, .OBJC_ASSOCIATION_RETAIN)
}
}
static func indexPathForSubRow(_ subRow: NSInteger, inRow row: NSInteger, inSection section: NSInteger) -> IndexPath {
var indexPath = IndexPath(row: row, section: section)
indexPath.subRow = (subRow as Int)
print(subRow)
print(indexPath.subRow)
return indexPath
}
}
let indexPath = IndexPath.indexPathForSubRow(5, inRow: 1, inSection: 2)
print(indexPath.subRow)
Tested in Xcode version 8.2.1 & Swift 3.0
Any help will be appreciated.
IndexPath
is a struct, which don't support associated objects. You can easily check it in the setter by directly trying to read back the set object:
set {
let subRowObj = (newValue as NSInteger)
objc_setAssociatedObject(self, &SubRowObjectKey, subRowObj, .OBJC_ASSOCIATION_RETAIN)
let subRowObj2 = objc_getAssociatedObject(self, &SubRowObjectKey)
print(subRowObj2 ?? "nil") // prints "nil"
}
Even if the code in the setter would have worked , the whole construct still doesn't hold: Since structs are copied when transferred / assigned (at least when modified via copy on write mechanism), your associated objects won't be included in that copy, so you'll lose that information anyhow, sooner or later.
Nevertheless, instead of extending IndexPath
you could extend NSIndexPath
which then works fine -- but I guess this is not what you want, because you want to influence the IndexPath that you get from a table view...
Based on maddy's answer this is my IndexPath extension that adds a subRow property.
extension IndexPath {
init(subRow: Int, row: Int, section: Int) {
self.init(indexes: [IndexPath.Element(section), IndexPath.Element(row), IndexPath.Element(subRow)])
}
var subRow: Int {
get { return self[index(at: 2)] }
set { self[index(at: 2)] = newValue }
}
var row: Int {
get { return self[index(at: 1)] }
set { self[index(at: 1)] = newValue }
}
var section: Int {
get { return self[index(at: 0)] }
set { self[index(at: 0)] = newValue }
}
private func index(at idx: Int) -> IndexPath.Index {
return self.startIndex.advanced(by: idx)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.