Swift로 둘 이상의 사용자 지정 셀이있는 UITableview


111

다른 사용자 정의 tableViewCell과 함께 UITableview를 사용하고 싶습니다. 내 3 개의 셀은 다음과 같습니다.

  • Cell1 : 이미지와 레이블이 있어야합니다.
  • Cell2 : 두 개의 레이블이 있어야합니다.
  • Cell3 : dayPicker가 있어야합니다.

셀에 대한 태그를 코딩하고 싶지 않습니다. Swift에서 어떻게 관리 할 수 ​​있습니까? 모든 셀에 대해 고유 한 클래스를 코딩해야합니까? 하나의 tableviewController를 사용할 수 있습니까? 다른 셀에 데이터를 어떻게 채울 수 있습니까?

iOS 장치의 연락처 앱과 같은 tableView를 생성하고 싶습니다.



답변:


270

먼저 질문에 대한 답변부터 시작하겠습니다.

모든 셀에 대해 고유 한 클래스를 코딩해야합니까? => 예, 그렇게 생각합니다. 적어도 나는 그렇게 할 것입니다.

하나의 tableviewController를 사용할 수 있습니까? => 예, 할 수 있습니다. 그러나 뷰 컨트롤러 내에 테이블 뷰를 가질 수도 있습니다.

다른 셀에 데이터를 어떻게 채울 수 있습니까? => 조건에 따라 다른 셀에 데이터를 채울 수 있습니다. 예를 들어 처음 두 행이 첫 번째 유형의 셀과 같기를 원한다고 가정합니다. 따라서 첫 번째 유형의 셀을 생성 / 재사용하고 데이터를 설정하기 만하면됩니다. 스크린 샷을 보여 주면 더 분명해질 것 같아요.

ViewController 내부의 TableView가있는 예제를 보여 드리겠습니다. 기본 개념을 이해하면 원하는대로 시도하고 수정할 수 있습니다.

1 단계 : 사용자 지정 TableViewCell 3 개를 만듭니다. 이름을 FirstCustomTableViewCell, SecondCustomTableViewCell, ThirdCustomTableViewCell로 지정했습니다. 더 의미있는 이름을 사용해야합니다.

여기에 이미지 설명 입력

2 단계 : Main.storyboard로 이동하여 View Controller 내부에 TableView를 끌어다 놓습니다. 이제 테이블보기를 선택하고 ID 검사기로 이동합니다. "Prototype Cells"를 3으로 설정합니다. 여기서 방금 TableView에 3 가지 종류의 셀이있을 수 있다고 말했습니다.

여기에 이미지 설명 입력

3 단계 : 이제 TableView와 ID 검사기에서 첫 번째 셀을 선택하고 Custom 클래스 필드에 "FirstCustomTableViewCell"을 입력 한 다음 속성 검사기에서 식별자를 "firstCustomCell"로 설정합니다.

여기에 이미지 설명 입력

여기에 이미지 설명 입력

다른 모든 사용자에 대해 동일한 작업을 수행합니다. 사용자 지정 클래스를 각각 "SecondCustomTableViewCell"및 "ThirdCustomTableViewCell"로 설정합니다. 또한 식별자를 secondCustomCell 및 thirdCustomCell로 연속적으로 설정합니다.

4 단계 : 사용자 지정 셀 클래스를 편집하고 필요에 따라 콘센트를 추가합니다. 귀하의 질문에 따라 편집했습니다.

PS : 클래스 정의 아래에 콘센트를 넣어야합니다.

따라서 FirstCustomTableViewCell.swift에서

class FirstCustomTableViewCell: UITableViewCell {

당신은 당신의 라벨과 이미지보기 콘센트를 넣을 것입니다.

