오늘은 이 헛헛한 좋아요 버튼을 눌렀을 때 클릭애니메이션을 구현해보려고 한다.
버튼액션의 경우 controller가 담당하는 부분이라서 UI만 모아져있는 view에서 작업하는게 아닌
MovieDetailViewController에서 작업해야한다.
// 버튼 액션만 따로 정리
private func buttonActions() {
movieDetailView.likeButton.addTarget(self, action: #selector(likeButtonTapped(_:)), for: .touchUpInside)
}
앞으로 공유버튼과 예매하기 버튼, 예고편 재생버튼 등 액션을 정리해야하니 따로 메서드를 정의해주고
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
buttonActions() // 버튼 액션
}
따로 이렇게 넣어주면 깔꼼하다.
// 버튼 클릭 애니메이션
private func animateButtonPress(_ button: UIButton) {
UIView.animate(withDuration: 0.1,
animations: {
// 눌렸을 때 크기가 작아짐
button.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
},
completion: { _ in
// 애니메이션 완료 후 원래 크기로 돌아옴
UIView.animate(withDuration: 0.1) {
button.transform = CGAffineTransform.identity
}
})
}
animateButtonPress 라는 메서드를 하나 만들어주었다.
이 메서드는 버튼을 눌렀을 때 호출되어서 UIButton 타입의 button을 파라미터로 받을 예정이다.
그리고 버튼을 눌렀을 때 애니메이션을 통해 크기가 작아졌다가 원래 크기로 돌아오는 효과를 넣었고
눌렀음을 인지할 수 있도록 했다. 각 부분을 설명하자면,
UIView.animate(withDuration:animations:completion:)
는 애니메이션을 수행하는 메서드다.
withDuration: 0.1
: 애니메이션의 지속 시간을 0.1초로 설정해주고,
animations
: 애니메이션이 진행될 동안 수행할 동작을 지정하는데 여기서는 버튼의 크기를 줄이는 애니메이션을 정의한다.
button.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
transform
속성을 사용해 크기를 변경해준다.CGAffineTransform(scaleX: 0.9, y: 0.9)
는 버튼의 가로와 세로 크기를 각각 90%로 축소한다 라는 것이고그로 인해 버튼이 눌렸을 때 버튼의 크기가 10% 작아지는 효과를 주게 된다.completion
: 애니메이션이 끝난 후 실행되는 클로저다.
UIView.animate(withDuration: 0.1)
로 0.1초 내에 버튼의 크기를 원래 크기로 돌아가게 애니메이션을 추가한다.button.transform = CGAffineTransform.identity
는 버튼의 transform
을 초기 상태로 되돌린다.CGAffineTransform.identity
는 기본 CGAffineTransform
값을 의미하는데,이렇게 하면 버튼을 눌렀을 때, 버튼의 크기가 10% 줄어든 후, 0.1초 뒤에 원래 크기로 돌아오는 애니메이션을 진행하게 되고,
이 애니메이션은 두 번의 UIView.animate
를 사용해 순차적으로 실행되는 것을 볼 수 있다.
첫 번째는 크기를 줄이는 애니메이션, 두 번째는 원래 크기로 되돌리는 애니메이션이다.
그렇다면 이제 색상을 변경해줄 차례인데,
위에서 addTarget
으로 likeButtonTapped
을 지정해 주었으니 코드를 작성해봤다.
@objc private func likeButtonTapped(_ sender: UIButton) {
animateButtonPress(sender)
// 버튼 색상 변경
if sender.titleColor(for: .normal) == .lightGray {
sender.setTitleColor(.systemRed, for: .normal)
sender.layer.borderColor = UIColor.red.cgColor
} else {
sender.setTitleColor(.lightGray, for: .normal)
sender.layer.borderColor = UIColor.lightGray.cgColor
}
}
_ sender
의 경우 계산기를 만들 때도 썼는데, UIButton는 UIButton 타입의 sender 매개변수를 받아오기 때문에
클릭된 버튼에 대한 정보를 처리할 수 있게 해준다.
그래서 animateButtonPress(sender)
로 아까 만든 버튼이 클릭될 때 애니메이션 효과를 넣어준다.
sender.titleColor(for: .normal)
titleColor(for:)
는 버튼의 제목 텍스트 색을 가져오는 메서드 인데, .normal
은 버튼이 일반 상태일 때의 색을 의미한다..lightGray
인지 확인하고 있는 것이다.if sender.titleColor(for: .normal) == .lightGray
lightGray
일 경우(아직 좋아요를 누르지 않은 상태), 아래 코드를 실행해서 색을 변경한다.sender.setTitleColor(.systemRed, for: .normal)
는 버튼의 텍스트 색을 systemRed
로 변경한다.sender.layer.borderColor = UIColor.red.cgColor
는 버튼의 타이틀 글자 뿐만 아니라 테두리 색도 빨간색으로 변경해야해서 추가해야한다. else
lightGray
가 아니라면(이미 좋아요를 클릭한 상태라면), 버튼의 색을 다시 원래 상태로 되돌린다.sender.setTitleColor(.lightGray, for: .normal)
는 버튼의 텍스트 색을 lightGray
로 변경하고sender.layer.borderColor = UIColor.lightGray.cgColor
를 통해 마찬가지로 버튼의 테두리 색도 회색으로 되돌려준다.animateButtonPress(sender)
를 호출했기 때문에 버튼 클릭 시 애니메이션 효과도 함께 적용된다.
나하아아아이스
"좋아요" 버튼에 애니메이션과 색상 변경을 적용한 작업은 생각보다 간단한 기능이었지만 사용자 인터페이스에서 중요한 역할을 한다.
버튼을 클릭할 때 시각적 피드백을 주는 애니메이션과 색상 변화는 사소한 걸로 보이지만 이미 많은 앱에서는 기본으로 들어가있는 기능이었다.
구현 과정을 진행하면서 인터페이스 디자인에 대해 계속 고민하는 습관은 좋은 것 같다는 생각이 들었다.
애니메이션 기능을 넣을 때 버튼 클릭 시 크기 변화 외에도 버튼이 눌릴 때 회전하거나 다른 변형 효과를 추가할 수 있었던걸 알게 됐는데,
이런 효과들은 사용자의 흥미를 유도하고, 앱의 인터페이스를 더 다채롭게 만들 수 있기 때문에 나중에 한번 구현해보는 것도 좋겠다 싶었다.
저렇게 세부적으로 애니메이션 적용해본 적이 없어서 그런지 신기하네용