본문 바로가기

Swift

imageView를 버튼처럼 사용하기



ImageView를 버튼처럼..

버그없는 최종 소스는 이것이다. 이 소스의 특징은 CollectionViewCell 안에 있는 imageView에서 제스쳐를 인식하고 CollectionView에서 해당 제스쳐를 처리하도록 한 것이다.

CollectionView Class에서 아래와 같이 UITapGestureRecognizer를 target:self로 생성하고 이 제스쳐를 cell.imageView에 추가하는 것이 핵심이다.

    cell.imageView.userInteractionEnabled = true
    let nextTap = UITapGestureRecognizer(target: self, action: #selector(handleNextTap))
    cell.imageView.addGestureRecognizer(nextTap)

이벤트를 받아 처리하는 부분은 아래와 같다.

collectionView를 스크롤하여 section 2의 첫 번째 row로 스크롤 시킨다.
func handleNextTap(sender: UITapGestureRecognizer) { debugPrint("next")

        // 제스쳐가 끝났는지 확인 후 코드 진행
        if sender.state == .Ended {
            debugPrint("next..2")
            if (sender.view as? UIImageView) != nil {
                let indexPath = NSIndexPath(forRow: 0, inSection: 1)
                collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .CenteredVertically, animated: true)
            }
        }

    }

처음에 등록했던 소스는 버그가 있다.

아래 소스는 하나의 UITapGestureRecognizer를 두 군데의 UIView에서 사용하였는데 실제 코드를 돌려보니 마지막에 addGestureRecognizer딘 UIView에서만 제스쳐를 인식했다. 이유를 확인하여 보니 UITapGestureRecognizer는 싱글뷰에만 해당되므로 멀티뷰에 제스쳐를 인식시키기 위해서는 그 만큼 UITapGestureRecognizer를 생성해야 한다고 한다.


imageView는 addTarget 메소드가 없어서 별도로 제스쳐 이벤트를 연결시켜주어야 한다.
아래처럼 코딩하면 imageView를 버튼처럼 사용할 수 있다. 아래 예제는 imageView 뿐만 아니라 textField의 키보드를 해제시키기 위한 역할도 같이 하는 메소드이다.

    //
    // dismiss keyboard를 위해 호출되는 메소드
    // 본 클래스의 viewDidLoad 마지막 부분에 두 줄 추가
    // let dismissTap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    // self.view.addGestureRecognizer(dismissTap)
    //
    func handleTap(sender: UITapGestureRecognizer) {
        debugPrint("touchesBegan")

        // 제스쳐가 끝났는지 확인 후 코드 진행
        if sender.state == .Ended {
            if let af = activeField {
                af.endEditing(true)
            }

            if let imageView = sender.view as? UIImageView {
                debugPrint("imageView = \(imageView)")
                let indexPath = NSIndexPath(forRow: 0, inSection: 1)
                collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
            }
        }

    }