cell.playButton.tag = indexPath.row
cell.playButton.addAction(UIAction { [weak self] _ in
...생략...
}
위와 같은 형태로 cell의 버튼에 tag를 달아 cell에 있는 버튼이 눌릴 때 마다 버튼이 눌릴 때의 로직을 만들었는데 테이블 뷰가 리로드 될때 마다 액션이 중첩되어서 두 번 리로드 했으면 버튼이 두 번 눌리는 버그가 발생했다..
addAction 메서드는 특정 이벤트(.touchUpInside 등)가 발생했을 때 실행할 UIAction을 버튼에 추가합니다. 이 메서드의 중요한 특징은 여러 번 호출되면 액션이 중복해서 추가됨
위 코드에서 addAction을 한 번 호출하면 버튼이 클릭될 때 "Button clicked"가 출력됨
그러나 addAction이 동일한 버튼에 대해 여러 번 호출되면, 기존 액션이 유지된 채로 새로운 액션이 추가됨
특성 | addAction | addTarget(_:action:for:) |
---|---|---|
핸들러 | 클로저(UIAction) | @objc 메서드 |
중복 액션 처리 | 중복 액션이 누적됨 | 동일한 target과 Selector는 덮어씀 |
코드 구조 | 클로저를 사용하여 간결하게 작성 가능 | 메서드를 별도로 정의해야 함 |
사용 가능 버전 | iOS 14 이상 | iOS 2.0 이상 |
실제로 위 코드에서 addTarget으로 변경하면 버그가 발생하진 않는다.
하지만 두 번 호출하는 것 자체가 문제이긴 하다...
let button = UIButton(type: .system)
for i in 0...3 {
button.addAction(UIAction { _ in
print("Action \(i)")
}, for: .touchUpInside)
}
//결과
Action 0
Action 1
Action 2
Action 3
let button = UIButton(type: .system)
for i in 0...3 {
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
}
@objc func buttonTapped() {
print("Button tapped")
}
//결과
Button tapped
정리하다보니까 당연한 것은 생각도 들고...