상세 컨텐츠

본문 제목

[ Swift ] 간단한 랜덤 속담 App

APPLE/Swift

by pandada 2022. 10. 5. 20:38

본문

반응형

이번에는 그동안 배웠던 내용을 토대로 간단하게 랜덤으로 속담이 출력되는 App을 만들어보려고 한다.

우선적으로 현재는 기초 단계의 App을 만드는 것이기 때문에 DB 연결은 하지 않을 것이다.

소스 안에 텍스트를 넣어서 랜덤으로 Label에 표기가 되도록 하는 예제이다.

 

우선 프로젝트를 하나 새롭게 생성을 하도록 하자.

< 프로젝트 생성 >

이렇게 Project를 생성하고, 적당한 위치에 프로젝트 경로를 설정하여 Project를 생성을 하였다.

Project 생성을 진행하였으니 이제 UI를 구성해보도록 하자.

 

이전에 진행했던 AutoLayout과 마찬가지로 StoryBoard에서 작업을 진행해보자.

 

< Label 추가 >

Label을 어떻게 추가하는지 모르는 분들이라면 이전 글을 다시 한번 복습하고 오기를 추천한다.

필자는 Label을 하나 만들었고, Label의 Text는 "랜덤으로 보는 속담"으로 변경하였다.

 

그리고 margin으로 탑, 트레일링, 리딩에 각각 24씩 margin을 넣고 제약조건을 추가하였다.

이부분 또한 이전글인 AutoLayout에서 진행을 했던 부분으로 이전글을 참고하길 바란다.

 

< View 추가 >

이번에는 View를 추가하였다. 그리고 View의 background 색상은 gray로 지정을 하였다.

참고로 색상을 원하는 색상으로 넣고 싶다면, background를 선택하면 맨 아래에 custom이 있다.

이쪽에서는 RGB 값을 각각 넣을 수 있음으로 원하는 대로 색상을 지정하면 된다.

 

< constraints 추가 >

해당 View에 제약조건을 추가하였다. 필자의 경우에는 위의 Label에서 했던 부분과 동일하게 탑, 트레일링, 리딩 부분을 각각 30으로 margin을 주었고, 높이는 150으로 고정값을 입력하였다. 

 

현재 지정해놨던 View 안에 속담이 랜덤으로 표기가 되도록 진행해볼 것이다. 따라서 새성해둔 View 안에 Label 2개를 추가하였다.

위의 Label에는 속담을 표현할 것이고, 아래 Label에는 뜻을 표현해볼 예정이다.

 

< 각 Label Constraints 추가 >

 

우선 위의 Label에는 탑 , 트레일링, 리딩을 각각 20으로 줬고, 아래 Label 에는 바텀, 트레일링 리딩을 각각 20으로 margin을 주었다.

 

그럼 이제 Label과 Label 사이를 정하기 위해서 위의 Label을 클릭하여 동일하게 20으로 주었더니 StoryBoard에 빨간색으로 화살표가 생기는 것을 확인할 수 가 있다.

 

< Error 내용 >

이렇게 View Controller Scene 의 옆에 빨간색 동그라미 화살표가 있는데 해당 화살표를 클릭하면 어디서 에러가 발생했고, 에러의 내용이 뭔지를 확인할 수가 있다. 

 

 

에러의 내용을 확인해보면 Content hugging property를 설정하라고 알려주는 에러의 문구이다.

 

< Content hugging property 설정 >

Content hugging property를 사이드의 인스펙터 메뉴를 확인하여 설정할 수 있다.

하지만 우선적으로 Content hugging property의 개념부터 짚고 넘어가도록 하자.

 

UI Framwork 에서 제공되는 일부 View에는 컨텐츠 고유 사이즈라는 개념이 있다.

예를 들면 라벨, 버튼 들과 같은 뷰의 속성 텍스트나 이미지에 따라 크기가 결정되는 뷰들이 있다.

 

이러한 뷰들은 다른뷰들간에 걸린 제약에 인해서 본래의 컨텐츠 고유의 사이즈보다 늘어나거나 줄어들게 된다.

이렇게 이런 제약조건들로 인해서 컨텐츠 고유 사이즈보다 늘어나가 되는 것을 Contents hugging이라고 하며, 줄어드는 것은 contents compressor registance라고 한다.

 

