[英]Swift 3: CollectionView didSelectItemAt get selected cell label
[英]swift: Label in collectionView cell
我的collectionView中有7個部分和3個cels。
單擊單元格時下載文件的代碼:
enum DownloadStatus {
case none
case inProgress
case completed
case failed
}
struct item {
var title : String!
var downloadStatus : DownloadStatus = .none
init(title: String) {
self.title = title
}
}
var downloadQ = [Int: [Int]]()
typealias ProgressHandler = (Int, Float) -> ()
var items = [[item]]()
var tableId = 0
var onProgress : ProgressHandler?
override func viewDidLoad() {
super.viewDidLoad()
items = [
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")],
[item(title: "item 2"),item(title: "item 2"),item(title: "item 2")]
]
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return media.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return media[section].count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
var item = self.items[indexPath.section][indexPath.row]
downloadQ[indexPath.section]?.append(indexPath.row)
var theArray = downloadQ[indexPath.section] ?? [Int]()
theArray.append(indexPath.row)
downloadQ[indexPath.section] = theArray
// Create the actions
let url = URL(string: "link")!
let downloadManager = DownloadManager()
downloadManager.identifier = indexPath.row
downloadManager.tableId = indexPath.section
downloadManager.folderPath = "folder"
let downloadTaskLocal = downloadManager.activate().downloadTask(with: url)
downloadTaskLocal.resume()
var cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! MasterViewCell
cell = self.collectionView?.cellForItem(at: indexPath) as! MasterViewCell
cell.label?.isHidden = false
downloadManager.onProgress = { (row, tableId, progress) in
DispatchQueue.main.async {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if appDelegate.masterVC == nil {
return
}
if appDelegate.masterVC.tableId != tableId {
return
}
let indexpath = IndexPath.init(row: row, section: indexPath.section)
var cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! MasterViewCell
cell = appDelegate.masterVC.collectionView.cellForItem(at: indexpath) as! MasterViewCell
cell.label?.text = "\(CGFloat(progress))%"
}
}
}
我的下載管理員課程:
import Foundation
import UIKit
extension URLSession {
func getSessionDescription () -> Int {
// row id
return Int(self.sessionDescription!)!
}
func getDebugDescription () -> Int {
// table id
return Int(self.debugDescription)!
}
}
class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate {
static var shared = DownloadManager()
var identifier : Int = -1
var tableId : Int = -1
var folderPath : String = ""
typealias ProgressHandler = (Int, Int, Float) -> ()
var onProgress : ProgressHandler? {
didSet {
if onProgress != nil {
let _ = activate()
}
}
}
override init() {
super.init()
}
func activate() -> URLSession {
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background.\(NSUUID.init())")
let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
urlSession.sessionDescription = String(identifier)
urlSession.accessibilityHint = String(tableId)
return urlSession
}
private func calculateProgress(session : URLSession, completionHandler : @escaping (Int, Int, Float) -> ()) {
session.getTasksWithCompletionHandler { (tasks, uploads, downloads) in
let progress = downloads.map({ (task) -> Float in
if task.countOfBytesExpectedToReceive > 0 {
return Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive)
} else {
return 0.0
}
})
//print("tbale id \(session.accessibilityHint ?? "hit")")
let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String) // 1357 as integer
let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String) // 1357 as integer
if let idx = downloadQ[someNumb!]?.index(of: some1!) {
downloadQ[someNumb!]?.remove(at: idx)
//print("remove:\(downloadQ)")
}
completionHandler(session.getSessionDescription(), Int(session.accessibilityHint!)!, progress.reduce(0.0, +))
}
}
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL){
let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String) // 1357 as integer
let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String) // 1357 as integer
if let idx = downloadQ[someNumb!]?.index(of: some1!) {
downloadQ[someNumb!]?.remove(at: idx)
//print("remove:\(downloadQ)")
}
let fileName = downloadTask.originalRequest?.url?.lastPathComponent
let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentDirectoryPath:String = path[0]
let fileManager = FileManager()
var destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appending("/\(folderPath)"))
do {
try fileManager.createDirectory(at: destinationURLForFile, withIntermediateDirectories: true, attributes: nil)
destinationURLForFile.appendPathComponent(String(describing: fileName!))
try fileManager.moveItem(at: location, to: destinationURLForFile)
}catch(let error){
print(error)
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String) // 1357 as integer
let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String) // 1357 as integer
if let idx = downloadQ[someNumb!]?.index(of: some1!) {
downloadQ[someNumb!]?.remove(at: idx)
//print("remove:\(downloadQ)")
}
if totalBytesExpectedToWrite > 0 {
if let onProgress = onProgress {
calculateProgress(session: session, completionHandler: onProgress)
}
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
//debugPrint("Progress \(downloadTask) \(progress)")
}
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String) // 1357 as integer
let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String) // 1357 as integer
if let idx = downloadQ[someNumb!]?.index(of: some1!) {
downloadQ[someNumb!]?.remove(at: idx)
//print("remove:\(downloadQ)")
}
//debugPrint("Task completed: \(task), error: \(String(describing: error))")
}
}
但我有一個問題。 我的應用程序崩潰在這一行 - cell = self.collectionView?.cellForItem(at:indexPath)as! MasterViewCell
出現此問題:致命錯誤:在展開Optional值時意外發現nil。 怎么解決?
您面臨的問題是由於細胞重用。 每次在集合或表格中滾動時,通常會對舊單元格進行雙擊。 這意味着無論何時顯示新單元格cellForRow
(表格)或itemForRow
(集合),您都必須擁有能夠為其提供數據的單元格。
如果您只將有關下載過程的數據存儲到單元格中,那么當prepareForReuse:
系統調用被調用時,您將丟失它們,因為單元格會被重置。
另一種方法是使用靜態單元格。 因為靜態單元格永遠不會被重置。 但是,只有當您在屏幕上使用少量項目時,這才有用。 如果你有數十或數百個單元,那么它的性能成本非常高。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.