 @IBOutlet weak var myImageView: UIImageView!
 @IBOutlet weak var myLabel: UILabel!

SecondCustomTableViewCell.swift에서 다음과 같이 두 개의 레이블을 추가하십시오.

import UIKit

class SecondCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var myLabel_1: UILabel!
    @IBOutlet weak var myLabel_2: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

그리고 ThirdCustomTableViewCell.swift는 다음과 같이 보일 것입니다.

import UIKit

class ThirdCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var dayPicker: UIDatePicker!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

5 단계 : ViewController에서 TableView에 대한 Outlet을 만들고 스토리 보드에서 연결을 설정합니다. 또한 클래스 정의에 UITableViewDelegate 및 UITableViewDataSource를 프로토콜 목록으로 추가해야합니다. 따라서 클래스 정의는 다음과 같아야합니다.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

그런 다음 테이블 뷰의 UITableViewDelegate 및 UITableViewDatasource를 컨트롤러에 연결하십시오. 이 시점에서 viewController.swift는 다음과 같이 보일 것입니다.

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

추신 : ViewController 내부에서 TableView가 아닌 ​​TableViewController를 사용한다면이 단계를 건너 뛸 수 있습니다.

6 단계 : Cell 클래스에 따라 이미지 뷰와 레이블을 셀에 끌어다 놓습니다. 그런 다음 스토리 보드에서 콘센트에 대한 연결을 제공합니다.

7 단계 : 이제 뷰 컨트롤러에서 UITableViewDatasource의 필수 메서드를 작성합니다.

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
            //set the data here
            return cell
        }
        else if indexPath.row == 1 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
            //set the data here
            return cell
        }
        else {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
            //set the data here
            return cell
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

1
func cellForRowAtIndexPath에 " 'UITableViewCell'(0x1dfbfdc) 유형의 값을 'Projekt.TitelTableViewCell'(0x89568)로 캐스팅 할 수 없습니다."라는 메시지가 표시됩니다. 저는 UITableViewController를 사용하고 있으며 "TitelZelle"셀의 ID 검사기에서 설정 한 사용자 지정 셀 "TitelZelle"에 대해 "TitelTableViewCell"클래스가 있습니다. 무엇을해야합니까?
Easyglider

나는 내 세포를 캐스팅했습니다! TitelTableViewCell을 사용하여이 셀의 사용자 정의 UI 요소를 채 웁니다.
Easyglider 2015-06-12

7
TitelTableViewCell 등이 시도 => 세포 = tableView.dequeueReusableCellWithIdentifier (indexPath "TitelZelle", forIndexPath)하자
나타샤

2
@PradipKumar, 문제가 무엇입니까? 당신의 오류는 무엇입니까? Btw, 질문이 있으면 질문해야합니다. 특정 문제와 관련하여이를 이해하거나 명확히하는 데 도움이되는 댓글은 작성자가 게시했습니다. 문제가 있으면 질문하고 자신의 게시물을 시작해야합니다.
나타샤

1
numberOfRowsInSection은 tableview가 원하는 행 수를 결정하는 데 도움이됩니다. 따라서 메서드가 행 수를 결정하는 데 도움이되는 절만 제공해야합니다. indexpath.row == 0은 이미 행이 있지만 그 당시 테이블은 행이 있는지 여부를 알 수 없음을 의미합니다. 그래서 그렇게해야합니다.
Natasha

32

Swift 3.0 + 최소 코드로 업데이트

기본 개념 : 동적 셀 프로토 타입을 사용하여 테이블보기를 만듭니다. 식별자를 할당하고 각 셀 프로토 타입에 대한 사용자 정의 테이블보기 셀 클래스를 만듭니다. 테이블보기의 델리게이트 메서드에서 사용자 지정 셀을 시작하고 표시합니다.

1. 스토리 보드에 셀 만들기

tableView를 뷰 컨트롤러로 드래그하고 프로토 타입 셀을 추가 한 다음 UI 요소를 테이블 뷰 셀에 드롭하고 필요한 경우 제약 조건을 적절하게 추가합니다.

여기에 이미지 설명 입력

2. 사용자 정의 UITableViewCell클래스 만들기

프로젝트에 다음 코드를 추가하십시오. 뷰 컨트롤러 클래스 바로 위에 놓았습니다.

class FirstTableCell: UITableViewCell {
}

class SecondTableCell: UITableViewCell {
}

class ThirdTableCell: UITableViewCell {   
}

3. 셀 프로토 타입에 사용자 정의 클래스 및 식별자 할당

스토리 보드의 각 셀 프로토 타입에 대해 2 단계에서 만든 사용자 지정 클래스를 할당 한 다음 고유 식별자를 입력합니다.

여기에 이미지 설명 입력

4. UI 요소를 신속한 코드에 연결

컨트롤 드래그 테이블 뷰를 뷰 컨트롤러 클래스에 연결합니다. 1 단계에서 셀 프로토 타입에 추가되는 UI 요소를 제어하고 해당 테이블보기 셀 클래스에 연결하십시오.

여기에 이미지 설명 입력

5. 컨트롤러보기 및 테이블보기 제어를위한 코드 추가

뷰 컨트롤러가 테이블 뷰 델리게이트를 따르도록합니다.

class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate

에서 viewDidLoad테이블 뷰의 델리게이트 및 데이터 소스를 설정합니다.

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.dataSource = self
    self.tableView.delegate = self

}

