issue navigator이 떴을때 iOS에서  UI 요소의 위치와 크기를 동적으로 조정하기 위한 시스템 인  오토 레이아웃(Autolayout)이 필요

//
//  ViewController.swift
//  BMI_kdh
//
//  Created by 소프트웨어컴퓨터 on 2024/11/13.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtHeight: UITextField!
    @IBOutlet weak var txtWeight: UITextField!
    @IBOutlet weak var lblResult: UILabel!
    @IBAction func calcBmi(_ sender: UIButton) {
        let weight = 60.0
        let height = 170.0
        let bmi = weight / (height*height*0.0001) // kg/m*m
        let shortenedBmi = String(format: "%.1f", bmi)
        var body = ""
        if bmi >= 40 {
            body = "3단계 비만"
        } else if bmi >= 30 && bmi < 40 {
            body = "2단계 비만"
        } else if bmi >= 25 && bmi < 30 {
            body = "1단계 비만"
        } else if bmi >= 18.5 && bmi < 25 {
            body = "정상"
        } else {
            body = "저체중"
        }
        print("BMI:\(shortenedBmi), 판정:\(body)")
        
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    
}

버튼을 누를때 앱에서는 안보이고 debug area에  보임

//
//  ViewController.swift
//  BMI_kdh
//
//  Created by 소프트웨어컴퓨터 on 2024/11/13.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtHeight: UITextField!
    @IBOutlet weak var txtWeight: UITextField!
    @IBOutlet weak var lblResult: UILabel!
    @IBAction func calcBmi(_ sender: UIButton) {
        let weight = Double(txtWeight.text!)!//txtWeight.text은 옵셔널 string임 강제 언래핑!해야됨, double도 강제 언래핑! /text필드에 둘 다 값을 넣지 않으면 crash가 남
        let height = Double(txtHeight.text!)!
        let bmi = weight / (height*height*0.0001) // kg/m*m
        let shortenedBmi = String(format: "%.1f", bmi)
        var body = ""
        if bmi >= 40 {
            body = "3단계 비만"
        } else if bmi >= 30 && bmi < 40 {
            body = "2단계 비만"
        } else if bmi >= 25 && bmi < 30 {
            body = "1단계 비만"
        } else if bmi >= 18.5 && bmi < 25 {
            body = "정상"
        } else {
            body = "저체중"
        }
        print("BMI:\(shortenedBmi), 판정:\(body)")
        lblResult.text = "BMI:\(shortenedBmi), 판정: \(body)"
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    
}
let height = Double(txtHeight.text!)!
let weight = Double(txtWeight.text!)!

첫 번째 !: txtHeight.text와 txtWeight.text는 옵셔널(Optional) 타입입니다. 즉, 이 값이 nil일 수도 있음을 나타냅니다. !를 사용하여 이 옵셔널 값을 강제로 언래핑하여 실제 문자열 값을 가져옵니다. 만약 이 값이 nil이라면 런타임 오류가 발생합니다.

두 번째 !: Double(txtHeight.text!)와 Double(txtWeight.text!)는 문자열을 Double 타입으로 변환하는 시도입니다. 문자열이 숫자로 변환될 수 없는 경우 nil이 반환됩니다. 따라서 이 값을 다시 강제로 언래핑하여 Double 값을 가져옵니다. 이 경우에도 nil이라면 런타임 오류가 발생합니다.

 

<guard let을 사용하여 코드 수정>

guard let heightText = txtHeight.text, 
      let height = Double(heightText) else {
    print("Height 입력값이 올바르지 않습니다.")
    return
}

print("Height: \(height)")

guard let weightText = txtWeight.text, 
      let weight = Double(weightText) else {
    print("Weight 입력값이 올바르지 않습니다.")
    return
}

print("Weight: \(weight)")
//
//  ViewController.swift
//  BMI_kdh
//
//  Created by 소프트웨어컴퓨터 on 2024/11/13.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtHeight: UITextField!
    @IBOutlet weak var txtWeight: UITextField!
    @IBOutlet weak var lblResult: UILabel!
    @IBAction func calcBmi(_ sender: UIButton) {
        if txtHeight.text == "" || txtWeight.text == "" {//값이 없으면 안내문이 뜨고 , 색을 red 로 지정함
            lblResult.textColor = .red
            lblResult.text = "키와 체중을 입력하세요!"
            return
        }else{
            let weight = Double(txtWeight.text!)!
            let height = Double(txtHeight.text!)!
            let bmi = weight / (height*height*0.0001) // kg/m*m
            let shortenedBmi = String(format: "%.1f", bmi)
            var body = ""
            if bmi >= 40 {
                body = "3단계 비만"
            } else if bmi >= 30 && bmi < 40 {
                body = "2단계 비만"
            } else if bmi >= 25 && bmi < 30 {
                body = "1단계 비만"
            } else if bmi >= 18.5 && bmi < 25 {
                body = "정상"
            } else {
                body = "저체중"
            }
            print("BMI:\(shortenedBmi), 판정:\(body)")
            lblResult.text = "BMI:\(shortenedBmi), 판정: \(body)"
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    
}

전체 선택후 ctrl +i : 소스 정렬

 

//
//  ViewController.swift
//  BMI_kdh
//
//  Created by 소프트웨어컴퓨터 on 2024/11/13.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var txtHeight: UITextField! // 키 입력 필드
    @IBOutlet weak var txtWeight: UITextField! // 체중 입력 필드
    @IBOutlet weak var lblResult: UILabel! // 결과를 출력할 레이블
    
    @IBAction func calcBmi(_ sender: UIButton) { // BMI 계산 버튼 클릭 시 호출되는 함수
        // 입력값이 비어 있는지 확인
        if txtHeight.text == "" || txtWeight.text == "" {
            lblResult.textColor = .red // 경고 메시지 색상 설정
            lblResult.text = "키와 체중을 입력하세요!" // 안내 메시지 출력
            return // 함수 종료
        } else {
            // 입력된 키와 체중을 Double로 변환
            let weight = Double(txtWeight.text!)!
            let height = Double(txtHeight.text!)!
            // BMI 계산 (kg/m²)
            let bmi = weight / (height * height * 0.0001) 
            let shortenedBmi = String(format: "%.1f", bmi) // 소수점 1자리로 포맷팅
            
            var body = "" // BMI 판정을 저장할 변수
            var color = UIColor.white // 초기 배경색을 하얀색으로 설정
            
            // BMI 값에 따른 판정 및 색상 설정
            if bmi >= 40 {
                color = UIColor(displayP3Red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) // 3단계 비만 (빨간색)
                body = "3단계 비만"
            } else if bmi >= 30 && bmi < 40 {
                color = UIColor(displayP3Red: 0.7, green: 0.0, blue: 0.0, alpha: 1.0) // 2단계 비만 (어두운 빨간색)
                body = "2단계 비만"
            } else if bmi >= 25 && bmi < 30 {
                color = UIColor(displayP3Red: 0.4, green: 0.0, blue: 0.0, alpha: 1.0) // 1단계 비만 (좀 더 어두운 빨간색)
                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 = "저체중"
            }
            
            // 결과 레이블의 배경색 설정
            lblResult.backgroundColor = color
            lblResult.clipsToBounds = true // 레이블의 경계선 처리
            lblResult.layer.cornerRadius = 10 // 레이블의 모서리를 둥글게 설정
            lblResult.text = "BMI:\(shortenedBmi), 판정: \(body)" // 결과 출력
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰가 로드된 후 추가 설정이 필요할 경우 여기에 작성
    }
}

결과 나올때 결과에 따라 배경색이 바뀌는 코드 + 결과 레이블 둥글게하는 코드 추가

 

 

universal: 고해상도 ( 아이패드, 아이폰 사진 전부 가능하게하는 )

tab bar controller 선택하면 화면이 하나 더 생김

 

(apple hig: apple 디자인 가이드라인)

 

tab bar controller 화면을 ctrl누르고 드래그 후 view controllers 누르기

 

**메뉴얼 세그웨이(Manual Segue)**와 **릴레이션 세그웨이(Relationship Segue)**의 차이점

 

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 기초 프로그래밍 14주차  (0) 2024.12.04
iOS 프로그래밍 기초 13주차  (0) 2024.11.27
iOS 프로그래밍 기초 11주차  (0) 2024.11.13
iOS 기초 프로그래밍 10주차  (0) 2024.11.06
iOS 기초 프로그래밍 9주차  (0) 2024.10.30

 

 

09 페이지 이동하기 - 페이지 컨트롤

 

 

 

import UIKit

// 이미지 파일 이름을 저장하는 배열
var images = [ "01.png", "02.png", "03.png", "04.png", "05.png", "06.png" ]

class ViewController: UIViewController {
    // 이미지 뷰와 페이지 컨트롤을 아울렛으로 연결
    @IBOutlet var imgView: UIImageView!
    @IBOutlet var pageControl: UIPageControl!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰가 로드된 후 추가 설정
        
        // 페이지 컨트롤의 페이지 수를 이미지 배열의 수로 설정
        pageControl.numberOfPages = images.count
        // 현재 페이지를 3으로 설정 (4번째 이미지)
        pageControl.currentPage = 3
        
        // 페이지 인디케이터 색상 설정
        pageControl.pageIndicatorTintColor = UIColor.blue
        pageControl.currentPageIndicatorTintColor = UIColor.yellow
        
        // 초기 이미지 설정 (첫 번째 이미지)
        imgView.image = UIImage(named: images[0])
    }

    // 페이지 컨트롤의 값이 변경될 때 호출되는 메서드
    @IBAction func pageChange(_ sender: UIPageControl) {
        // 현재 페이지에 해당하는 이미지를 이미지 뷰에 설정
        imgView.image = UIImage(named: images[pageControl.currentPage])
    }
}

 

 

 

10 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기

 

-tabbar controller

화면 밑에 tab으로 다른 화면으로 빠르게 이동해줌

 

-navigation controller

앱에서 화면 간의 전환을 쉽게 만들기 위해 사용

 

 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // 재사용 가능한 셀을 큐에서 가져옵니다. "myCell" 식별자를 사용합니다.
    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

    // items 배열에서 현재 행의 데이터로 텍스트 레이블을 설정합니다.
    cell.textLabel?.text = items[(indexPath as NSIndexPath).row]
    
    // itemsImageFile 배열에서 현재 행의 이미지로 이미지 뷰를 설정합니다.
    cell.imageView?.image = UIImage(named: itemsImageFile[(indexPath as NSIndexPath).row])

    // 구성된 셀을 반환합니다.
    return cell
}

 

 

12 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기

//
//  TableViewController.swift
//  Table
//
//  Created by BeomGeun Lee on 2021.
//

import UIKit

// 아이템 목록과 이미지 파일 이름 배열
var items = ["책 구매", "철수와 약속", "스터디 준비하기"]
var itemsImageFile = ["cart.png", "clock.png", "pencil.png"]

class TableViewController: UITableViewController {

    @IBOutlet var tvListView: UITableView! // 테이블 뷰 아울렛
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // 선택 상태를 유지하려면 주석 해제
        // self.clearsSelectionOnViewWillAppear = false

        // 내비게이션 바에 편집 버튼 추가
        self.navigationItem.leftBarButtonItem = self.editButtonItem
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 뷰가 나타날 때 테이블 뷰를 갱신
        tvListView.reloadData()
    }
    
    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // 테이블 뷰의 섹션 수 반환
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 섹션에 있는 행의 수 반환
        return items.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 재사용 가능한 셀을 큐에서 가져옴
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        // 해당 행의 텍스트와 이미지를 설정
        cell.textLabel?.text = items[(indexPath as NSIndexPath).row]
        cell.imageView?.image = UIImage(named: itemsImageFile[(indexPath as NSIndexPath).row])

        return cell
    }
    
    // Override to support conditional editing of the table view.
    // 셀 편집 가능 여부 설정
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // 삭제 버튼 클릭 시 데이터 소스에서 해당 아이템 삭제
            items.remove(at: (indexPath as NSIndexPath).row)
            itemsImageFile.remove(at: (indexPath as NSIndexPath).row)
            tableView.deleteRows(at: [indexPath], with: .fade) // 테이블 뷰에서 행 삭제
        } else if editingStyle == .insert {
            // 새로운 아이템 추가 시 처리 (현재는 구현 안 됨)
        }
    }
    
    override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        // 삭제 확인 버튼의 제목 설정
        return "삭제"
    }

    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        // 행 이동 처리
        let itemToMove = items[(fromIndexPath as NSIndexPath).row]
        let itemImageToMove = itemsImageFile[(fromIndexPath as NSIndexPath).row]
        items.remove(at: (fromIndexPath as NSIndexPath).row)
        itemsImageFile.remove(at: (fromIndexPath as NSIndexPath).row)
        items.insert(itemToMove, at: (to as NSIndexPath).row)
        itemsImageFile.insert(itemImageToMove, at: (to as NSIndexPath).row)
    }
    
    // Override to support conditional rearranging of the table view.
    // 행 이동 가능 여부 설정
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    // MARK: - Navigation

    // 내비게이션을 위한 준비 작업
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // segue.identifier가 "sgDetail"인 경우
        if segue.identifier == "sgDetail" {
            let cell = sender as! UITableViewCell // 선택된 셀
            let indexPath = self.tvListView.indexPath(for: cell) // 셀의 인덱스 경로
            let detailView = segue.destination as! DetailViewController // 목적지 뷰 컨트롤러
            detailView.reciveItem(items[((indexPath! as NSIndexPath).row)]) // 선택된 아이템 전달
        }
    }
}

 

