iOS

[iOS] BMI 계산기 앱 3

챎 님 2024. 12. 4. 16:31
더보기

이 포스트는 한성현 교수님의 iOS 프로그래밍 기초 수업을 듣고 작성되었습니다.

오늘은 3 주 동안 만들어오던 BMI 계산기 앱을 완성해 보겠습니다.

먼저, 들어가기 전에 오토 레이아웃에 대해 알아 보며 시작하겠습니다.

 

# Auto LayOut

이는 iOS 및 macOS 앱 개발에서 사용되는 레이아웃 시스템으로,

다양한 화면 크기와 해상도에 적응할 수 있도록 UI 요소의 위치와 크기를 자동으로 조정하는 기능입니다.

 

이의 특징으로는

1. 제약 조건(Constraints): 오토 레이아웃은 UI 요소 간의 관계를 정의하는 제약 조건을 사용하여 요소의 위치와 크기를 결정합니다.

예를 들어, 한 요소가 다른 요소의 위, 아래, 왼쪽, 오른쪽에 얼마나 떨어져 있는지를 설정할 수 있습니다.


2. 유연성: 다양한 화면 크기와 방향에 맞춰 UI가 자동으로 조정되므로, 여러 기기에서 일관된 사용자 경험을 제공합니다.


3. 동적인 크기: UI 요소는 콘텐츠의 크기에 따라 자동으로 조정될 수 있어, 다양한 텍스트 길이나 이미지 크기에 대응할 수 있습니다.

4 .성능 최적화: 오토 레이아웃은 레이아웃 계산을 최적화하여 성능을 개선합니다. 필요하지 않은 경우 레이아웃 업데이트를 최소화합니다.

네 가지로 정리해 볼 수 있습니다.

 

그렇다면, xcode 에서 오토 레이아웃을 어떻게 지정할 수 있을까요?

제약 조건 추가를 통해 진행할 수 있습니다.
UI 요소를 선택한 후, 제약 조건 버튼 사용하여 지정할 수 있습니다.
오른쪽 하단의 'Add New Constraints' 버튼(사각형 아이콘)을 클릭하여, 요소의 상하좌우 간격을 설정할 수 있습니다. 원하는 값을 입력하고 'Add Constraints' 버튼을 클릭합니다.

# 제약 조건 추가

이제 앱에 적용을 해 보겠습니다.

이렇게 추가된 것을 확인할 수 있겠죠?

 

# 앱 아이콘 지정

마지막으로 아이콘 변경을 해 보겠습니다.

저는 IconFinder 에서 이미지를 하나 가져와서 1024 픽셀로 크기 조정을 해 준 뒤에,

이렇게 집어 넣었습니다!

시뮬레이터 내에서는 이렇게 되는 것을 확인할 수 있습니당.

 

# LaunchScreen 구성

런치 스크린은 화면이 로딩되기 전에 잠깐 보이는 화면입니다.

이 화면을 한 번 꾸며 보겠습니다.

이렇게 구성해 보았습니다.

... 잡으려고 했지만 실패했습니다. 저렇게 잠깐 뜨는 부분이 런치 스크린이라고 볼 수 있습니다.

 

# SketchView

다음은 스케치 뷰를 하나 더 추가해 보겠습니다.

저번에 교수님이 주신 앱 코드들을 훑어볼 때 봤었던 앱 중 하나를 불러와서 제 앱에 붙여 보았습니다.

이렇게 화면을 복사 붙여넣기 해 주고,

코드들도 불러와서 붙였습니다.

그 뒤, 탭 바 컨트롤러와 연결해 준다면

아래 아이콘이 네 개로 변경되면서 Sketch 창에서는 그림을 그릴 수 있는 창이 완성됩니다.

이렇게 BMI 앱을 완성해 보았습니다!

 

 

이제는 차차 위 앱을 변형하여 보겠습니다.

 

# BMI 창

먼저 BMI 를 계산하는 창에 목표 체중을 입력하면 그 무게까지 얼마나 남았는지 알려 주는 기능을 추가하였습니다.

이는 

