1) 새 ViewController 추가 (Shift + cmd + l )
2) TabBar에서 Ctrl 키 누르고 새 컨트롤러로 드래그 -> Relationship segue 의 view Controllers 클릭
=> Item Scene으로 변경됨
3) Item의 별표를 클릭하여 Web으로 변경 -> Web Scene으로 변경됨, 이미지도 network로
4) 새 파일 Cocoa Touch Class 로 만듦 -> 이름 WebViewController, 부모 클래스 : UIViewClass
5) WebScene의 identity Inspector에서 클래스 연결

deprecated : 부정적인 의미 O, 하지만 기술적·관리적 이유로 “정중하게 폐기 예정”이라는 느낌
Legacy: 부정적 의미 강함, “구닥다리”, “낡아서 바꾸고 싶지만 아직 쓰는 중”

//
// Web1ViewController.swift
// B_BMIYOO
//
// Created by Induk-cs on 2025/11/24.
//버튼을 눌렀을때 naver로 이동하는 코드 - gpt
import UIKit
import WebKit
class Web1ViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func goNaver(_ sender: UIButton) {
if let url = URL(string: "https://m.naver.com") {
let request = URLRequest(url: url)
webView.load(request)
}
}
}

URL Protocol만 바꿔줘도 다양한 앱이나 웹을 실행할 수 있음.
웹사이트를 열기 위한 과정
1) URL 설정

2) URLRequest : 서버에 응답요청

- 함수의 매개변수가 진하게 되어있는거는 반드시 명시해야되는 것이고, 흐릿한 부분은 디폴트값이 있어서 안써도됨.

url은 failable initializer라서 옵셔널형임
** 원래는 아래의 과정을 통해서 WebKit.framework를 추가해야 컴파일 시에 에러안나고 동작함. **
현재 사용버전인 14버전이 자동으로 해주기 때문에 따로 하지않아도 잘 동작하는 것임 -> 시험에 나올 수 있음



강제 언래핑은 url이 없을 시 동작을 안함.
첫번째 방법으로 언래핑

옵셔널이 풀려있는 것을 확인가능


url만 필수, 나머지는 디폴트값이 존재
- Web Tab을 클릭시 내 블로그 화면이 바로 뜨도록 하는 코드 추가
//
// Web1ViewController.swift
// B_BMIYOO
//
// Created by Induk-cs on 2025/11/24.
//
import UIKit
import WebKit
class Web1ViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
guard let url1 = URL(string:"https://dunoning52.tistory.com") else { return }
let request = URLRequest(url: url1)
webView.load(request)
// Do any additional setup after loading the view.
}
@IBAction func goNaver(_ sender: UIButton) {
guard let url1 = URL(string:"https://m.naver.com") else { return }
//모바일 사이트는 www. 대신에 m.만 써도 됨
let request = URLRequest(url: url1)
webView.load(request)
}
}
//리펙토링 코드 -> gpt
import UIKit
import WebKit
class Web1ViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
loadURL("https://dunoning52.tistory.com")
}
@IBAction func goNaver(_ sender: UIButton) {
loadURL("https://m.naver.com")
}
}
// MARK: - URL 로딩 기능 분리
extension Web1ViewController {
/// 입력한 URL 문자열을 로드하는 공통 메서드
func loadURL(_ urlString: String) {
guard let url = URL(string: urlString) else {
print("❌ 잘못된 URL: \(urlString)")
return
}
let request = URLRequest(url: url)
webView.load(request)
}
}

시뮬레이터를 돌려보면 UI가 화면에 맞지 않음 -> 앱 스토어 출시 불가.
경고가 뜨는 이유가 이것 때문임. 화면 디자인을 제대로 하지 않았다.

Align 이라고 하는 auto-layout 메뉴임

