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

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

Сообщение Anonymous »

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

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

override func viewDidLoad() {
super.viewDidLoad()

setupCollectionView()
setupScrollView()
setupDownloadItems()
}

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

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

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)
if indexPath.row < self.items.count {
let item = self.items[indexPath.row]
cell.title.text = "\(String(format: "%.f%%", item.progress * 100))"
}
return cell
default: return self.configure(CarouselCell.self, with: item, for: indexPath)
}
}
}

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)
}

func setupCollectionView() {
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()
}

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 = 64
section.orthogonalScrollingBehavior = .groupPagingCentered
section.contentInsetsReference = .none
section.visibleItemsInvalidationHandler = { (items, offset, environment) in

items.forEach { item in
let distanceFromCenter = abs((item.frame.midX - offset.x) - environment.container.contentSize.width / 2.0)
let minScale: CGFloat = 0.7
let maxScale: CGFloat = 1.1
let scale = max(maxScale - (distanceFromCenter / environment.container.contentSize.width), minScale)
item.transform = CGAffineTransform(scaleX: scale, y: scale)
}
}

return section
}
}

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

print("-")

_ = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { timer in
guard self.progress
cell < /p>
class CarouselCell: UICollectionViewCell, SelfConfiguringCell {

static let reuseIdentifier: String = "carouselCell"

var topSpaceView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

var imageView: UIImageView = {
let image = UIImageView()
image.contentMode = .scaleAspectFill
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()

var titleImageView: UIImageView = {
let image = UIImageView()
image.contentMode = .scaleAspectFill
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()

var textView: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.layer.borderColor = UIColor.red.cgColor
view.layer.borderWidth = 3
view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
var title: UILabel = {
let label = UILabel()
label.textColor = .white
label.textAlignment = .center
label.sizeToFit()
label.font = UIFont(name: "Marker Felt", size: 24)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
var progressView: UIProgressView = {
let view = UIProgressView(progressViewStyle: .bar)
view.center = view.center
view.setProgress(0.0, animated: true)
view.trackTintColor = .clear
view.tintColor = .white.withAlphaComponent(0.15)
view.clipsToBounds = true
view.layer.borderColor = UIColor.red.cgColor
view.layer.borderWidth = 3
view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

var bottomSpaceView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

var stackView: UIView = {
let stack = UIView()
stack.layer.shadowColor = UIColor.black.cgColor
stack.layer.shadowOffset = CGSize.zero
stack.layer.shadowOpacity = 0.6
stack.layer.shadowRadius = 3
stack.translatesAutoresizingMaskIntoConstraints = false
return stack
}()

override var isHighlighted: Bool {
didSet { if oldValue == false && isHighlighted { highlight() }
else if oldValue == true && !isHighlighted { unHighlight() }
}
}

var imageTask: AnyCancellable?
var titleImageTask: AnyCancellable?

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

override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstraints()
}

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

func setupViews() {
stackView.addSubview(topSpaceView)
stackView.addSubview(imageView)
stackView.addSubview(titleImageView)
stackView.addSubview(textView)
stackView.addSubview(bottomSpaceView)

contentView.addSubview(stackView)

textView.addSubview(progressView)
textView.addSubview(title)

stackView.sendSubview(toBack: textView)
textView.bringSubview(toFront: title)
}

func setupConstraints() {

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

topSpaceView.topAnchor.constraint(equalTo: stackView.topAnchor, constant: 0).isActive = true
topSpaceView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.07).isActive = true
topSpaceView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
topSpaceView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true

imageView.topAnchor.constraint(equalTo: topSpaceView.bottomAnchor, 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

titleImageView.topAnchor.constraint(equalTo: topSpaceView.bottomAnchor, constant: 0).isActive = true
titleImageView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.7).isActive = true
titleImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true
titleImageView.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

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

bottomSpaceView.topAnchor.constraint(equalTo: textView.bottomAnchor, constant: 0).isActive = true
bottomSpaceView.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: 0.07).isActive = true
bottomSpaceView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
bottomSpaceView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).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.stackView.transform = .init(scaleX: scale, y: scale)
self.textView.transform = .init(scaleX: scale, y: scale)
}, completion: nil)
}
func highlight() {
animateScale(to: 0.9, duration: 0.4)
}
func unHighlight() {
animateScale(to: 1, duration: 0.38)
}

func configure(with item: Item) {

title.text = item.title
textView.backgroundColor = .green
textView.layer.borderColor = UIColor.green.cgColor
progressView.layer.borderColor = UIColor.green.cgColor

titleImageTask = Future() { promise in
UIImage(named: item.titleImage)?.prepareForDisplay(completionHandler: { loadedImage in
promise(Result.success(loadedImage))
})
}
.receive(on: DispatchQueue.main)
.sink { image in
self.titleImageView.image = image
}

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 = image
}
}
}

также попробовал использовать Touchesbegan /touchesEnded вместо Ishighlighted, но результат был таким же:
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
highlight()
}

override func touchesEnded(_ touches: Set, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
unHighlight()
}

override func touchesCancelled(_ touches: Set, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
unHighlight()
}
< /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 index: Int
let identifier: String
let title: String
let subtitle: String
let item: [Item]
}

public struct Item: Decodable, Hashable {
let index: Int
let title: String
let image: String
let titleImage: String
let backgroundColor: String
let borderColor: String
}
< /code>
json < /p>
[
{
"index": 1,
"identifier": "carouselCell",
"title": "",
"subtitle": "",
"item": [
{
"index": 1,
"title": "0",
"image": "cover1",
"titleImage": "title1",
"backgroundColor": "5896CC",
"borderColor": "3274AF",
},
{
"index": 2,
"title": "0",
"image": "cover2",
"titleImage": "title2",
"backgroundColor": "895138",
"borderColor": "703A22",
},
{
"index": 3,
"title": "0",
"image": "cover3",
"titleImage": "title3",
"backgroundColor": "804136",
"borderColor": "62322A",
},
{
"index": 4,
"title": "0",
"image": "cover4",
"titleImage": "title4",
"backgroundColor": "3E78A3",
"borderColor": "2A597D",
},
]
},
]



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

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

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

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

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

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