iOS 프로그래밍 11주차
출처:
- Do it! 스위프트로 아이폰 앱 만들기 입문, 송호정, 이범근 저,이지스퍼블리싱, 2023년 01월 20일
- https://www.yes24.com/Product/Goods/116918114
- https://github.com/doitswift/example
----------------------------------------
02 Hello World 앱 만들며 Xcode에 완벽 적응하기
03 원하는 이미지 화면에 출력하기 - 이미지 뷰
04 데이트 피커 사용해 날짜 선택하기
05 피커 뷰 사용해 원하는 항목 선택하기
06 얼럿 사용해 경고 표시하기
07 웹 뷰로 간단한 웹 브라우저 만들기
08 맵 뷰로 지도 나타내기
09 페이지 이동하기 - 페이지 컨트롤
10 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기
11 내비게이션 컨트롤러 이용해 화면 전환하기
12 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기
13 음악 재생하고 녹음하기
14 비디오 재생 앱 만들기
15 카메라와 포토 라이브러리에서 미디어 가져오기
16 코어 그래픽스로 화면에 그림 그리기
17 탭과 터치 사용해 스케치 앱 만들기
18 스와이프 제스처 사용하기
19 핀치 제스처 사용해 사진을 확대/축소하기
--------------------------------------------------------------------------------------
09
// UIKit 프레임워크를 불러옵니다. UI 요소를 사용하기 위해 필요합니다.
import UIKit
// 이미지 파일 이름을 저장하는 배열을 정의합니다.
var images = [ "01.png", "02.png", "03.png", "04.png", "05.png", "06.png" ]
// ViewController 클래스는 UIViewController를 상속합니다.
class ViewController: UIViewController {
// UIImageView와 UIPageControl 아웃렛을 연결합니다.
@IBOutlet var imgView: UIImageView!
@IBOutlet var pageControl: UIPageControl!
// viewDidLoad 메서드는 뷰가 로드될 때 호출됩니다.
override func viewDidLoad() {
super.viewDidLoad()
// 추가적인 설정을 여기서 수행합니다.
// 페이지 컨트롤의 페이지 수를 이미지 배열의 개수로 설정합니다.
pageControl.numberOfPages = images.count
// 초기 현재 페이지를 3으로 설정합니다.
pageControl.currentPage = 3
// 페이지 인디케이터의 색상을 흰색으로 설정합니다.
pageControl.pageIndicatorTintColor = UIColor.white
// 현재 페이지 인디케이터의 색상을 파란색으로 설정합니다.
pageControl.currentPageIndicatorTintColor = UIColor.blue
// 이미지 뷰의 초기 이미지를 이미지 배열의 첫 번째 이미지로 설정합니다.
imgView.image = UIImage(named: images[0])
}
// pageControl의 값이 변경될 때 호출되는 액션 메서드입니다.
@IBAction func pageChange(_ sender: UIPageControl) {
// 현재 페이지에 해당하는 이미지를 이미지 뷰에 표시합니다.
imgView.image = UIImage(named: images[pageControl.currentPage])
}
}
10. 탭 바 컨트롤러
화면 밑에 탭으로 여러개의 화면으로 빨리 진행할 수 있도록 하는 컨트롤러이다.
11.
네비게이션 컨트롤러
12
// UIKit 프레임워크를 불러옵니다.
import UIKit
// 테이블에 표시할 항목과 해당 이미지 파일 이름을 저장하는 배열을 정의합니다.
var items = ["책 구매", "철수와 약속", "스터디 준비하기"]
var itemsImageFile = ["cart.png", "clock.png", "pencil.png"]
// TableViewController 클래스는 UITableViewController를 상속받아 테이블 뷰를 관리합니다.
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) {
tvListView.reloadData()
}
// MARK: - Table view data source
// 섹션 수를 반환합니다. 섹션은 1개로 설정되어 있습니다.
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
// 각 섹션의 행 수를 반환합니다. items 배열의 개수를 반환하여 행 수를 설정합니다.
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 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
*/
// 테이블 뷰에서 삭제 기능을 지원합니다.
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 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 func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
*/
// MARK: - Navigation
// 세그웨이를 사용하여 화면을 전환하기 전에 준비 작업을 합니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 세그웨이 식별자가 "sgDetail"일 때 실행됩니다.
if segue.identifier == "sgDetail" {
// 전환될 셀을 가져와 해당 셀의 인덱스를 구합니다.
let cell = sender as! UITableViewCell
let indexPath = self.tvListView.indexPath(for: cell)
// 세그웨이의 목적지 뷰 컨트롤러를 DetailViewController로 캐스팅합니다.
let detailView = segue.destination as! DetailViewController
// 선택된 항목의 텍스트를 DetailViewController로 전달합니다.
detailView.reciveItem(items[((indexPath! as NSIndexPath).row)])
}
}
}
컨트롤러: 기능적인 부분
Q: iOS앱을 만들때 가장 많이 사용하는 컨트롤러
A: iOS 앱 개발에서 가장 많이 사용하는 컨트롤러는 UIViewController와 UITableViewController입니다.
- UIViewController: 모든 화면의 기본이 되는 컨트롤러로, 화면을 관리하고 여러 UI 요소를 배치하는 데 사용됩니다. UIViewController를 통해 다양한 화면 전환 방식과 함께 사용자 인터페이스를 구성할 수 있습니다.
- UITableViewController: 리스트 형태로 데이터를 보여줄 때 주로 사용됩니다. 메시지 목록, 설정 화면 등 다양한 형태의 리스트를 손쉽게 구현할 수 있고, 셀을 편집, 삭제, 이동하는 등의 기능도 쉽게 추가할 수 있습니다.
이외에도 UICollectionViewController, UINavigationController, UITabBarController 등도 많이 사용되는 컨트롤러입니다.
13
//
// ViewController.swift
// Audio
//
// Created by BeomGeun Lee on 2021.
//
// UIKit과 AVFoundation 프레임워크를 불러옵니다.
import UIKit
import AVFoundation
// ViewController 클래스는 UIViewController를 상속받고, AVAudioPlayerDelegate와 AVAudioRecorderDelegate를 채택하여 오디오 재생 및 녹음을 관리합니다.
class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
// 오디오 플레이어와 파일 URL 변수 선언
var audioPlayer : AVAudioPlayer!
var audioFile : 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!
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)
} 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)")
}
do {
try session.setActive(true)
} catch let error as NSError {
print("Error-setActive : \(error)")
}
}
// 재생 초기 설정 함수
func initPlay() {
do {
audioPlayer = try AVAudioPlayer(contentsOf: audioFile)
} 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
}
// TimeInterval 값을 문자열로 변환하는 함수 (분:초 형식)
func convertNSTimeInterval2String(_ time: TimeInterval) -> String {
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 {
initRecord()
}
}
// 녹음 버튼 눌렀을 때 호출되는 함수
@IBAction func btnRecord(_ sender: UIButton) {
if (sender as AnyObject).titleLabel?.text == "Record" {
audioRecorder.record()
(sender as AnyObject).setTitle("Stop", for: UIControl.State())
progressTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: timeRecordSelector, userInfo: nil, repeats: true)
} else {
audioRecorder.stop()
progressTimer.invalidate()
(sender as AnyObject).setTitle("Record", for: UIControl.State())
btnPlay.isEnabled = true
initPlay()
}
}
// 녹음 시간 업데이트 함수
@objc func updateRecordTime() {
lblRecordTime.text = convertNSTimeInterval2String(audioRecorder.currentTime)
}
}
14
//
// ViewController.swift
// MoviePlayer
//
// Created by Ho-Jeong Song on 2021/11/26.
//
// UIKit과 AVKit 프레임워크를 불러옵니다.
import UIKit
import AVKit
// ViewController 클래스 정의
class ViewController: UIViewController {
// 뷰가 로드될 때 실행되는 함수
override func viewDidLoad() {
super.viewDidLoad()
// 초기 설정을 여기서 할 수 있습니다.
}
// 내부 파일 재생 버튼이 눌렸을 때 실행되는 함수
@IBAction func btnPlayInternalMovie(_ sender: UIButton) {
// 앱 번들에 포함된 "FastTyping.mp4" 파일 경로를 가져옴
let filePath: String? = Bundle.main.path(forResource: "FastTyping", ofType: "mp4")
// 파일 경로를 NSURL로 변환
let url = NSURL(fileURLWithPath: filePath!)
// 비디오 재생 함수 호출
playVideo(url: url)
}
// 외부 파일 재생 버튼이 눌렸을 때 실행되는 함수
@IBAction func btnPlayerExternalMovie(_ sender: UIButton) {
// 외부 URL의 비디오 파일 주소 설정
let url = NSURL(string: "https://dl.dropboxusercontent.com/s/e38auz050w2mvud/Fireworks.mp4")!
// 비디오 재생 함수 호출
playVideo(url: url)
}
// 비디오 재생 기능을 담당하는 함수
private func playVideo(url: NSURL) {
// AVPlayerViewController 인스턴스 생성
let playerController = AVPlayerViewController()
// AVPlayer 인스턴스 생성하여 url을 할당
let player = AVPlayer(url: url as URL)
// AVPlayerViewController의 player에 AVPlayer 설정
playerController.player = player
// 현재 뷰 컨트롤러에서 AVPlayerViewController를 모달로 띄우고, 재생 시작
self.present(playerController, animated: true) {
player.play()
}
}
}
15
16
17
//
// ViewController.swift
// Sketch
//
// Created by Ho-Jeong Song on 2021/12/01.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var imgView: UIImageView! // 그림을 그릴 UIImageView
@IBOutlet var txtLineSize: UITextField! // 선의 두께를 입력할 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
}
// 사용자가 화면을 터치했을 때 호출되는 함수
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에 설정
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
}
// 새로운 기능: 선택된 색상을 텍스트로 표시하는 기능 추가
@IBOutlet var lblColorDisplay: UILabel! // 선택된 색상을 표시할 UILabel
func updateColorDisplay() {
switch lineColor {
case UIColor.black.cgColor:
lblColorDisplay.text = "Black"
case UIColor.red.cgColor:
lblColorDisplay.text = "Red"
case UIColor.green.cgColor:
lblColorDisplay.text = "Green"
case UIColor.blue.cgColor:
lblColorDisplay.text = "Blue"
default:
lblColorDisplay.text = "Custom Color"
}
}
// 색상 버튼들이 눌릴 때마다 선택된 색상을 표시하도록 설정
@IBAction func btnChangeLineColorBlackWithLabel(_ sender: UIButton) {
lineColor = UIColor.black.cgColor
updateColorDisplay()
}
@IBAction func btnChangeLineColorRedWithLabel(_ sender: UIButton) {
lineColor = UIColor.red.cgColor
updateColorDisplay()
}
@IBAction func btnChangeLineColorGreenWithLabel(_ sender: UIButton) {
lineColor = UIColor.green.cgColor
updateColorDisplay()
}
@IBAction func btnChangeLineColorBlueWithLabel(_ sender: UIButton) {
lineColor = UIColor.blue.cgColor
updateColorDisplay()
}
}
18
19
--------------------------------------------------------------------------------------------
BMI 앱 만들기
클래스의 프로퍼티 선언에 IBOutlet와 IBInspectable 사용
클래스의 메서드 선언에 IBAction과 IBSegueAction 사용
이미지는 Assets.xcassets에 넣음
숫자만 나옴