티스토리 뷰


안녕하세요.  delegate정리 두번째 시간입니다. 

UITextFieldDelegate에 이어서 

UIPickerViewDelegate도 설명해드릴까해요 :)

delegate의 개념이 아직 잘 잡히지 않으셨다면 

http://zeddios.tistory.com/8를 읽고 이 글을 읽으시는 것을 추천드릴게요 XD



역시나 간단한 예제이니 따라하기 쉬우실 거에요!


프로젝트를 하나 만들어주고 

Main.storyboard에 pickerView를 하나 추가해주세요.





그리고 저 pickerView를 사용하려면 

@IBOutlet변수를 하나 만들어줘야 겠죠?




늘 하시던 것처럼 control키를 누른채로 

@IBOutlet변수를 하나 만들어주세요!





그리고 처음 PickerView를 사용하시는 분들은 저같은 실수를 할 지도 모르겠네요 ㅎㅎ 저는 처음에 당연히 PickerView에 대한 액션을 만들려고 control키를 누른채로 @IBAction함수를 만들려고 했지만 





action이 없는 것 보이시나요? 


그럼 어떻게 PickerView에 내가 원하는 데이터를 넣고..

내가 하고싶은 것들을 어떻게 하지? 라고 생각하실거에요.




그럴때를 대비해 바로 UIPickerViewDelegate가 있답니다 :)

Delegate라고 써져있으니 이 프로토콜은 뭘까요? 

"나는 UIPickerView에 대한 프로토콜이야. 내 안에 너가 하고싶은 일들이 함수로 정해져 있으니까 

(구현은 안된상태) 니가 원하는 함수 하나 정해서 너가 하고싶은대로 구현해"

라고 말하고 있는거에요!!!





pickerView를 사용하기 위해서는 UIPickerViewDelegate말고도 

UIPickerViewDataSource라는 프로토콜이 하나 더 필요하답니다.

이 둘은 쌍으로 같이 다닌다고 생각하시면 됩니다. 

그러면 UITextFieldDelegate에서 했듯이 





채택작업과 대리자를 위임하는 과정을 써주세요.


1. UIPickerViewDelegate,UIPickerViewDataSource 

이 프로토콜을 채택할게.


2. 이 프로토콜을 준수하면서 나 대신 일을 수행할 대리자를 정할게. 

( self = ViewController )


자.. 여기까지 잘 따라오시고 있으신가요?

혹시 갑자기 오류가 뜨지 않으셨나요?




바로 이 오류요!! 


저도 처음에 PickerView예제를 차례대로 따라하다가 이 오류가 나서 정말 당황했었답니다. 

다들 잘 따라하는 것 같은데.. 왜 나만 오류가 나는거지..? 하구요..ㅎㅎ..

(그래서 처음엔 UIPickerViewDataSource를 그냥 없앴었답니다; 하지만 이러면 안돼요!! )

여러분들도 지금 오류가 났을거에요. 한번 저 오류를 같이 없애봅시다 :)


일단 오류 메세지를 한번 같이 봐 볼까요? 

Type 'ViewController' does not conform to protocol 'UITableViewDataSource'

대충 해석하면 .."지금 ViewController가 UIPickerViewDataSource 프로토콜을 준수하고 있지 않은거 같아"라고 하는 것 같아요.
나는 지금 UIPickerViewDataSource프로토콜을 채택하기만 했는데.. 무슨 소리지? 
하실거에요.
이 궁금증은 UIPickerViewDataSource의 정의 부분을 보면 알 수 있답니다.
command키를 누른채로 UIPickerViewDataSource에 커서를 갖다 대 볼까요? 그럼 파랗게 UIPickerViewDataSource가 하이라이팅 되는 것을 보실 수 있으실거에요.
클릭합니다. 
그러면!!!



이렇게!! UIPickerViewDataSource 프로토콜의 

정의 부분으로 넘어온 것을 보실 수 있을거에요.

만약 나는 저 방법으로 정의 부분으로 못 넘어왔다 하시는 분들은

UIPickerViewDataSource를 클릭후 마우스 오른쪽 버튼을 누르시면



저렇게 Jump to Definition이라는 창이 보이실 거에요. 클릭해줍니다. 


자 정의 부분을 다시 한 번 볼까요?




흐음.. 봐도 뭐가 문제인지 모르겠어..

일단 저 public func ~으로 시작하는 함수들은 이 프로토콜에서 제공하는 함수 인것은 아시겠죠? 


"나는 이 함수를 아직 사용하지도 않았는데.. 왜 오류가 나는거지?" 

-------->바로 이것이 오류입니다.



아직 무슨 소리인지 잘 모르시겠죠? 저 UIPickerViewDataSource 정의 부분에서 스크롤을 조금만 더 내리면 





아까 우리가 같이 채택했던 UIPickerViewDelegate 가 보이실 거에요. 


여기서 잠깐 궁금하지 않으신가요? 




Type 'ViewController' does not conform to protocol 'UITableViewDataSource'







