묻고 답해요
148만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결최신 SwiftUI와 UIKit과 함께하는 올인원 iOS 앱 개발 강의
섹션 3. SwiftUI 포폴용 앱 강의는 언제 쯤 올려주실 수 있으신지요?
안녕하세요.강의 목차에 보면섹션 3. SwiftUI 포폴용 앱 - 제작중 이라고 나와 있습니다.이 강의는 언제쯤 올려주실 수 있으신지요?
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
Closure2 강의에서 예문처럼 똑같이 myfunc2, myfunc3 만들었을때
저 같은경우에는 myfunc2,myfunc3 를 만들었을때 myfunc라고 타입했을경우 아무것도 안뜨는데 오류인가요?ㅠㅠ
-
해결됨[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기
AnimalKR - ContentView에서 질문있습니다.
파일명 : AnimalListView.swift 왜 AnimalListview는 subview인데 @ObservedObject let animal : Animal이라고 선언 하지 않고 왜 let animal : Animal 이라고 선언한건가요?
-
미해결야곰의 스위프트 기본 문법 강좌
강의 자료 다운받을 수 있나요?
안녕하세요, 강의 자료 다운받을 수 있는지 문의드립니다. 감사합니다.
-
미해결앨런 iOS 앱 개발 (15개의 앱을 만들면서 근본원리부터 배우는 UIKit) - MVVM까지
UIView는 왜 필요한가요?
안녕하세요.현재 "코드로 UI짜기" 강좌를 진행 중입니다.문득 이런 생각이 들어 질문 드립니다. UIView 없이 바로 라벨이랑 텍스트 필드만 사용하면 안되는건가요? UIView의 역활은 어떤 것이 있는지요.검색 능력 부족인지 웹에서는 좋은 답을 찾지 못해 질문드립니다. - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기
소스코드 관련 질문
안녕하세요. Date Picker강의에서 currentDate, dateFormatter는computed property인가요??그러면 get이 생략된건가요??var currentDate: String { // calculate property ... } var dateFormatter : DateFormatter{ ... }
-
해결됨[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기
Core 1 - SafeArea 관련 질문있습니다!
안녕하세요, SafeArea강의를 듣던 중 궁금한게 생겨 질문드립니다!2번 화면을 구성할때 마지막으로 ScrollView에 background Color와 ignoresSafeArea를 적용시키면서 강의가 마무리 되는데, 보시는 것처럼 ScrollView에는 따로 ignoresSafeArea를 해주지않아도 결과가 같습니다. 혹시 SwiftUI가 업데이트 되면서 ScrollView는 자동으로 ignoresSafeArea가 적용되는 걸까요??
-
미해결앨런 iOS 앱 개발 (15개의 앱을 만들면서 근본원리부터 배우는 UIKit) - MVVM까지
weightTextField에서 엔터를 눌러도 키보드가 안내려가는 문제(활용앱 37강 07:00)
extension ViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if Int(string) != nil || string == "" { return true }// 글자 입력을 허용 return false // 글자 입력을 허용하지 않음 } func textFieldShouldReturn(_ textField: UITextField) -> Bool { // 두개의 텍스트필드를 모두 종료 (키보드 내려가기) if heightTextField.text != "", weightTextField.text != "" { weightTextField.resignFirstResponder() return true // 두번째 텍스트필드로 넘어가도록 } else if heightTextField.text != "" { weightTextField.becomeFirstResponder() return true } return false } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { heightTextField.resignFirstResponder() weightTextField.resignFirstResponder() } } 위와 같이 입력을 했는데 두 텍스트필드를 입력하고 엔터를 누르면 밑 사진처럼 숫자 입력 키보드에서 한글 입력 키보드로 바뀌기만 할 뿐 키보드가 내려가지 않습니다.. 무엇이 문제일까요??저 상태에서 화면 다른 부분을 터치했을 때 내려가긴 합니다.
-
미해결
Closure 실전 세번째 설명 질문입니다.
강의을 수강하면서 아래의 함수를 사용하려고 하는데 if name.contains 구문에서아래와 같은 오류가 발생됩니다.let names = ["apple", "air", "brown", "red", "orange", "blue", "candy"] func someFind(find: String) -> [String] { var newNames = [String]() for name in names { if name.contains(find) { newNames.append(name) } } return newNames } Cannot convert value of type 'String' to expected argument type 'String.Element' (aka 'Character')강의에서는 잘 되는데, 제가 선언해서 저 함수를 쓰려고할때 발생되는 에러 메세지인데..String에서는 Charater Type밖에 찾을 수 없다고 합니다. 왜 강사님 코드는 되고 저는 안되는것인가요..?문자열 배열에서 검색한번 해보려고 하는데 오류가 발생되는데... 왜 이런 오류가 발생되는것인가요. ㅠㅠ
-
해결됨[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기
안녕하세요 Jacob님!
안녕하세요! 이번에 새로 강의를 듣게 된 학생입니다.강의 정말 잘 듣고 있으며 정리글에 대해 질문을 드리고자합니다.저는 평소에 무료강의를 들을때 깃허브에 마크다운으로 정리하곤 합니다.이번 강의도 정리를 하고싶은데 강의노트 포함, 자료실에서 받은 코드 파일은 당연히 올리지 않지만, 출처를 밝히며 제가 따라친 코드와 결과물 정도를 마크다운에 작성해 올려도되는지 여쭙고싶습니다!
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
클론강의 tableViewCell
8:17 에 데이터모델을 받는 변수를 왜 굳이 함수로 만드는 이유를 자세히 알려주세요20:10 에 왜 movieModel처음에 nil에 할당 되어 있다가 바로 movieMoel 데이터가 안담겨지나요 ? 비동기적으로 처리한 데이터를 movieModel에 넣었을때, collectionView를 reloadData를 한 이유를 컨트롤러 생성 과정을 통해 자세히 알려주세요
-
미해결개발하는 정대리 스위프트 기초 문법
클로저 사용 방법의 다양성
클로저를 사용하는 다양한 방법에 대해서 공부할 수 있었습니다.그렇다면 Swift는 왜 이렇게 같은 결과 같에 대해서 다양한 표현 방식을 가지고 있는 건가요?또 실제 코딩시 상황마다 적절한 형태가 존재 하는건가요?
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
Location.pin강의에서 self질문이요
안녕하세요 강의내용중에 질문있어서 글올립니다.PinLandMark라는 열거형에서 var title: String { return "\(self)" // self는 case를 가르킴 }이부분에 해당하는 self가 열거형의 case를 나타낸다고 이해했는데 왜 그렇게 되나요?밑의코드인 var coordinate:CLLocationCoordinate2D { switch self { case .Deoksugung: return .init(latitude: <#T##CLLocationDegrees#>, longitude: <#T##CLLocationDegrees#>) case .Hyeongbokgung: return .init(latitude: <#T##CLLocationDegrees#>, longitude: <#T##CLLocationDegrees#>) case .SeoulCityHall: return .init(latitude: <#T##CLLocationDegrees#>, longitude: <#T##CLLocationDegrees#>) } }의경우 switch self가 PinLandmark를 가르키지않나요?제가 이해한건 self라는건 class,struct,열거형의 인스턴스를 가르킨다고알고있는데 제가 잘못이해한건가요?
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
넷플릭스 table cell 관련해서 질문이 있습니다.
안녕하세요. 넷플릭스 프로젝트를 따라하면서 제가 수강하면서 뭔가를 놓친건지 막혔었다가 해결한 부분이 있습니다. 테이블 섹션마다 영화, 팟캐스트 등의 이미지를 보여주는 콜렉션뷰의 높이는 UICollectionViewDelegateFlowLayout로 sizeForItemAt 메소드로 설정해줬는데 테이블뷰의 row 높이를 설정해주지 않아서 콜렉션 셀의 높이와 너비를 지정했음에도 사진처럼 적용되지 않는 현상이 있었습니다.해결은 테이블뷰 델리게이트로 heightForRowAt으로 높이값을 콜렉션 셀의 높이값보다 크게 지정해줘서 해결은 됐습니다. 해결은 했는데 강의를 수강하면서 테이블뷰 row의 높이값을 설정하는 부분을 못본 것 같은데 제가 뭔가 놓친건지 질문드립니다.P.S. 좋은 강의 감사합니다 🙏
-
미해결앨런 iOS 앱 개발 (15개의 앱을 만들면서 근본원리부터 배우는 UIKit) - MVVM까지
cornerRadius가 적용이 안되는 문제가 있어 질문드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요. 앨런님현재 코드로 ToDoApp을 만들고 있는데 DetailView 부분을 코딩하면서 색상 버튼 부분에 cornerRadius가 적용이 안되는 문제가 있어 질문드립니다.현재까지 제가 해결을 위해 확인한 부분은 아래와 같습니다.setupSaveButtonConstraints()를 호출 시 red, green, blue, purple 버튼에 cornerRadius 적용되지 않습니다.setupButtonCorner() 함수의 호출 지점을 layoutSubView()의 super 호출 전 또는 후로 설정해 보았지만 적용되지 않았습니다.setupButtonCorner() 함수에서 button에 height를 설정해서 실행해 보았지만 적용되지 않았습니다.이 문제를 해결할 수 있는 방법이 뭐가 있을까요?import UIKit final class DetailView: UIView { // MARK: - Color Buttons let redButton: UIButton = { let button = UIButton() button.setTitle("Red", for: .normal) // button.setTitleColor(MyColor.red.buttonColor, for: .normal) // button.backgroundColor = MyColor.red.backgroudColor button.titleLabel?.font = UIFont.systemFont(ofSize: 15) // button.translatesAutoresizingMaskIntoConstraints = false return button }() let greenButton: UIButton = { let button = UIButton() button.setTitle("Green", for: .normal) // button.setTitleColor(MyColor.green.buttonColor, for: .normal) // button.backgroundColor = MyColor.green.backgroudColor button.titleLabel?.font = UIFont.systemFont(ofSize: 15) // button.translatesAutoresizingMaskIntoConstraints = false return button }() let blueButton: UIButton = { let button = UIButton() button.setTitle("Blue", for: .normal) // button.setTitleColor(MyColor.blue.buttonColor, for: .normal) // button.backgroundColor = MyColor.blue.backgroudColor button.titleLabel?.font = UIFont.systemFont(ofSize: 15) // button.translatesAutoresizingMaskIntoConstraints = false return button }() let purpleButton: UIButton = { let button = UIButton() button.setTitle("Purple", for: .normal) // button.setTitleColor(MyColor.purple.buttonColor, for: .normal) // button.backgroundColor = MyColor.purple.backgroudColor button.titleLabel?.font = UIFont.systemFont(ofSize: 15) // button.translatesAutoresizingMaskIntoConstraints = false return button }() lazy var buttons: [UIButton] = [redButton, greenButton, blueButton, purpleButton] lazy var colorButtonStackView: UIStackView = { let st = UIStackView(arrangedSubviews: [redButton, greenButton, blueButton, purpleButton]) st.axis = .horizontal st.spacing = 15 st.alignment = .fill st.distribution = .fillEqually return st }() // MARK: - Text View let mainTextView: UITextView = { let textView = UITextView() textView.backgroundColor = .clear textView.font = UIFont.systemFont(ofSize: 14) textView.textColor = .black return textView }() lazy var backgroundView: UIView = { let view = UIView() view.addSubview(mainTextView) view.backgroundColor = MyColor.red.backgroudColor return view }() // MARK: - Update Button let saveButton: UIButton = { let button = UIButton() button.titleLabel?.font = UIFont.systemFont(ofSize: 15) button.setTitleColor(.white, for: .normal) button.backgroundColor = MyColor.red.backgroudColor return button }() override init(frame: CGRect) { super.init(frame: frame) setupDetailView() setupButtonColor() setupConstraints() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setupDetailView() { self.backgroundColor = .white self.addSubview(colorButtonStackView) self.addSubview(backgroundView) self.addSubview(saveButton) backgroundView.clipsToBounds = true backgroundView.layer.cornerRadius = 10 saveButton.clipsToBounds = true saveButton.layer.cornerRadius = 8 layoutSubviews() } func setupConstraints() { setupColorButtonSVConstraints() setupBackgroundViewConstraints() setupMainTextViewConstraints() // 왜 이걸 설정하면 색깔 버튼의 cornerRadius가 변경이 안될까요? setupSaveButtonConstraints() // setupButtonCorner() } func setupColorButtonSVConstraints() { print(#function) colorButtonStackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ colorButtonStackView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: 25), colorButtonStackView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -25), colorButtonStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 20), // colorButtonStackView.bottomAnchor.constraint(equalTo: backgroundView.topAnchor, constant: -40), colorButtonStackView.heightAnchor.constraint(equalToConstant: 35) ]) } func setupBackgroundViewConstraints() { print(#function) backgroundView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ backgroundView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: 25), backgroundView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -25), backgroundView.topAnchor.constraint(equalTo: colorButtonStackView.bottomAnchor, constant: 40), // backgroundView.bottomAnchor.constraint(equalTo: saveButton.topAnchor, constant: -40), backgroundView.heightAnchor.constraint(equalToConstant: 200) ]) } func setupMainTextViewConstraints() { print(#function) mainTextView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ mainTextView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 15), mainTextView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor, constant: -15), mainTextView.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 8), mainTextView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -8) ]) } func setupSaveButtonConstraints() { print(#function) saveButton.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ saveButton.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: 25), saveButton.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -25), saveButton.topAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: 40), saveButton.heightAnchor.constraint(equalToConstant: 40) ]) } func setupButtonColor() { print(#function) buttons.forEach { button in button.setTitleColor(MyColor(rawValue: Int64(buttons.firstIndex(of: button)!) + 1)?.buttonColor, for: .normal) button.backgroundColor = MyColor(rawValue: Int64(buttons.firstIndex(of: button)!) + 1)?.backgroudColor } } override func layoutSubviews() { print(#function) super.layoutSubviews() setupButtonCorner() } func setupButtonCorner() { print(#function) buttons.forEach { button in button.clipsToBounds = true button.layer.cornerRadius = button.bounds.height / 2 } } }
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
Capturing Valus
cloule 3번째 강의에서 // Capturing Valus// reference Type(class, function, closure)// value Type(Int, String, Array, Dictionary, struct)라고 알려주셨는데 String은 reference type가아닌가요?
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
안녕하세요 todolist강의중에서 UI구성중 xib파일 오토레이아웃질문입니다.
안녕하세요 xib파일에서 오토레이아웃 설정중에 오류가 나와서 질문드려요위와같이 xib파일에서 테이블셀에 오토레이아웃을 적용했는데 시뮬레이터에서는 오토레이아웃이 적용이안되고있습니다. xocde껐다 실행하기와 컴퓨터를 껐다켰는데도 이러는데 혹시 왜이러는건지 질문드려도될까요?
-
미해결앨런 iOS Concurrency(동시성) - 디스패치큐와 오퍼레이션큐의 이해
global큐에 sync로 작업을 보냈을 때는 터지지 않는 이유가 궁금합니다.
안녕하세요.강의 잘 듣고 있습니다!sync를 공부하다가 의문이 생겨서 질문 남깁니다.메인스레드에서 메인큐로 sync로 작업을 보내면ui를 보여줘야할 메인에서 작업을 한없이 기다리게 되니 크래시가 난다고 알고 있습니다.강의에서, 메인에서 글로벌큐로 sync로 작업을 보내더라도 실질적으로는 메인에서 작업을 한다고 하셨는데요.그렇다면 실질적으로는 메인에서 sync로 작업을 하는 것과 다를 바가 없는데, 그런 경우에는 왜 크래시가 발생하지 않는 건가요?
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
환율 강의 테이블뷰에서 데이터 관련 질문있습니다.
안녕하세요 강의진행하면서 궁금한게있어서 질문드립니다.저의 경우 처음 Picker 뷰에서 rates배열에 url로 데이터 파싱한 데이터를 Table탭에서 delegate패턴을 이용해서 가져오는식으로 데이터를 가져오려 했습니다.먼저 Picker코드입니다. // // ViewController.swift // Exchange Rate // // // import UIKit class PickerViewController: UIViewController { @IBOutlet weak var usdTextField: UITextField! @IBOutlet weak var selectedCurrency: UITextField! @IBOutlet weak var selectedCurrencyName: UILabel! @IBOutlet weak var currencyPicker: UIPickerView! var rates: [(String,Double)]? // table data delegate weak var delegate: tableDataDelegate? // picker row변화에 따른 observer property 계산 var selectedRow = 0 { didSet { selectedCurrencyName.text = rates?[selectedRow].0 selectedCurrency.text = calculateCurrency() } } func calculateCurrency() -> String { let selectedValue = rates?[selectedRow].1 ?? 0 let usdValue = Double(usdTextField.text ?? "") ?? 0 let resultValue = String(format: "%.2f", (selectedValue * usdValue)) return resultValue } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.navigationItem.title = "Currency Converter Picker" fetchJson() //picker 연결 currencyPicker.delegate = self currencyPicker.dataSource = self // textField delegate usdTextField.delegate = self // porotcol delegate } func fetchJson() { let urlString = "https://open.er-api.com/v6/latest/USD" guard let url = URL(string: urlString) else {return} // data task URLSession.shared.dataTask(with: url) { data, res, err in guard let data = data else {return} do { let currencyModel = try JSONDecoder().decode(CurrencyModel.self,from: data) // rates: [key:value] 형태 // let rates = currencyModel.rates?.map { [$0 : $1] } // let rates2 :[(String,Double)]? = currencyModel.rates?.sorted(by: { dic1, dic2 in // dic1.key < dic2.key // sorted같은걸하면 Dictionary.Element가되서 tuple로 바뀜 // }) self.rates = currencyModel.rates?.sorted{ $0.key<$1.key } // picker 새로고침해야 데이터 내용이 보임 DispatchQueue.main.async { self.currencyPicker.reloadAllComponents() } // get table data print("rate: ",self.rates!) self.delegate?.getData(data: self.rates! ) // print("currentModel",currencyModel) } catch { print(err!) } }.resume() } } extension PickerViewController:UIPickerViewDelegate,UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return rates?.count ?? 0 } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { let key = rates?[row].0 ?? "" let value = rates?[row].1.description ?? "" return key + " " + value } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { selectedRow = row } } extension PickerViewController:UITextFieldDelegate { func textFieldDidChangeSelection(_ textField: UITextField) { selectedCurrency.text = calculateCurrency() } } 저의 경우 DispatchQueue.main.async { self.currencyPicker.reloadAllComponents() } // get table data print("rate: ",self.rates!) self.delegate?.getData(data: self.rates! )여기서 rates가 전부불어와지면 delegate를 이용해서 해당데이터를 table뷰로 가져오려고 의도했습니다. table데이터입니다.// // ListViewController.swift // Exchange Rate // // import UIKit protocol tableDataDelegate:AnyObject { func getData(data:[(String,Double)]) } class ListViewController: UIViewController { // Data list var conData = [(String,Double)?]() @IBOutlet weak var udsLabel: UILabel! @IBOutlet weak var costTextField: UITextField! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.navigationItem.title = "Currency Converter Table" self.udsLabel.text = "UDS" // table // tableView.delegate = self tableView.dataSource = self let sb = UIStoryboard(name: "Main", bundle: nil) guard let detailVC = sb.instantiateViewController(withIdentifier: "PickerViewController") as? PickerViewController else {return} detailVC.delegate = self tableView.rowHeight = 100 } } extension ListViewController:UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { print("cor: ",conData) return 10 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell") as! MyTableViewCell cell.currencyLabel.text = "good" cell.valueLabel.text = "allaal" return cell } } extension ListViewController: tableDataDelegate{ func getData(data: [(String,Double)]) { print("data: ",data) self.conData = data // print(self.conData) } } 여기서 delegate프로토콜을 만들고 Picker뷰에서 가져온 데이터를 conData라는 배열에 담아서 저는 담겨진 데이터를 이용해서 테이블뷰에 데이터를 뿌리는식으로 작업하려했는데 이런식으로 하니 프로토콜이 제대로 안되서인지 conData에 데이터가 담기지 않고 빈배열이 나옵니다.. 저의경우 table뷰에서 델리게이트를 사용한다고 위임하는 코드를 let sb = UIStoryboard(name: "Main", bundle: nil) guard let detailVC = sb.instantiateViewController(withIdentifier: "PickerViewController") as? PickerViewController else {return} detailVC.delegate = self이렇게 Main에있는 스토리보드를 가져와서 권환을 위임했는데 이게 틀린걸까요?어디가 잘못됐는지 잘모르겠습니다.. 답변 부탁드립니다!
-
미해결성공적인 진짜 iOS 개발자 되기 [기초부터 실무까지]
환율 네트워크처리1 질문있습니다.
안녕하세요 강의 41:46분에pickerView 의 delegate중에서 didSelecRow에 관해서 궁금한게있는데 해당 delegate속성이 picker로인해 선택된 row를 반환해준다고 알고있습니다.궁금한게[ didSeleectRow가있는 delegate메서드를 사용하려면 저는 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { selectedRow = row } 여기 함수안에서 var selectedRow = 0 { didSet { selectedCurrencyName.text = rates?[selectedRow].0 selectedCurrency.text = calculateCurrency() } }위에 해당하는 코드를 작성해야 함수가 작동된다고 생각했는데 강사님 강의보니 그게아니더라구요 왜 그런건가요? 가만생각해보니 didSelecRow에서 현재 선택된 row정보만 얻기위한 용도로 pickerView didSelectRow 델리게이트 메서드를 이용했고 row정보를 얻었으니 화면에 뿌려주는 역활은 굳이 안해도되기떄문에 위의코드처럼 따로 didSet속성을 이용해서 화면을 나타낸걸로 이해했는데 제가 이해한게 맞을까요?