"이 버튼은 가로 세로로 돌려도 항상 가운데에 위치하도록 하겠다" 라는 의미.
add constraints 누르면 적용
Xcode에서 오토 레이아웃을 설정하는 방법 - 시험 범위는 아님
Xcode에서 오토 레이아웃(Auto Layout) 을 설정하는 방법을 가장 쉽게 이해할 수 있도록 단계별로 정리해줄게.
(초보자용 + 실무에서 바로 쓰는 방식 둘 다 포함!)
🚀 1. 오토 레이아웃이란?
화면 크기가 달라도 UI가 깨지지 않도록
제약(Constraints) 을 걸어서 위치와 크기를 고정하거나 비율로 유지하는 시스템.
✅ 2. Xcode에서 오토 레이아웃 적용하는 기본 흐름
Step 1. 스토리보드에서 View 선택
오토레이아웃을 설정하려는 버튼/라벨/이미지 등을 클릭.
Step 2. 아래쪽의 "Add New Constraints" 버튼 클릭
스토리보드 아래에 있는 버튼들 중:
🔧 아이콘 순서 중 가운데 있는 것
⬜️ | ⬛️
처럼 생긴 Constraints 추가 버튼 클릭.
Step 3. 여백(Spacing) 설정하기
팝업이 뜨면…
- 상 / 하 / 좌 / 우 여백
- Width(가로) / Height(세로)
등을 넣을 수 있음.
예:
- 좌우 간격 20
- 위에서 100
등.
여백 값을 입력하면 선이 빨갛게 → 선택된 상태.
Step 4. “Add Constraints” 버튼 클릭
선택된 제약이 실제로 적용됨.
✅ 3. Auto Layout의 기본 원리
오토레이아웃은 위치 + 크기가 결정되어야 한다.
따라서 보통 아래 2개 이상을 잡아야 문제 없음:
- 좌우 거리 or 가운데 정렬
- 위/아래 거리
- width/height or content 기반 크기
📌 4. 제일 많이 쓰는 Auto Layout 조합 예시
✔ 버튼을 화면 가운데 놓기
- 버튼 선택
- 아래쪽 Align 메뉴 클릭 (두 번째 아이콘)
- Horizontally in Container 체크
- Vertically in Container 체크
- Add 2 Constraints 클릭 → 끝
✔ 이미지뷰 화면 전체에 꽉 채우기
- 이미지뷰 선택
- Add Constraints 클릭
- 상/하/좌/우 모두 0 입력
- Add Constraints → 끝
✔ UI를 상단에 고정하고 여백 주기
- 위(Top) = 20
- Leading(왼쪽) = 16
- Trailing(오른쪽) = 16
- 높이(Height) 44
끝!
🧭 5. Auto Layout 설정 버튼들 설명
버튼 기능| ⬜️⇄⬛️ (Add New Constraints) | 상/하/좌/우 여백, Width/Height 설정 |
| 🟦↔️🟦 (Align) | 가운데 정렬, 좌/우 정렬, baseline 정렬 |
| ↔️⟷↔️ (Resolve Auto Layout Issues) | 경고 수정, 프레임 업데이트 |
| ➕ (Pin) | 오브젝트 간 간격 고정 |
⚠️ 6. 자주 발생하는 오류 + 해결법
❓ “Ambiguous Layout”
제약이 부족해서 위치/크기 확정 불가
➡ 제약을 하나 더 추가해라 (특히 width/height 또는 양 끝 여백)
❓ “Conflicting Constraints”
서로 모순되는 제약
➡ 둘 중 하나 삭제
❓ 프레임이 안 맞음
➡ “Update Frames” 클릭
✔️ 필요하면 내가 UI 모양 보고 정확한 오토레이아웃 제약 조합도 잡아줄 수 있음
(예: 로그인 화면, 상단바, WebView fullscreen 등)
UI 스크린샷 보여주면 직접 제약 세팅해줄까?

4가지 방법이 존재 - Stack View를 많이 사용함
-문법 설명 p.72 (시험에 무조건 출제)
present(_:animated:completion:) 함수.
func present( _ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil )
UIViewController에 속해있는 함수로, 화면에 무언가를 보여줄 때 사용

아주 좋다!
아래에서 present(_:animated:completion:) 함수가 무엇이고, 어떤 상황에서 어떻게 쓰는지 기초 → 중급 → 실전 예시 순으로 가장 이해하기 쉽게 설명해줄게.
🚀 1. 이 함수는 뭐하는 함수인가?
present(_:animated:completion:) 는
현재 화면(ViewController) 위에 새로운 화면을 모달로 띄우는 기능이다.
즉:
- 전체 화면으로 띄우기
- 바텀시트처럼 올리기
- 팝업처럼 띄우기
모두 이 함수로 가능!
🧩 2. 함수 구조 다시 보기
func present(
_ viewControllerToPresent: UIViewController,
animated flag: Bool,
completion: (() -> Void)? = nil
)
파라미터 설명
파라미터 설명| viewControllerToPresent | 화면에 띄울 뷰 컨트롤러 |
| animated | 전환 애니메이션을 사용할지 여부 |
| completion | 화면 표시가 끝난 뒤 실행할 코드 (옵션) |
🎯 3. 가장 기본적인 사용법 (정석)
예: SecondViewController 화면을 모달로 띄우기
let vc = SecondViewController()
present(vc, animated: true)
이렇게 하면 자동으로 화면이 위로 올라오며 표시됨.
🎯 4. 스토리보드 기반 사용법
스토리보드에서 “SecondVC” 라는 Identifier가 있다면:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SecondVC")
present(vc, animated: true)
🎯 5. 전체화면으로 띄우기 (iOS13 이후 권장)
모달이 카드 형태로 뜨는 게 싫다면:
let vc = SecondViewController()
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true)
🎯 6. completion 사용 예시
화면을 띄운 후 특정 작업을 하고 싶을 때 사용.
예: 화면 띄운 후 알림 띄우기
let vc = SecondViewController()
present(vc, animated: true) {
print("화면 표시 완료!")
}
또는:
present(vc, animated: true) {
self.showToast("화면이 열렸습니다!")
}
🎯 7. 버튼 누르면 화면 전환 예시
@IBAction func openNext(_ sender: UIButton) {
let vc = SecondViewController()
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true)
}
🎯 8. 바텀시트처럼 띄우기
let vc = SecondViewController()
vc.modalPresentationStyle = .pageSheet
present(vc, animated: true)
🎯 9. 팝업 스타일로 띄우기
let vc = PopupViewController()
vc.modalPresentationStyle = .overCurrentContext
vc.modalTransitionStyle = .crossDissolve
present(vc, animated: true)
🎯 10. dismiss로 닫기
모달로 띄운 화면은 dismiss로 닫는다.
dismiss(animated: true)
🧠 정리
present() 는 다음과 같은 상황에서 사용한다:
✔ 새로운 화면 모달로 열기
✔ 하단에서 올리는 형태 구현
✔ 전체 화면 전환
✔ 반투명 팝업 띄우기
✔ completion으로 후처리 실행
원하면
- NavigationController push 방식과의 차이
- 모달 스타일들(.formSheet, .popover, .overFullScreen 등) 비교
- 실제 UI 스토리로 연결된 예제
도 더 자세히 설명해줄게!