iOS 앱을 만들 때 가장 많이 사용하는 UI 요소

1. UILabel: 텍스트를 표시하는 데 사용됩니다. 주로 제목이나 설명을 나타낼 때 사용됩니다.

2. UIButton: 사용자와의 상호작용을 위한 버튼입니다. 다양한 스타일과 동작을 정의할 수 있습니다.

3. UIImageView: 이미지를 표시하는 데 사용됩니다. 사진이나 아이콘 등 다양한 이미지를 표시할 수 있습니다.

4. UITableView: 리스트 형태로 데이터를 표시할 때 사용됩니다. 스크롤이 가능한 목록을 만들 수 있습니다.

 

 

13 음악 재생하고 녹음하기

-

AVAudioPlayer 사용하기 위해선

import AVFoundation추가해야됨

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
    
    var audioPlayer: AVAudioPlayer! // 오디오 재생을 위한 AVAudioPlayer
    var audioFile: URL! // 오디오 파일 URL
    
    let MAX_VOLUME: Float = 10.0 // 최대 볼륨 값
    
    var progressTimer: Timer! // 재생 진행 상태를 업데이트하기 위한 타이머
    
    // 타이머 업데이트 메서드를 위한 셀렉터
    let timePlayerSelector: Selector = #selector(ViewController.updatePlayTime)
    let timeRecordSelector: Selector = #selector(ViewController.updateRecordTime)

    // UI 아울렛 변수들
    @IBOutlet var pvProgressPlay: UIProgressView! // 재생 진행 상태를 표시하는 프로그레스 뷰
    @IBOutlet var lblCurrentTime: UILabel! // 현재 재생 시간 레이블
    @IBOutlet var lblEndTime: UILabel! // 총 재생 시간 레이블
    @IBOutlet var btnPlay: UIButton! // 재생 버튼
    @IBOutlet var btnPause: UIButton! // 일시 정지 버튼
    @IBOutlet var btnStop: UIButton! // 정지 버튼
    @IBOutlet var slVolume: UISlider! // 볼륨 조절 슬라이더
    
    @IBOutlet var btnRecord: UIButton! // 녹음 버튼
    @IBOutlet var lblRecordTime: UILabel! // 녹음 시간 레이블
    
    var audioRecorder: AVAudioRecorder! // 오디오 녹음을 위한 AVAudioRecorder
    var isRecordMode = false // 녹음 모드 여부
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰 로드 후 추가 설정
        selectAudioFile() // 오디오 파일 선택
        if !isRecordMode {
            initPlay() // 재생 초기화
            btnRecord.isEnabled = false // 녹음 버튼 비활성화
            lblRecordTime.isEnabled = false // 녹음 시간 레이블 비활성화
        } else {
            initRecord() // 녹음 초기화
        }
    }
    
    func selectAudioFile() {
        // 녹음 모드에 따라 오디오 파일 선택
        if !isRecordMode {
            audioFile = Bundle.main.url(forResource: "Sicilian_Breeze", withExtension: "mp3") // 재생할 파일
        } else {
            let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            audioFile = documentDirectory.appendingPathComponent("recordFile.m4a") // 녹음 파일 경로
        }
    }
    
    func initRecord() {
        // 녹음을 위한 설정
        let recordSettings = [
            AVFormatIDKey: NSNumber(value: kAudioFormatAppleLossless as UInt32),
            AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
            AVEncoderBitRateKey: 320000,
            AVNumberOfChannelsKey: 2,
            AVSampleRateKey: 44100.0
        ] as [String: Any]
        
        do {
            audioRecorder = try AVAudioRecorder(url: audioFile, settings: recordSettings) // AVAudioRecorder 초기화
        } catch let error as NSError {
            print("Error-initRecord: \(error)") // 오류 처리
        }
        audioRecorder.delegate = self // 델리게이트 설정
        slVolume.value = 1.0 // 기본 볼륨 설정
        audioPlayer.volume = slVolume.value // 재생기 볼륨 설정
        lblEndTime.text = convertNSTimeInterval2String(0) // 종료 시간 초기화
        lblCurrentTime.text = convertNSTimeInterval2String(0) // 현재 시간 초기화
        setPlayButtons(false, pause: false, stop: false) // 버튼 상태 설정
        
        let session = AVAudioSession.sharedInstance() // 오디오 세션 생성
        do {
            try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default) // 카테고리 설정
            try AVAudioSession.sharedInstance().setActive(true) // 세션 활성화
        } catch let error as NSError {
            print("Error-setCategory: \(error)") // 오류 처리
        }
    }
    
    func initPlay() {
        // 재생을 위한 초기 설정
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: audioFile) // AVAudioPlayer 초기화
        } catch let error as NSError {
            print("Error-initPlay: \(error)") // 오류 처리
        }
        slVolume.maximumValue = MAX_VOLUME // 슬라이더 최대값 설정
        slVolume.value = 1.0 // 기본 볼륨 설정
        pvProgressPlay.progress = 0 // 프로그레스 뷰 초기화
        
        audioPlayer.delegate = self // 델리게이트 설정
        audioPlayer.prepareToPlay() // 재생 준비
        audioPlayer.volume = slVolume.value // 볼륨 설정
        
        lblEndTime.text = convertNSTimeInterval2String(audioPlayer.duration) // 종료 시간 표시
        lblCurrentTime.text = convertNSTimeInterval2String(0) // 현재 시간 초기화
        setPlayButtons(true, pause: false, stop: false) // 버튼 상태 설정
    }
    
    func setPlayButtons(_ play: Bool, pause: Bool, stop: Bool) {
        // 버튼 활성화 상태 설정
        btnPlay.isEnabled = play
        btnPause.isEnabled = pause
        btnStop.isEnabled = stop
    }
    
    func convertNSTimeInterval2String(_ time: TimeInterval) -> String {
        // NSTimeInterval을 문자열로 변환
        let min = Int(time / 60)
        let sec = Int(time.truncatingRemainder(dividingBy: 60))
        let strTime = String(format: "%02d:%02d", min, sec)
        return strTime
    }

    @IBAction func btnPlayAudio(_ sender: UIButton) {
        // 재생 버튼 클릭 시 호출
        audioPlayer.play() // 오디오 재생
        setPlayButtons(false, pause: true, stop: true) // 버튼 상태 설정
        progressTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timePlayerSelector, userInfo: nil, repeats: true) // 타이머 시작
    }
    
    @objc func updatePlayTime() {
        // 재생 시간 업데이트
        lblCurrentTime.text = convertNSTimeInterval2String(audioPlayer.currentTime) // 현재 시간 레이블 업데이트
        pvProgressPlay.progress = Float(audioPlayer.currentTime / audioPlayer.duration) // 프로그레스 뷰 업데이트
    }
    
    @IBAction func btnPauseAudio(_ sender: UIButton) {
        // 일시 정지 버튼 클릭 시 호출
        audioPlayer.pause() // 오디오 일시 정지
        setPlayButtons(true, pause: false, stop: true) // 버튼 상태 설정
    }
    
    @IBAction func btnStopAudio(_ sender: UIButton) {
        // 정지 버튼 클릭 시 호출
        audioPlayer.stop() // 오디오 정지
        audioPlayer.currentTime = 0 // 재생 시간 초기화
        lblCurrentTime.text = convertNSTimeInterval2String(0) // 현재 시간 레이블 초기화
        setPlayButtons(true, pause: false, stop: false) // 버튼 상태 설정
        progressTimer.invalidate() // 타이머 중지
    }
    
    @IBAction func slChangeVolume(_ sender: UISlider) {
        // 볼륨 슬라이더 값 변경 시 호출
        audioPlayer.volume = slVolume.value // 오디오 볼륨 설정
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        // 오디오 재생 완료 시 호출
        progressTimer.invalidate() // 타이머 중지
        setPlayButtons(true, pause: false, stop: false) // 버튼 상태 설정
    }
    
    @IBAction func swRecordMode(_ sender: UISwitch) {
        // 녹음 모드 스위치 변경 시 호출
        if sender.isOn {
            audioPlayer.stop() // 재생 중지
            audioPlayer.currentTime = 0 // 재생 시간 초기화
            lblRecordTime.text = convertNSTimeInterval2String(0) // 녹음 시간 초기화
            isRecordMode = true // 녹음 모드 활성화
            btnRecord.isEnabled = true // 녹음 버튼 활성화
            lblRecordTime.isEnabled = true // 녹음 시간 레이블 활성화
        } else {
            isRecordMode = false // 녹음 모드 비활성화
            btnRecord.isEnabled = false // 녹음 버튼 비활성화
            lblRecordTime.isEnabled = false // 녹음 시간 레이블 비활성화
            lblRecordTime.text = convertNSTimeInterval2String(0) // 녹음 시간 초기화
        }
        selectAudioFile() // 오디오 파일 선택
        if !isRecordMode {
            initPlay() // 재생 초기화
        } else

 

14 비디오 재생 앱 만들기

//
//  ViewController.swift
//  MoviePlayer
//
//  Created by Ho-Jeong Song on 2021/11/26.
//

import UIKit
import AVKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰가 로드된 후 추가 설정
    }

    @IBAction func btnPlayInternalMovie(_ sender: UIButton) {
        // 내부 파일 mp4 재생
        let filePath: String? = Bundle.main.path(forResource: "FastTyping", ofType: "mp4") // 내부 파일 경로
        let url = NSURL(fileURLWithPath: filePath!) // NSURL 객체 생성

        playVideo(url: url) // 비디오 재생 함수 호출
    }
    
    @IBAction func btnPlayerExternalMovie(_ sender: UIButton) {
        // 외부 파일 mp4 재생
        let url = NSURL(string: "https://dl.dropboxusercontent.com/s/e38auz050w2mvud/Fireworks.mp4")! // 외부 URL 생성

        playVideo(url: url) // 비디오 재생 함수 호출
    }
    
    private func playVideo(url: NSURL) {
        // 비디오 재생을 위한 함수
        let playerController = AVPlayerViewController() // 비디오 플레이어 컨트롤러 생성
        
        let player = AVPlayer(url: url as URL) // AVPlayer 객체 생성
        playerController.player = player // 플레이어를 플레이어 컨트롤러에 설정
        
        self.present(playerController, animated: true) {
            player.play() // 비디오 재생 시작
        }
    }
}

 

 

17 탭과 터치 사용해 스케치 앱 만들기



import UIKit

class ViewController: UIViewController {
    @IBOutlet var imgView: UIImageView! // 그림을 그릴 이미지 뷰
    
