반응형
앱을 만들 때 키보드를 사용 후 키보드를 제외한 빈 곳을 터치했을 때 키보드를 내려가게 하려면 touchesBegan(_:with:) 메서드를 이용한다. 하지만 tableView 또는 scrollView 에서는 touchesBegan(_:with:) 메서드가 안먹힌다.
그 이유는 tableView 또는 scrollView는 스크롤 기능이 있기 때문에 스크롤을 하려면 일단 한 번의 터치를 하게 되기 때문이다.
이 문제를 해결하기 위해서는 UITapGestureRecognizer 를 이용해 제스처를 인식하도록 해야한다.
override func viewDidLoad() {
super.viewDidLoad()
//탭 핸들러 추가
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:)))
view.addGestureRecognizer(tapGesture)
}
//터치 발생시 작동하는 함수
@objc func handleTapGesture(sender: UITapGestureRecognizer) {
//이곳에 탭 제스처 했을시 원하는 코드 작성
handleTap(sender: sender)
}
나의 경우는 빨간색 박스친 부분이 tableView 부분인데 할일을 적는 행 부분과 추가버튼(+버튼) 클릭시에는 제스처를 인식하지 않고 그 두곳을 제외한 나머지 공간을 클릭시에 키보드를 내려가게 하고 싶었다.
여러개의 UIViewController 에서 사용하기 위해 프로토콜을 만들고
protocol TapHandling {
func handleTap(sender: UITapGestureRecognizer)
}
탭한 위치가 테이블뷰 또는 버튼일 경우 리턴 처리를 했다.
extension TapHandling where Self: UIViewController {
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == .ended {
// 터치한 뷰가 테이뷰셀 또는 버튼이면 리턴시키고, 나머지는 키보드 내리기
if let touchView = sender.view?.hitTest(sender.location(in: sender.view), with: nil) {
if touchView is UITableViewCell || touchView is UIButton { return }
}
view.endEditing(true)
}
sender.cancelsTouchesInView = false
}
}
그리고 제스처를 인식하고싶은 뷰컨트롤러에서 프로토콜을 채택하면 된다
final class yourViewController: UIViewController, TapHandling { //프로토콜 채택
override func viewDidLoad() {
super.viewDidLoad()
//탭 핸들러 추가
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:)))
view.addGestureRecognizer(tapGesture)
}
//터치 발생시 작동하는 함수
@objc func handleTapGesture(sender: UITapGestureRecognizer) {
//이곳에 탭 제스처 했을시 원하는 코드 작성
handleTap(sender: sender)
}
}
반응형