completion은 디폴트 값이 존재

completion : 화면을 보여준 후에 할 일을 작성

AVPlayer 는 모든 로직 담당, AVPlayerViewController는 시각적을 보여주기 위한 기능 -> 기능을 분담하고 있다.

세 코드의 차이점을 알아둘 것. -> 세번째 코드가 가장 안정적인 UI를 가짐
** 클로저 ** => 익명함수
func add(x: Int, y: Int) -> Int {
return(x+y)
}
let add1 = {(x: Int, y: Int) -> Int in
return(x+y)
}
print(add(x:10,y:20))
print(add1(30,40)) //argument label 사용 X, 쓰면 에러남
let multiply = {(a: Int, b: Int) -> Int in
return a * b
}
var result = multiply(10, 20)
print(result)
let add = {(a: Int, b: Int) -> Int in
return a + b
}
result = add(10, 20)
print(result)
func math(x: Int, y: Int, cal: (Int, Int) -> Int) -> Int {
return cal(x, y)
}
result = math(x: 10, y: 20, cal: add)
//cal에서 해당 클로저를 입력받아서 math 함수가 그 결과값을 출력
print(result)
result = math(x: 10, y: 20, cal: multiply)
print(result)
let multiply = {(a: Int, b: Int) -> Int in
return a * b
}
var result = multiply(10, 20)
let add = {(a: Int, b: Int) -> Int in
return a + b
}
result = add(10, 20)
func math(x: Int, y: Int, cal: (Int, Int) -> Int) -> Int {
return cal(x, y)
}
result = math(x: 10, y: 20, cal: add)
//cal에서 해당 클로저를 입력받아서 math 함수가 그 결과값을 출력
print(result)
result = math(x: 10, y: 20, cal: multiply)
print(result)
result = math(x: 10, y: 20, cal: {(a: Int, b: Int) in
return a + b
}) //cal 부분에 클로저 자체를 삽입, -> Int 를 생략가능
print(result)
result = math(x: 10, y: 20, cal: { //cal을 다 삭제 후 $로 받는것도 가능
return $0 + $1
}) //$를 사용한 것을 매개변수 생략한 단축인자(shorthand argument name)라고 함
//$0이 첫번째, $1이 두번째 인자
print(result)
result = math(x: 10, y: 20, cal: { $0 + $1 }) //return도 생략가능
print(result)

위의 코드와 한꺼번에 실행
result = math(x: 10, y: 20, cal: {(a: Int, b: Int) -> Int in
return a + b
}) //클로저 소스를 매개변수에 직접 작성
print(result)
result = math(x: 10, y: 20) {(a: Int, b: Int) -> Int in
return a + b
}//trailing closure
print(result)
result = math(x: 10, y: 20) {(a: Int, b: Int) in
return a + b
} //trailing closure, 리턴형 생략
print(result)
result = math(x: 10, y: 20) { return $0 + $1 } //trailing closure, 매개변수 생략하고 단축인자사용
print(result)
result = math(x: 10, y: 20) { $0 + $1 } //return 생략
print(result)'iOS' 카테고리의 다른 글
| iOS_3grade - 1주차 (1) | 2026.03.03 |
|---|---|
| iOS_프로젝트 (1) | 2025.12.08 |
| iOS_week12 (0) | 2025.11.17 |
| iOS_week10 (0) | 2025.11.03 |
| iOS_week9 (0) | 2025.10.27 |