Swift 첫 포스팅에 이어서
Do it! 스위프트로 아이폰 앱 만들기 입문 책 보면서 차근차근 진행중입니다
틈틈이 안 바쁠때마다 eBook 꺼내서 하나씩 소스 코드 따라 치면서 진행중입니다 ㅎㅎㅎ
벌써 책에 11파트를 들어가는데 슬슬 어려워지고있네요
특히 아직도 이해가 안되는 부분은 델리게이트?
자바, vue, js 할때 델리게이트 라는건 한번도 들어본적이 없는데 xcode swift에서 처음 접해봐서 어렵습니다.
11강 - 내비게이션 컨트롤러 익숙하지 않아서 차근차근 파헤치면서 블로그 쓰면서 다시 복습하는 시간 가질려구요
내비게이션 컨트롤러 ( Navigation Controller ) ?
애플문서, 블로그를 찾아보면 다음과 같이 정의했습니다.
"A container view controller that defines a stack-based scheme for navigating hierarchical content."
("계층적 콘텐츠 탐색을 위한 스택 기반 방식을 정의하는 컨테이너 뷰 컨트롤러.")
스택 기반이라고 하는것은 쌓아가는 구조 !
예를들면 사파리 브라우저, 크롬을 사용할때 뒤로가기나 앞으로 가기 눌러 전 화면에 접근할수있는데 이것이 스택구조입니다
Navigation Controller 시작하기
main 스토리보드에서 View controller 를 클릭하고 Editor -> Embed In -> Navigation Controller
항목을 클릭합니다!
짜잔
그러면 처음에 없었던 내비게이션 컨트롤러가 포함되었습니다
뷰 컨트롤러 제목을 달아주기위해서 뷰 컨트롤러에 상단 부분 파란색 박스로 된 부분 클릭하면 활성이 됩니다!
그러고 오른쪽 Attribute inspector 버튼을 클릭하여 네비게이션 아이템 타이틀영역에 제목을 입력해주면
사진처럼 "메인화면" 항목이 나옵니다!
세그웨이 (Segue) ??
₩
원하는 방법은 Edit 버튼을 오른쪽 마우스로 새로운 뷰 컨트롤러에 갖다 놓으면 검은색 창이 나와요!
Action Segue -> Show 선택합니다!
Edit 버튼을 클릭하면 새로운 뷰 컨트롤러 화면으로 갔다가 돌아오는 형태를 취하게 됩니다!
이모티콘 바로 위에 줄 하나가 생성이 됩니다!
세그웨이 (Segue) 생성 되었습니담
이 세그웨이가 생성되면서 코딩 없어도 화면 전환을 할 수 있습니다
코코아 터치 클래스란 ?
코코아(Cocoa)란 애플 환경에서 맥이나 ios 용 애플리케이션을 제작하기 위한 도구들의 모음 입니다.
보통 UI 기능들을 많이 사용하고 있습니다. 그런데 맥과 다른게 ios 의 경우 터치와 관련된 여러 기능들이 추가되었는데 이를 지원하기 위한 도구들의 모음이 코코아 터치입니다.
그리고 UI 를 ios 용으로 변경하고 다양한 터치 관련 기능을 클래스로 만들어 놓은것이 코코아 터치 클래스입니다.
( iOS , iPadOS 등 애플 기기에서 구동되는 애플리케이션을 개발하기 위해 사용하는 통합 프레임워크 )
뷰 컨트롤러에 관한 클래스도 이 코코아 터치 클랙스 입니다.
prepare 함수란 ?
prepare 함수는 해당 세그웨이가 해당 뷰 컨트롤러로 전환되기 직전에 호출되는 함수이며 데이터 전달을 위해 사용됩니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
<#code#>
}
현재 개발 진행중에 메인화면 -> 수정 화면으로 이동하고 데이터를 서로 주고 받을수있도록 만들고있슴
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let editViewController = segue.destination as! EditViewController
if segue.identifier == "editButton" {
// 버튼을 클릭한경우 (수정 버튼 )
} else if segue.identifier == "editBarButton" {
// 바 버튼을 클릭한 경우
}
}
prepare 함수를 사용하는데 이해가 안되는 부분이 있어서 쳇 GPT 한테 물어가며 이해하는중
( 사실 !, ? 옵셔닝 부분도 미세하게 알고있음 .. )
알아야할것들
✅ override : prepare(for:sender:) 메서드는 UIViewController 의 기본 기능이기 때문에 오버라이드해서 사용해야함
*( 오버라이드 란 ? 상위 클래스에서 정의된 내용을 하위 클래스에서 변경하여 재 정의하는것 )
✅ segue : 어떤 화면 전환이 발생했는지 정보를 담고있음 /
sender : 화면 전환을 유발한 객체(버튼 등) 전달됨
✅ 목적지(도착할 화면) 가져오기
let editViewController = segue.destination as! EditViewController
segue.destination : 전환될 화면 (뷰 컨트롤러) 의미함 ////// 나 수정 페이지로 넘어간다~
as! EditViewController : EditViewController 로 다운캐스팅해서 사용함
segue.destination 타입이 UIViewController 이기 때문에 EditViewController 속성이나 메서드를 사용하려면 다운캐스팅 해야함
as! ==> 강제 다운캐스팅
만약 타입이 다르면 크래시 될 위험이 있으므로 as? 를 권장함 ( gpt 가 권장함 )
🤔 근데 궁금한게 내가 만든 EditViewController 타입도 UIViewController 로 상속 받았는데 다운캐스팅을 왜 하지 ?
이유는 segue.destination 타입이 UIViewController 이기 때문에
print 부분은 주석 했다고 생각하고
만약 다운캐스팅 처리 안하고 바로 EditViewController 에 있는 변수에 값을 넣으려고 하면
갑자기 UIViewController 에는 lblWay 변수가 없다고 한다
말그대로 segue.destination 은 UIViewController 로 선언되어 있어서 UIViewController lblWay 속성이 있다고 보장할수없음 !
✅ segue.identifier 란 ?
세그웨이에 적어놓은 identifier (식별) 명칭이다!
⭐️ 처음 페이지 접근 메인 컨트롤러
//
// ViewController.swift
// Navigation_test
//
// Created by 성신혜 on 2/5/25.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let editViewController = segue.destination as! EditViewController
if segue.identifier == "editButton" {
// 버튼을 클릭한경우 (수정 버튼 )
editViewController.textWayValue = "수정 버튼 클릭 / use button"
} else if segue.identifier == "editBarButton" {
// 바 버튼을 클릭한 경우
editViewController.textWayValue = "Edit 버튼 클릭 / use bar button"
}
}
}
⭐️ 버튼 클릭하면 바라보는 컨틀롤러
//
// EditViewController.swift
// Navigation_test
//
// Created by 성신혜 on 2/5/25.
//
import UIKit
class EditViewController: UIViewController {
var textWayValue: String = ""
@IBOutlet var lblWay: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
lblWay.text = textWayValue
}
@IBAction func btnDone(_ sender: UIButton) {
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
❓ 근데 수정 버튼 클릭해서 editViewController 접근한거 이해하는데
왜 아울렛 변수로 바로 연결해서 텍스트 넣으면 되는거 아닌가? 왜 textWayValue 라는 변수를 따로 만들어서 데이터를 전달하는 걸까?
prepare 는 화면이 넘어가기 전에 호출되는 메서드로 이때 lblWay 는 아직 메모리에 존재하지 않을 수도 있다!
📌 prepare 함수 실행 시점
1. ViewController 에서 EditViewController 이동하는 세그웨이 실행됨
2. prepare 함수 호출됨 (( EditViewController 의 viewDidLoad 실행 안됨 !! ))
3. EditViewController 의 viewDidLoad 실행되면서 화면이 로드됨
4. 사용자가 EdieVeiwController 봄
아아 우리 선생님 쳇 gpt 말로는
lblWay 는 IBOutlet 이기 때문에 아.... 잠시 main 스토리보드에 레이블 UI 요소 이구나
그리고 textWayValue 는 일반 변수이므로 인스턴스가 생성되면서 메모리에 할당되니 ,....
일반 변수에 먼저 추가하구나
와우 와우 와우
홈 화면에서 Edit 로 클릭해서 수정화면으로 가거나, 수정 버튼 클릭했을때 수정 화면 이동시 어떤 버튼에 따라 메세지가 변경되는지
확인까지함!!
뷰 전환과 함께 메시지 전달하기!!
수정화면에서 -> 메인화면으로 메시지 전달하기
뷰 마다 데이터 전송하려면 프로토콜 형태의 델리게이트를 추가해야합니다!
👾 프로토콜이란 ?
프로토콜(Protocol) 이란 특정 객체가 갖추어야 할 기능이나 속성에 대한 설계도! 라고 할 수 있습니다
프로토콜은 실질적으로 아무런 내용이 없습니다.
다만, 단순한 선언 형태만 갖습니다.
흠 회사에서 java 백엔드에서 모드버스 프로토콜 사용했는데 이거는 다른 개념으로 통신 규칙을 정의하는 표준이네 !!
좀 어렵다 너 ... swift 나 아직 델리게이트도 100% 이해했다고 자부 할수없음 ... 걍 위임하는애..? 사실
왜 위임 ? 대신 왜 해주지 싶음 ㅎ...
protocol EditDelegate {
func didMessageEditDone(_ controller: EditViewController, message: String)
}
프로토콜 추가했습니다 ( 이유는 뷰 전환할때 메세지 전달 하기 위! 해! 서 ! )
자자 그러니 EditDelegate 라고 프로토콜 이름을 정했고~ 그 안에 didMessageEditDone 이라는 함수를 정의했어!
그러고 필요한 controller 에다가 상속을 했고!
상속 하고 나서 didMessageEditDone 정의 안하면 에러 나니깐 정의까지 해야함 !
또또 시작되는 혼란속으로~~~
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
자자
홈 = 메인화면 - ViewController
수정 화면 - EditVeiwController
✅ ViewController.swift 와 EditViewController.swift 역할 정리
➡️ ViewController와 EditViewController는 데이터를 주고받기 위한 관계야.
➡️ ViewController에서 EditViewController로 이동한 후,
➡️ EditViewController에서 변경한 내용을 다시 ViewController로 전달하는 구조야.
여기서 갑자기 editViewController.delegate = self ??
왜 갑자기 self ?
흠 보면 ( gpt 말로는 )
ViewController 본인 객체가 자기자신이 EdotViewController 의 delegate 로 설정하는 코드다 ......
어느정도 이해함 와 3번 넘게 보고보고 이해함
메인화면에서 수정해주세요 라고 입력하고 수정 또는 Edit 버튼 누르면 "수정해주세요" 문구가 남고
수정화면에서 수정 가능합니다! 변경하고 완료 누르면
메인화면에 "수정 가능합니다! "
라고 문구 변경된거 확인됨 !!
만약 수정 화면에서 글자 변경하고 완료 안누르고 왼쪽 메인화면 클릭하면
어떻게 될까?
ㅎㅎㅎㅎㅎㅎ
당연히 수정화면에서 변경한 글자가 아닌!
메인화면에 써둔 그대로 남아있었다~~
'코딩 > Swift' 카테고리의 다른 글
Swift 시작하게 된 이유, xcode 활용방법, 아울렛 변수 및 액션 함수에 대해서 (0) | 2025.01.22 |
---|