왜 오류메세지는  UIPickerViewDataSource를 콕 찝어서 말했을까요? 같이 채택한   UIPickerViewDelegate는 왜 말 안한거지?

그 이유는 바로 optional에 있습니다.

UIPickerViewDelegate의 정의 부분을 다시 한 번 볼까요?



함수 앞에 붙혀진 optional이 보이시나요? 


다시 UIPickerViewDataSource의 정의 부분으로 가볼게요.



여기에는 함수 앞에  optional이 없네요!! 


결론부터 말씀드리자면,  optional이 붙지 않은 함수들은 무조건 채택과 동시에 swift파일 안에 선언을 해주어야 합니다. 

우리가 오류가 난 이유는 꼭 선언해 주어야 하는 이 함수들을 선언하지 않아서 입니다.


ViewController.swift파일로 다시 돌아가




 public func numberOfComponents(in pickerView: UIPickerView) -> Int {

        return 1

    }

    

    public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        return Array.count

        

    }




를 추가해 주세요.
오류가 없어진게 보이시나요?

이제 왜 오류가 난지 아시겠나요? 
optional이 붙지않은 함수들은 반드시 이렇게 구현을 해주어야 합니다. 
여기서 Array는 저의 배열이름이에요. 
저는 var Array = ["red","green","blue"] 라고 해주었답니다.
이 형식대로 해주시되, 이름과 넣고싶은 picker 이름들만 변경해주세요. 
(let Array도 가능한거 같아요.)

자 이제 실행시켜 볼까요?




앗..색깔 이름들이 안나오고 ?들만 나오네요. 

우리가 구현한 함수들을 볼까요?

  public func numberOfComponents(in pickerView: UIPickerView) -> Int {

        return 1

    }

    

    public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        return Array.count

        

    }





뭔가..numberOfComponents, return Array.count를 하는 것보니 제 배열안에 있는 갯수들만 보는 것 같지 않나요? 


자 그럼 이제 진짜 제 배열안에 있는 원소들을 PickerView에 나오게 해줘볼게요. 당연히  UIPickerViewDelegate안에 정의되어있는 함수겠죠?




func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        return Array[row]

    }





를 추가해주세요. 반환타입도 String이고, return Array[row]..라니 뭔가 제 배열에 있는 원소들을 리턴해준다는 소리같은데...

일단 실행해 볼까요? 



짜잔! 이제 저희가 원하는 모습으로 나왔네요!! 

잘 따라 오셨나요?

오늘은 이 예제를 잘 따라오지 못하셨어도 괜찮아요. 이 글의 목적은 

"프로토콜을 채택할 때는 반드시 같이 선언해주어야하는 함수들이 있나 확인하는 습관을 들여야 한다"라는 생각때문에 쓴 것입니다 :)



도움이 되었으면 좋겠어요! :)


댓글
  • 프로필사진 신정민 좋은 정보 감사합니다 !
    너무 이해 잘되게 잘 설명 해주시네요!!!!^^
    2017.08.09 15:00
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 감사합니다 :) 2017.12.28 13:39 신고
  • 프로필사진 semtong1013@hotmail.com 좋은정보 감사합니다. 2017.12.28 12:38
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 XD 2017.12.28 13:39 신고
  • 프로필사진 ljh30321 덕분에 너무 쉽게 배웠습니다. 감사합니다! 2018.08.24 13:48
  • 프로필사진 dowitcher@naver.com 안녕하세요 Zedd님 유익한 블로그 포스팅 정독하고 있습니다ㅎㅎ
    delegate에 대해서 직관적으로 설명해주셔서 이해가 잘됐습니다.

    사소한 궁금점이 있다면 마지막 문단에

    "이 함수는 이 기능만은 무조건 수행해야해..."라고 해주고 싶을 때가 있겠죠?
    그럴 때 바로 optional을 이용하면 된답니다.

    라고 써주셨는데 protocol안에 함수를 작성할 때 이 기능만은 무조건 수행해야해 하려면 optional을 빼줘야하는게 아닌가요?
    잠깐 혼동이 되서 적어봅니다 .

    포스팅 잘보고 있습니다! :)
    2018.10.05 12:15
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 헉..그러네요 ㅠㅠㅠ이제야 발견하다니... 알려주셔서 감사합니다. 수정했어요 :) 2018.10.05 13:04 신고
  • 프로필사진 안녕하세요 Zedd님~
    iOS 관련 글 정독중인 입문자입니다.
    다름이 아니라 질문이 있어서요..^^
    게시글 내용들이 예제를 따라하며 작성하셨다고 되어있는데 혹시 그 예제들을 어디서 찾아볼 수 있을까요?ㅎㅎ
    2020.04.01 00:00
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 아 예제를 따라했다고 썼나요..? 따로 찾아볼 수 있는 곳은 지금은 없습니다. 구글링 하면 많이 나올 것 같아요. 2020.04.01 10:57 신고
  • 프로필사진 찬양 갓제드 !!! 항상 감사합니닷! 2020.05.05 16:03
댓글쓰기 폼
Total
3,401,655
Today
121
Yesterday
3,443