Войти

Tap Animation CollectionCell

Одним из основных направлений в разработке приложений для iOS является инткреактивность. В качестве примеров вы можете увидеть класс UIFeedbackGenerator (отвечает за тактильный отклик), звуки клавиатуры, 3D Touch для быстрых действий и многое другое. Добавлять обратную связь с интерфейсом - хорошая практика.

Есть простой способ добавить больше интeрактивности для вашего CollectionView. Сейчас сделаем обработку тапа, будто ячейка нажимается на уровень ниже. Пример реализации вы можете посмотреть, если зажать ячейку любой статьи этого приложения. На самом деле сделать это очень просто, особенно для UICollectionViewCell.

Начнём

У UICollectionViewCell есть проперти isHighlighted. Оно изменяется при нажатии - пока удерживается палец на ячейке, статус проперти будет установлен в true. Переопределим проперти и используем проперти transform:

override var isHighlighted: Bool {
 didSet {
  if self.isHighlighted {
   self.transform = self.transform.scaledBy(x: 0.96, y: 0.96)
  } else {
   self.transform = .identity
  }
 }
}

В такой реализации скейл будет изменяться не анимированно, можете попробовать.

К счастью, сделать анимированный скейл не сложно. Нам нужно использовать функцию animateWithDuration() класса UIView. Но так как статус isHighlighted может изменится в любой момент, даже до завершения анимации, нам нужно обеспечить измнение анимации в любой момент, даже когда скейл не завершился. Для этого в options достаточно передать .beginFromCurrentState:

UIView.animate(withDuration: 0.27, usingSpringWithDamping: 1, initialSpringVelocity: 1.0, options: [.beginFromCurrentState], animations: {
 if self.isHighlighted {
  self.transform = self.transform.scaledBy(x: 0.96, y: 0.96)
 } else {
  self.transform = .identity
 }
})

Изменяем фон

Если вы использовали приложение Shortcut, то видели что при нажатии ячейки ее заполняющий цвет становится темнее. Это еще один лайфхак, который поможет имитировать глубокое нажатие ячейки. Сделать это не сложно. Нам нужно инициализировать объект UIView черного цвета с 0-вой прозрачностью, добавить как савью на ячейку. Теперь добавим немного кода:

UIView.animate(withDuration: 0.27, usingSpringWithDamping: 1, initialSpringVelocity: 1.0, options: [.beginFromCurrentState], animations: {
 if self.isHighlighted {
  self.transform = self.transform.scaledBy(x: 0.96, y: 0.96)
  self.gradeView.alpha = 0.1
 } else {
  self.transform = .identity
  self.gradeView.alpha = 0
 }
})

Для контента

Настройте alpha для gradeView по своему вкусу. Аналогично мы реализуем прозрачность для контента на ячейке, который вы могли видеть на превью:

if self.isHighlighted {
 self.transform = self.transform.scaledBy(x: 0.96, y: 0.96)
 self.titleLabel.alpha = 0.7
} else {
 self.transform = .identity
 self.titleLabel.alpha = 1
}

Результат

Настроив кривые для анимации, мы получим следующий код:

override var isHighlighted: Bool{
 didSet {
  UIView.animate(withDuration: 0.27, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1.0, options: [.curveEaseOut, .beginFromCurrentState], animations: {
   self.gradeView.alpha = self.isHighlighted ? 0.1 : 0
   self.titleLabel.alpha = self.isHighlighted ? 0.35 : 1
   self.transform = self.isHighlighted ? self.transform.scaledBy(x: 0.96, y: 0.96) : .identity
  })
 }
}

Как видите, используя тернарную условную операцую можно намного сократить объём кода. Если условия перед ? верно, то выполнится первый блок (до двоеточия). Если условие не верно, вызовется второй блок (после двоеточия).

Надеюсь этот простой лайфхак сделает ваши CollectionView лучше.

Стоит глянуть