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

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

Сообщение Anonymous »

У меня есть представление о коллекции. Когда я прикасаюсь к ячейке, анимация из класса Celloction Cellcelcell играет. Когда я нажимаю на ячейку, процесс загрузки файла начинается в методе DidSelectiTemat . Чтобы обновить процесс, я использую код здесь ReloadItem (IndexPath: IndexPath) Проблема в том, что, если при загрузке файла я пытаюсь коснуться ячейки, анимация будет воспроизводиться один раз, например, прыжок или зацеп Это вообще не будет работать при прикосновении, пока файл не будет загружен. Кроме того, во время загрузки, когда ячейка снова нажимается, метод DidSelectiTemat не будет вызван до тех пор, пока файл не будет загружен. Тот факт, что метод DidSelectiTemat не вызывается во время загрузки файлов, хорош. Это предотвращает загрузку одного и того же файла несколько раз. Но проблема в том, что я не понимаю, почему это происходит, потому что я нигде не написал такого кода. Как исправить анимацию и почему selectiTemat не вызывается во время загрузки файла?
cod > Я удалил весь код, связанный с загрузкой, чтобы сохранить рассматриваемое пространство и заменил его на таймер для моделирования прогресса загрузки файла < /p>
Коллекция: < /p>
class CarouselController: UIViewController, UICollectionViewDelegate {

var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource?
let sections = Bundle.main.decode([Section].self, from: "carouselData.json")
var progressA = 0.0

override func viewDidLoad() {
super.viewDidLoad()
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.isScrollEnabled = false
collectionView.delegate = self
collectionView.contentInsetAdjustmentBehavior = .never
view.addSubview(collectionView)
collectionView.register(CarouselCell.self, forCellWithReuseIdentifier: CarouselCell.reuseIdentifier)
createDataSource()
reloadData()
}

@objc func createDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
cell.title.text = "\(self.progressA)"
print(self.progressA)
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progressA 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 = 64
section.orthogonalScrollingBehavior = .groupPagingCentered
section.contentInsetsReference = .none

return section
}
}

func configure(_ cellType: T.Type, with item: Item, for indexPath: IndexPath) -> 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)
}

}
< /code>
cell < /p>
import Combine

class CarouselCell: UICollectionViewCell, SelfConfiguringCell {

static let reuseIdentifier: String = "carouselCell"

var imageView: UIImageView = {
let image = UIImageView()
image.contentMode = .scaleToFill
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
var textView: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
var title: UILabel = {
let label = UILabel()
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

override var isHighlighted: Bool {
didSet { if oldValue == false && isHighlighted { animateScale(to: 0.9, duration: 0.4) }
else if oldValue == true && !isHighlighted { animateScale(to: 1, duration: 0.38) }
}
}

var imageTask: AnyCancellable?

override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
imageTask?.cancel()
}

override init(frame: CGRect) {
super.init(frame: frame)

contentView.addSubview(imageView)
contentView.addSubview(textView)
textView.addSubview(title)

imageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
imageView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.7).isActive = true
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true
imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true

textView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.16).isActive = true
textView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 24).isActive = true
textView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -24).isActive = true
textView.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: -6).isActive = true
textView.layer.cornerRadius = contentView.frame.size.height*0.16/2

title.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 0).isActive = true
title.trailingAnchor.constraint(equalTo: textView.trailingAnchor, constant: 0).isActive = true
title.topAnchor.constraint(equalTo: textView.topAnchor, constant: 0).isActive = true
title.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: 0).isActive = true

}

private func animateScale(to scale: CGFloat, duration: TimeInterval) {
UIView.animate( withDuration: duration, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.5, options: [.beginFromCurrentState], animations: {
self.imageView.transform = .init(scaleX: scale, y: scale)
self.textView.transform = .init(scaleX: scale, y: scale)
}, completion: nil)
}

func configure(with item: Item) {
title.text = "item.title"
textView.backgroundColor = .green

imageTask = Future() { promise in
UIImage(named: item.image)?.prepareForDisplay(completionHandler: { loadedImage in
promise(Result.success(loadedImage))
})
}
.receive(on: DispatchQueue.main)
.sink { image in
self.imageView.image = UIImage(named: "cover2")
}
}

required init?(coder: NSCoder) {
fatalError("error")
}

}
< /code>
exother: < /p>
extension Bundle {
func decode(_ type: T.Type, from file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to locate \(file) in bundle.")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) from bundle.")
}
let decoder = JSONDecoder()
guard let loaded = try? decoder.decode(T.self, from: data) else {
fatalError("Failed to decode \(file) from bundle.")
}
return loaded
}
}

protocol SelfConfiguringCell {
static var reuseIdentifier: String { get }
func configure(with item: Item)
}

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

[ {
"identifier": "carouselCell",
"item": [

{
"index": 1,
"title": "0",
"image": "cover1",
},

] }, ]

на основе ответа @Rob

kvo variant (не работает)
Я получаю прогресс внутри наблюдателя, но текст ячейки не обновляется. Почему? < /P>
var nameObservation: NSKeyValueObservation?
@objc dynamic var progress = 0.0

func createDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item in
switch self.sections[indexPath.section].identifier {
case "carouselCell":
let cell = self.configure(CarouselCell.self, with: item, for: indexPath)
self.nameObservation = self.observe(\.progress, options: .new) { vc, change in
cell.title.text = "\(self.progress)"
}
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progress

Подробнее здесь: https://stackoverflow.com/questions/793 ... ction-view
Ответить

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

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

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

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

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