평범한 컴공 대학생의 공부일지

iOS Swift BMI 계산기 앱 만들기(1) 본문

iOS Swift

iOS Swift BMI 계산기 앱 만들기(1)

Taram 2023. 11. 26. 21:46

※이 iOS 카테고리의 글 들은 학교 강의와 과제를 기반으로 작성한 것입니다.※


이번 포스트에서는 BMI 계산기 앱을 만들기에 대해 다뤄 보겠습니다.
저번 포스트에서 앱을 만들기 앞서 BMI 계산 코드를 알아보았습니다. 그 코드를 이용해 BMI 계산기 앱을 만들어 보겠습니다.

  1. 프로젝트 생성
    먼저 프로젝트를 생성합니다. 관련 내용은 "Xcode로 간단한 앱 만들기"에서 다뤄보았으므로 간단하게 넘어가겠습니다.
    1) 제품 이름 : bmiTaram
    2) 식별자 : ~.bmiTaram
    3) 인터페이스 : 스토리보드(storyboard)를 사용
    4) 언어 : Swift
    5) Use Core Data : 데이터베이스를 연결하지 않으므로 체크 해제

프로젝트 생성

   2. 배경 색상 지정
       ViewController -> View -> background 색상을 원하는 색으로 지정

배경색상 지정

   3. 디자인 세팅
       1) cmd + shift + L -> Label 4개 -> 3개 : BMI Calculator, Height(cm), Weight(kg) = Text형식
                                                         -> 1개 : 결과 = 변수 형식
       2) TextField -> 2개 : 사용자 입력을 받는 칸 생성
       3) Button -> 1개 : 클릭하면 TextField에 입력된 값으로 BMI을 계산하는 함수(Action) 실행
       4) ImageView -> 1개 : 원하는 이미지 삽입

디자인 세팅

   4. 실행 화면
       -> 실행 화면 ->왼쪽 상단  I/O -> Keyboard -> Connect HardWare Keyboard 해제
           - 위 방법 사용 시 컴퓨터 키보드를 사용하는 것이 아닌 아이폰 자체의 키보드를 사용할 수 있습니다.

실행 화면(디자인)

   5. 디자인 경고 확인
       왼쪽 오류 탭에서 다수의 경고 창을 확인 -> 아이폰의 화면 회전 시 디자인이 이상해지는 것을 확인할 수 있다.
        -> "Views without any layout constraints may clip their content or overlap other views" 오류 ->
       한글로 "레이아웃 제약이 없는 뷰는 내용을 자르거나 다른 뷰와 겹칠 수 있습니다" -> 즉 레이아웃 제약에 대한 경고

       - 해결 방법(Chat GPT 사용)
          1. 적절한 레이아웃 제약 설정: 각각의 뷰에 대해 적절한 위치, 크기, 간격 등의 레이아웃 제약을 설정합니다. 안드로이드에서는 XML 파일에서 레이아웃을 정의하고, iOS에서는 Interface Builder나 코드를 사용하여 Auto Layout을 구성할 수 있습니다.
          2. 자동 레이아웃 시스템 활용: iOS에서는 Auto Layout, 안드로이드에서는 ConstraintLayout과 같은 자동 레이아웃 시스템을 활용하여 여러 디바이스 크기와 화면 방향에 대응할 수 있습니다. 이를 통해 화면 크기가 변경되더라도 레이아웃이 유연하게 조절됩니다.
          3. Safe Area 고려 (iOS): iOS에서는 Safe Area를 활용하여 디바이스의 화면에 적절한 여백을 유지할 수 있습니다. Safe Area를 사용하면 화면의 경계에 가까운 부분에 뷰를 배치할 때도 안전하게 표시됩니다.
          4. 테스트와 디버깅: 앱을 다양한 디바이스에서 테스트하고, 레이아웃이 예상대로 동작하는지 확인합니다. 디버깅 도구를 사용하여 레이아웃 문제를 해결합니다.
          5. 디바이스 별로 최적화: 특정 디바이스에 따라 UI를 최적화하는 작업을 진행합니다. 이는 각 플랫폼의 가이드라인과 사용자 경험을 고려하여 수행됩니다.

레이아웃 제약에 따른 회전 시 경고 발생

   6. 버튼 모서리 둥글게 만들기
       - Button -> Identity Inspector -> User Defined Runtime Attributes
                       -> Key Path : layer.cornerRadius = layer의 모서리 반지름 길이
                           Type : Number = Value의 자료형 지정
                           Value : 7 = 반지름 길이를 7로 설정
       - BMI 계산 Button의 모서리가 둥글어진 것을 확인할 수 있다.

버튼 모서리 둥글게 만들기

   7. Decimal Pad 설정
       - 몸무게와 키를 입력하는 TextField를 클릭하면 영어, 숫자 등을 입력할 수 있는 쿼티 키보드가 나오게 됩니다.
         사용자가 숫자가 아닌 다른 값을 입력하면 에러를 일으킬 수 있기에 숫자 패드만 나오게 해 보도록 하겠습니다.
       - 원하는 TextField 클릭 -> Text Input Traits -> Keyboard Type을 Decimal Pad로 지정
          -> Decimal Pad : 10진수 숫자만 나타내는 Pad 