이 고유 컨텐츠 고유 사이즈 변경에도 우선순위가 있는데 컨텐츠 고유 사이즈보다 늘어났을 때 늘어나게 할지 줄어들게 할지 정할 수 있는데 이런 우선순위를 정하는 것이 hugging priority라고 한다.

 

이를 바탕으로 hugging priority를 설정해보도록 하자.

hugging priority의 우선 순위가 높으면 컨텐츠 고유 크기를 유지하고 낮으면 컨텐츠 크기가 늘어난다.

 

< hugging Priority 설정 >

현재 문제가 되는 hugging property 부분이 vertical 즉, 세로인 부분으로 인하여 세로 부분의 우선 순위를 아래의 Label을 250으로 변경을 하였더니 이렇게 아래의 Label이 커진 부분을 확인할 수가 있었다.

 

그럼 반대로 위의 Label의 hugging priority를 249으로 설정을 하게 된다면 반대로 위의 Label이 늘어나는 것을 확인할 수 있다.

이렇게 hugging priority를 변경해줌으로 인하여 에러가 사라진 것을 확인할 수 가 있다.

 

참고로 priority 값은 1 ~ 1000까지 1의 단의로 가질 수 있으며, 1000은 required / 750은 high / 500은 midium / 250은 row로 판단을 하면 된다. 250단위로 미리 지정해져있는 경우가 있기 때문에 해당 값들은 사용하지 않고, 다른 값을 사용하는 것이 좋다.

 

하지만 필자는 기초 단계를 현재 진행하고 있기 때문에 해당 부분은 무시하고 값을 넣었다.

 

그럼 이제 Label에 길게 문구를 입력해보자.

 

< Label Line 설정 >

임의의 텍스트를 마구잡이로 입력을 해보았다.

Excel처럼 셀의 크기에 맞게 줄바꿈을 하고 싶다면 인스펙터 창에서 Lines를 0으로 설정하면 우측의 이미지와 같이 줄바꿈이 되는 것을 확인할 수가 있다.

만약 2로 하면 2줄만 표기가 되고, 3으로 3줄만 표기가 되는 부분이다.

또한 Label의 텍스트가 Label의 사이즈를 넘어갈 경우에는 제약조건 에러가 또한 표기가 된다.

 

< compression registance error >

compression registance error가 표기가 되는 것을 확인할 수 있다.

에러의 내용을 확인하면 compression registance 우선 순위를 설정하라고 표기가 뜨는 것 또한 확인할 수 있다.

이러한 에러가 나오는 이유는 속담 Label에 엄청 긴 문자열이 들어가서 문자열을 표기하는게 불가능하기 때문이다.

이럴경우 compression registance 우선 순위를 설정하여 어떤 Label의 크기를 유지시킬지 결정을 해줘야한다.

 

우선 순위가 높으면 Label 자신의 크기를 유지하고, 우선순위가 낮으면 크기가 줄어들게 된다.

 

< content compression registance priority >

좌측의 이미지인 경우에는 현재 크기가 넘치는 우선 순위의 값을 1000으로 변경을 했을 때고, 우측의 이미지인 경우에는 500으로 변경을 했을 때이다.

위에서 언급했다 싶이 우선순위가 높을 수록 자신을 유지하기 때문에 좌측의 이미지는 글자들이 생략이 되는 부분이고, 우측의 이미지인 경우에는 우선 순위를 낮췄음으로 크기가 커져서 아래의 Label이 실종된 것을 확인할 수가 있다.

 

이렇게 컨텐츠의 크기에 따라 사이즈를 늘어나게할 것인지, 줄어들게 할것인지 미리 정할 수가 있다.

 

 

그럼 이제 랜덤으로 내용이 바뀔 수 있도록 버튼을 추가해보도록 하자.

 

< Center Horizontally >

버튼을 추가하여 해당 버튼이 위의 View의 가운데에 정렬할 수 있도록 Center Horizontally를 적용해주었다.

그리고 이후에 뷰와 버튼의 간격을 30만큼 떨어지도록 constraints를 추가하였다. 또한 필자의 경우에는 Button의 이름을 "속담 돌리기"로 지정을 하였다.

 

