09 페이지 이동하기 - 페이지 컨트롤
page를 넘겨주는 컨트롤러 입니다
import UIKit // UIKit 프레임워크를 가져옴
// 이미지 파일 이름을 저장한 배열
var images = [ "01.png", "02.png", "03.png", "04.png", "05.png", "06.png" ] // 사용할 이미지 파일 이름 배열
class ViewController: UIViewController { // ViewController 클래스 정의, UIViewController를 상속
@IBOutlet var imgView: UIImageView! // UIImageView를 IBOutlet으로 연결하여 이미지 표시
@IBOutlet var pageControl: UIPageControl! // UIPageControl을 IBOutlet으로 연결하여 페이지 제어
override func viewDidLoad() { // 뷰가 메모리에 로드된 후 호출되는 메서드
super.viewDidLoad() // 부모 클래스의 viewDidLoad 호출
// 페이지 컨트롤의 페이지 수를 이미지 배열의 개수로 설정
pageControl.numberOfPages = images.count
// 현재 페이지를 3으로 설정 (0부터 시작하므로 4번째 페이지)
pageControl.currentPage = 3
// 페이지 인디케이터의 기본 색상 설정
pageControl.pageIndicatorTintColor = UIColor.blue // 기본 인디케이터 색상: 파란색
// 현재 페이지 인디케이터의 색상 설정
pageControl.currentPageIndicatorTintColor = UIColor.brown // 현재 페이지 인디케이터 색상: 갈색
// imgView에 첫 번째 이미지를 설정
imgView.image = UIImage(named: images[0]) // "01.png" 이미지 설정
}
// 페이지가 변경될 때 호출되는 액션 메서드
@IBAction func pageChange(_ sender: UIPageControl) { // UIPageControl의 값이 변경될 때 호출
// 선택된 페이지에 해당하는 이미지를 imgView에 설정
imgView.image = UIImage(named: images[pageControl.currentPage]) // 현재 페이지의 이미지 설정
}
}
10 탭 바 컨트롤러 이용해 여러 개의 뷰 넣기
화면 밑에 탭으로 여러개의 화면을 전환 할 수 있는 거이 탭 바 컨트롤러입니다.
11 내비게이션 컨트롤러 이용해 화면 전환하기
누르면 화면이 이동하고 돌아오는 버튼을 누르면 다시 돌아오는 것이 네비게이션 컨트롤러 입니다
12 테이블 뷰 컨트롤러 이용해 할 일 목록 만들기
//
// TableViewController.swift
// Table
//
// Created by BeomGeun Lee on 2021.
//
import UIKit // UIKit 프레임워크를 가져옴
// 항목 목록과 항목 이미지 파일 이름 배열 정의
var items = ["책 구매", "철수와 약속", "스터디 준비하기"] // 표시할 항목들
var itemsImageFile = ["cart.png", "clock.png", "pencil.png"] // 각 항목에 해당하는 이미지 파일 이름
class TableViewController: UITableViewController { // UITableViewController를 상속한 TableViewController 클래스 정의
@IBOutlet var tvListView: UITableView! // UITableView를 IBOutlet으로 연결하여 테이블 뷰 참조
override func viewDidLoad() { // 뷰가 메모리에 로드된 후 호출되는 메서드
super.viewDidLoad() // 부모 클래스의 viewDidLoad 호출
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false // 뷰가 다시 나타날 때 선택 상태 유지 여부 설정
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.leftBarButtonItem = self.editButtonItem // 내비게이션 바에 편집 버튼 추가
}
override func viewWillAppear(_ animated: Bool) { // 뷰가 나타나기 직전에 호출되는 메서드
tvListView.reloadData() // 테이블 뷰의 데이터를 다시 로드하여 최신 상태로 업데이트
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int { // 섹션 수를 반환하는 메서드
// #warning Incomplete implementation, return the number of sections
return 1 // 현재 섹션 수는 1로 설정
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 섹션 내의 행 수를 반환하는 메서드
// #warning Incomplete implementation, return the number of rows
return items.count // items 배열의 개수만큼 행 수를 반환
}
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 false if you do not want the specified item to be editable.
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) // items 배열에서 항목 삭제
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?
iOS앱에서 가장 많이 사용하는 컨트롤러
UITableViewController: 목록 형태의 데이터를 표시하는 데 사용됩니다. 데이터의 행을 표시하고, 선택 및 편집 기능을 제공합니다.
UICollectionViewController: 격자 형태의 데이터를 표시하는 데 사용됩니다. 유연한 레이아웃을 지원하며, 다양한 방식으로 아이템을 배치할 수 있습니다.
UINavigationController: 여러 화면 간의 네비게이션을 관리하는 컨트롤러로, 스택 구조를 사용하여 화면 전환을 처리합니다.
UITabBarController: 여러 개의 뷰 컨트롤러 간에 탭을 통해 전환할 수 있도록 하는 컨트롤러입니다.
이 외에도 특정 기능에 따라 다양한 컨트롤러들이 사용되지만, 기본적으로 UIViewController를 중심으로 다른 컨트롤러들이 구성됩니다.
13 음악 재생하고 녹음하기
//
// ViewController.swift
// Audio
//
// Created by BeomGeun Lee on 2021.
//
import UIKit // UIKit 프레임워크를 가져옴
import AVFoundation // 오디오 재생 및 녹음을 위한 AVFoundation 프레임워크를 가져옴
class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate { // 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 연결
@IBOutlet var pvProgressPlay: UIProgressView! // 재생 진행 상태를 표시하는 UIProgressView
@IBOutlet var lblCurrentTime: UILabel! // 현재 재생 시간을 표시하는 UILabel
@IBOutlet var lblEndTime: UILabel! // 오디오의 총 시간을 표시하는 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! // 녹음 시간을 표시하는 UILabel
var audioRecorder: AVAudioRecorder! // 오디오 녹음을 위한 AVAudioRecorder 인스턴스
var isRecordMode = false // 녹음 모드 여부를 나타내는 플래그
override func viewDidLoad() { // 뷰가 로드된 후 호출되는 메서드
super.viewDidLoad() // 부모 클래스의 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") // 번들에서 오디오 파일 URL 가져오기
} else { // 녹음 모드일 경우
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] // 문서 디렉토리 경로 가져오기
audioFile = documentDirectory.appendingPathComponent("recordFile.m4a") // 녹음 파일 URL 설정
}
}
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)") // 오류 발생 시 출력
}
do {
try session.setActive(true) // 세션 활성화
} catch let error as NSError {
print("Error-setActive: \(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) { // 오디오 재생 완료 시 호출
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()
// Do any additional setup after loading the view.
}
@IBAction func btnPlayInternalMovie(_ sender: UIButton) {
// 내부 파일 mp4
let filePath:String? = Bundle.main.path(forResource: "FastTyping", ofType: "mp4")
let url = NSURL(fileURLWithPath: filePath!)
playVideo(url: url)
}
@IBAction func btnPlayerExternalMovie(_ sender: UIButton) {
// 외부 파일 mp4
let url = NSURL(string: "https://dl.dropboxusercontent.com/s/e38auz050w2mvud/Fireworks.mp4")!
playVideo(url: url)
}
private func playVideo(url: NSURL) {
let playerController = AVPlayerViewController()
let player = AVPlayer(url: url as URL)
playerController.player = player
self.present(playerController, animated: true) {
player.play()
}
}
}
한가지는 외부에 있는 동영상을 가져오는 것이고 다른 하나는 내부에 있는 동영상을 가지고 오는 것 입니다
15 카메라와 포토 라이브러리에서 미디어 가져오기
BMI 앱 만들어보기
기존 BMI 앱들을 벤치마킹
BMI 앱 기획서
1. 앱 개요
앱 이름: BMI Calculator (가칭)
목표: 사용자가 자신의 체질량지수(BMI)를 쉽게 계산하고, 건강한 체중 범위를 이해하며, 맞춤형 건강 정보를 제공하는 앱.
2. 주요 기능
2.1 BMI 계산기
사용자 입력: 키(㎝), 체중(㎏) 입력
BMI 계산: BMI = 체중(kg) / (키(m) * 키(m))
결과 표시: 계산된 BMI 값과 함께 체중 범주(저체중, 정상, 과체중, 비만) 표시
2.2 건강 정보 제공
BMI 범주 설명: 각 BMI 범주에 대한 설명과 건강 위험 요소 안내
체중 목표 설정: 사용자가 목표 체중을 설정할 수 있도록 지원하고, 목표 달성을 위한 권장 체중 조절 방법 제공
2.3 식단 및 운동 가이드
추천 식단: 각 BMI 범주에 맞는 건강한 식단 예시 제공
운동 추천: 체중 감량 또는 유지에 도움이 되는 운동 프로그램 제공
2.4 사용자 맞춤형 기능
사용자 프로필: 나이, 성별, 활동 수준 등을 입력하여 개인 맞춤형 BMI 계산 및 건강 정보 제공
진행 상황 추적: 사용자가 체중 변화를 기록하고, 목표 체중에 도달하는 과정을 시각적으로 보여주는 그래프 제공
2.5 알림 기능
목표 체중 달성을 위한 알림: 주기적인 알림 설정 기능 제공
운동 및 식사 알림: 사용자가 설정한 시간에 운동 또는 식사 알림 전송
3. 디자인
3.1 UI/UX
심플하고 직관적인 인터페이스: 사용자가 쉽게 탐색할 수 있도록 설계
모바일 친화적인 디자인: 다양한 화면 크기에 맞춰 최적화
비주얼 요소: 그래프, 아이콘, 이미지 등을 활용하여 시각적 정보 제공
3.2 색상 및 테마
색상 팔레트: 건강과 관련된 색상(녹색, 파란색) 사용
다크 모드 지원: 사용자 설정에 따라 다크 모드 지원
4. 마케팅 전략
4.1 타겟 사용자
건강 관리에 관심이 있는 성인
체중 조절을 원하는 사용자
운동 및 식단 관리에 관심이 있는 사용자
4.2 홍보 방법
SNS 마케팅: 인스타그램, 페이스북 등 소셜 미디어를 활용하여 사용자 사례 및 건강 정보 공유
블로그 및 유튜브: 건강 관련 블로그 및 유튜브 채널과 협력하여 앱 리뷰 및 사용법 소개
앱스토어 최적화: 키워드 최적화 및 사용자 리뷰 관리
5. 기술 스택
프로그래밍 언어: Swift
프레임워크: UIKit, Core Data (사용자 데이터 저장)
API: 건강 관련 정보 제공을 위한 외부 API 연동 가능성 검토
6. 출시 일정
MVP 개발: 3개월
테스트 및 피드백: 1개월
최종 출시: 4개월 후
7. 예산
개발 비용: 인건비, 서버 비용, 디자인 비용 포함
마케팅 비용: 광고, 프로모션 비용 포함
이 기획서는 기본적인 구조를 제공하며, 필요에 따라 추가적인 세부사항을 조정하거나 추가할 수 있습니다. 사용자 피드백을 통해 지속적으로 개선해 나가는 것이 중요합니다.
BMI 계산하는 방법
UI디자인 -> Outlet 작성 -> Action 기능 작성 -> Connection inspector 로 한번만 연결된 게 맞는지 확인 -> 소스코드 작성
과거에는 프로그램 이름이었습니다.
IBOutlet과 IBAction이 잘 생성 되었고 한번만 연결 되었는지 꼭 체크.
일반 아이폰 같은 경우는 1x만 써도되지만 iPad나 화면이 커질경우 2x와 3x도 써줘야 해요
해상도 높은 사진을 가져와 사진 크기를 줄여가면서 넣는것이 가장 좋은 방법입니다.
Decimal Pad를 지정해주면 숫자패드만 나옵니다!