마지막으로 최소 요구 사항에 따라 테이블보기를 제어하는 ​​두 가지 대리자 메서드를 추가합니다.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
        // Set up cell.label
        return cell
    } else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
        // Set up cell.button
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
        // Set up cell.textField
        return cell
    }
}

6. 한번 시도해보세요 :)

여기에 이미지 설명 입력


환상적입니다! 나는 당신의 애니메이션을 좋아합니다.
iphaaw

각 셀에 헤더를 넣을 수 있습니까? 그렇다면 어떻게?
Pruthvi Hariharan

@PruthviHariharan 모든 또는 대부분의 셀에 대해 "헤더"를 사용하려는 경우 관리에 더 많은 코드가 필요하고 성능에 영향을주는 헤더 셀 또는 섹션 헤더를 구현하는 것은 좋지 않습니다. 내 제안은 프로토 타입 셀 위에 뷰를 배치하고 "헤더"처럼 보이게하는 것입니다
Fangming

@FangmingNing 작은 예를 들어 설명해 주시겠습니까? 감사합니다
Pruthvi Hariharan

UIViewController 대신 UITableViewController를 사용하는 경우 5 단계가 필요하지 않습니다.
Deepak Thakur

0

위의 답변이 가장 좋은 답변이지만이 문제가 발생하는 데는 수많은 이유가 있습니다. 이 문제가있는 사람을위한 또 다른 잠재적 인 해결책은 다음과 같습니다.

내 문제는 스토리 보드 뷰가 아닌 ViewController 클래스에 속한다는 것입니다. 그래서 스토리 보드 셀에 대한 나의 참조는 스토리 보드가 사용되지 않았기 때문에 의미가 없었습니다.

나는 이것을하고 있었다 :

let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)

그리고 다음과 같이해야했습니다.

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "SubViewStoryboardController") as! SubViewController
nextViewController.passedData = diseases[indexPath.row].name
self.present(nextViewController, animated:true, completion:nil)

이것이 누군가를 돕기를 바랍니다.


-22

UITableViewController상속 UIViewController이미 것을 UITableviewDataSourceUITableviewDelegate자체에 매핑.

하위 클래스를 UITableViewController사용 TableView하거나 ViewController. 그 후에 cellForRowAtIndexPath and numberOfRowsInSection.NET Framework에서 선언 된 필수 메서드 ( )를 구현해야 합니다 UITableviewDataSource.

또한 스토리 보드에서 고유 한 ID로 셀 프로토 타입을 만들어야합니다.

(예 : 제목, 부제)와 함께 기본 유형의 셀이 있습니다. 특별한 구성이 필요하지 않은 경우에도 사용할 수 있습니다.

따라서 선택기의 경우 사용자 지정 셀을 만들어야합니다. UITableViewCell날짜 선택기를 포함하는 필요한 사용자 지정 클래스를 만들고 델리게이트를 사용하여 원하는 결과를 ViewController.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.