화면 전환 방법 크게 2가지



위에 활성된 부분은 각
네비게이션 컨트롤러 -> 네비게이션 바

뷰 컨트롤러 -> 네비게이션 아이템(백버튼)

네이비게이션 컨트롤러 추가시 변경 내용













화면에 제일 먼저 나타나는 뷰 -> root view controller

prepare (외부 내부 : 자료형, sender 외부내부 겸함:자료형)
->sugue가 실행되기 전에 자동으로 호출되는 매소드
prepare(for:sender:)는 UIKit의 UIViewController 에서 제공하는 메서드로, 화면 전환(Segue)이 실행되기 직전에 데이터를 전달하거나 목적지 뷰 컨트롤러를 설정할 때 사용합니다.
기본 형태
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
}
언제 호출될까?
예를 들어 스토리보드에서 ViewController A → ViewController B로 Segue를 연결해 놓았다면,
- 사용자가 버튼을 누름
- Segue가 시작됨
- prepare(for:sender:) 호출
- ViewController B가 화면에 표시됨
즉, 목적지 ViewController가 나타나기 직전에 실행됩니다.
목적지 ViewController에 데이터 전달하기
ViewController B
class DetailViewController: UIViewController {
var userName: String?
}
ViewController A
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let destinationVC = segue.destination as! DetailViewController
destinationVC.userName = "Kim"
}
}
이렇게 하면 DetailViewController가 표시될 때 userName에 "Kim"이 전달됩니다.
segue.identifier를 사용하는 이유
한 ViewController에서 여러 개의 Segue를 사용할 수 있기 때문입니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "showProfile":
let vc = segue.destination as! ProfileViewController
vc.userId = 100
case "showSettings":
let vc = segue.destination as! SettingsViewController
vc.theme = "Dark"
default:
break
}
}
sender는 무엇인가?
Segue를 발생시킨 객체가 전달됩니다.
예를 들어 버튼이 여러 개라면:
@IBAction func buttonTapped(_ sender: UIButton) {
performSegue(withIdentifier: "showDetail", sender: sender)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let button = sender as? UIButton {
print(button.tag)
}
}
어떤 버튼이 화면 전환을 발생시켰는지 확인할 수 있습니다.
Navigation Controller가 있는 경우
목적지 컨트롤러가 Navigation Controller 안에 포함되어 있을 수 있습니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nav = segue.destination as? UINavigationController,
let detailVC = nav.topViewController as? DetailViewController {
detailVC.userName = "Kim"
}
}
performSegue와 함께 사용
코드로 Segue를 실행할 수도 있습니다.
performSegue(withIdentifier: "showDetail", sender: self)
그러면 자동으로:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 여기 호출됨
}
이 실행된 후 화면이 전환됩니다.
전체 예제
class ViewController: UIViewController {
var selectedName = "Alice"
@IBAction func moveButtonTapped(_ sender: UIButton) {
performSegue(withIdentifier: "showDetail", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let detailVC = segue.destination as! DetailViewController
detailVC.userName = selectedName
}
}
}
class DetailViewController: UIViewController {
var userName: String?
override func viewDidLoad() {
super.viewDidLoad()
print(userName ?? "")
}
}
실행 결과:
Alice
핵심 정리
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
- Segue가 실행되기 직전 호출됨
- 목적지 ViewController에 데이터를 전달할 때 사용
- segue.identifier로 어떤 Segue인지 구분
- segue.destination으로 목적지 ViewController 접근
- sender로 화면 전환을 발생시킨 객체 확인 가능
- performSegue()를 호출해도 자동으로 실행됨
Swift 개발에서는 "화면 전환 전에 데이터 전달" 이라는 용도로 가장 많이 사용되는 메서드입니다.
url을 가지고 특정 웹 사이트를 보여주는 소스
a.b.com사이트를 웹뷰로 보여주는 swift 방법을 설명해줘
=>
OS에서 a.b.com 사이트를 앱 내부에서 웹뷰로 보여주려면 보통 WKWebView를 사용합니다. UIWebView는 오래전에 deprecated 되었습니다.
1. WKWebView 추가하기
코드만으로 구현
import UIKit
import WebKit
class WebViewController: UIViewController {
private var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(webView)
if let url = URL(string: "https://a.b.com") {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
2. Storyboard 사용하기
ViewController에 WKWebView 연결
import UIKit
import WebKit
class WebViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://a.b.com")!
let request = URLRequest(url: url)
webView.load(request)
}
}
Storyboard에서:
- ViewController 추가
- WKWebView를 드래그해서 배치
- IBOutlet 연결
3. 버튼 클릭 시 웹뷰 화면으로 이동
첫 번째 화면
@IBAction func openWeb(_ sender: UIButton) {
performSegue(withIdentifier: "showWeb", sender: self)
}
웹뷰 화면
class WebViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
var urlString: String?
override func viewDidLoad() {
super.viewDidLoad()
if let urlString,
let url = URL(string: urlString) {
webView.load(URLRequest(url: url))
}
}
}
데이터 전달 (prepare(for:sender:))
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showWeb" {
let vc = segue.destination as! WebViewController
vc.urlString = "https://a.b.com"
}
}
4. 로딩 상태 표시
class WebViewController: UIViewController, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
let url = URL(string: "https://a.b.com")!
webView.load(URLRequest(url: url))
}
func webView(_ webView: WKWebView,
didStartProvisionalNavigation navigation: WKNavigation!) {
print("로딩 시작")
}
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!) {
print("로딩 완료")
}
}
5. 뒤로 가기 지원
@IBAction func backButtonTapped(_ sender: UIButton) {
if webView.canGoBack {
webView.goBack()
}
}
6. 외부 브라우저 대신 앱 내부에서 열기
기본적으로:
UIApplication.shared.open(url)
를 사용하면 Safari가 열립니다.
앱 내부에서 보여주려면:
webView.load(URLRequest(url: url))
를 사용해야 합니다.
7. 특정 사이트만 허용하기
예를 들어 a.b.com 외의 사이트 이동을 막고 싶다면:
extension WebViewController: WKNavigationDelegate {
func webView(
_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
) {
if let host = navigationAction.request.url?.host,
host.contains("a.b.com") {
decisionHandler(.allow)
} else {
decisionHandler(.cancel)
}
}
}
실무에서 가장 많이 쓰는 형태
import UIKit
import WebKit
class WebViewController: UIViewController {
private let webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
webView.frame = view.bounds
let url = URL(string: "https://a.b.com")!
webView.load(URLRequest(url: url))
}
}
이 구조를 기반으로 prepare(for:sender:)에서 URL을 전달받아 다양한 웹 페이지를 표시하는 방식이 가장 일반적입니다.