    var lastPoint: CGPoint! // 마지막 터치 위치
    var lineSize: CGFloat = 2.0 // 선의 두께
    var lineColor = UIColor.black.cgColor // 선의 색상

    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰가 로드된 후 추가 설정
    }

    @IBAction func btnClearImageView(_ sender: UIButton) {
        // 이미지 뷰를 지우는 버튼 액션
        imgView.image = nil // 이미지 뷰의 이미지를 nil로 설정
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 시작될 때 호출
        let touch = touches.first! as UITouch // 첫 번째 터치 가져오기
        
        lastPoint = touch.location(in: imgView) // 마지막 터치 위치 설정
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 이동할 때 호출
        UIGraphicsBeginImageContext(imgView.frame.size) // 새로운 그래픽 컨텍스트 시작
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor) // 선 색상 설정
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round) // 선 끝 모양 설정
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize) // 선 두께 설정
        
        let touch = touches.first! as UITouch // 첫 번째 터치 가져오기
        let currPoint = touch.location(in: imgView) // 현재 터치 위치
        
        // 현재 이미지를 그래픽 컨텍스트에 그리기
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 선을 그리기
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y)) // 시작점 설정
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currPoint.x, y: currPoint.y)) // 끝점 설정
        UIGraphicsGetCurrentContext()?.strokePath() // 선 그리기
        
        imgView.image = UIGraphicsGetImageFromCurrentImageContext() // 그린 이미지를 이미지 뷰에 설정
        UIGraphicsEndImageContext() // 그래픽 컨텍스트 종료
        
        lastPoint = currPoint // 마지막 위치 업데이트
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 끝날 때 호출
        UIGraphicsBeginImageContext(imgView.frame.size) // 새로운 그래픽 컨텍스트 시작
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor) // 선 색상 설정
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round) // 선 끝 모양 설정
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize) // 선 두께 설정
        
        // 현재 이미지를 그래픽 컨텍스트에 그리기
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 마지막 터치 위치에서 선 그리기
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y)) // 마지막 점에서 자신으로 선을 그리기
        UIGraphicsGetCurrentContext()?.strokePath() // 선 그리기
        
        imgView.image = UIGraphicsGetImageFromCurrentImageContext() // 그린 이미지를 이미지 뷰에 설정
        UIGraphicsEndImageContext() // 그래픽 컨텍스트 종료
    }
    
    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        // 흔들림 제스처가 끝날 때 호출
        if motion == .motionShake {
            imgView.image = nil // 흔들림 제스처로 이미지 뷰 지우기
        }
    }
}
//
//  ViewController.swift
//  Sketch
//
//  Created by Ho-Jeong Song on 2021/12/01.
//

import UIKit

class ViewController: UIViewController {
    @IBOutlet var imgView: UIImageView! // 그림을 그릴 이미지 뷰
    @IBOutlet var txtLineSize: UITextField! // 선의 두께를 입력받는 텍스트 필드
    
    var lastPoint: CGPoint! // 마지막 터치 위치
    var lineSize: CGFloat = 2.0 // 선의 기본 두께
    var lineColor = UIColor.red.cgColor // 선의 기본 색상

    override func viewDidLoad() {
        super.viewDidLoad()
        // 뷰가 로드된 후 추가 설정
        txtLineSize.text = String(Int(lineSize)) // 현재 선 두께를 텍스트 필드에 표시
    }

    @IBAction func btnClearImageView(_ sender: UIButton) {
        // 이미지 뷰를 지우는 버튼 액션
        imgView.image = nil // 이미지 뷰의 이미지를 nil로 설정
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 시작될 때 호출
        let touch = touches.first! as UITouch // 첫 번째 터치 가져오기
        lastPoint = touch.location(in: imgView) // 마지막 터치 위치 설정
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 이동할 때 호출
        UIGraphicsBeginImageContext(imgView.frame.size) // 새로운 그래픽 컨텍스트 시작
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor) // 선 색상 설정
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round) // 선 끝 모양 설정
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize) // 선 두께 설정
        
        let touch = touches.first! as UITouch // 첫 번째 터치 가져오기
        let currPoint = touch.location(in: imgView) // 현재 터치 위치
        
        // 이미지 뷰의 현재 내용을 그래픽 컨텍스트에 그리기
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 선 그리기
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y)) // 시작점 설정
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currPoint.x, y: currPoint.y)) // 끝점 설정
        UIGraphicsGetCurrentContext()?.strokePath() // 선 그리기
        
        imgView.image = UIGraphicsGetImageFromCurrentImageContext() // 그린 이미지를 이미지 뷰에 설정
        UIGraphicsEndImageContext() // 그래픽 컨텍스트 종료
        
        lastPoint = currPoint // 마지막 위치 업데이트
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        // 터치가 끝날 때 호출
        UIGraphicsBeginImageContext(imgView.frame.size) // 새로운 그래픽 컨텍스트 시작
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor) // 선 색상 설정
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round) // 선 끝 모양 설정
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize) // 선 두께 설정
        
        // 이미지 뷰의 현재 내용을 그래픽 컨텍스트에 그리기
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 마지막 터치 위치에서 선 그리기
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y)) // 마지막 점에서 자신으로 선 그리기
        UIGraphicsGetCurrentContext()?.strokePath() // 선 그리기
        
        imgView.image = UIGraphicsGetImageFromCurrentImageContext() // 그린 이미지를 이미지 뷰에 설정
        UIGraphicsEndImageContext() // 그래픽 컨텍스트 종료
    }
    
    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        // 흔들림 제스처가 끝날 때 호출
        if motion == .motionShake {
            imgView.image = nil // 흔들림 제스처로 이미지 뷰 지우기
        }
    }
    
    @IBAction func txtEditChange(_ sender: UITextField) {
        // 텍스트 필드의 내용이 변경될 때 호출
        if txtLineSize.text != "" {
            lineSize = CGFloat(Int(txtLineSize.text!)!) // 입력된 값을 선 두께로 설정
        }
    }
    
    @IBAction func txtDidEndOnExit(_ sender: UITextField) {
        // 텍스트 필드에서 입력이 끝날 때 호출
        lineSize = CGFloat(Int(txtLineSize.text!)!) // 입력된 값을 선 두께로 설정
    }
    
    @IBAction func txtTouchDown(_ sender: UITextField) {
        // 텍스트 필드가 터치될 때 호출
        txtLineSize.selectAll(UITextField.self) // 텍스트 필드의 모든 텍스트 선택
    }
    
    @IBAction func btnChangeLineColorBlack(_ sender: UIButton) {
        // 검은색 버튼 클릭 시 호출
        lineColor = UIColor.black.cgColor // 선 색상을 검은색으로 설정
    }
    
    @IBAction func btnChangeLineColorRed(_ sender: UIButton) {
        // 빨간색 버튼 클릭 시 호출
        lineColor = UIColor.red.cgColor // 선 색상을 빨간색으로 설정
    }
    
    @IBAction func btnChangeLineColorGreen(_ sender: UIButton) {
        // 초록색 버튼 클릭 시 호출
        lineColor = UIColor.green.cgColor // 선 색상을 초록색으로 설정
    }
    
    @IBAction func btnChangeLineColorBlue(_ sender: UIButton) {
        // 파란색 버튼 클릭 시 호출
        lineColor = UIColor.blue.cgColor // 선 색상을 파란색으로 설정
    }
}

 

기존 bmi 앱

https://apps.apple.com/us/app/bmi-calculator-weight-loss/id666822519?see-all=customers-also-bought-apps

 

‎BMI Calculator – Weight Loss

‎With this BMI Calculator you can calculate your Body Mass Index to find your ideal weight. It's the ideal companion app for your weight loss program. No matter if you want to lose weight or gain weight, this app can help you evaluate your current weight

apps.apple.com


BMI 앱 기획서
1. 앱 개요
1.1 앱 이름
HealthCalc: BMI Calculator
1.2 앱 설명
HealthCalc는 사용자가 자신의 BMI(체질량지수)를 쉽게 계산하고, 건강을 관리하는 데 도움을 주는 앱입니다. 사용자 친화적인 인터페이스와 다양한 기능을 통해 체중 관리와 건강한 생활 습관을 촉진합니다.
2. 주요 기능
2.1 사용자 입력
**키(cm)**와 체중(kg) 입력을 위한 텍스트 필드 제공
입력 유효성 검사: 숫자가 아닌 경우 오류 메시지 표시
2.2 BMI 계산
사용자가 입력한 값으로 BMI를 계산하고, 결과를 실시간으로 업데이트
계산된 BMI 값에 따라 건강 상태 메시지 제공 (예: 저체중, 정상 체중, 과체중, 비만)
2.3 결과 저장 및 기록
사용자의 BMI 계산 기록을 저장하고, 이전 기록을 확인할 수 있는 기능 제공
기록된 데이터를 기반으로 그래프 또는 차트로 시각화하여 건강 변화 추적 가능
2.4 추가 기능
건강 팁: BMI에 따라 맞춤형 건강 팁 제공 (예: 운동 추천, 식단 조절)
목표 설정: 사용자가 목표 체중을 설정하고, 이를 달성하기 위한 계획 수립
알림 기능: 정기적으로 체중 측정을 하도록 알림 설정
2.5 다국어 지원
다양한 언어로 앱을 제공하여 글로벌 사용자층 확보
3. UI/UX 디자인
3.1 디자인 원칙
심플하고 직관적인 UI: 사용자가 쉽게 이해하고 사용할 수 있도록 간결한 디자인
일관된 색상 및 폰트: 건강과 관련된 차분한 색상 사용 (예: 초록색, 파란색)
3.2 화면 구성
홈 화면: 키와 체중 입력 필드, 계산 버튼, 결과 표시 영역
결과 화면: BMI 결과, 건강 상태 메시지, 이전 기록 버튼
기록 화면: 과거 BMI 기록 목록, 그래프 표시
설정 화면: 알림 설정, 언어 선택, 도움말
4. 경쟁 분석
4.1 기존 인기 앱 분석
MyFitnessPal: 체중 관리와 영양 추적에 강점을 가진 앱. 다양한 기능과 사용자 커뮤니티 제공.
BMI Calculator: 간단하고 직관적인 BMI 계산 기능. 사용자 친화적인 인터페이스.
Lose It!: 체중 감량 목표 설정 및 추적 기능 제공. 사용자 맞춤형 다이어트 계획.
4.2 차별점
HealthCalc는 BMI 계산뿐만 아니라, 사용자 맞춤형 건강 팁과 목표 설정 기능을 통해 보다 포괄적인 건강 관리 솔루션을 제공합니다.
5. 마케팅 전략
5.1 타겟 사용자
건강 관리를 원하는 일반 사용자
체중 감량 및 운동을 목표로 하는 사용자
5.2 홍보 전략
소셜 미디어 플랫폼을 통한 광고 및 캠페인
건강 관련 블로그 및 웹사이트와의 협업
사용자 후기를 통한 신뢰성 확보
6. 개발 계획
6.1 기술 스택
프론트엔드: Swift, UIKit
백엔드: Firebase (데이터 저장 및 사용자 인증)
디자인 도구: Figma 또는 Sketch
6.2 개발 일정
1개월: 기획 및 디자인
2개월: 개발 및 내부 테스트
1개월: 베타 테스트 및 피드백 반영
1개월: 출시 준비 및 마케팅
7. 예상 비용
개발 인력, 디자인, 마케팅 비용 등을 포함한 예산 계획 수립

 

 

 

1. ui디자인

2.outlet

3.action

4. connections inspector로 outlet이나 action 이 한번만 연결된 것인지 확인

5.action에 소스코드 작성

 이미지는 assets.xcassets에 넣고 alt키를 눌러서 옮기는 이유는 선명하게(?)하기 위해

 

Decimal pad

출처:

----------------------------------------
02 Hello World 앱 만들며 Xcode에 완벽 적응하기
03 원하는 이미지 화면에 출력하기 - 이미지 뷰
04 데이트 피커 사용해 날짜 선택하기
05 피커 뷰 사용해 원하는 항목 선택하기
06 얼럿 사용해 경고 표시하기
07 웹 뷰로 간단한 웹 브라우저 만들기
08 맵 뷰로 지도 나타내기
09 페이지 이동하기 - 페이지 컨트롤
10 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기
11 내비게이션 컨트롤러 이용해 화면 전환하기
12 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기
13 음악 재생하고 녹음하기
14 비디오 재생 앱 만들기
15 카메라와 포토 라이브러리에서 미디어 가져오기
16 코어 그래픽스로 화면에 그림 그리기
17 탭과 터치 사용해 스케치 앱 만들기
18 스와이프 제스처 사용하기
19 핀치 제스처 사용해 사진을 확대/축소하기

+) 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 프로그래밍 기초 13주차  (0) 2024.11.27
iOS 기초 프로그래밍 12주차  (0) 2024.11.20
iOS 기초 프로그래밍 10주차  (0) 2024.11.06
iOS 기초 프로그래밍 9주차  (0) 2024.10.30
iOS 프로그래밍 기초 7주차  (0) 2024.10.16

connections Inspector 중요

 

is intlal view insets-> 화살표

 

사진 크기 1024

 

 

iOS에서 UILabel을 사용하는 기본적인 예제

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UILabel 생성
        let myLabel = UILabel()
        
        // 레이블 속성 설정
        myLabel.text = "안녕하세요, iOS!"
        myLabel.textColor = .black
        myLabel.font = UIFont.systemFont(ofSize: 24)
        myLabel.textAlignment = .center
        
        // 레이블의 크기와 위치 설정
        myLabel.frame = CGRect(x: 0, y: 0, width: 300, height: 50)
        myLabel.center = view.center  // 화면 중앙에 배치
        
        // 레이블을 뷰에 추가
        view.addSubview(myLabel)
    }
}

