我使用Koloda库来管理屏幕上的可拖动卡片。
我的数据源是一个UIImage数组:
private var numberOfRecommendedUsers: UInt = 5
let urlPicture = NSURL(string:"http://...")
let imageData = NSData(contentsOfURL: urlPicture!)
self.dataSource = {
var array: Array<UIImage> = []
for _ in 0..<numberOfRecommendedUsers {
array.append(UIImage(data: imageData!)!)
}
return array
}()
刷卡时,我将一张卡添加到数据源并重新加载数据():
func koloda(koloda: KolodaView, didSwipeCardAtIndex index: UInt, inDirection direction: SwipeResultDirection) {
let urlPicture = NSURL(string:"http:...")
let imageData = NSData(contentsOfURL: urlPicture!)
self.dataSource.insert(UIImage(data: imageData!)!, atIndex: kolodaView.countOfCards)
kolodaView.reloadData()
}
效果很好,但耗费大量内存(用户会刷掉数百张卡片)。
刷卡时,不再使用。 因此,当添加新卡时,解决方案是将其从数据源中删除。因此,数据源将始终仅消耗内存中的5个元素。
我发现这样做的唯一方法如下:
func koloda(koloda: KolodaView, didSwipeCardAtIndex index: UInt, inDirection direction: SwipeResultDirection) {
let urlPicture = NSURL(string:"http:...")
let imageData = NSData(contentsOfURL: urlPicture!)
self.dataSource.insert(UIImage(data: imageData!)!, atIndex: kolodaView.countOfCards)
self.dataSource.removeAtIndex(0)
kolodaView.resetCurrentCardIndex()
}
问题是resetCurrentCardIndex()
调用会在每次滑动时重新加载加载动画的卡片。
预期的行为是在数据源的末尾添加一张新卡,并删除已经滑动的第一个元素而没有任何动画。
有什么办法吗?或者也许有一个更好,更合适的解决方案,我没有看到......
感谢任何反馈。
我刚刚找到了一种在重装卡片时删除动画的方法。有一种委托方法可以实现:
func kolodaShouldApplyAppearAnimation(koloda: KolodaView) -> Bool {
return !self.reloadData
}
滑动委托方法变为:
func koloda(koloda: KolodaView, didSwipeCardAtIndex index: UInt, inDirection direction: SwipeResultDirection) {
let urlPicture = NSURL(string:"http:...")
let imageData = NSData(contentsOfURL: urlPicture!)
self.dataSource.insert(UIImage(data: imageData!)!, atIndex: kolodaView.countOfCards)
self.dataSource.removeAtIndex(0)
self.reloadData = true
kolodaView.resetCurrentCardIndex()
self.reloadData = false
}
这就是我所期望的行为,如果某人有更好或更合适的解决方案,请随时提出建议。
我实施了詹姆斯提出的建议。
我为了在koloda视图中显示的内容制作了一个类:
private var numberOfUsers: UInt = 5
class KolodaUser {
var photoUrlString = ""
var firstname = ""
var age = 0
var id = ""
init () {
}
convenience init(_ dictionary: Dictionary<String, AnyObject>) {
self.init()
firstname = (dictionary["firstname"] as? String)!
photoUrlString = ((dictionary["pictures"]) as? [String])![0]
age = (dictionary["age"] as? Int)!
id = (dictionary["id"] as? String)!
}
}
@IBOutlet weak var kolodaView: KolodaView!
var koloUsers = Array<KolodaUser>()
加载视图后,我从远程数据库中获取5个用户数据:
func fetchUsers() {
getUsers(limit: 5, onCompleted: {(users) in
for user in users! {
if let koloUserDic = user as? Dictionary<String, AnyObject> {
self.koloUsers.append(KolodaUser(koloUserDic))
}
}
dispatch_async(dispatch_get_main_queue()) {
self.kolodaView.reloadData()
}
})
}
现在,我的koloda委托方法如下:
func koloda(koloda: KolodaView, didSwipeCardAtIndex index: UInt, inDirection direction: SwipeResultDirection) {
if direction == .Left {
// get one user from DB
getUsers(limit: 1, onCompleted: {(users) in
for user in users! {
if let koloUserDic = user as? Dictionary<String, AnyObject> {
self.koloUsers.append(KolodaUser(koloUserDic))
}
}
dispatch_async(dispatch_get_main_queue()) {
self.kolodaView.reloadData()
}
})
}
}
func koloda(koloda: KolodaView, viewForCardAtIndex index: UInt) -> UIView {
let kolodaUserView = NSBundle.mainBundle().loadNibNamed("KolodaUserView",
owner: self, options: nil)[0] as? KolodaUserView
let user = self.koloUsers[Int(index)]
kolodaUserView?.photoImageView?.setImageWithUrl(NSURL(string: "http://.../" + user.photoUrlString)!)
kolodaUserView?.nameAndAgeLabel?.text = "\(user.firstname)" + ", " + "\(user.age)"
return kolodaUserView!
}
函数setImageWithUrl
来自https://github.com/namanhams/Swift-UIImageView-AFNetworking存储库。
关于此解决方案,您可以注意到k KolodaUser
对象被无限地添加到koloda视图数据源数组中。
如果用户刷了一千次,这将导致一个非常大的阵列,但我认为这不会是一个内存问题。也许我错了?
感谢您对此新解决方案的任何反馈。