관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] UITableViewCell, UICollectionViewCell의 셀에 highlighted 이미지 적용 방법 (UIView.transition, UIView.animate) 본문

iOS 응용 (swift)

[iOS - swift] UITableViewCell, UICollectionViewCell의 셀에 highlighted 이미지 적용 방법 (UIView.transition, UIView.animate)

jake-kim 2022. 5. 28. 17:12

highlighted 될 때 원하는 이미지 표출

normal 이미지 highlighted 이미지

Highlighted에 원하는 이미지 표출 구현 아이디어

  • 커스텀 셀을 정의할때 highlighted를 override하여 highlighted될 시점에 UIView.transition 애니메이션을 통해 애니메이션을 변경했다가, comletion 블럭에서 다시 이미지를 복구
  • UIImageView의 이미지가 변하는 애니메이션은 UIView.animate는 적용이 안되고 UIView.transtion을 사용해야 동작하는것을 주의

Highlighted 애니메이션 처리 주의할 점

  • UITableViewCell은 메소드에서 이벤트를 받아서 처리
final class MyTableViewCell: UITableViewCell {
  override func setHighlighted(_ highlighted: Bool, animated: Bool) {...} 
}
  • UICollectionViewCell은 프로퍼티에서 이벤트를 받아서 처리
final class MyCollectionViewCell: UICollectionViewCell {
  override var isHighlighted: Bool { ... }
}

구현

  • 커스텀 셀 정의
    • UITableView를 사용할 것이므로 테이블 셀 서브클래싱
import UIKit

final class MyCell: UITableViewCell {
  static let id = "MyCell"
  
}
  • 셀에 표출할 UI 선언
  private let backgroundImageView: UIImageView = {
    let view = UIImageView()
    view.image = UIImage(named: "background-normal")
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
  }()
  private let label: UILabel = {
    let label = UILabel()
    label.textColor = .white
    label.font = .systemFont(ofSize: 24)
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
  }()
  • 레이아웃
  // MARK: Initializer
  @available(*, unavailable)
  required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    
    self.contentView.addSubview(self.backgroundImageView)
    self.contentView.addSubview(self.label)
    
    NSLayoutConstraint.activate([
      self.backgroundImageView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor),
      self.backgroundImageView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor),
      self.backgroundImageView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor),
      self.backgroundImageView.topAnchor.constraint(equalTo: self.contentView.topAnchor),
    ])
    NSLayoutConstraint.activate([
      self.label.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor),
      self.label.centerXAnchor.constraint(equalTo: self.contentView.centerXAnchor),
    ])
  }
  • highlighted 구현
    • UITableViewCell을 사용할 것이므로 setHighlighted 메소드 재정의
    • highlighted상태일때 0.08초동안 highlighted 이미지로 변경한 후 다시 원래 이미지로 변경하는 코드
    • (만약 UICollectionViewCell을 사용한다면 isHighlighted 프로퍼티에서 didSet으로 처리)
  override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    super.setHighlighted(highlighted, animated: animated)
    
    guard highlighted else { return }
    // UIView.animate를 사용하면 동작하지 않는것을 주의
    UIView.transition(
      with: self.backgroundImageView,
      duration: 0.08,
      options: .transitionCrossDissolve,
      animations: { self.backgroundImageView.image = UIImage(named: "background-highlighted") },
      completion: { _ in self.backgroundImageView.image = UIImage(named: "background-normal") }
    )
  }
  • 데이터 입력받는 prepare 구현 (완성)
  override func prepareForReuse() {
    super.prepareForReuse()
    
    self.prepare(text: nil)
  }
  
  func prepare(text: String?) {
    self.label.text = text
  }

* 전체 코드: https://github.com/JK0369/ExHighlightedImageCell

Comments