aspect fit으로 하는게 좋음

 

import UIKit

class ViewController: UIViewController {
    var x :Int = 0
    
    @IBOutlet weak var labelnumber: UILabel!
    @IBOutlet weak var lblHello: UILabel!
    
    
    @IBAction func btnDown(_ sender: UIButton) {
        x = x-1 //마이너스 버튼 누르면 숫자가 줄어든다
        labelnumber.text = String(x)
    }
    @IBAction func btnUp(_ sender: UIButton) {
        x = x+1//플러스 버튼 누르면 S가 숫자로 바뀌고 숫자가 늘어남
        labelnumber.text = String(x)
       
    }
    
    @IBOutlet weak var txtName: UITextField!
    
    @IBAction func btnSend(_ sender: UIButton) {
        lblHello.text = "Hi, " + txtName.text!
        print(lblHello.text, txtName.text)
    }
  @IBAction func btnReset(_ sender: UIButton) {
      lblHello.textColor = .systemBlue
      lblHello.text = "안녕하세요!"
      txtName.text = ""
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    
}

 

03 원하는 이미지 화면에 출력하기 - 이미지 뷰

아래는 주어진 Swift 코드에 대한 주석입니다. 각 부분의 기능을 설명합니다.

```swift
//
//  ViewController.swift
//  ImageView
//
//  Created by Ho-Jeong Song on 2021/11/23.
//

import UIKit

// ViewController 클래스 정의
class ViewController: UIViewController {
    // 이미지 확대 여부를 나타내는 변수
    var isZoom = false
    // 이미지 온, 오프 상태에 대한 UIImage 변수
    var imgOn: UIImage?
    var imgOff: UIImage?

    // IBOutlet으로 연결된 UIImageView와 UIButton
    @IBOutlet var imgView: UIImageView!
    @IBOutlet var btnResize: UIButton!
    
    // 뷰가 로드될 때 호출되는 메서드
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 이미지 파일을 로드하여 변수에 저장
        imgOn = UIImage(named: "lamp_on.png")
        imgOff = UIImage(named: "lamp_off.png")
        
        // 초기 이미지로 imgOn 설정
        imgView.image = imgOn
    }

    // UIButton 클릭 시 호출되는 액션 메서드
    @IBAction func btnResizeImage(_ sender: UIButton) {
        let scale: CGFloat = 2.0 // 확대/축소 비율
        var newWidth: CGFloat, newHeight: CGFloat

        // 현재 확대 상태에 따라 이미지 뷰의 크기를 조정
        if (isZoom) {   // true일 경우 (이미지가 확대된 상태)
            newWidth = imgView.frame.width / scale // 너비 축소
            newHeight = imgView.frame.height / scale // 높이 축소
            
            // 버튼의 제목을 "확대"로 변경
            btnResize.setTitle("확대", for: .normal)
        }
        else {  // false일 경우 (이미지가 축소된 상태)
            newWidth = imgView.frame.width * scale // 너비 확대
            newHeight = imgView.frame.height * scale // 높이 확대
            
            // 버튼의 제목을 "축소"로 변경
            btnResize.setTitle("축소", for: .normal)
        }
        
        // 이미지 뷰의 크기를 새로운 크기로 설정
        imgView.frame.size = CGSize(width: newWidth, height: newHeight)
        
        // isZoom 상태를 반전시켜 다음 클릭 시 동작 변경
        isZoom = !isZoom
    }
    
    // UISwitch 클릭 시 호출되는 액션 메서드
    @IBAction func switchImageOnOff(_ sender: UISwitch) {
        // 스위치가 켜져 있으면 imgOn 이미지 설정
        if sender.isOn {
            imgView.image = imgOn
        } else { // 스위치가 꺼져 있으면 imgOff 이미지 설정
            imgView.image = imgOff
        }
    }
}
```

### 주석 요약
- 이 코드는 iOS 앱의 ViewController를 정의하고, 이미지 뷰와 버튼, 스위치를 통해 이미지를 확대/축소하거나 변경하는 기능을 제공합니다.
- `viewDidLoad` 메서드는 뷰가 로드될 때 초기 설정을 담당합니다.
- `btnResizeImage` 메서드는 버튼 클릭 시 이미지를 확대하거나 축소합니다.
- `switchImageOnOff` 메서드는 스위치의 상태에 따라 이미지를 변경합니다. 

이런 자료를 참고했어요.
[1] velog - [Swift] ViewController 화면전환 방법 (https://velog.io/@5n_tak/Swift-ViewController-%ED%99%94%EB%A9%B4%EC%A0%84%ED%99%98-%EB%B0%A9%EB%B2%95)
[2] 티스토리 - [iOS/Swift] ViewController 화면 전환 방법 3가지 (https://eunoia3jy.tistory.com/210)
[3] 티스토리 - [iOS/swift] 이미지 뷰 (ImageView) 앱 만들기 - 무니봇 IT 블로그 (https://moonibot.tistory.com/4)
[4] 네이버 블로그 - [iOS] ViewController의 특징과 생명주기 - 네이버 블로그 (https://m.blog.naver.com/doctor-kick/222424663918) 

뤼튼 사용하러 가기 > https://agent.wrtn.ai/5xb91l

 

 

04 데이트 피커 사용해 날짜 선택하기

 

 

06 얼럿 사용해 경고 표시하기

import UIKit

class ViewController: UIViewController {
    
    let imgOn = UIImage(named: "lamp-on.png")
    let imgOff = UIImage(named: "lamp-off.png")
    let imgRemove = UIImage(named: "lamp-remove.png")
    
    var isLampOn = true
    
    @IBOutlet var lampImg: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        lampImg.image = imgOn
    }

    @IBAction func btnLampOn(_ sender: UIButton) {
        if(isLampOn==true) {
            let lampOnAlert = UIAlertController(title: "경고", message: "현재 On 상태입니다", preferredStyle: UIAlertController.Style.alert)
            let onAction = UIAlertAction(title: "네, 알겠습니다.", style: UIAlertAction.Style.default, handler: nil)
            lampOnAlert.addAction(onAction)
            present(lampOnAlert, animated: true, completion: nil)
        } else {
            lampImg.image = imgOn
            isLampOn=true
        }
    }
    
    @IBAction func btnLanpOff(_ sender: UIButton) {
        if isLampOn {
            let lampOffAlert = UIAlertController(title: "램프 끄기", message: "램프를 끄시겠습니까?", preferredStyle: UIAlertController.Style.alert)

            let offAction = UIAlertAction(title: "네", style: UIAlertAction.Style.default, handler: {
                ACTION in self.lampImg.image = self.imgOff
                self.isLampOn=false
            })
            let cancelAction = UIAlertAction(title: "아니오", style: UIAlertAction.Style.default, handler: nil)

            lampOffAlert.addAction(offAction)
            lampOffAlert.addAction(cancelAction)

            present(lampOffAlert, animated: true, completion: nil)
        }
    }
    
    @IBAction func btnLampRemove(_ sender: UIButton) {
        let lampRemoveAlert = UIAlertController(title: "램프 제거", message: "램프를 제거하시겠습니까?", preferredStyle: UIAlertController.Style.alert)

        let offAction = UIAlertAction(title: "아니오, 끕니다(off).", style: UIAlertAction.Style.default, handler: {
            ACTION in self.lampImg.image = self.imgOff
            self.isLampOn=false
        })
        let onAction = UIAlertAction(title: "아니오, 켭니다(on).", style: UIAlertAction.Style.default) {
            ACTION in self.lampImg.image = self.imgOn
            self.isLampOn=true
        }
        let removeAction = UIAlertAction(title: "네, 제거합니다.", style: UIAlertAction.Style.destructive, handler: {
            ACTION in self.lampImg.image = self.imgRemove
            self.isLampOn=false
        })

        lampRemoveAlert.addAction(offAction)
        lampRemoveAlert.addAction(onAction)
        lampRemoveAlert.addAction(removeAction)

        present(lampRemoveAlert, animated: true, completion: nil)
    }
    
}

 

 

07 웹 뷰로 간단한 웹 브라우저 만들기

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    @IBOutlet var txtUrl: UITextField!
    @IBOutlet var myWebView: WKWebView!
    @IBOutlet var myActivityIndicator: UIActivityIndicatorView!
    
    func loadWebPage(_ url: String) {
        let myUrl = URL(string: url)
        let myRequest = URLRequest(url: myUrl!)
        myWebView.load(myRequest)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        myWebView.navigationDelegate = self
        loadWebPage("https://cpp-programming-202312045.tistory.com")
    }
    
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        myActivityIndicator.startAnimating()
        myActivityIndicator.isHidden = false
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        myActivityIndicator.stopAnimating()
        myActivityIndicator.isHidden = true
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        myActivityIndicator.stopAnimating()
        myActivityIndicator.isHidden = true
    }
    
    func checkUrl(_ url: String) -> String {
       var strUrl = url
        let flag = strUrl.hasPrefix("http://")
        if !flag {
            strUrl = "http://" + strUrl
        }
        return strUrl
    }

    @IBAction func btnGotoUrl(_ sender: UIButton) {
        let myUrl = checkUrl(txtUrl.text!)
        txtUrl.text = ""
        loadWebPage(myUrl)
    }
    
    @IBAction func btnGoSite1(_ sender: UIButton) {
        loadWebPage("http://fallinmac.tistory.com")
    }
    
    @IBAction func btnGoSite2(_ sender: UIButton) {
        loadWebPage("http://blog.2sam.net")
    }
    
    @IBAction func btnLoadHtmlString(_ sender: UIButton) {
        let htmlString = "<h1> HTML String </h1><p> String 변수를 이용한 웹페이지 </p> <p><a href=\"http://2sam.net\">2sam</a>으로 이동</p>"
        myWebView.loadHTMLString(htmlString, baseURL: nil)
    }
    
    @IBAction func btnLoadHtmlFile(_ sender: UIButton) {
        let filePath = Bundle.main.path(forResource: "htmlView", ofType: "html")
        let myUrl = URL(fileURLWithPath: filePath!)
        let myRequest = URLRequest(url: myUrl)
        myWebView.load(myRequest)
    }
    
    @IBAction func btnStop(_ sender: UIBarButtonItem) {
        myWebView.stopLoading()
    }
    
    @IBAction func btnReload(_ sender: UIBarButtonItem) {
        myWebView.reload()
    }
    
    @IBAction func btnGoBack(_ sender: UIBarButtonItem) {
        myWebView.goBack()
    }
    
    @IBAction func btnGoForward(_ sender: UIBarButtonItem) {
        myWebView.goForward()
    }
    
}

 

내장형 웹 브라우저 보여주고 싶을때 : 웹 뷰 사용

 

 

08 맵 뷰로 지도 나타내기

import UIKit  // UIKit 프레임워크를 임포트하여 UI 관련 기능을 사용할 수 있도록 함
import MapKit // MapKit 프레임워크를 임포트하여 지도 관련 기능을 사용할 수 있도록 함

class ViewController: UIViewController, CLLocationManagerDelegate {
    // UIViewController를 상속받고, CLLocationManagerDelegate 프로토콜을 채택

    @IBOutlet var myMap: MKMapView!  // 지도 뷰를 연결하는 아울렛
    @IBOutlet var lblLocationInfo1: UILabel!  // 위치 정보를 표시할 레이블 1
    @IBOutlet var lblLocationInfo2: UILabel!  // 위치 정보를 표시할 레이블 2
    
    let locationManager = CLLocationManager()  // 위치 관리 객체 생성
    
    override func viewDidLoad() {
        super.viewDidLoad()  // 부모 클래스의 viewDidLoad 호출
        // 뷰가 로드된 후 추가 설정을 수행
        lblLocationInfo1.text = ""  // 레이블 1 초기화
        lblLocationInfo2.text = ""  // 레이블 2 초기화
        locationManager.delegate = self  // 위치 관리자의 델리게이트를 현재 뷰 컨트롤러로 설정
        locationManager.desiredAccuracy = kCLLocationAccuracyBest  // 위치 정확도를 최대로 설정
        locationManager.requestWhenInUseAuthorization()  // 앱 사용 중 위치 권한 요청
        locationManager.startUpdatingLocation()  // 위치 업데이트 시작
        myMap.showsUserLocation = true  // 사용자 위치 표시 활성화
    }
    
    func goLocation(latitudeValue: CLLocationDegrees, longitudeValue: CLLocationDegrees, delta span: Double) -> CLLocationCoordinate2D {
        let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)  // 위도와 경도로 CLLocationCoordinate2D 객체 생성
        let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)  // 줌 레벨을 설정하는 span 객체 생성
        let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)  // 중심과 줌 레벨로 MKCoordinateRegion 객체 생성
        myMap.setRegion(pRegion, animated: true)  // 지도의 지역을 설정하고 애니메이션 효과 적용
        return pLocation  // 생성한 위치 반환
    }

    func setAnnotation(latitudeValue: CLLocationDegrees, longitudeValue: CLLocationDegrees, delta span: Double, title strTitle: String, subtitle strSubtitle: String) {
        let annotation = MKPointAnnotation()  // 새 주석(annotation) 객체 생성
        annotation.coordinate = goLocation(latitudeValue: latitudeValue, longitudeValue: longitudeValue, delta: span)  // 주석의 좌표 설정
        annotation.title = strTitle  // 주석의 제목 설정
        annotation.subtitle = strSubtitle  // 주석의 부제 설정
        myMap.addAnnotation(annotation)  // 지도에 주석 추가
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let pLocation = locations.last  // 가장 최근의 위치 정보 가져오기
        _ = goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)  // 위치를 지도에 설정
        CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: { (placemarks, error) -> Void in  // 역 지오코딩을 통해 주소 정보 가져오기
            let pm = placemarks!.first  // 첫 번째 placemark 가져오기
            let country = pm!.country  // 국가 정보 가져오기
            var address: String = country!  // 주소 초기화 (국가 포함)
            if pm!.locality != nil {  // 지역 정보가 있는 경우
                address += " "  // 공백 추가
                address += pm!.locality!  // 지역 정보 추가
            }
            if pm!.thoroughfare != nil {  // 도로 정보가 있는 경우
                address += " "  // 공백 추가
                address += pm!.thoroughfare!  // 도로 정보 추가
            }
            
            self.lblLocationInfo1.text = "현재 위치"  // 레이블 1에 현재 위치 텍스트 설정
            self.lblLocationInfo2.text = address  // 레이블 2에 주소 텍스트 설정
        })
        
        locationManager.stopUpdatingLocation()  // 위치 업데이트 중지
    }

    @IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
        if sender.selectedSegmentIndex == 0 {  // 첫 번째 세그먼트 선택 시
            self.lblLocationInfo1.text = ""  // 레이블 1 초기화
            self.lblLocationInfo2.text = ""  // 레이블 2 초기화
            locationManager.startUpdatingLocation()  // 위치 업데이트 시작
        } else if sender.selectedSegmentIndex == 1 {  // 두 번째 세그먼트 선택 시
            setAnnotation(latitudeValue: 37.63207, longitudeValue: 127.0554, delta: 0.01, title: "인덕대학", subtitle: "노원구 월계동")  // 인덕대학 주석 추가
            self.lblLocationInfo1.text = "보고 계신 위치"  // 레이블 1에 텍스트 설정
            self.lblLocationInfo2.text = "한국폴리텍대학 강릉캠퍼스"  // 레이블 2에 텍스트 설정
        } else if sender.selectedSegmentIndex == 2 {  // 세 번째 세그먼트 선택 시
            setAnnotation(latitudeValue: 37.556876, longitudeValue: 126.914066, delta: 0.1, title: "이지스퍼블리싱", subtitle: "서울시 마포구 잔다리로 109 이지스 빌딩")  // 이지스퍼블리싱 주석 추가
            self.lblLocationInfo1.text = "보고 계신 위치"  // 레이블 1에 텍스트 설정
            self.lblLocationInfo2.text = "이지스퍼블리싱 출판사 "  // 레이블 2에 텍스트 설정
        }
    }
}

 

