Как исправить зависание прокрутки просмотра коллекции?IOS

Программируем под IOS
Ответить
Anonymous
 Как исправить зависание прокрутки просмотра коллекции?

Сообщение Anonymous »

Я использую этот код, чтобы показать ход загрузки файла в ячейках представления моей коллекции. Все работает нормально. А если я не загружаю файл, я могу легко прокручивать представление коллекции, коснувшись ячейки представления коллекции. Но когда я закрываю файл, у меня возникают проблемы с прокруткой. Если я касаюсь ячейки коллекций, мое представление прокрутки не прокручивается.
мой код:

Код: Выделить всё

import UIKit

enum DownloadStatus {
case none
case inProgress
case completed
case failed
}

struct item {
var number: Int!
var downloadStatus: DownloadStatus = .none
var progress: Float = 0.0
init(number: Int) { self.number = number }
}

var downloadQueue = [Int: [Int]]()
var masterIndex = 0

extension URLSession {
func getSessionDescription () -> Int { return Int(self.sessionDescription!)! } // Item ID
func getDebugDescription () -> Int { return Int(self.debugDescription)! }      // Collection ID
}

class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate {

static var shared = DownloadManager()
var identifier : Int = -1
var collectionId : Int = -1
var folderPath : String = ""
typealias ProgressHandler = (Int, Int, Float) -> ()

var onProgress : ProgressHandler? {
didSet { if onProgress != nil { let _ = activate() } }
}
var onSuccess: ((Int) -> Void)? //  Void)? //  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(collectionId)
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
}
})
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)

let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String)

if let idx = downloadQueue[someNumb!]?.firstIndex(of: some1!) {
downloadQueue[someNumb!]?.remove(at: idx)
print("remove:: did finish :: \(downloadQueue)")
}
onSuccess?(collectionId) // call when download success

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) {
if totalBytesExpectedToWrite >  0 {
if let onProgress = onProgress {
calculateProgress(session: session, completionHandler: onProgress)
}
}
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

let stringNumb = (session.accessibilityHint ?? "hit")
let someNumb = Int(stringNumb as String)

let string1 = (session.sessionDescription ?? "hit")
let some1 = Int(string1 as String)
onError?(error, collectionId) // call when download error
if let idx = downloadQueue[someNumb!]?.firstIndex(of: some1!) {
downloadQueue[someNumb!]?.remove(at: idx)
print("remove when complete:\(downloadQueue)")
}
}

}

public struct Item: Decodable, Hashable {
let index: Int
let title: String
let image: String
let backgroundColor: String
let borderColor: String
}

public struct Section: Decodable, Hashable {
let index: Int
let identifier: String
let title: String
let subtitle: String
let item: [Item]
}

class CollectionController: UIViewController, UICollectionViewDelegate {

typealias ProgressHandler = (Int, Float) -> ()
var onProgress : ProgressHandler?
var items = [item]()

var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource?
let sections: [Section] = [.init(index: 0, identifier: "carouselCell", title: "title", subtitle: "sub", item: [
Item(index: 0, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 1, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 2, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 3, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 4, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 5, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 6, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 7, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 8, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 9, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 10, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 11, title: "Hello", image: "", backgroundColor: "", borderColor: ""),
Item(index: 12, title: "Hello", image: "", backgroundColor: "", borderColor: "")
])]

override func viewDidLoad() {
super.viewDidLoad()
createCollectionView()
setupScrollView()

let count = dataSource!.snapshot().numberOfItems
for index in 0...count {
items.append(item(number: index))
}
}

func setupScrollView() {
collectionView.collectionViewLayout = createCompositionalLayout()
collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredHorizontally, animated: false)
}

func createDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { [weak self] collectionView, indexPath, item in
guard let self = self else { return UICollectionViewCell() }
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
if indexPath.row <  self.items.count { //  T {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { fatalError(" — \(cellType)") }
cell.configure(with: item)
return cell
}

func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections(sections)
for section in sections { snapshot.appendItems(section.item, toSection: section) }
dataSource?.apply(snapshot)
}

func createCollectionView() {
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.delegate = self
collectionView.contentInsetAdjustmentBehavior = .never
view.addSubview(collectionView)
collectionView.register(CarouselCell.self, forCellWithReuseIdentifier: CarouselCell.reuseIdentifier)

createDataSource()
reloadData()
}

func createCompositionalLayout() -> UICollectionViewLayout {
UICollectionViewCompositionalLayout { (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) ->  NSCollectionLayoutSection? in

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupWidth = (layoutEnvironment.container.contentSize.width * 1.05)/3
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(groupWidth), heightDimension: .absolute(groupWidth))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: (layoutEnvironment.container.contentSize.height/2) - (groupWidth/2), leading: 0, bottom: 0, trailing: 0)
section.interGroupSpacing = 20
section.orthogonalScrollingBehavior = .groupPagingCentered

return section
}
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let directory: String = path[0]

var queueArray = downloadQueue[indexPath.row+1] ?? [Int]()
queueArray.append(indexPath.row+1)

downloadQueue[indexPath.row+1] = queueArray

let url = URL(string: "https://file-examples.com/storage/fec85039006734629a992d7/2017/04/file_example_MP4_640_3MG.mp4")!
let downloadManager = DownloadManager()
downloadManager.identifier = indexPath.row+1
downloadManager.collectionId = indexPath.row+1
downloadManager.folderPath = "\(indexPath.row+1)"
let downloadTaskLocal = downloadManager.activate().downloadTask(with: url)
downloadTaskLocal.resume()

//var item = items[indexPath.row] 

Подробнее здесь: [url]https://stackoverflow.com/questions/79239405/how-to-fix-collection-view-scrolling-freezes[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»