Decimal Pad 설정

   8. Label, Button, txtField 연결
       1) View의 각 Label, Button, txtField를 ctrl + 클릭 + 드래그
       2) lblResult : BMI을 계산한 결과를 나타는 Label -> 변수
           txtField(Weight, Height) : 사용자의 값을 받을 txtField -> 변수
           calcBmi : txtField의 값으로 BMI를 계산할 Button -> 함수(Action)

각 요소들 연결

   9. 연결 관계 확인
       1) Outlets -> lblResult, txtWeight, txtHeight가 정상적으로 연결된 것을 확인
       2) Actions -> calcBmi가 정상적으로 연결된 것을 확인
           * 노란색 삼각형 오류가 발생한 부분은 x를 클릭해 삭제 -> 다시 추가

연결 관계 확인

   10. 버튼 클릭 시 bmi 계산 결과를 콘솔 창에 출력
         1) print문을 사용 -> 콘솔 창에 결과를 출력 -> 코드에 이상이 없는지 확인
         2) 오류 없이 정상적으로 값이 출력되는 것을 확인 후 다음 단계 진행하기
              -> 안 해도 되는 과정이지만 나중에 오류 발생 시 찾아내기 힘들어집니다. 꼭 중간 출력을 해보시는 걸 추천드립니다.

버튼 클릭 시 bmi 계산 결과를 콘솔 창에 출력

   11. 옵셔널 바인딩 오류 

         1) 사용자의 값을 받아와야 함 -> Double(txtHeight.txt!), Double(txtWeight.text!)!로 지정
         2) 옵셔널 바인딩 오류 발생 -> 여기서 height의 자료형은 Double?
              -> 즉, Double? 은 옵셔널을 나타내며 이러한 옵셔널 값과 * 연산자를 실행할 수 없음을 나타냅니다.
         3) 이를 해결하기 위해 Double(txtWeight.text!)! 와 같이 지정해주어야 합니다.

옵셔널 바인딩 오류

   12. 옵셔널 바인딩 수정 후 실행 화면
         1) let height = Double(txtHeight.text!)!로 수정
         2) 실행 시 옵셔널 바인딩 오류가 발생하지 않고 정상적으로 출력되는 것을 확인할 수 있습니다.

옵셔널 바인딩 오류 수정 후 해결

   13. 옵셔널 값 오류
         1) Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional Value
             -> 강제 언래핑 시에 nil이 발견되어 예상치 못한 상황에서 앱이 강제 종료되는 Runtime 에러
             -> 옵셔널 부분을 설명하는 포스트에서 nil 값을 풀어헤치게 되면 프로그램이 강제 종료되는 에러를 확인했었습니다.

옵셔널 값 오류


         2) 해결 방법(Chat GPT 사용)
             

해결 방법

   14. result Label에 출력
         1) 일단 사용자가 입력을 한다는 가정하에 진행하겠습니다.
         2) 그대로 코드를 작성한 후 Simulator 실행 -> 값을 대입 후 BMI 계산 Button 클릭
             -> 함수가 정상적으로 작동되어 result Label에 출력되는 것을 확인할 수 있습니다.

result Label에 출력

   15. 예외처리를 통한 오류 방지
         1) 위에서의 오류 방지 하기 위해 예외처리 사용
             * 예외처리란? 오류가 발생할 부분을 예상하여 오류가 발생하는 조건을 충족하는 해당 부분을 실행하지 않도록 지정하는 것
         2) if txtWeight.text == "" || txtHeight.text == "" {
             }
             -> 만약 txtWeight.txt나 txtHeight.text의 값이 없을 경우
             -> 콘솔 창에 Error을 출력
             -> lblResult.text의 색을 red로 지정
             -> lblResult.text의 텍스트를 "키와 체중을 입력하세요"라는 재 확인 텍스트로 변경

예외 처리를 통한 오류방지

   16. 비만도에 따른 색상 변경
         1) Text만 바뀌면 가시성이 좋지 않으므로 lblResult의 색상을 변경(lblResult.backgroundColor = color)
              -> 3단계 비만 : 1.0 red
              -> 2단계 비만 : 0.7 red
              -> 1단계 비만 : 0.4 red
              -> 정상 : 1.0 blue
              -> 저체중 : 1.0 green
         2) lblResult.clipsToBounds = true
             -> UIView 클래스의 속성 중 하나인 clipsToBounds를 설정
             -> 해당 뷰가 자신의 서브 뷰를 자르는지 여부 결정
             -> View의 경계를 벗어나는 부분이 보이지 않도록 하여 View의 모양을 자를 수 있습니다.
         3) lblResult.layer.cornerRadius = 20
             -> 모서리의 반지름을 20으로 설정하고 20만큼 둥글게 처리
             -> lblResult.clipsToBounds = true와 연결되어 모서리 반지름을 20만큼 잘라냅니다.

비만도에 따른 색상 변경, 버튼 둥글게 만들기


평소에 Java, JSP, JS, 네트워크 프로그래밍과 같은 Back-end 기술을 많이 접하다 보니 앱의 버튼 모서리를 둥글게 만드는 것도 조금은 낯설었습니다. Front 기술도 낯설지 않도록 꾸준히 해야 한다는 것을 새삼 느끼게 되었으며 한 가지에 치중하면 안 되겠다는 생각이 가장 많이 든 하루였던 것 같습니다. 여러분들도 한 가지에만 치중되지 않고 관련된 여러 분야를 최대한 공부해 보시길 바랍니다.
피드백은 언제나 환영입니다!!!