출처:

----------------------------------------
02 Hello World 앱 만들며 Xcode에 완벽 적응하기
03 원하는 이미지 화면에 출력하기 - 이미지 뷰
04 데이트 피커 사용해 날짜 선택하기
05 피커 뷰 사용해 원하는 항목 선택하기
06 얼럿 사용해 경고 표시하기
07 웹 뷰로 간단한 웹 브라우저 만들기
08 맵 뷰로 지도 나타내기
09 페이지 이동하기 - 페이지 컨트롤
10 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기
11 내비게이션 컨트롤러 이용해 화면 전환하기
12 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기
13 음악 재생하고 녹음하기
14 비디오 재생 앱 만들기
15 카메라와 포토 라이브러리에서 미디어 가져오기
16 코어 그래픽스로 화면에 그림 그리기
17 탭과 터치 사용해 스케치 앱 만들기
18 스와이프 제스처 사용하기
19 핀치 제스처 사용해 사진을 확대/축소하기

 

 

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 기초 프로그래밍 12주차  (0) 2024.11.20
iOS 프로그래밍 기초 11주차  (0) 2024.11.13
iOS 기초 프로그래밍 9주차  (0) 2024.10.30
iOS 프로그래밍 기초 7주차  (0) 2024.10.16
iOS 프로그래밍 기초 6주  (0) 2024.10.15

앱 개발

1단계 : 프로젝트 생성

 

Minimum Deployments 는 너무 높게 주면 안됨

Orientation 폰을 돌렸을때 앱이 돌아가게 할 건지..

 

placeholder

 

keyboard->Toggle Software Keyboard

 

import UIKit // UIKit 프레임워크를 임포트하여 iOS 사용자 인터페이스를 구성할 수 있게 함

class ViewController: UIViewController { // ViewController라는 이름의 클래스를 정의하며, UIViewController를 상속받음

    override func viewDidLoad() { // 뷰가 메모리에 로드된 후 호출되는 메서드를 오버라이드
        super.viewDidLoad() // 부모 클래스의 viewDidLoad 메서드를 호출하여 기본 설정을 수행
        // Do any additional setup after loading the view. // 뷰 로딩 후 추가적인 설정을 할 수 있는 부분 (현재는 비어 있음)
    }
}

outlet변수 추가하는 방법

연결되어있는 거 끄기(연결이 중복돼 있는 경우) 경고 표시 있는 거 지우기

 

1. 기본 UILabel 생성 및 텍스트 설정

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UILabel 생성
        let myLabel = UILabel()
        myLabel.text = "안녕하세요!" // 텍스트 설정
        myLabel.textColor = .black // 텍스트 색상 설정
        myLabel.font = UIFont.systemFont(ofSize: 24) // 글꼴 크기 설정
        myLabel.textAlignment = .center // 텍스트 정렬 설정
        
        // UILabel의 프레임 설정
        myLabel.frame = CGRect(x: 50, y: 100, width: 300, height: 50)
        
        // 뷰에 UILabel 추가
        self.view.addSubview(myLabel)
    }
}

2. UILabel을 IBOutlet으로 연결하여 텍스트 업데이트

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel! // 스토리보드에서 연결된 UILabel
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UILabel의 텍스트 업데이트
        myLabel.text = "안녕하세요, Swift!" // 텍스트 설정
    }
}

breakpoint는 드래그해서 없애면 됨

 

 

 

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 프로그래밍 기초 11주차  (0) 2024.11.13
iOS 기초 프로그래밍 10주차  (0) 2024.11.06
iOS 프로그래밍 기초 7주차  (0) 2024.10.16
iOS 프로그래밍 기초 6주  (0) 2024.10.15
iOS프로그래밍 기초 5주차  (0) 2024.10.03

 

데이터를 property

<객체지향 언어인 Swift, Java, C#, JavaScript, Python에서 클래스를 생성하고 객체를 만드는 방법에 대해 각각 간단한 예제>

1. Swift

class Dog {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func bark() {
        print("\(name) says Woof!")
    }
}

// 객체 생성
let myDog = Dog(name: "Buddy")
myDog.bark()

2. Java

class Dog {
    String name;

    Dog(String name) {
        this.name = name;
    }

    void bark() {
        System.out.println(name + " says Woof!");
    }
}

// 객체 생성
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy");
        myDog.bark();
    }
}

3. C#

class Dog {
    public string Name { get; set; }

    public Dog(string name) {
        Name = name;
    }

    public void Bark() {
        Console.WriteLine($"{Name} says Woof!");
    }
}

// 객체 생성
class Program {
    static void Main() {
        Dog myDog = new Dog("Buddy");
        myDog.Bark();
    }
}

4. JavaScript

class Dog {
    constructor(name) {
        this.name = name;
    }

    bark() {
        console.log(`${this.name} says Woof!`);
    }
}

// 객체 생성
const myDog = new Dog("Buddy");
myDog.bark();

5. Python

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name} says Woof!")

# 객체 생성
my_dog = Dog("Buddy")
my_dog.bark()

-각 언어에서 클래스는 class 키워드를 사용하여 정의되고, 객체는 해당 클래스의 인스턴스를 생성하여 만듭니다. 각 예제에서 Dog 클래스를 만들고, name 속성을 통해 개의 이름을 설정한 후, bark 메서드를 호출하여 개가 짖는 모습을 출력합니다.

 

 

 

<각 객체지향 언어에서 상속을 구현하는 방법에 대해 간단한 예제>

1. Swift

class Animal {
    func makeSound() {
        print("Animal sound")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Woof!")
    }
}

// 객체 생성
let myDog = Dog()
myDog.makeSound()  // 출력: Woof!

2. Java

class Animal {
    void makeSound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof!");
    }
}

// 객체 생성
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.makeSound();  // 출력: Woof!
    }
}

3. C#

class Animal {
    public virtual void MakeSound() {
        Console.WriteLine("Animal sound");
    }
}

class Dog : Animal {
    public override void MakeSound() {
        Console.WriteLine("Woof!");
    }
}

// 객체 생성
class Program {
    static void Main() {
        Dog myDog = new Dog();
        myDog.MakeSound();  // 출력: Woof!
    }
}

4. JavaScript

class Animal {
    makeSound() {
        console.log("Animal sound");
    }
}

class Dog extends Animal {
    makeSound() {
        console.log("Woof!");
    }
}

// 객체 생성
const myDog = new Dog();
myDog.makeSound();  // 출력: Woof!

5. Python

class Animal:
    def make_sound(self):
        print("Animal sound")

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

# 객체 생성
my_dog = Dog()
my_dog.make_sound()  # 출력: Woof!

위의 예제에서 각 언어는 Animal 클래스를 기본 클래스로 하고, Dog 클래스가 이를 상속받아 makeSound 또는 make_sound 메서드를 오버라이드하여 개의 소리를 출력하는 방법을 보여줍니다.

 

에러 원인: class 안에 있는 stored property는 반드시 초기값이 있어야한다

해결방법>

1.초기값 직접 지정하는 방법

var x : Int
class Man{
    var age : Int = 0
    var weight : Double = 0.0
}

2. 옵셔널로 만드는 방법(자동으로 nill 초기화됨)

var x : Int
class Man{
    var age : Int? //nill로 초기화 되어 있는거임 
    var weight : Double?
}

 

 

인스턴스 만들고 메서드와 프로퍼티 접근

class Man{
    var age : Int = 0
    var weight : Double = 0.0
    func display(){
        print(age,weight)
    }
}
var x : Int
var kim : Man = Man()//클래스명 다음의 괄호는 눈에 보이지 않는 defaultinitializer 나타냄
kim.age = 10

var Kim : Man = Man() //:Man은 생략 가능

var Kim = Man()

class Man{
    var age : Int = 0
    var weight : Double = 0.0
    func display(){
        print("나이: \(age), 몸무게: \(weight)")
    }
}
var kim : Man = Man()//클래스명 다음의 괄호는 눈에 보이지 않는 defaultinitializer 나타냄
print(kim.age)
kim.age = 10
kim.weight = 20.5
print(kim.age,kim.weight)
kim.display()

 

 

<클래스(class or type) 메서드>

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
   print("나이=\(age), 몸무게=\(weight)")
  }
  class func cM(){
    print("cM은 클래스 메서드입니다.")
  }
  static func scM(){
    print("scM은 클래스 메서드(static)")
  }
}
var han : Man = Man()//클래스명 다음의 괄호는 눈에 보이지 않는 defaultinitializer 나타냄
print(han.age)
han.age = 10
han.weight = 20.5
print(han.age,han.weight)
han.display()//인스턴스 메서드는 인스턴스가 호출
Man.cM()//클래스 메서드는 클래스가 호출/class키워드로 만든 클래스메서드는 자식 클래스에서 override가능 함
Man.scM()//클래스 메서드는 클래스가 호출