//
//  ViewController.swift
//  BMI_ycr
//
//  Created by 윤채림 on 11/13/24.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtHeight: UITextField!
    @IBOutlet weak var txtWeight: UITextField!
    @IBOutlet weak var lblResult: UILabel!
    @IBOutlet weak var goalWeight: UITextField!
    @IBOutlet weak var lblWeightDifference: UILabel!
    
    @IBAction func calcBmi(_ sender: UIButton) {
        if txtHeight.text == "" || txtWeight.text == "" || goalWeight.text == "" {// "" 은 nil 이 아니고 null 로 값이 없는 것을 의미
            lblResult.textColor = .red
            lblResult.text = "키와 체중을 입력하세요잉!"
            lblWeightDifference.text = "목표 체중을 입력하세요잉!"
            return
        } else {
            let weight = Double(txtWeight.text!)!
            let height = Double(txtHeight.text!)!
            let goalWeight = Double(goalWeight.text!)!
            let bmi = weight / (height*height*0.0001) // kg/m*m
            let shortenedBmi = String(format: "%.1f", bmi)
            var body = ""
            var color = UIColor.white
            if bmi >= 40 {
                color = UIColor(displayP3Red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
                body = "3단계 비만"
            } else if bmi >= 30 && bmi < 40 {
                color = UIColor(displayP3Red: 0.7, green: 0.0, blue: 0.0, alpha: 1.0)
                body = "2단계 비만"
            } else if bmi >= 25 && bmi < 30 {
                color = UIColor(displayP3Red: 0.4, green: 0.0, blue: 0.0, alpha: 1.0)
                body = "1단계 비만"
            } else if bmi >= 18.5 && bmi < 25 {
                color = UIColor(displayP3Red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
                body = "정상"
            } else {
                color = UIColor(displayP3Red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)
                body = "저체중"
            }
            // print("BMI:\(shortenedBmi), 판정:\(body)")
            lblResult.backgroundColor = color
            lblResult.clipsToBounds = true
            lblResult.layer.cornerRadius = 10
            lblResult.textColor = .white
            lblResult.text = "BMI: \(shortenedBmi), 판정: \(body)"
            
            let weightDifference = goalWeight - weight
                       if weightDifference > 0 {
                           lblWeightDifference.text = "목표 체중까지 \(String(format: "%.1f", weightDifference)) kg 남았어요잉..."
                       } else if weightDifference < 0 {
                           lblWeightDifference.text = "\(String(format: "%.1f", -weightDifference))    kg 초과했어요잉 ㅠㅠ "
                       } else {
                           lblWeightDifference.text = "목표 체중에 도달했어요잉!"
                       
               }
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        lblWeightDifference.text = "" // 초기화
    }
    
    
}

goalWeight 와 WeightDiffference 를 받아와서 코드를 돌릴 수 있게 구현하였습니다.

 

# Video 창

 

play button 을 눌렀을 때 밑에 있는 라벨이 APT 시작! 😍 이라는 멘트가 띄워지게 코드를 수정하였습니다.

//
//  VideoViewController.swift
//  BMI_ycr
//
//  Created by 윤채림 on 11/27/24.
//

import UIKit
import AVKit

class VideoViewController: UIViewController {

    @IBOutlet weak var lblMessage: UILabel!
    @IBAction func playVideo(_ sender: UIButton) {
        guard let videoPath = Bundle.main.path(forResource: "APT", ofType: "mp4") else{ return }
        let videoURL = URL(filePath: videoPath)
        let player1 = AVPlayer(url: videoURL)
        let playerController = AVPlayerViewController()
        playerController.player = player1
            self.present(playerController, animated: true) {
            player1.play()
                self.lblMessage.text = "APT 시작! 😍"
        }

        
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        lblMessage.text = ""


    }
    


}

 

# web 창

여기는 원래 티스토리와 유튜브 링크만 불러올 수 있도록 구현되어있었는데,

추가적으로 네이버까지 불러오도록 코드를 수정하였습니다.

 

//
//  WebViewController.swift
//  BMI_ycr
//
//  Created by 윤채림 on 11/27/24.
//

import UIKit
import WebKit

class WebViewController: UIViewController {

    
    @IBOutlet weak var webView: WKWebView!
    @IBAction func goYoutube(_ sender: UIButton) {
        guard let url = URL(string: "https://m.youtube.com") else { return }
        let request = URLRequest(url: url)
        webView.load(request)
    }
    
    
    @IBAction func goNaver(_ sender: UIButton) {
        guard let url = URL(string: "http://m.naver.com") else { return }
        let request = URLRequest(url: url)
        webView.load(request)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        guard let url = URL(string: "https://dbsc0f1a.tistory.com/") else { return }
                let request = URLRequest(url: url)
                webView.load(request)

    }
    

 

}

 

# Sketch 창

마지막으로 스케치 창에는 배경색을 앱 색과 동일하게 만들어 주면 통일감을 맞추어 주며,

앱을 새로 업그레이드 시켰습니다.

 


앱을 업그레이드 시키기 전 모든 기능을 구현한 코드는 깃허브에 업로드 하였습니다.

https://github.com/cherry1m/BMI_Calculator

'iOS' 카테고리의 다른 글

[iOS] 생성형 AI 및 오픈 API 활용  (0) 2025.03.05
[iOS] 클로저 Closure  (0) 2024.12.11
[iOS] BMI 계산기 앱 2  (0) 2024.11.27
[iOS] BMI 계산기 앱  (1) 2024.11.20
[iOS] 간단한 앱 구현  (1) 2024.11.13