본문 바로가기

ComputerScience/ios App(Storyboard)

ios - 14 Segue

728x90

1 목표

- 이전 포스트에 이어서 작업을 진행해보자.

- 이번에는 셀을 클릭하면 새로운 view controller 화면이 modal형식으로 나타나도록 해보자.

2 새로운 View Controller 추가

- 가장 먼저 할 것은 새로운 view controller를 추가하는 것이다.

- 아래 내용이 담긴 새로운 swift파일을 만든다.

import UIKit

class DetailViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

- storyboard에 새로운 View Controller object를 추가하고 이전에 만들었던 DetailViewController class와 연결한다.

3 Detail View Controller 꾸미기

- 새로운 view controller에 컴포넌트를 채워보자.

- button을 추가하여 outlet을 연결하고 image로 모양을 만든다.

- close 함수의 내부를 좀 살펴보자

- dismiss는 현재 view controller를 화면에서 사라지게 하는 함수이다.

- completion은 dismiss되고 난 후 동작할 내용을 전달하면 수행해준다. 현재는 nil로 되어있다.

- 이미지와 레이블을 넣고 outlet으로 연결한다.

4 두 View Controller 연결하기 (Segue)

- Bounty View Controller클릭 -> control키 누른채로 마우스를 Detail view Controller로 드래그 -> present Modally 선택

- 그럼 아래처럼 두 view controller가 연결된다. 

- 두 view controller를 연결하는 화살표를 세그웨이라고 하고 클릭해서 이름을 지어 주자. showDetail이라고 이름 지었다.

- Bounty View Controller의 셀이 클릭 되었을 때 segue를 수행하기 위한 코드를 넣어주자

- performSegue함수에 아까 showDetail이라고 이름 붙인 세그웨이를 전달해주자

import UIKit

class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
    let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]
    
    
    .....
    .....
    .....
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("---->  \(indexPath.row)")
        performSegue(withIdentifier: "showDetail", sender: nil)
    }

}

class ListCell: UITableViewCell {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
}

5 segue way로 연결된 View controller간의 데이터 전달

- bounty View controller에서 Detail view controller로 데이터를 전달하면 그 데이터를 받아서 viewDidLoad가 수행될때 ui를 업데이트 하도록 하자.

- viewDidLoad는 view controller가 메모리에 올라오자마자 바로 실행되는 함수이다.

import UIKit

class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
    let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]
    
    ...
    ...
    ...
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("---->  \(indexPath.row)")
        performSegue(withIdentifier: "showDetail", sender: indexPath.row)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            let vc = segue.destination as? DetailViewController
           
            if let index = sender as? Int {
                vc?.name = nameList[index]
                vc?.bounty = bountyList[index]
            }
        }
    }
}

class ListCell: UITableViewCell {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
}

- BountyViewController에서 어떤 셀이 눌렸을 때 segue를 수행하기 위해 performSegue를 호출했다. 이때 sender로 클릭된 셀의 index를 넘긴다.

- 그럼 이 sender를 prepare라는 함수가 받아서 세그웨이로 값을 전달 할 수 있다.

- prepare는 performSegue 수행 전, 준비하는 단계이다. 먼저 "showDetail" Segue way로 값을 전달할 것이고 segue의 목적지(뷰컨트롤러)를 vc에 저장한다.

- sender로 넘겨받은 index를 활용해서 목적지인 vc의 name과 bounty에 데이터를 저장한다. 

import UIKit

class DetailViewController: UIViewController {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
    
    var name: String?
    var bounty: Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }
    
    func updateUI() {
        if let name = self.name, let bounty = self.bounty {
            let img = UIImage(named: "\(name).jpg")
            imgView.image = img
            nameLabel.text = name
            bountyLabel.text = "\(bounty)"
        }
    }
    @IBAction func close(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
}

- detail view controller에서는 값을 전달 받고 내용을 업데이트 해야 한다.

- detail view controller가 메모리에 올라와서 수행되려고 하면 가장먼저 viewDidLoad의 내용이 실행된다.

- updateUI는 segue way로 전달받은 name bounty를 가지고 현재 연결된 UI 컴포넌트를 초기화 해준다.

6 결과 확인

728x90
반응형

'ComputerScience > ios App(Storyboard)' 카테고리의 다른 글

ios - 16 CollectionView  (0) 2021.08.03
ios - 15 Design Pattern  (0) 2021.08.02
ios - 13 Custom Cell  (0) 2021.07.28
ios - 12 Table View, Table View Cell  (0) 2021.07.25
ios - 11 swift 기본문법(Class)  (0) 2021.07.25