*designated initializer

class Man{
    var age : Int = 0
    var weight : Double = 0.0
    init(yourAge: Int, yourWeight : Double){
        age = yourAge
        weight = yourWeight
    } //designated initializer
    func display(){
        print("나이:\(age), 몸무게:\(weight)")
    }
}

var han : Man = Man.init(yourAge: 5, yourWeight:10.3)
print(han.age)
han.display()//인스턴스 메서드는 인스턴스가 호출
han.age = 10
han.weight = 20.5
han.display()

 

 

Swift에서 UI 이미지와 관련된 클래스를 사용하는 순서

  1. UIImage: 기본 이미지 클래스로, 이미지 데이터를 저장하고 표시하는 데 사용됩니다.
  2. UIImageView: 이미지를 화면에 표시하는 뷰 클래스입니다. UIImage를 포함하여 화면에 이미지를 보여줍니다.
  3. UIImagePickerController: 사용자에게 사진 라이브러리나 카메라에서 이미지를 선택하게 하는 컨트롤러입니다.
  4. CIImage: Core Image 프레임워크에서 이미지 처리를 위한 클래스입니다. 이미지 필터링 및 변환에 사용됩니다.
  5. PHAsset: Photos 프레임워크에서 사진 및 비디오 자산을 나타내는 클래스입니다. 이미지 및 비디오의 메타데이터에 접근할 수 있습니다.

 

 

 

 

init 다음에 ?가 있으면 failable initializers

 

 

 

class Man{
var age : Int = 0
var weight : Double = 0.0

    init?(age: Int, weight : Double){//? =>failable initializer쓰는 방법
        if age <= 0 || weight <= 0.0 {
            return nil
            
        }else{
            self.age = age
            self.weight = weight
        }
    }
    func display(){
        print("나이:\(age), 몸무게 :\(weight)")
    }
}

var han : Man? = Man(age: 5 ,weight: 10.3)//선언할때 옵셔널 man형으로 선언해야한다 (?,! 붙이기)
han!.display()
han!.age = 10
han!.weight = 20.5

 

1,2번 많이 씀

 

class Man{
var age : Int = 0
var weight : Double = 0.0

    init?(age: Int, weight : Double){//? =>failable initializer쓰는 방법
        if age <= 0 || weight <= 0.0 {
            return nil
            
        }else{
            self.age = age
            self.weight = weight
        }
    }
    func display(){
        print("나이:\(age), 몸무게 :\(weight)")
    }
}

var han : Man? = Man(age: 0 ,weight: 10.3)
if let han{// 옵셔널 풀린 han
    han.display()
}//좋은 방법

-옵셔널 선언하고~ 풀어주는 방법

class Man{
var age : Int = 0
var weight : Double = 0.0

    init?(age: Int, weight : Double){//? =>failable initializer쓰는 방법
        if age <= 0 || weight <= 0.0 {
            return nil
            
        }else{
            self.age = age
            self.weight = weight
        }
    }
    func display(){
        print("나이:\(age), 몸무게 :\(weight)")
    }
}

if let han = Man(age: 0 ,weight: 10.3){
    han.display()
}

 

class Man {
    var age: Int // 나이를 저장할 변수
    var weight: Double // 몸무게를 저장할 변수
    
    // 나이와 몸무게를 출력하는 메서드
    func display() {
        print("나이=\(age), 몸무게=\(weight)")
    }
    
    // 초기화 메서드, 나이가 0 이하일 경우 nil 반환
    init?(age: Int, weight: Double) {
        if age <= 0 {
            return nil // 나이가 0 이하이면 nil을 반환하여 인스턴스 생성을 실패시킴
        } else {
            self.age = age // 나이가 유효하면 초기화
        }
        self.weight = weight // 몸무게 초기화
    }
}

// 1-1. 옵셔널 형으로 선언하여 kim 변수 생성
var kim: Man? = Man(age: 1, weight: 3.5)

// 1-2. 옵셔널 바인딩을 사용하여 kim의 값을 안전하게 언래핑
if let kim1 = kim {
    kim1.display() // kim1이 nil이 아닐 경우 display 메서드 호출
}

// 2. 인스턴스 생성과 동시에 옵셔널 바인딩
if let kim2 = Man(age: 2, weight: 5.5) {
    kim2.display() // kim2가 nil이 아닐 경우 display 메서드 호출
}

// 3. 인스턴스 생성하면서 바로 강제 언래핑
var kim3: Man = Man(age: 3, weight: 7.5)! // Man 인스턴스가 nil이 아님을 확신하고 강제 언래핑
kim3.display() // kim3의 display 메서드 호출

// 4. 옵셔널 인스턴스를 사용시 강제 언래핑
var kim4: Man? = Man(age: 4, weight: 10.5) // 옵셔널 형으로 kim4 생성
kim4!.display() // kim4가 nil이 아님을 확신하고 강제 언래핑하여 display 메서드 호출

 

 

상속, 오버라이딩 , failable initializers 이 포함이 된 간단한 소스 예제

// 기본 클래스
class Animal {
    var name: String // 동물의 이름
    
    // failable initializer: 이름이 비어있으면 nil 반환
    init?(name: String) {
        if name.isEmpty {
            return nil // 이름이 비어있으면 초기화 실패
        }
        self.name = name // 이름 초기화
    }
    
    // 기본 동물 소리 메서드
    func makeSound() {
        print("동물이 소리를 냅니다.")
    }
}

// 서브 클래스
class Dog: Animal {
    
    // 오버라이드: Dog 클래스의 소리 메서드
    override func makeSound() {
        print("\(name)는 멍멍하고 짖습니다.") // Dog의 소리
    }
}

// 사용 예시

// 1. failable initializer 사용 예
if let myDog = Dog(name: "Buddy") { // 초기화 성공
    myDog.makeSound() // 출력: Buddy는 멍멍하고 짖습니다.
} else {
    print("이름이 비어 있습니다.")
}

// 2. failable initializer 실패 예
if let myCat = Animal(name: "") { // 초기화 실패
    myCat.makeSound()
} else {
    print("이름이 비어 있습니다.") // 출력: 이름이 비어 있습니다.
}

 

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 기초 프로그래밍 10주차  (0) 2024.11.06
iOS 기초 프로그래밍 9주차  (0) 2024.10.30
iOS 프로그래밍 기초 6주  (0) 2024.10.15
iOS프로그래밍 기초 5주차  (0) 2024.10.03
iOS프로그래밍 4주차  (0) 2024.09.25

함수 기본 개념

  • 정의: 함수는 특정 작업을 수행하는 코드 블록.
  • 매개변수 (Parameters): 함수 정의에서 사용되는 변수로, 함수가 실행될 때 데이터를 받을 자리표시자.
  • 인수 (Arguments): 함수 호출 시 실제로 전달되는 값 

매개변수와 인수의 차이

  • 매개변수: 함수 정의에서 사용되는 변수
  • 인수: 함수 호출 시 전달되는 실제 값

반환값

  • 함수는 작업이 끝난 후 값을 반환할 수 있으며, 이 반환값은 다른 연산에 사용할 수 있음.

메서드와 함수의 차이

  • 메서드 (Method): 특정 클래스, 구조체 또는 열거형 내에 정의된 함수로, 객체 지향 프로그래밍에서 사용.

 

