-
200928 - TILTIL/2021 2020. 9. 29. 02:32
Swift 문법
오늘도 새로운 진도를 나가지 않고 전에 배운 개념을 복습했다.
- 연산자
- 조건문
- Value Binding Pattern
iOS
테이블 뷰의 값을 전달하기
저번에 구현에 실패한 테이블 뷰의 값을 다음 화면에 전달하는 앱 구현에 성공했다.
저번 실패의 원인은 두 번째 화면의 연결이 잘못된 게 문제였다.
분명 연결을 잘 시켜서 화면이 넘어가는 것까지 확인했었는데 어떤 원인으로 잘못 연결이 되었는지 모르겠다....
import Foundation struct Person { let name: String let address: String }
테이블 뷰의 값은 구조체로 선언을 했고 프로퍼티로 name과 address를 가진다.
var list: [Person] = [ Person(name: "Beepeach", address: "Korea"), Person(name: "Zelda", address: "Hyrule"), Person(name: "Apple", address: "US") ]
구조체 배열을 만들어서 세개의 인스턴스를 생성했다.
가려진 비밀번호를 확인하는 경우와 비슷하게
- 이름을 클릭한다.
- 두번째 화면이 메모리에 생성된다.
- prepare(for:sender:) 메서드가 실행된다.
- 두 번째 화면(segue.destination)의 Action과 Outlet이 연결된다.
- 화면이 전환된다.
이 순서를 따르기 때문에 간단하게 list의 address의 값을 addressLabel.text에 넣을 수 없었고
가장 큰 문제는 내가 선택한 이름의 인덱스를 알아야 .address 프로퍼티에 접근할 수 있기 때문에 선택된 인덱스를 알아야 했다.
선택된 인덱스는 TableView가 알기때문에 listTableViews.indexPath(for:) 메서드를 이용하여 옵셔널 바인딩시켰다.
그리고 마찬가지로 두 번째 화면에서 프로퍼티를 생성하여 2번 순서에서 value가 생성되도록 하고 다운캐스팅을 통해 value 프로퍼티에 접근해서 선택한 배열을 저장했다.
guard let cell = sender as? UITableViewCell, let indexPath = listTableViews.indexPath(for: cell), let vc = segue.destination as? SecondViewController else { return } vc.value = list[indexPath.row]
그리고 두번째 화면에서 addressLabel.text에 value?.address를 저장했다.
addressLabel.text = value?.address
아래는 전체 코드이다.
import Foundation struct Person { let name: String let address: String }
import UIKit class ViewController: UIViewController { var list: [Person] = [ Person(name: "Beepeach", address: "Korea"), Person(name: "Zelda", address: "Hyrule"), Person(name: "Apple", address: "US") ] @IBOutlet weak var listTableViews: UITableView! // 1. 테이블뷰가 인덱스를 알려준다. // 2. 알려준 인덱스의 주소를 vc.value에 넣는다. override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let cell = sender as? UITableViewCell, let indexPath = listTableViews.indexPath(for: cell), let vc = segue.destination as? SecondViewController else { return } vc.value = list[indexPath.row] } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return list.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let p = list[indexPath.row] cell.textLabel?.text = p.name cell.detailTextLabel?.text = String(p.address) return cell } }
import UIKit class SecondViewController: UIViewController { var value: Person? @IBOutlet weak var addressLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() addressLabel.text = value?.address } }
아직 extension 부분은 이해가 되지 않았다. 보고 따라한 수준. 그리고 그 부분을 제외하고 내가 구현했지만 시간이 지나니까 다시 생소해졌다. 내일 다시 한번 만들어 봐야겠다.
728x90'TIL > 2021' 카테고리의 다른 글
201001 - TIL (0) 2020.10.02 200930 - TIL (0) 2020.10.01 200926 - TIL (0) 2020.09.27 200925 - TIL (0) 2020.09.26 200923 - TIL (0) 2020.09.24