添加/删除动态koloda视图

时间:2016-05-01 11:26:08

标签: ios swift swipe

我使用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
}

这就是我所期望的行为,如果某人有更好或更合适的解决方案,请随时提出建议。

编辑2

我实施了詹姆斯提出的建议。

我为了在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视图数据源数组中。 如果用户刷了一千次,这将导致一个非常大的阵列,但我认为这不会是一个内存问题。也许我错了?

感谢您对此新解决方案的任何反馈。

0 个答案:

没有答案