iOS 테이블뷰에서 많이 사용하는 메서드

  1. tableView(_:numberOfRowsInSection:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    • 기능: 지정된 섹션에 표시할 행의 수를 반환합니다. 필수적으로 구현해야 하는 메서드입니다.
  2. tableView(_:cellForRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    • 기능: 지정된 행에 대한 셀을 구성하여 반환합니다. 셀의 내용을 설정합니다.
  3. tableView(_:didSelectRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    • 기능: 사용자가 특정 행을 선택했을 때 호출됩니다. 선택된 행에 대한 동작을 정의합니다.
  4. tableView(_:heightForRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    • 기능: 특정 행의 높이를 반환합니다. 동적으로 높이를 조정할 수 있습니다.
  5. tableView(_:willDisplay:forRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
    • 기능: 특정 셀이 화면에 표시되기 직전에 호출됩니다. 셀의 스타일 조정이나 애니메이션을 적용할 수 있습니다.
  6. numberOfSections(in:)
    • 메서드 자료형: func numberOfSections(in tableView: UITableView) -> Int
    • 기능: 테이블뷰의 섹션 수를 반환합니다. 기본적으로 1을 반환하지만, 여러 섹션을 사용할 수 있습니다.
  7. tableView(_:canEditRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
    • 기능: 특정 행이 편집 가능한지 여부를 반환합니다. 행 편집 기능을 활성화할 때 사용됩니다.
  8. tableView(_:commit:forRowAt:)
    • 메서드 자료형: func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
    • 기능: 사용자가 행을 편집할 때 호출됩니다. 삭제, 추가 등의 동작을 처리합니다.

Guard 문

  • 도입: Swift 2에 도입된 구문
  • 기능: 조건식이 거짓(false)일 경우 실행되는 else 절을 반드시 포함해야 함.
    • else 절 내의 코드는 현재 코드 흐름을 빠져나갈 수 있는 구문(return, break, continue, throw 등)을 포함해야 하며, 다른 함수를 호출할 수도 있음.

기본 구조

guard <불리언 표현식> else {
    // 거짓일 경우 실행될 코드
    <코드 블록을 빠져 나갈 구문>
}
// 참일 경우 실행되는 코드는 이곳에 위치
  • 조기 출구(early exit): 특정 조건에 맞지 않을 경우 현재의 함수나 반복문에서 빠져나가는 전략을 제공.

Guard~let 활용

  • 사용 범위: return, break, continue, throw 등이 가능한 상황에서 사용 가능.
  • 가독성: 옵셔널 바인딩을 통해 다중 if~else를 피하고, 코드 가독성을 높임.
  • 함수 외부에서의 사용: guard let으로 언래핑된 변수는 guard 문 밖에서도 사용할 수 있음. 반면, if 문으로 언래핑된 변수는 그 안에서만 사용 가능.

guard~let의 활용

var x = 1
while true {
guard x < 5 else { break }
print(x) 
x = x + 1
}
  1. 조건식이 거짓일 때: guard 문이 실행되어 else 블록의 코드가 수행되고, 지정된 제어문으로 빠져나감.
  2. 조건식이 참일 때: 이후 코드가 정상적으로 실행됨.

 

 

 

guard let~else로 옵셔널 바인딩

func multiplyByTen(value: Int?) {
guard let number = value else {//조건식이 거짓(nil)일 때 else 블록 실행
print("nil")
return
}
print(number*10) //조건식이 참일 때 실행, 주의 : number를 guard문 밖인 여기서도 사용 가능
}
multiplyByTen(value: 3) //30
multiplyByTen(value: nil)//nil
multiplyByTen(value: 10)//100

 

 

if~let vs. guard~let

func printName(firstName:String, lastName:String?){
// if let
if let lName = lastName { // lastName이 nil이 아니면
print(lName,firstName)
}
else{print("성이 없네요!")
}
// guard let
//guard let lName= lastName else { // lastName이 nil이면
//print("성이 없네요!")
//return // early exit
//}
//print(lName,firstName)
}
printName(firstName:"길동", lastName:"홍")//홍 길동
printName(firstName: "길동", lastName:nil)//성이 없네요!

 

 

디폴트 매개변수(아규먼트) 정의하기

func sayHello(count: Int, name: String = "길동") -> String {
    return ("\(name), 너의 번호는 \(count)")
}

var message = sayHello(count: 10, name: "소프트")
// 결과: "소프트, 너의 번호는 10"

message = sayHello(count: 100)
print(message) // 결과: "길동, 너의 번호는 100"

 

 

함수로부터 여러 개의 결과 반환하기

func converter(length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
let yards = length * 0.0277778
let centimeters = length * 2.54
let meters = length * 0.0254
return (yards, centimeters, meters)
}
var lengthTuple = converter(length:10)
print(lengthTuple) //(yards: 0.277778, centimeters: 25.4, meters: 0.254)
print(lengthTuple.yards) //0.277778
print(lengthTuple.centimeters) //25.4
print(lengthTuple.meters) //0.254

 

 

 

2개의 정수를 입력받아 가감제 리턴

import Foundation

func sss(x: Int, y: Int) -> (sum: Int, sub: Int, mul: Int, div: Double, mod: Int) {
    let sum = x + y
    let sub = x - y
    let mul = x * y
    let div = Double(x) / Double(y) // 같은 자료형만 연산 가능
    let mod = x % y // 나머지 연산
    return (sum, sub, mul, div, mod)
}

var result = sss(x: 10, y: 3)
print(result.sum) // 13
print(result.sub) // 7
print(result.mul) // 30
print(result.div) // 3.33333333333333
print(result.mod) // 1

// 소수점 3자리로 출력
String(format: "%.3f", result.div)////string은 구조체라서 import Foundation써야함
// 3.333

// 함수의 자료형 출력
print(type(of: sss)) // (Int, Int) -> (sum: Int, sub: Int, mul: Int, div: Double, mod: Int)

 

가변 매개변수(variadic parameter)

func displayStrings(strings: String...) //string... =>string이 몇개가 와도 관계가 없다
{
for string in strings {
print(string)
}
}
displayStrings(strings: "일", "이", "삼", "사")
displayStrings(strings: "one", "two")
displayStrings(strings: "one", "two","a","b","c")

 

과제 : 가변 매개변수(variadic parameter) 임의의 개수의 정수 값의 합을 출력하는 함수를 작성하여 호출

func add(numbers:Int...){
    var sum:Int=0
    for num in numbers{
        sum += num
    }
    print(sum)
}

add(numbers:1,2,3) //6
add(numbers:2,2,2,2,2) //10
add(numbers:1,1,1,1,1,1,1,1,1,1) //10
add(numbers:1,1,1,1) //4

 

Swift 3에서는 inout의 위치가 바뀜( call by address하고 싶은 매개변수의 자료형 앞에 inout 씀)

var myValue = 10
func doubleValue (value: inout Int) -> Int {
value += value
return(value)
}

print(myValue)//10
print(doubleValue(value : &myValue)) //20
print(myValue)//20

Swift 문자열 서식(swift string format 자리수)

import Foundation
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")

 

함수 : 일급 객체 실습

// num에 1을 더하는 함수
func up(num: Int) -> Int {
    return num + 1
}

// num에서 1을 빼는 함수
func down(num: Int) -> Int {
    return num - 1
}

// up 함수를 toUp 변수에 할당
let toUp = up
// up 함수 호출
print(up(num: 10)) // 결과: 11
// toUp 변수 호출
print(toUp(10)) // 결과: 11

// down 함수를 toDown 변수에 할당
let toDown = down

// 함수 타입을 매개변수로 받아 결과를 출력하는 함수
func upDown(Fun: (Int) -> Int, value: Int) {
    let result = Fun(value)
    print("결과 = \(result)")
}

// toUp(10) 호출
upDown(Fun: toUp, value: 10) // 결과: 결과 = 11
// toDown(10) 호출
upDown(Fun: toDown, value: 10) // 결과: 결과 = 9

// Bool 값을 기반으로 함수를 결정하여 반환하는 함수
func decideFun(x: Bool) -> (Int) -> Int {
    if x {
        return toUp // true일 경우 toUp 반환
    } else {
        return toDown // false일 경우 toDown 반환
    }
}

// decideFun 호출하여 true일 경우 toUp을 반환
let r = decideFun(x: true) // let r = toUp
print(type(of: r)) // 결과: (Int) -> Int
// r(10) 호출
print(r(10)) // 결과: 11 (toUp(10) 호출)

 

 

first class object : (1)함수를 변수에 저장 가능

// 인치를 피트로 변환하는 함수
func inchesToFeet(inches: Float) -> Float {
    return inches * 0.0833333 // 1인치는 약 0.0833 피트
}

// inchesToFeet 함수를 toFeet 변수에 할당하여 함수처럼 사용
let toFeet = inchesToFeet

// toFeet 함수를 사용하여 인치 값을 피트로 변환
let result = toFeet(10) // 10 인치를 피트로 변환
print(result) // 결과 출력

 

클로저 표현식

// 두 정수를 더하는 함수
func add(x: Int, y: Int) -> Int {
    return (x + y)
}
print(add(x: 10, y: 20)) // 결과: 30
print(type(of:add))

// 클로저 정의
let add1 = { (x: Int, y: Int) -> Int in
    return (x + y) // 중괄호가 필요
}
print(add1(10, 20)) // 결과: 30
print(type(of:add1))

 

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 기초 프로그래밍 9주차  (0) 2024.10.30
iOS 프로그래밍 기초 7주차  (0) 2024.10.16
iOS프로그래밍 기초 5주차  (0) 2024.10.03
iOS프로그래밍 4주차  (0) 2024.09.25
iOS프로그래밍 기초 2주차  (0) 2024.09.11

<복습 간단 정리>

1. 변수 및 데이터 타입

  • 변수 선언
    • 기본: var myNumber = 10 (타입 추론)
    • 명시적: var myNumber: Int = 10 (타입 명시)
  • 데이터 타입
    • Int: 정수형
    • Float: 단정도 부동소수점
    • Double: 배정도 부동소수점
    • Bool: 불리언 (true/false)
    • Character: 단일 문자
    • String: 문자열
    • Void: 반환값 없음

2. 예외 처리

  • 공백 처리 주의: var x: Int와 같이 '=' 양쪽에 일관된 공백 필요.

3. 정수 데이터 타입

  • 부호 있는 정수: Int, Int8, Int16 등
  • 부호 없는 정수: UInt8, UInt16 등
  • Int 권장: 플랫폼에 맞는 크기 사용
  • 최솟값/최댓값: Int.min, Int.max

4. 부동 소수점 데이터 타입

  • Double: 64비트, 소수점 15자리 정확도
  • Float: 32비트, 소수점 6자리 정확도

5. 변수와 상수

  • 변수 (var): 값 변경 가능
  • 상수 (let): 값 변경 불가능
  • 튜플: 여러 값을 하나로 묶음

6. 연산자

  • 증가/감소: x += 1, x -= 1
  • 비교 연산자: ==, !=, >, <, >=, <=
  • 불리언 논리 연산자: !, &&, ||

7. 반복문

  • for-in: 컬렉션이나 범위를 반복
  • while: 조건이 true일 때 반복
  • repeat-while: 몸체를 최소 한 번 실행
  • break: 반복문 조기 종료
  • continue: 다음 반복으로 이동

8. 조건문

  • if문: 불리언 조건에 따라 코드 실행
  • if-else: 참/거짓에 따라 다른 코드 실행
  • switch-case: 특정 값에 대한 여러 경우 처리

9. 옵셔널 타입

  • 정의: nil을 가질 수 있는 타입
  • 선언: var myVar: Int?
  • 강제 언래핑: myVar! (nil일 경우 오류 발생)
  • 옵셔널 바인딩: 안전하게 언래핑 (if let 사용)

 

<함수와 메서드>

-함수를 선언하는 방법

func sayHello() -> Void { // -> Void생략 가능
     print("Hello")
     
 }
 sayHello()

 

 

func add(x: Int, y: Int) -> Int{                  
return(x+y)//return x+y (괄호 없어도 됨)
 }
 func sayHello()->Void
{
    print("Hello")
}
 print(type(of:sayHello))//()->() Void는 빈 튜플플
 print(add(x:10, y:20))//30
 print(type(of:add))//자료형 출력력,(Int, Int)-> Int

 

-내부매개변수(parameter name) 이름과 외부 매개변수(argument label) 이름

func add(first x: Int,second y: Int) -> Int{                  
return(x+y)//계산은 parameter name
 }

 print(add(first:10, second:20))//30, 호출할때는 argument label사용
 print(type(of:add))//자료형 출력력,(Int, Int)-> Int

-

func add( _ x: Int, with y: Int) -> Int{                  
return(x+y)
 }

 print(add(10, with:20))//30,

시험 잘 나옴

func add( _ x: Int, with y: Int) -> Int{  
print(#function)///add(_:whith:)
return(x+y)
 }

 print(add(10, with:20))/30
func add(_ x: Int, with y: Int) -> Int {  
    print(#function)//add(:with:)
    return x + y
}

print(add(10, with: 20))//30

func add1(x: Int, y: Int) -> Int { 
    print(#function)//add1(x:y:)
    return x + y 
}

print(add1(x: 10, y: 20))//30
func add2(first x: Int, second y: Int) -> Int { 
    print(#function)//add2(first:second:)
    return x + y 
}

print(add2(first: 10, second: 20))//30
func add3(_ x: Int, _ y: Int) -> Int { 
    print(#function)//add3(_:_:)
    return x + y 
}

print(add3(10,20))//30
// 1. multiplyByTen 함수
func multiplyByTen(value: Int?) {
    guard let number = value else {
        print("nil")
        return
    }
    print(number * 10)
}

multiplyByTen(value: 3)   // 30
multiplyByTen(value: nil)  // nil
multiplyByTen(value: 10)   // 100

// 2. printName 함수
func printName(firstName: String, lastName: String?) {
    // if let
    if let lName = lastName {
        print(lName, firstName)
    } else {
        print("성이 없네요!")
    }
    
    // guard let
    guard let lName = lastName else {
        print("성이 없네요!")
        return
    }
    print(lName, firstName)
}

printName(firstName: "길동", lastName: "홍")  // 홍 길동
printName(firstName: "길동", lastName: nil)  // 성이 없네요!

// 3. sayHello 함수
func sayHello(count: Int, name: String = "길동") -> String {
    return ("\(name), 너의 번호는 \(count)")
}

print(sayHello(count: 1))  // 길동, 너의 번호는 1
print(sayHello(count: 2, name: "철수"))  // 철수, 너의 번호는 2

// 4. converter 함수
func converter(length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
    let yards = length * 0.0277778
    let centimeters = length * 2.54
    let meters = length * 0.0254
    return (yards, centimeters, meters)
}

var lengthTuple = converter(length: 10)
print(lengthTuple)  // 길이를 변환한 튜플 출력
print(lengthTuple.yards)        // 0.277778 
print(lengthTuple.centimeters)  // 25.4 
print(lengthTuple.meters)       // 0.254 

// 5. sss 함수
func sss(x: Int, y: Int) -> (sum: Int, sub: Int, div: Double) {
    let sum = x + y
    let sub = x - y
    let div = Double(x) / Double(y) // 같은 자료형만 연산 가능
    return (sum, sub, div)
}

var result = sss(x: 10, y: 3)
print(result.sum)  // 13 // 합계 출력
print(result.sub)  // 7 // 차이 출력
print(result.div)  // 3.3333333333333335 // 나눗셈 결과 출력

// 6. displayStrings 함수
func displayStrings(strings: String...) {
    for string in strings {
        print(string)
    }
}
displayStrings(strings: "일", "이", "삼", "사")  // 출력값: 일 이 삼 사
displayStrings(strings: "one", "two")  // 출력값: one two
/////////
var myValue = 10
func doubleValue(value: inout Int) -> Int {
    value += value
    return(value)
}
print(myValue)  // 출력값: 10
print(doubleValue(value: &myValue))  // 출력값: 20
print(myValue)  // 출력값: 20
////////
let weight = 60.0
let height = 170.0
let bmi = weight / (height * height * 0.0001) // kg/m*m 
var body = ""

if bmi >= 40 {
    body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
    body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
    body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
    body = "정상"
} else {
    body = "저체중" 
}

print("BMI:\(bmi), 판정:\(body)")  // 출력값: BMI:20.761245674740486, 판정: 정상

// 9. calcBMI 함수
import Foundation
func calcBMI(weight: Double, height: Double) {  // Void형
    let bmi = weight / (height * height * 0.0001) // kg/m*m 
    let shortenedBmi = String(format: "%.1f", bmi) 
    switch bmi {
    case 0.0..<18.5:
        print("BMI:\(shortenedBmi),판정:저체중")
    case 18.5..<25.0:
        print("BMI:\(shortenedBmi),판정:정상")
    case 25.0..<30.0:
        print("BMI:\(shortenedBmi),판정:1단계 비만")
    case 30.0..<40.0:
        print("BMI:\(shortenedBmi),판정:2단계 비만")
    default:
        print("BMI:\(shortenedBmi),판정:3단계 비만") 
    }
}

calcBMI(weight: 62.5, height: 172.3) // BMI:21.0, 판정:정상 // BMI 계산 및 판정 출력

 

 

 

 

 

출처: 한성현 교수님 수업자료

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Swift' 카테고리의 다른 글

iOS 프로그래밍 기초 7주차  (0) 2024.10.16
iOS 프로그래밍 기초 6주  (0) 2024.10.15
iOS프로그래밍 4주차  (0) 2024.09.25
iOS프로그래밍 기초 2주차  (0) 2024.09.11
<1주차>iOS 프로그래밍 기초  (2) 2024.09.04

<프로그래밍 언어에서 가장 많이 사용하는 연산자>

  1. 대입 연산자 (=): 변수에 값을 할당하는 데 사용됩니다.
  2. 산술 연산자 (+, -, *, /, %): 기본적인 수학 연산을 수행합니다.
  3. 비교 연산자 (==, !=, <, >, <=, >=): 값들을 비교하여 불리언 결과를 반환합니다.
  4. 논리 연산자 (&&, ||, !): 논리적인 계산을 수행합니다.
  5. 증감 연산자 (++, --): 변수의 값을 증가시키거나 감소시킵니다.

 

<증가 연산자와 감소 연산자>

Swift에서는 ++와 -- 연산자가 없음.

  • 증가: 변수 += 1
  • 감소: 변수 -= 1

<비교 연산자>

== (값 비교):

  • 두 값이 동일한지를 비교합니다.

=== (참조 비교):

  • 두 클래스 인스턴스가 동일한 객체를 참조하는지를 비교합니다.
  • 값이 아닌 메모리 주소를 비교합니다.

 

범위연산자

 

시험(중요)

 

 

클래스로 부터 객체를 만드는 소스 예시

C++

#include <iostream>
using namespace std;

class Person {
public:
    string name;
    int age;

    Person(string n, int a) : name(n), age(a) {}
};

int main() {
    Person person("홍길동", 30);
    cout << person.name << "의 나이는 " << person.age << "세입니다." << endl;
    return 0;
}

Java

class Person {
    String name;
    int age;

    Person(String n, int a) {
        name = n;
        age = a;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("홍길동", 30);
        System.out.println(person.name + "의 나이는 " + person.age + "세입니다.");
    }
}

Python

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("홍길동", 30)
print(f"{person.name}의 나이는 {person.age}세입니다.")

JavaScript

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

const person = new Person('홍길동', 30);
console.log(`${person.name}의 나이는 ${person.age}세입니다.`);

 

 

xcode 정렬: ctrl+i

 

1~9출력

for i in 0..<10 {
print(i)
}
for i in 0...9 {
print(i)
}

 

 

이름 9번 출력

for _ in 0...9 {//= 0; i < 10; i+=1 {
print("kdh")
}

 

// 0부터 9까지 반복
for i in 0...9 {
    // i에 1을 더한 값을 출력하고 "kdh"라는 문자열을 붙임
    print("\(i + 1): kdh")
}

 

xcode 주석: commend +/

 

<배열의 항목 접근>

// 문자열 배열을 정의
let names = ["A", "B", "C", "D"]

// 배열의 인덱스 1부터 끝까지 반복
for name in names[1...] {
    // 현재 이름을 출력
    print(name)
}

 

 

<if문>

// 변수 x를 10으로 초기화
var x = 10

// x가 5보다 큰지 확인
if x > 5 {
    // 조건이 참일 경우 메시지를 출력
    print("5보다 큽니다")
}

 

 

 

 

swift제어문 예시

1. 조건문

 

if 

let number = 10

if number > 5 {
    print("5보다 큽니다") // 조건이 참일 때 실행
}

 

if-else 

let number = 3

if number > 5 {
    print("5보다 큽니다")
} else {
    print("5보다 작거나 같습니다") // 조건이 거짓일 때 실행
}

 

switch 

let fruit = "사과"

switch fruit {
case "바나나":
    print("바나나입니다.")
case "사과":
    print("사과입니다.") // 해당하는 케이스 실행
default:
    print("다른 과일입니다.")
}

 

2. 반복문

for 

for i in 1...5 { // 1부터 5까지 반복
    print(i) // 1, 2, 3, 4, 5 출력
}

while 

var count = 0

while count < 3 {
    print("Count는 \(count)") // Count는 0, 1, 2 출력
    count += 1
}

repeat-while 

var count = 0

repeat {
    print("Count는 \(count)") // Count는 0, 1, 2 출력
    count += 1
} while count < 3

3. 제어 흐름 변경

break 

for i in 1...5 {
    if i == 3 {
        break // i가 3이면 반복문 종료
    }
    print(i) // 1, 2 출력
}

continue 

for i in 1...5 {
    if i == 3 {
        continue // i가 3이면 다음 반복으로 넘어감
    }
    print(i) // 1, 2, 4, 5 출력
}

 

 

optional 

(implicitly unwrapped)

var x : Int = 10
print(x)//10
var y : Int? = 20 //optional 변수 (자료형 뒤에 ?)
print(y!)//20 //optional 변수의 값을 저장할 경우 변수 뒤에 !해야됨/ 안하면 => 출력값: Optional(20)

 

nil(값이 없다)

var y : Int? // 초기값 없앰
print(y)//nil(값이 없다)

 

 

// 변수 x를 Int 타입으로 선언하고 10으로 초기화
var x: Int = 10
print(x) // x의 값을 출력: 10

// 변수 y를 Int? (옵셔널) 타입으로 선언하고 20으로 초기화
var y: Int? = 20

// y의 값을 강제로 언래핑하여 1을 더한 후 다시 y에 할당
y = y! + 1 // y의 값이 nil이 아닐 때만 안전하게 언래핑 가능
print(y) // y의 값을 출력: 21

 

 

 

<optional binding(여러 옵셔널 값 동시에 언래핑)>

var x : Int?
//x = 10
if x != nil {
print(x!)
}
else {
    print("nil")//nil
}

var x : Int?
x = 10
if let x {
    print(x)//10
}

 

var x : Int? = 10
var y : Int! = 20
var z : Int = 1
print(x,y,z)
z = x!
print(z)
z = y!
print(z)
if let x, let y {
    print(x,y)
}

 

사용자가 사용하는 것 같지 않으면 자동으로 풀어버림

var x : Int? = 10
var y : Int! = 20
var z : Int = 1
print(x,y,z)
z = x! + 1
print(z)
z = y + 1
print(z)
if let x, let y {
    print(x,y)
}

var x : Int? //= 10
var y : Int = 0
y = x ?? 1
print(x,y)//nil 1

swift에서 optional 푸는 방법을 많이 사용하는 순서

1. 강제 언래핑 (Force Unwrapping)

! 연산자를 사용하여 옵셔널 값을 강제로 언래핑합니다. 주의: 값이 nil일 경우 런타임 오류가 발생합니다

let optionalValue: Int? = 10
let value = optionalValue! // 강제 언래핑

2. 옵셔널 바인딩 (Optional Binding)

if let 또는 guard let을 사용하여 옵셔널 값을 안전하게 언래핑합니다. 값이 nil이 아닐 경우에만 실행됩니다.

if let unwrappedValue = optionalValue {
    print(unwrappedValue) // 값이 있을 경우 실행
}
------
guard let unwrappedValue = optionalValue else {
    return // 값이 nil일 경우 함수 종료
}
print(unwrappedValue)

3. nil 병합 연산자 (Nil Coalescing Operator)

?? 연산자를 사용하여 옵셔널 값이 nil일 경우 기본 값을 제공합니다.

let value = optionalValue ?? 0 // optionalValue가 nil이면 0을 사용

4. 옵셔널 체이닝 (Optional Chaining)

옵셔널 값의 속성이나 메소드를 호출할 때 사용합니다. 값이 nil이면 호출이 무시됩니다.

 

let length = optionalValue?.description.count // nil이면 length도 nil이 됨

5. 옵셔널 배열 (Optional Array)

배열의 요소로 옵셔널을 사용하고, compactMap을 이용하여 nil이 아닌 값만 필터링할 수 있습니다.

let optionalArray: [Int?] = [1, nil, 2, nil, 3]
let values = optionalArray.compactMap { $0 } // [1, 2, 3]

 

출처: 한성현 교수님 수업자료

'Swift' 카테고리의 다른 글

iOS 프로그래밍 기초 7주차  (0) 2024.10.16
iOS 프로그래밍 기초 6주  (0) 2024.10.15
iOS프로그래밍 기초 5주차  (0) 2024.10.03
iOS프로그래밍 기초 2주차  (0) 2024.09.11
<1주차>iOS 프로그래밍 기초  (2) 2024.09.04

데이터 과학

통계학, 데이터 분석, 머신러닝 등을 활용하여 문제 해결을 위한 최적의 솔루션을 창출하는 분야

 

데이터 분석

  • 기술통계: 데이터를 정량화하고 요약하는 기법.
  • 탐색적 데이터 분석: 데이터의 주요 특징을 시각적으로 표현하고 분석하는 방법.
  • 가설검정: 데이터를 기반으로 특정 가정의 합당성을 평가하는 통계적 방법.

 

구글 코랩 실행 단축키

• Ctrl + Enter : 해당 셀을 실행하고 커서를 해당 셀에 두는 경우(결과 값만)

• Shift + Enter : 해당 셀을 실행하고 커서를 다음 셀로 이동

• Alt + Enter : 해당 셀을 실행하고 셀을 삽입한 후 커서를 삽입한 셀로 넘기는 경우

 

구글 코랩 셀조작 단축

• Ctrl + M A = 코드 셀 위에 삽입

•Ctrl + M B = 코드 셀 아래 삽입

•Ctrl + M D = 셀 지우기

• Ctrl + M Y = 코드 셀로 변경

• Ctrl + M M = 텍스트 셀로 변경

•Ctrl + M Z = 실행 취소

 

 

 

 

출처: 고수정 교수님 수업자료 참고

'데이터 분석' 카테고리의 다른 글

상관관계분석  (0) 2024.11.30
데이터 전처리  (0) 2024.11.26
웹 크롤링 기초  (0) 2024.11.23
python기초 정리  (0) 2024.09.21

 

a = 5
for i in range(1,4):
print(str(a))

-연산자

 

조건문

if:  조건이 참이면 실행

if~else: 조건이 참이면 if이후만 실행하고 거짓이면 else이후만 실행

if~elif~else 여러조건을 if와 elif에 각각 할당하여 조건이 참인 부분만 실행하고 만약 모두 거짓이면 else 이후만 실행

a = 5
if a == 5:
print(‘맞음’)

 

반복문

-while문 : 주어진 조건이 참인 동안 계속 반복, 조건이 거짓이 되면 반복 종료

a = 5
i=1
#3번 반복하기
while i <= 3:
print(str(a))
i += 1

-for in range 문: 반복할 횟수가 정해져 있을떄 주로 사용

a = 5
for i in range(1,4):
print(str(a))

콜렉션 자료형

-데이터를 효율적으로 처리하기 위한 일종의 자료구조

튜플(Tuple)

-순서가 있는 데이터의 목록

tuple_1 = 1, 2, 3 #(1,2,3)
print(tuple_1, type(tuple_1)) #(1,2,3) <class 'tuple'>
print(len(tuple_1)) #튜플의 크기 ,3

세트

-데이터 중복을 허용하지 않으며, 데이터 입력 순서는 중요하지 않음

set_1 = {1, '가', '나', 1, 2}
set_2 = set({1, 2, 3, 1})
print(set_1) #{1, '가', 2, '나’} 
print(set_2) #{1, 2, 3}

 

리스트: 데이터를 다루기 편리하여 매우 자주 활용되는 콜렉션 자료형

append  추가

insert 삽입

remove삭제

sort정렬

#리스트 생성하기
list_1 = [1, 2, 3]
print(list_1) #[1,2,3]
#리스트 수정
list_1.append(100)
list_1.remove(1)
list_1.insert(0,100) #인덱스 0
print(list_1) #[100,2,3,100]

 

딕셔너리 

- 단어 그대로 사전과 같은 자료형으로 값과 키가 한 쌍을 이루어 요소가 된는 자료구조

-신속하게 값을 찾아내야 할 때 사용

#딕셔너리 생성하기
dic_1 ={'birth':1990}
print(dict_1['birth]) #1990
#키와 값 추가하기
dict_1['weight'] = 60.5
print(dict_1) #{'birth': 1990, 'weight': 60.5}

 

함수: (≒수학에서의 함수)기능을 정의한 가장 작은 단위

# 함수 정의
def sum1(a): #def는 함수를 정의할때 사용/ sum1은 함수이름/ a는 함수가 입력받는 매개변수
for i in a:
print(i)
list_a = [1, 2]
sum1(list_a) # 호출

 

 

 

 

 

출처: 고수정 교수님 수업자료

'데이터 분석' 카테고리의 다른 글

상관관계분석  (0) 2024.11.30
데이터 전처리  (0) 2024.11.26
웹 크롤링 기초  (0) 2024.11.23
1. 데이터 분석  (0) 2024.09.21

+ Recent posts