IOS) UITapGestureRecognizer로 뷰 간 이동시 발생하는 문제점 해결

김다정·2020년 4월 4일
1

IOS

목록 보기
2/2

문제점

이번에 마주친 문제점은 UITapGestureRecognizer로 뷰 간 이동을 할 때 데이터를 같이 전달할 때 발생하였다.

하고싶은 기능 : UIView 클릭시 데이터들을 같이 넘겨주며 화면 전환

UIButton 클릭시 화면 전환하는 addTarget과 다르게 UIView 클릭시 화면 전환을 하게 하려면 UITapGestureRecognizer를 사용해야 한다.

처음 썼던 코드를 보면 가관이다.

let tapMethod = #selector(NextVC.handleTap(_:))
let tappy = MyTapGesture(target: NextVC(), action: tapMethod)
view.addGestureRecognizer(tappy)

...

class MyTapGesture: UITapGestureRecognizer {
    var image = String()
    var userName = String()
}

UITapGesture의 target을 넘어갈 ViewController로 설정하여 넘겨받은 데이터들을 사용하는 handleTap이라는 메소드를 action으로 불러왔었다.

해결 방안

TapGesture를 UIView에 엮기

func initTapListener() {
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(pressNextVC)))
    }

일단 view라는 UIView에 addGestureRecognizer로 UITapGestureRecognizer를 엮어준다.

그리고,

view.isUserInteractionEnabled = true

이 코드는 필수로 써줘야한다.

각 파라미터들을 살펴보면 target은 UITapGestureRecognizer를 실행시킬 화면으로 self를 적어주고, action은 실행할 메소드를 적어주었다.

화면 전환 메소드 정의

@objc func pressNextVC() {
    let nextVC = NextVC()
    
    // 화면 전환되는 코드
    self.navigationController?.pushViewController(nextVC, animated: true)
    
    // NextVC에서 전달받은 파라미터들을 받아 사용하는 메소드 호출
    nextVC.handleTap(param1, param2)
}

전달받은 데이터 사용하는 메소드 정의

// NextVC.swift
@objc func handleTap(userName:String, image:String) {
        self.userLabel.text = userName
        
        // 이미지 url로 불러오는 코드
        let url = URL(string: image!)
        let data = try! Data(contentsOf: url!)
        self.userImageView.image = UIImage(data: data)
}

여기서 또 하나의 문제가 발생한다.

Fatal error: Unexpectedly found nil while unwrapping an Optional value

디버그를 찍어보니 userLabel과 userImageView가 nil값을 갖는다.

NextVC.xib와의 연결은 문제 없는 상황 무엇이 문제일까?

또 디버그를 찍어보니 NextVC의 handleTap메소드가 viewDidLoad() 보다 먼저 호출되어 각 컴포넌트들의 참조되는 값이 제대로 들어가있지 않았던 것이었다.

또 해결 방안

@objc func pressNextVC() {
        let nextVC = NextVC()
        self.navigationController?.pushViewController(nextVC, animated: true)
        nextVC.viewDidLoad()
        nextVC.handleTap(userName: userName, image: image)
}

이렇게 NextVC의 viewDidLoad() 메소드를 handleTap 메소드보다 먼저 (명시적으로) 호출 시켜주었다.

IOS와 Swift에 대한 기초적인 이해가 부족한 채로 개발을 하려니 여러 어려움을 겪는다.

이번 글에 대한 해결 문제로 하루를 다 보냈는데 (약 7시간,,,?)

오늘의 교훈 : 모르는게 있으면 주변에 물어보자

주변에 IOS 개발자들이 점점 늘어났으면 좋겠다,,,,,!

profile
예비 시니어 개발자

0개의 댓글