xcode7.x Swift 에 대해서 질문이 있습니다.(1. 컨테이너뷰란?, 2.테이블뷰의 셀을 선택함에 따라서 연결되지않은 테이블에도 영향을 줄수있는가?)

조회수 1810회

안녕하세요. 현재 처음으로 ios 어플을 만들어보고 있는 학생입니다.

현재 제가 만들고자 하는 화면은 3분할을 하여 한번에 띄우려고 합니다. 궁금한 부분은 '스플릿뷰컨트롤러'는 아이패드가 아니면 그렇게 의미가 있지 않다고 알고있습니다. 시뮬레이터를 돌려봤더니 6s plus 이외에는 화면이 분할되어 보이지도 않더군요.... 그래서 찾은 방법이 '컨테이너뷰' 인데요 제가 원하는데로 화면이 각각 따로따로 구역이 나누어져 보이더군요.... 거기까지는 좋았지만 처음써보다 보니 이렇게 쓰는게 맞는건지 제가 이 기능을 알맞게 효율적으로 사용하는지 궁금합니다. 물론 애플의 공식사이트에서 한번 보기는 했지만 잘 이해가 안되서요...

이미지

두번째로는 3분할된 화면중 좌측의 테이블뷰의 셀이 선택됨에 따라서 우측 컨테이너 뷰에 미리 만들어둔 뷰를 호출할수 있는 방법을 알고싶습니다.

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    1 - 컨테이너 뷰란?

    컨트롤러 모두가 공유 할 수 있는 재사용 가능한 뷰를 구성할 수 있는 뷰입니다. 컨테이너뷰 전에는 UIView를 통해 재사용 가능한 뷰를 사용 했는데 스토리보드에는 별도로 볼 수 없었는데 그걸 보완한 뷰라고 할 수 있습니다.

    2 - 조금 복잡하기는 하지만 뷰를 호출할수 있습니다..

    부모뷰에서 prepareForSegue를 통해 컨테이너뷰 이름으로 판별해서 컨테이너뷰를 잡아 줍니다. 중요한건 컨테이너뷰가 호출 되기전에 prepareForSegue가 호출되고 컨테이너뷰의 클래스가 호출이 됩니다. 초기값이 필요한 컨테이너뷰라면 여기서 초기값 세팅해주면 됩니다.

    import UIKit
    
    class ViewController: UIViewController, VcTableDelegate {
    
        var vc_button : Vc_button? = nil
        var vc_table : Vc_table? = nil
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
        {
    
            //여기서 호출된 후 각 컨테이너뷰에 연결된 클래스로 이동해서 viewDidLoad()호출 됨
            if (segue.identifier == "buttonview") {
                vc_button = segue.destinationViewController as? Vc_button
                //vc_button?.delegate = self
                vc_button?.str_title = "Hello World"
    
            } else if (segue.identifier == "tableView") {
                vc_table = segue.destinationViewController as? Vc_table
                vc_table?.delegate = self
            }
        }
    
        //델레게이트를 통해 값을 전달
        func func_cellSelect(str: String) {
            self.vc_button!.func_recevieTableCell(str)
        }
    }
    

    Vc_button 클래스

    import UIKit
    
    class Vc_button: UIViewController {
    
        var str_title = ""
    
        @IBOutlet var lb_title: UILabel!
        @IBOutlet var iv_suji: UIImageView!
        @IBOutlet var view_back: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            lb_title.text = str_title
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
        //받은 값을 통해 UI 변경
        func func_recevieTableCell(str : String) {
    
            switch str {
            case "라벨 바꾸기":
                lb_title.text = str
            case "사진 보여주기":
                iv_suji.image = UIImage(named: "a2.jpg")
            case "뷰 백그라운드 바꾸기":
                view_back.backgroundColor = UIColor.yellowColor()
            default:
                break
            }
        }
    }
    

    Vc_table 클래스 에서 테이블 뷰를 세팅 해준다음에 셀이 선택함에 따라 델레게이트를 통해 옆에 컨테이너뷰에 값을 변경 해주면 될거 같습니다.

    import UIKit
    
    protocol VcTableDelegate : class {
        func func_cellSelect(str : String)
    }
    
    class Vc_table: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
        weak var delegate:VcTableDelegate?
    
        @IBOutlet var tb_table: UITableView!
        let arr_list : [String] = ["라벨 바꾸기", "사진 보여주기", "뷰 백그라운드 바꾸기"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            tb_table.delegate = self
            tb_table.dataSource = self
            tb_table.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        //MARK: 테이블뷰 델레게이트, 데이터소스
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return arr_list.count
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
            cell.textLabel?.text = arr_list[indexPath.row]
            return cell
    
        }
    
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            //델레게이트로 부모뷰에 메소드 호출
            delegate?.func_cellSelect(arr_list[indexPath.row])
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
        }
    
        func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            return 50;
        }
    
    }
    
    

    전체 코드는 이 [링크][1]를 통해서 다운 받아서 확인 해보세요. (드랍박스 링크입니다.)

    그리고 컨테이너뷰에 대해 기본적인 세팅은 여기를 참조 하시면 좋을꺼 같습니다.

    궁금한점이나 안되는 부분이 있으면 댓글로 말씀해주세요. 확인해보고 아는 범위 안에서 대답해드리겠습니다.

    그리고 틀린 점이 있다면 언제든지 편집요청해주세요. :)

    [1]: https://www.dropbox.com/s/nsh43f1b61u5z2c/contaierview.zip

    • 정말정말 감사드립니다. 막막했던 부분에 대해 자세히 알려주시고 참고자료까지 알려주셔서 감사드립니다.!! 한경민 2016.7.16 17:01
    • 혹시 구조체로 이루어진 배열도 보낼수 있나요??? 한경민 2016.7.19 15:27
    • 서로 뷰마다 구조체가 다르기때문에 아마 불가능하지 않을까 싶습니다. 하지만 뷰컨트롤러에 구조체를 만드는것이 아니라 classg화시키면 가능하지 않을까 싶습니다. NSObject로 하나 만든 다음에 그 안에서 데이터를 만든다면 보내는데 문제는 없을꺼 같습니다. myoung 2016.7.19 18:18
    • 감사합니다! 한경민 2016.7.19 18:39

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)