기본적인 UI는 다 만들어봤다. 그럼 이제 버튼을 클릭했을 때에 위의 Label에는 속담이 나오고 아래의 Label에는 뜻이 나올 수 있도록 기능구현을 한번 해보도록 하자.

 

< IBOulet으로 ViewController 연결 >

기능 구현을 위해서 IBOulet으로 ViewController와 UI 부분을 연결해보았다.

속담이 표기될 라벨을 클릭하여 마우스 오른쪽을 눌러 ViewController에 드래그앤드랍을 하여 IBOulet을 추가하였다.

 

< IBOulet name 설정 >

필자의 경우 속담이 표기될 Label의 이름을 quoteLabel로 연결했으며, 뜻이 표기될 라별의 이름은 meanLabel로 표기를 진행했다.

 

또한 버튼이 눌렀을때에 속담과 뜻이 변경이 되어야 함으로 Button에 대한 액션 함수도 정의를 했다.

Action 함수를 정의하기 위해서는 이전 글에서 진행했던 것과 같이 IBOulet을 연결하는거 처럼 마우스 오른쪽 클릭후 드랙그 앤드랍을 하면 된다.

 

< ViewController 연결 완료 >

이렇게 ViewController에 연결을 하면 기능 구현을 위한 연결은 어느정도 끝난 것 같다.

속담 돌리기 버튼을 클릭할 때마다 changeBtn의 함수가 호출이 될 예정이다.

 

그러면 이제 속담을 가지고 있는 구조체를 생성을 한번 해보도록 하자.

위에서 언급한 대로 필자는 현재 기초 단계를 진행하기 때문에 DB연결 내용 부분은 제외한다고 했다.

그러니 속담을 가질 수 있는 구조체를 생성해주어야 한다.

 

구조체 생성을 위해 새로운 파일을 생성하자.

 

< Swift 파일 생성 >

좌측 네비게이터에서 최상단 프로젝트 아래의 폴더에 Swift 파일을 추가하였다.

Swift 파일 추가는 해당 폴더 우측클릭 후 new File을 눌러 Swift 파일을 선택 후 Next를 눌러준다.

필자의 경우에는 구조체 파일의 이름을 Proverb_Struct로 명명했다. 이후에 Create를 눌러 파일의 생성을 완료하자.

 

< 구조체 선언 및 구조체 생성 >

새로 생성된 Swift 파일에 구조체를 선언을 하였다.

Proverb_Struct.Swift 파일에 구조체의 이름은 Proverb_S로 지정을 했고, 속담이 들어갈 상수 proverb와 뜻이 들어갈 상수 mean을 선언하였다.

그리고 나서 ViewController에 proverb 라는 Proverb_S의 구조체의 구조를 가지고 있는 proverb 구조체 배열을 생성하였다.

필자의 경우 9개의 속담과 뜻을 만들었다. 상황이 된다면 더 만들어도 되지만 어차피 간단한 테스트임으로 인하여 대략 이정도만 추가해도 좋을듯 싶다.

 

그러면 이제 "속담 돌리기" 버튼이 클릭될 때 마다 quoteLabel에는 proverb 구조체 배열의 proverb가 나타나게 하고, meanLabel에는 proverb 구조체 배열의 mean이 표기될 수 있도록 Action 함수를 작성해보도록 하자.

 

< Action 함수 구현 >

필자의 경우 친절하게 주석을 달아준 내용과 같이 0 ~ 8 까지 생성하는 random 수를 구현하였다.

arc4random_uniform(n)은 0 ~ n-1 까지의 수를 발생시키는 random 함수이다.

추가로 여기서 Int형으로 형변환을 시켜준 것은 배열의 인덱스 값이 정수임으로 인하여 Int 형으로 형변환을 시켜줬다.

그렇지 않으면 소수점으로 표기가 되기 때문에 구조체 배열의 인덱스 값이 올바르지 않기 때문에 에러가 발생하게 된다.

 

그리고 이후에 random_proverb 상수를 선언하여 전역 변수로 선언한 proverb[n] 의 데이터를 가질 수 있도록 구현을 하였다.

이후에 각각의 proverb와 mean을 표기할 수 있도록 진행을 하였다.

 

command + R 을 눌러서 빌드를 한번 해보도록 하자.

정상적으로 버튼이 클릭될 때마다 랜덤하게 속담과 뜻이 표기되는 것을 확인할 수 있다.

 

