我试图将我的主页图片分页,以便不会一次性加载我的所有元素。我有一个活动模型
import Foundation
import FirebaseDatabase.FIRDataSnapshot
struct Event: MGKeyed {
let currentEventKey: String
let currentEventName: String
let currentEventImage: String
let currentEventPromo: String?
let currentEventDescription: String
//nested properties
let currentEventStreetAddress: String
let currentEventCity: String
let currentEventState: String
let currentEventDate: String?
let currentEventTime: String?
let currentEventZip: Int
//nested properties stop
var currentAttendCount: Int
var isAttending = false
var eventDictionary: [String: Any]{
let dateDict = ["start:date":currentEventDate, "start:time": currentEventTime]
return ["event:name":currentEventName,"event:imageURL" : currentEventImage,
"event:description": currentEventDescription, "attend:count": currentAttendCount,
"event:street:address": currentEventStreetAddress,"event:zip": currentEventZip,
"event:state": currentEventState, "event:city": currentEventCity, "event:promo": currentEventPromo ?? "", "event:date": dateDict]
}
init(currentEventKey: String, dictionary: [String:Any]) {
self.currentEventKey = currentEventKey
self.currentEventName = dictionary["event:name"] as? String ?? ""
self.currentEventImage = dictionary["event:imageURL"] as? String ?? ""
self.currentEventDescription = dictionary["event:description"] as? String ?? ""
self.currentEventPromo = dictionary["event:promo"] as? String ?? ""
self.currentAttendCount = dictionary["attend:count"] as? Int ?? 0
//nested properties
self.currentEventStreetAddress = dictionary["event:street:address"] as? String ?? ""
self.currentEventCity = dictionary["event:city"] as? String ?? ""
self.currentEventState = dictionary["event:state"] as? String ?? ""
self.currentEventZip = dictionary["event:zip"] as? Int ?? 0
let eventDate = dictionary["event:date"] as? [String: Any]
self.currentEventDate = eventDate?["start:date"] as? String ?? ""
self.currentEventTime = eventDate?["start:time"] as? String ?? ""
}
init?(snapshot: DataSnapshot) {
guard let dict = snapshot.value as? [String : Any],
let currentEventName = dict["event:name"] as? String,
let currentEventImage = dict["event:imageURL"] as? String,
let currentEventDescription = dict["event:description"] as? String,
let currentEventPromo = dict["event:promo"] as? String,
let currentEventStreetAddress = dict["event:street:address"] as? String,
let currentEventCity = dict["event:city"] as? String,
let currentEventState = dict["event:state"] as? String,
let currentEventZip = dict["event:zip"] as? Int,
let currentAttendCount = dict["attend:count"] as? Int,
let eventDate = dict["event:date"] as? [String: Any],
let currentEventDate = eventDate["start:date"] as? String,
let currentEventTime = eventDate["start:time"] as? String
else { return nil }
self.currentEventKey = snapshot.key
self.currentEventName = currentEventName
self.currentEventImage = currentEventImage
self.currentEventDescription = currentEventDescription
self.currentEventStreetAddress = currentEventStreetAddress
self.currentEventCity = currentEventCity
self.currentEventState = currentEventState
self.currentEventZip = currentEventZip
self.currentAttendCount = currentAttendCount
self.currentEventPromo = currentEventPromo
self.currentEventDate = currentEventDate
self.currentEventTime = currentEventTime
}
}
此事件要求我遵守下面列出的MGKeyed协议
import Foundation
import UIKit
protocol MGKeyed {
var key: String? { get set }
}
class MGPaginationHelper <T: MGKeyed> {
let pageSize: UInt
let serviceMethod: (UInt, String?, @escaping (([T]) -> Void)) -> Void
var state: MGPaginationState = .initial
var lastObjectKey: String?
init(pageSize: UInt = 1, serviceMethod: @escaping (UInt, String?, @escaping (([T]) -> Void)) -> Void) {
self.pageSize = pageSize
self.serviceMethod = serviceMethod
}
// 1
func paginate(completion: @escaping ([T]) -> Void) {
// 2
switch state {
// 3
case .initial:
lastObjectKey = nil
fallthrough
// 4
case .ready:
state = .loading
serviceMethod(pageSize, lastObjectKey) { [unowned self] (objects: [T]) in
// 5
defer {
// 6
if let lastObjectKey = objects.last?.key{
self.lastObjectKey = lastObjectKey
}
// 7
self.state = objects.count < Int(self.pageSize) ? .end : .ready
}
// 8
guard let _ = self.lastObjectKey else {
return completion(objects)
}
// 9
let newObjects = Array(objects.dropFirst())
completion(newObjects)
}
// 10
case .loading, .end:
return
}
}
func reloadData(completion: @escaping ([T]) -> Void) {
state = .initial
paginate(completion: completion)
}
}
enum MGPaginationState {
case initial
case ready
case loading
case end
}
此方法负责分页。我的第一个问题是分页永远不会停止并继续加载相同的1或2个元素,我假设这是因为协议的符合性。我如何使我的事件模型符合该协议,因此它获得了一个不同的密钥,因此它知道何时停止?