본문 바로가기
카테고리 없음

Swift) UIButton 을 code로 만들 때, 버튼 실행 코드 넣기 (custom alert 만들기)

by DevJake 2021. 6. 3.

기존의 Alert 을 사용해서 Font 도 바꾸고 alert 창 모양도 바꿔보고 싶었다. 

워낙 Alert library 가 많아서 개인 프로젝트였으면 적당한 디자인의 alert library를 이용해서 사용했을텐데...

팀 프로젝트는 그런거 얄짤없다. 주어진 디자인에 무조건 맞추는게 개발자의 숙명 ㅠㅠ

 

이건 xcode에서 제공하는 기본 UIAlert 으로 만든 alert view다.

이래저래 찾아보니, 타이틀과 메시지 부분은 폰트도 바꿀수 있고, 색깔도 바꿀수 있고.. 여러 customizing 이 가능한데, 

유독 저 버튼은 폰트 색깔까진 바꿀수 있는데 폰트 자체를 바꾸진 못한다... 바꾸는 기능이 UIAlert을 통해서는 없다. 

수 시간동안 검색해서 내린 결론이다. 

 

그럼 어쩌지? 만들어야지 ㅠㅠ

만드는 방법은 간단하다. 노가다가 필요할 뿐 ㅠㅠ

Alert이 뜰 때, 뒷배경은 항상 약간 blur 처리가 되는 것을 기억한다. 그래서 backgroundView

전체 Alert 창의 골격을 잡아주는 baseView

타이틀과 메시지 부분이 들어갈 centerView

그리고 양 버튼 부분 View와 실제 버튼들, 그리고 타이틀, 메시지 라벨을 한땀한땀 만들어준다. 

일일이 뷰를 하나하나 만들어 줘야 한다

frame으로 위치 및 너비, 높이 잡아주고, 코너에 둥글에 모양도 잡고 배경색도 만들고..

저어기 alpha = 0 부분은... 왜 저렇게 처리해놨는지 곧 나온다!

그리고 이렇게 addSubview를 이용하여 차례대로, 순서대로, 차곡차곡 View를 넣어주면 된다. 

그런데 iOS 기본 Alert 이 나타날때 갑자기 퍽! 하고 나타나든가? 아니다. 

약간 스무스하게 나타난다. 그럼 animation 효과를 넣어야지

그래서 위의 addSubview 이후에 아래와 같이 넣어주면 

기존에 alpha 값을 0으로 놓아서 하나도 보이지 않던 것들이 

약 0.2초의 duration 을 거쳐서 저기 지정한 alpha값으로 스무스하게 나타난다. 

 

일단 이렇게 뷰는 만들어지는데.. 문제는 버튼 지정이다. 

아시다시피.. UIButton 을 storyboard가 아닌 메뉴얼로 만들려면 

addSubview로 넣었던 뷰들을 다시 모두 제거 

이렇게 버튼에 .addTarget을 연결해서 action: 부분에 @objc function 을 만들어줘야 한다. 

(참고로 저 위에 코드는 삭제 하기 전 스무스하게 다시 안보이게 처리 후, 뷰들을 제거 하는 코드)

 

버튼을 눌러서 떴었던 alert(custom views)을 다시 없애는 것까진 문제가 없다. 

근데 버튼을 눌러서 그 다음, 어떤 코드가 실행이 되야 한다. 

나가기 버튼이면 버튼을 눌렀을 때,  dismiss가 실행이 되어야 하니까.

 

AlertView 하나 만들어서 쓰고, 또 다른거 쓸때 하나 더 만들어서 쓸거면, 그냥 저 위에 exitAlert() 에 코드를 넣어도 된다.

하지만, 

노가다로 만든 custom view인데, 최소한 Title, Message, 두개 버튼 타이틀, 버튼 눌렀을 때 작동할 코드 정도는

바꿔서 쓸수 있게 만들어야 해야지. 

 

다른 swift파일에서 custom view를 불러와서 쓸때, 코드를 지정할 수 있게 하는 방법이 필요했다. 

 

 

여기서 고민이 시작됐다. 

1. addTarget으로 넘어갈때 selector 부분에 handler를 넣어서 할수 없을까?

실패!

2. 아 addTarget을 두개를 넣으면 되잖아!

응 안돼 돌아가 

이 위에 캡쳐한 코드는 직접 만들어 보면 build는 정상적으로 돌아가지만, alert 을 실행시키는 순간

Thread 1 : signal SIGABRT

라는 공포의 에러메시지가 발생한다. 저건 원인도 여러가지라, 저 메시지만 봐선 뭔지 아직 모른다. 거기까진 아직 실력이 안돼.....

위와 같이 작성하면, 

ButtonaddTarget은 별도의 swift 파일에 만들어 놓고

@objc function은 실제 적용할 ViewController 파일에서 처리하게 되는데, 

이게 뭔가 문제가 되는 것 같다. 아직 swift 내공이 부족해서 왜 안되는지는 모르겠지만..

3. 역시 stackOverflow 만세

코딩 하다 느낀건... 안되는 건 없다. 시간이 걸릴뿐이라는 것과

해답은 언제나 stackOverflow에 있다라는 것

 

아무 swift 파일에나 아래와 같은 코드를 추가한다. 

가져다 쓰긴 하는데, 100% 이해는 안되는 코드 

그럼, UIButton 에 closure, 즉, 실행할 코드를 추가할 수 있도록 만들어준다.

그리고 나서 해당 버튼에 아래와 같이 코드 추가

그럼 completion() 부분은 어떻게? 

@escaping 부분이 굉장히 중요하다. @escaping 관련 정리된 글을 한번 다시 보러가야겠네...

 

최종적으로 완성되었다. custom alert을 사용할때 아래와 같이 불러서 사용!

이렇게 코드를 넣어보고 

아래와 같이 작동시켜서 

print되는 것까지 확인. 

 

뭔가 코드가 조잡하고.. 다른 더 좋은 방법이 있을것 같긴 한데, 현 지식으론 이게 최선. 

전체 코드는 깃허브로 ㄱㄱ

https://github.com/hajini/CustomAlert

 

댓글