하지만 현재 Build한 App의 Label이 사이즈가 일치하지 않아 글자가 짤리는 부분으로 라벨을 선택한 후 인스펙터 영역에서 글자 사이즈를 좀 줄여주는 것도 좋을 것 같다.

 

< Label Font 변경 >

필자의 경우 각각의 라벨 글씨를 12로 하니까 보기도 편하고 글자도 안짤리는 것을 확인하였다.

또한 가운데 정렬이 되어 있지 않아 보기 불편했기 때문에 가운데 정렬도 진행을 하였다.

그리고 속담이 표기되는 quoteLabel을 Bold체로 변경을 해주었다.

 

 

< Build 화면 >

 

이렇게 랜덤으로 속담이 표기되는 App을 만들어봤다. "속담 돌리기" 버튼을 누를때마다 Action 함수를 호출하여 0 ~ 8까지의 난수를 발생시켜 구조체 배열에 접근을 하여, 구조체 배열에 있는 속담과 뜻을 표기할 수 있도록 구현을 해보았다.

 

이렇게 App을 한번 만들어봤으며, 해당 내용을 만들면서 필요했던 부분에 대해서 추가 정리를 하고 넘어가려고 한다.

대부분의 사람들이 그냥 한번 따라하고 말기 때문에... 복습의 중요성을 강조하려고 한다.

 

UIKit

  • UIKit Framework는 사용자 인터페이스를 관리하고 이벤트를 처리하는 것이 주 목적인 Framework
  • 어플리 케이션의 화면을 구성하는 많은 요소들이 UIKit Framework에 포함이 되어있다.
  • UI가 붙는 클래스들을 사용하려면 반드시 UIKit을 Import 시켜줘야한다.
  • ViewController 상단을 보면 자동으로 Import가 되어있는 것을 알 수 있다.

 

UIView

  • 화면을 구성하는 요소의 기본 클래스
  • 여러 UI component 들이 UIView를 상속받고 있다.

UIViewController

  • App의 근간을 이루는 객체
  • 전체적인 인터페이스의 Layout을 관리
  • 다른 View Controller와 같이 앱을 구성
  • 간단하게 하나하나를 관리하는 단위

 

AutoLayout

  • 서로 다른 아이폰의 해상도에 대응하기 위해
  • 제약조건을 이용하여 화면을 구성

 

IBOulet & IBAction

  • IBOulet : StoryBoard에 등록한 UI Object를 코드의 변수로 접근할 수 있도록 만들어 줌.
  • IBAction : Button과 연결시켜 함수로 적용할 수 있도록 해줌

 

Content Hugging

  • UI Label과 UI Button들과 같은 View의 속성, Text나 이미지에 따라 크기가 정해져 있는 View들이 있는데 이러한 View들은 다른 View들간에 걸린 제약에 의해 본래의 contens 고유 사이즈 보다 더 늘어나거나 줄어들 때에 더 늘어나는 것에 대한 저항을 의미함.
  • 우선순위가 높을 수록 크기를 유지하고 우선순위가 낮을 수록 크기가 늘어난다.

 

Compression Resistance

  • UI Label과 UI Button들과 같은 View의 속성, Text나 이미지에 따라 크기가 정해져 있는 View들이 있는데 이러한 View들은 다른 View들간에 걸린 제약에 의해 본래의 contens 고유 사이즈 보다 더 늘어나거나 줄어들 때에 더 줄어드는 것에 대한 저항을 의미함.
  • 우선순위가 높을 수록 크기를 유지하고 우선순위가 낮을 수록 크기가 줄어든다.

 

이렇게 첫 번째 App을 만들면서 진행했던 내용까지 복습을 완료 했다.

복습만이 살길이라고... 이런 비슷한 유형의 다른 App을 만들어 보는 것도 좋을 듯 싶다.

반응형

'APPLE > Swift' 카테고리의 다른 글

[ Swift ] 화면 전환 구현 1  (0) 2022.11.25
[ Swift ] UINavigationController  (0) 2022.10.12
[ Swift ] IBOulet & IBAction  (0) 2022.10.03
[ Swift ] AutoLayout  (0) 2022.10.02
[ Swift ] ViewController  (0) 2022.10.02

관련글 더보기

댓글 영역