Swift에서는 외부 매개변수명(Argument Label) 과 내부 매개변수명(Parameter Name) 을 구분하기 때문입니다.
WKWebView의 load 메서드 선언을 보면:
func load(_ request: URLRequest) -> WKNavigation?
여기서 _가 핵심입니다.
func load(_ request: URLRequest)
^
_는 외부 매개변수명을 사용하지 말라는 의미입니다.
그래서 호출할 때:
webView.load(request)
처럼 쓰고,
webView.load(request: request)
는 컴파일 에러가 발생합니다.
외부 매개변수명이 있는 경우
예를 들어:
func move(to position: Int) {
print(position)
}
호출:
move(to: 10)
여기서
- 외부 매개변수명: to
- 내부 매개변수명: position
입니다.
_를 사용한 경우
func move(_ position: Int) {
print(position)
}
호출:
move(10)
외부 매개변수명이 없어집니다.
URL 생성도 같은 원리
let url = URL(string: "https://a.b.com")
선언은:
init?(string: String)
이므로
URL("https://a.b.com")
는 안 되고,
URL(string: "https://a.b.com")
처럼 string:을 반드시 써야 합니다.
Swift API 디자인 규칙
Swift는 메서드를 영어 문장처럼 읽히게 만드는 것을 선호합니다.
예:
UIView.animate(withDuration: 0.3)
읽으면:
Animate with duration 0.3
반면
webView.load(request)
는
Load request
라고 자연스럽게 읽히므로 request:를 생략하도록 설계된 것입니다.
그래서 Apple API를 보면:
webView.load(request)
array.append(item)
view.addSubview(label)
처럼 목적어 역할의 첫 번째 인자는 _로 생략하는 경우가 많고,
present(vc, animated: true)
URL(string: ...)
animate(withDuration: ...)
처럼 의미를 명확히 해야 하는 경우는 외부 매개변수명을 사용합니다.
정리하면 load(request)가 가능한 이유는 load 메서드 정의가:
func load(_ request: URLRequest)
처럼 첫 번째 매개변수 앞에 _가 있기 때문입니다. _는 "호출할 때 매개변수 이름을 쓰지 마라"는 Swift 문법입니다.