스위프트의 테이블 뷰 컨트롤러 작업
에서 테이블 뷰 컨트롤러 작업 이 자습서에서는 테이블 뷰 컨트롤러의 작동 방식과 사용 방법을 단계별로 보여 드리겠습니다. 우리는 객체 지향 프로그래밍,위임 및 테이블 뷰의 비하인드 메커니즘에 뛰어 들어UITableViewController
의 전체 영역에 들어갈 것입니다.
테이블 뷰 컨트롤러는 구조화되고 반복 가능한 정보를 수직 목록에 표시합니다. 9268>클래스를 사용하여 테이블 뷰 컨트롤러를 빌드합니다.테이블 뷰 컨트롤러로 작업하는 것은 서브클래싱,위임 디자인 패턴 및 뷰 재사용과 같은 몇 가지 중요한 개발 개념을 사용하는 것을 의미합니다.
그것은 전문적이고 실용적인 이오스 개발자를위한 중요(당신!)테이블 뷰 컨트롤러 작업을 마스터합니다. UITableViewController
과 같은 다각적 인 사용자 인터페이스 구성 요소에 대한 작업에 익숙해지면 다른 더 복잡한 측면도 이해되기 시작할 것입니다.
준비 됐어? 의 다이빙 보자!
- 테이블 뷰 컨트롤러의 작동 방식
- 간단한 테이블 뷰 컨트롤러 설정
- 테이블 뷰 컨트롤러 데이터 소스 코딩
- 테이블 뷰 컨트롤러에 셀 제공
- 사용자 상호 작용에 응답
- 추가 읽기
테이블 뷰 컨트롤러의 작동 방식 뷰 컨트롤러 작동
이전에 테이블 뷰 컨트롤러를 사용한 적이 있습니다. 그들은 이오스 애플 리케이션에서 자주 사용하고 있습니다!
다음은 테이블 뷰 컨트롤러의 예입니다:
테이블 뷰 컨트롤러에는 일반적으로 다음과 같은 표시 구성 요소가 있습니다:
- 화면에 표시되는 사용자 인터페이스 구성 요소인 테이블 뷰 또는 뷰입니다. 테이블 뷰는
UITableView
클래스의 인스턴스이며UIScrollView
의 하위 클래스입니다. - 테이블 뷰에 표시된 반복 가능한 행 또는 뷰인 테이블 뷰 셀입니다. 테이블 뷰 셀은
UITableViewCell
클래스의 인스턴스이며,이 클래스는 종종 사용자 지정 테이블 뷰 셀을 만들기 위해 서브클래스됩니다.
테이블 뷰 컨트롤러는 또한 이러한 구성 요소의 사용에 의존합니다.:
- 테이블 뷰 대리자로,테이블 뷰의 레이아웃을 관리하고 사용자 상호 작용 이벤트에 응답합니다. 테이블 뷰 대리자는
UITableViewDelegate
클래스의 인스턴스입니다. - 테이블 뷰 셀 및 섹션을 포함하여 테이블 뷰의 데이터를 관리하는 테이블 뷰 데이터 원본입니다. 데이터 소스는
UITableViewDataSource
클래스의 인스턴스입니다.
탐색 컨트롤러는 종종 테이블 뷰 컨트롤러와 함께 테이블 뷰와 후속 뷰 컨트롤러 간의 탐색을 활성화하고 테이블 뷰 위에 탐색 모음을 표시하는 데 사용됩니다.
테이블 뷰 컨트롤러 작업의 가장 흥미로운 부분은 테이블 뷰 컨트롤러 자체입니다! 어떻게 그렇게?
모델 뷰 컨트롤러 아키텍처에 대해 잘 알고 있습니까? 모델 뷰 컨트롤러 아키텍처에 따라 테이블 뷰와 테이블 뷰 셀은 뷰이며 테이블 뷰 컨트롤러는 컨트롤러입니다.
보기는 사용자 인터페이스를 사용하여 사용자에게 정보를 눈에 띄게 표시합니다. 컨트롤러는 논리 구현,데이터 관리 및 의사 결정을 담당합니다. 다르게 말했다:당신은 컨트롤러를 볼 수 없습니다,하지만 거기,당신이보기를 통해 보는 것을 관리.
앱에서 테이블 뷰 컨트롤러를 사용할 때UITableViewController
클래스를 서브클래싱하는 것입니다. 이 클래스의 하위 클래스는 다음과 같습니다.
다음은 연락처 정보를 표시하는 예제 테이블 뷰 컨트롤러의 클래스 계층 구조입니다:
-
ContactsTableViewController
- 하위 클래스 인스턴스
UITableViewController
- 하위 클래스
UIViewController
- 하위 클래스
- 하위 클래스 인스턴스
객체 지향 프로그래밍의 원칙에 따라 클래스RaceCar
서브 클래스Vehicle
는maxSpeed
및drive()
와 같은 수퍼 클래스의 속성과 기능을 상속합니다.
Vehicle
클래스는RaceCar
의 수퍼 클래스라고합니다. 이 원칙을 상속이라고합니다.
혼란 스럽습니까? 그것은 될 수 있습니다! 이 같은 그것에 대해 생각: 테이블 뷰 컨트롤러가 제대로 작동하려면 여러 코드를 상속해야 하므로 모든 코드를 직접 작성할 필요가 없습니다. 클래스 계층 구조 및 웁은 그 상속을 구조화하기 위해 존재합니다.
테이블 뷰 컨트롤러를 사용하지 않고 테이블 뷰로 작업할 수 있습니다. 뷰 컨트롤러에UITableView
을 추가하고 테이블 뷰 대리자 및 데이터 소스 함수의 구현을 제공하면됩니다.
UITableViewController
클래스는 이러한 테이블 뷰 대리자 및 테이블 뷰 데이터 원본 함수의 기본 구현을 제공합니다. 즉,테이블 뷰 컨트롤러 작업의 중요한 측면이다!
이 튜토리얼의 다음 장에서 볼 수 있듯이,우리는 우리 자신의 구현으로 이러한 기능을 재정의합니다. 이를 통해 테이블 뷰 컨트롤러를 사용자 정의 할 수 있습니다.
개발 과정에 가입하여 스위프트 5 와 엑스코드 12 와 함께 훌륭한 앱을 빌드하는 방법에 대해 알아보세요.
간단한 테이블 뷰 컨트롤러 설정
좋아,연습으로 모든 것을 넣어 보자. 이 섹션에서는 간단한 테이블 뷰 컨트롤러를 만들 것입니다. 당신은 그것을 작동하게하는 데 필요한 기능을 구현하는거야,나는 그들이 우리가 함께 가서 어떻게 작동하는지 설명 할 것이다. 이제 이동하자!
:
- (기술적으로는 스위프트투이도 사용할 수 있지만,테이블 뷰 컨트롤러는 이 자습서의 범위를 벗어납니다.)
그것은 지루하고 손으로 사용자 정의 코드를 비생산적이다. 스토리보드를 조심하지 않으면 개발자가 복잡성을 숨깁니다. 스토리보드와 함께 작업하면서 스토리보드가 무대 뒤에서 어떻게 작동하는지 정확히 파악합니다.
다음은 무엇을 할 거 야:
먼저,파일을 통해 새 엑스 코드 프로젝트를 만듭니다. 응용 프로그램 템플릿을 선택 하 고 인터페이스에 대 한 스토리 보드를 선택 해야 합니다.
그런 다음 다음 단계를 수행하십시오:프로젝트 네비게이터에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 새 파일을 선택합니다…
UITableViewController
와 함께 파일을 저장하십시오.:
-
Main.storyboard
로 이동하여 기존 뷰 컨트롤러 장면 제거 - 라이브러리를 통해 스토리보드에 새 테이블 뷰 컨트롤러 추가
- 테이블 뷰 컨트롤러를 선택한 상태에서 속성 검사기로 이동하여 초기 뷰 컨트롤러 확인란
- 를 선택합니다.
ContactsTableViewController
그게 다야! 이제 프로젝트의 스토리 보드 안에 테이블 뷰 컨트롤러가 있고ContactsTableViewController
스위프트 클래스에 연결했습니다.
짐작했듯이ContactsTableViewController
클래스는UITableViewController
의 하위 클래스입니다. 당신은 클래스 선언의 상단에,스위프트 파일에서 볼 수 있습니다.
class ContactsTableViewController: UITableViewController { ···
이 구문은ContactsTableViewController
클래스가UITableViewController
의 하위 클래스임을 의미합니다.
옵션 키를 누른 상태에서”뷰 컨트롤러”를 마우스 오른쪽 단추로 클릭하면 클래스 선언에서UITableViewController
이UIViewController
의 하위 클래스이며UITableViewDelegate
및UITableViewDataSource
프로토콜을 따르는 것을 볼 수 있습니다.
즉,테이블 뷰 컨트롤러의 힘이다! 그것은 단지 우리에게 테이블 뷰를 만들기 위해 개별 구성 요소를 제공하지 않습니다,컨트롤러는 또한 기본 구현을 제공합니다. 그래서 테이블 뷰가있는 빈 뷰 컨트롤러를 만드는 대신UITableViewController
을 서브 클래스합니다.
이 시점에서Command-R
또는 재생 버튼으로 앱을 실행하고 빈 테이블보기 컨트롤러가 화면에 나타나는 것을 볼 수 있습니다.
왜 그런가요? 우리는 아직 아무것도 코딩하지 않았습니다! 테이블 뷰 컨트롤러에는 기본 구현이 있기 때문에 화면에 빈 셀이 표시됩니다. 깔끔한!
엑스 코드의 버전에 따라,우리는 당신의 앱 프로젝트의 초기 뷰 컨트롤러를 설정하는 장면 대리자를 사용했습니다. 자세한 내용은 여기를 참조하십시오:엑스 코드의 장면 위임
사이브와 펜촉은 기본적으로 같은 것입니다–그들은 레이아웃 정보를 포함합니다. 펜촉은 바이너리 형식입니다. 이것은 프로그래밍 언어와 컴파일러를 내장합니다..
테이블 뷰 컨트롤러 데이터 소스 코딩
이제 테이블 뷰 컨트롤러가 설정되었으므로 다시 실행해 보겠습니다. 이 장에서는 테이블 뷰 컨트롤러가 작동하도록 구현해야 하는 다양한 기능에 대해 살펴보겠습니다.
앞에서 설명한 대로 이러한 함수는 테이블 뷰 컨트롤러 대리자 또는 테이블 뷰 컨트롤러 데이터 원본에 속합니다. 이 두 프로토콜 모두 위임을 사용하여 테이블 뷰를 사용자 지정합니다.
UITableViewDataSource
의 가장 중요한 기능은 다음과 같습니다:
numberOfSections(in:)
tableView(_:numberOfRowsInSection:)
tableView(_:cellForRowAt:)
UITableViewDelegate
에 대한 다른 관련 기능은 다음과 같습니다:
tableView(_:didSelectRowAt:)
tableView(_:willDisplay:for:)
애플 개발자 문서에서 더 많은 기능을 찾을 수 있습니다.
연락처 데이터 추가
먼저 테이블 뷰 컨트롤러의 연락처 정보 데이터를 추가합니다. ContactsTableViewController
클래스에 다음 속성을 추가합니다:
let contacts:] = , , , , , , , , , , , , , , , , ]
이건 우리 모두가 갖고 싶은 롤로덱스죠,그렇죠? 작동 방법은 다음과 같습니다:
-
let contacts
은contacts
라는 이름을 가진 상수를 선언합니다. 클래스에 속성으로 추가 했으므로 모든 클래스 인스턴스는 클래스 코드 전체에서 이 상수에 액세스 할 수 있습니다. -
contacts
의 유형은]
이며,이는 문자열 배열의 배열입니다. 당신은 본질적으로 항목이 문자열 배열 인 배열을 만들고 있습니다. 변수 이름과 해당 형식은 콜론으로 구분됩니다:
) -
=
코드는contacts
에 배열 리터럴을 할당하고 몇 명의 억만 장자의 이름과 전화 번호로 채워집니다.
나중에contacts.count
을 사용하여 배열의 항목 수를 사용할 수 있습니다. 그리고 아래 첨자 구문을 사용하여contacts
와contacts
로 개별 이름과 전화 번호를 얻을 수 있습니다.
테이블 뷰 셀 클래스 등록
테이블 뷰 컨트롤러에서 셀을 사용하려면 먼저 테이블 뷰에 셀을 등록해야 합니다. 다음 두 가지 방법으로 수행할 수 있습니다:
- 테이블 뷰 셀 클래스와 식별자
- 를 제공하여 사용자 지정 테이블 뷰 셀을 사용할 때 테이블 뷰 셀과 식별자
를 제공하여 해당 셀을 등록할 가능성이 큽니다. 기본 테이블 뷰 셀 또는 다른 프로그래밍 방식 셀을 사용하는 경우 클래스를 등록합니다. 우리는 지금 클래스를 사용할 수 있습니다!
viewDidLoad()
함수에 다음 코드를 추가합니다:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
super.viewDidLoad()
줄 아래에 추가하십시오. 아시다시피viewDidLoad()
함수는 뷰 컨트롤러 수명 주기의 일부이며UIViewController
클래스에 속합니다.
뷰 컨트롤러의 수명 주기에서 이 이벤트에 응답하기 위해viewDidLoad()
함수를 재정의하여 뷰가 로드된 후 뷰를 설정할 수 있습니다. 우리의 경우,우리는 테이블 뷰 셀을 등록하는 함수를 사용하고 있습니다.
테이블 뷰 셀을 등록할 때 식별자도 제공해야 합니다. 이것은 단순히tableView(_:cellForRowAt:)
에서 셀을 큐 해제 할 때 나중에 사용할 수있는 이름과 셀의 클래스를 연결하는 것입니다.
너 아직도 나와 함께 있니? 의 이동하자!
구현”섹션 번호(:)”
우리가 구현하려는 첫 번째 대리자 함수는numberOfSections(in:)
입니다.
테이블 뷰에는 여러 섹션 또는 그룹이 있을 수 있습니다. 모든 그룹에는 셀의 세로 행 위에 떠 있는 머리글이 있습니다. 연락처 앱에서 연락처를 알파벳순으로 그룹화할 수 있습니다. 우리가 구축하고있는 응용 프로그램은 하나의 섹션이 있습니다. 클래스에 다음 함수를 추가합니다:
override func numberOfSections(in tableView: UITableView) -> Int{ return 1}
간단 하죠? 이 함수는 호출될 때1
를 반환합니다.이 기능을 사용하면 다음과 같은 기능을 사용할 수 있습니다. 섹션 수를 제공하는 대신 섹션의 행 수를 제공합니다. 테이블 뷰는 세로 목록의 셀을 표시하므로 모든 셀은 테이블 뷰의 행에 해당합니다.
우리가 구축하고있는 앱에는 단 하나의 섹션이 있으며 한 섹션에는contacts
배열의 항목 수와 동일한 항목 수가 있습니다. 그래서,그것은contacts.count
입니다!
클래스에 다음 함수를 추가합니다:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return contacts.count}
어떻게 작동하는지 볼? 우리는 단순히contacts.count
을 반환합니다. 다른 이름과 전화 번호를contacts
에 추가하면 테이블 뷰에도 잘 표시됩니다.
행 및 섹션 이해
연락처 앱은 1 차원이며 이름과 전화 번호 목록 하나만 표시하며 그룹을 사용하지 않습니다. 그러나 그룹화 된 테이블 뷰가있는 경우 어떻게해야합니까?
대부분의 경우contacts
배열과 같은 데이터 원본도 다차원이 됩니다. 첫 번째 수준에서는 그룹을 구성하고 두 번째 수준에서는 그룹 아래에 개별 항목을 구성합니다.
- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...
그룹 수는countries.count
와 같고 단일 그룹의 국가 수는countries.count
와 같으며x
는 섹션 색인입니다. 이 섹션 인덱스는tableView(_:numberOfRowsInSection:)
의 매개 변수로 제공됩니다.
이 두 함수에tableView
라는 매개 변수가 어떻게 있는지 알았습니까? 그것은 객체 지향 프로그래밍 원리의 일부입니다. 기술적으로 테이블 뷰 데이터 원본을 사용하고 대리자를 사용하여 여러 테이블 뷰를 사용자 지정할 수 있습니다. tableView
를 사용하여 작업 중인 테이블 뷰를 식별합니다.
당신이 이름으로 전화 번호,또는 회사에 의해 조직 된 전화 번호를 표시 할 수있는 연락처 응용 프로그램이 상상해보십시오. 예를 들어 테이블 뷰 컨트롤러를 재사용하여 여러 가지 방법으로 구현할 수 있습니다. 또는 당신은 레스토랑,장소 또는 스카이프 사용자 이름과 같은 유사한 정보를 표시하기 위해 연락처 응용 프로그램의 레이아웃을 재사용 할 경우? 웁와 코드 재사용이 들어오는 곳이다!
테이블 뷰 컨트롤러에 셀 제공
우리는 거기에 있습니다! 테이블 뷰 컨트롤러의 가장 중요한 기능인tableView(_:cellForRowAt:)
로 넘어가겠습니다.
우리는 세부 사항에 다이빙을하기 전에 함수를 구현합니다,하지만 당신은 그것에 대해 이해해야 할 몇 가지가있다:
- 라고 할 때 인덱스 경로가
- 셀을 다시 사용하는 방법
먼저ContactsTableViewController
클래스에 다음 함수를 추가합니다:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}
작동 방법은 다음과 같습니다:
- 이 함수는
UITableViewController
에서 수퍼 클래스 구현을 재정의합니다. 지금쯤은 이미 저것이 일하는 까 라고 너는 있있다,권리? 우리는 기본 구현을 무시하고 우리 자신을 대체합니다.UITableViewController
이 이미 테이블 뷰 대리자 및 데이터 원본을 구현했기 때문입니다. - 이전과 마찬가지로 함수에는 이 함수가 호출되는 테이블 뷰를 식별하는 데 사용할 수 있는 하나의 매개 변수
tableView
가 있습니다. - 다른 매개 변수는
indexPath
이며 인수 레이블은cellForRowAt
입니다. 인덱스 경로는 셀의row
및section
인덱스를 식별합니다. 나중에 더 자세히. - 함수 반환 유형은
UITableViewCell
입니다. 이봐,그건 흥미 롭군요. 이 함수는 테이블 뷰 컨트롤러에 의해 호출,우리는 테이블 뷰 셀을 제공 할 필요가있을 때마다!
이 응용 프로그램에서 연락처를 스크롤 할 때,셀이 화면에 표시 할 때마다,기능tableView(_:cellForRowAt:)
이 호출됩니다. 매번! 나는 잠시 당신에게 그것을 증명합니다.
다음으로 함수 본문을 작성해 보겠습니다. 함수 안에 다음 코드를 추가합니다:
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell
여기에 무슨 일이 일어나는지입니다:
- 먼저 식별자가 있는 셀을 큐에 해제합니다. 셀을 등록 할 때 이전에 사용한 것과 정확히 동일한 식별자입니다. 그런 식으로 테이블 뷰는 우리가 원하는 셀 유형을 알고 있습니다. 대기열이 제거된 셀은
cell
상수에 할당됩니다. 이제 작업 할 테이블 뷰 셀이 있습니다. 나중에 데 큐잉에 대한 자세한. - 그런 다음 콘솔에 몇 가지 정보를 인쇄합니다. 이 기능이 호출 될 때 응용 프로그램이 실행될 때 그래서 우리는 볼 수 있습니다.
- 그런 다음 이 테이블 뷰 셀의 텍스트 레이블에 연락처 이름을 지정합니다.
contacts
에는indexPath.row
를 사용하여 얻는 연락처 이름 값이 포함됩니다.UITableViewCell
의 모든 인스턴스에는UILabel
의textLabel
속성이 있고 해당 유형의 모든 레이블에는text
속성이 있습니다. 레이블에 텍스트를 설정 하는 데 사용 합니다.
걱정하지 마세요. 먼저 앱을 실행할 수 있는지 확인합니다. 연락처 이름이 보이십니까? 콘솔에 디버그 출력이 표시됩니까? 응용 프로그램을 스크롤 해보십시오!테이블 뷰 컨트롤러의 행은 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의 행과 테이블 뷰 컨트롤러의
연락처 앱을 실행하고 위아래로 스크롤하여 놀면 스크롤 할 때마다 디버그 출력이 콘솔에 표시된다는 것을 알 수 없습니다.
전에 화면에 없었던 셀이 나타날 때마다 함수tableView(_:cellForRowAt:)
이 호출되고 콘솔에 새 줄이 나타납니다.
그렇다면tableView(_:cellForRowAt:)
은 언제 호출됩니까? 테이블 뷰 셀이 필요 할 때마다 화면에 표시 할 수 있습니다!
테이블 뷰 컨트롤러가 셀이 필요하다고 판단하여tableView(_:cellForRowAt:)
을 호출합니다. 이 함수의 구현은 셀을 큐에 제거하고 변경 한 다음 테이블 뷰 컨트롤러에 다시 제공합니다. 그런 다음 테이블 뷰 컨트롤러와 사용자 정의 프레임 워크를 화면에 그래픽으로 렌더링합니다.
인덱스 경로 란 무엇입니까?
테이블 뷰 컨트롤러에tableView(_:cellForRowAt:)
의 셀이 필요할 때마다 함수에 대한 인수로 인덱스 경로를 제공합니다. 함수 본문 내에서 매개 변수indexPath
을 사용하여 테이블 뷰 컨트롤러에 필요한 셀을 정확히 알 수 있습니다.
인덱스 경로는 표의 주소 또는 좌표와 같습니다. 일반적인 그래프에는 엑스 축과 와이 축이 있으므로 해당 그래프의 좌표를0, 1
및42, 3
과 같이x, y
으로 표현할 수 있습니다. 마찬가지로 스프레드시트에는 인덱스가 있는 행과 열이 있습니다.
테이블 뷰는 섹션과 행을 사용합니다. 앞에서 설명한 것처럼 섹션을 사용하여 셀을 함께 그룹화 할 수 있습니다. 우리 앱에는 하나의 섹션 만 있으며contacts.count
행이 있습니다. 테이블 뷰의 행은 위에서 아래로 실행됩니다.
다르게 말했다:테이블 뷰의 섹션과 행은 스프레드 시트의 열과 행입니다. 인덱스 경로는 행과 섹션을 사용하여 테이블 뷰의 위치를 정의합니다.
행과 섹션은 인덱스라는 숫자로 표시됩니다. 이러한 인덱스는 0 에서 시작하므로 첫 번째 행과 섹션에는 인덱스 번호0
이 있습니다.
이전 스크린 샷을 돌아 보면 훨씬 더 의미가 있습니다. 첫 번째 셀에는 인덱스 경로0, 0
이 있고 두 번째 셀0, 1
가 있으며 인덱스 경로가0, 11
인 마지막으로 보이는 셀까지 계속됩니다.
테이블 뷰 재사용 메커니즘
테이블 뷰에서 가장 주목할만한 것은 셀 재사용 메커니즘입니다. 그것은 실제로 매우 간단합니다.
- 테이블 뷰 컨트롤러가 셀을 화면에 표시해야 할 때마다 이전에 논의한 것처럼 함수
tableView(_:cellForRowAt:)
이 호출됩니다. - 해당 함수가 호출될 때마다 새 테이블 뷰 셀을 만드는 대신 큐에서 이전에 생성된 셀을 선택합니다.
- 셀은 빈 상태로 재설정하고 모양을 지우고 셀은
tableView(_:cellForRowAt:)
에서 다시 사용자 정의됩니다. - 셀이 화면 밖으로 스크롤 될 때마다 파괴되지 않습니다. 대기열에 추가되어 재사용 대기 중입니다.
꽤 똑똑하지? 셀을 만들고 삭제하는 대신 다시 사용하기 만하면됩니다. 하지만…
셀을 재사용하는 데 메모리 집약도가 훨씬 적습니다. 테이블 뷰 컨트롤러는 셀을 만들고 삭제할 때 지속적으로 메모리에 씁니다. 메모리를 관리하는 것도 더 집중적 일 것입니다. 셀을 다시 사용할 때 메모리가 더 효율적으로 사용되고 메모리 작업이 덜 필요합니다.
또한 셀 생성 및 삭제에 비해 재사용에 관련된 작업이 적기 때문에 셀을 생성하고 삭제하는 대신 재사용하는 데 약간 덜 집중적입니다.
테이블 뷰를 빠르게 스크롤할 때 새 셀을 볼 수 없습니다.
셀 재사용과 관련된 코드는 다음과 같습니다:
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)
함수dequeueReusableCell(withIdentifier:)
은 셀 큐를 해제하려고 시도합니다. 큐에 셀이 없을 때,그것은 우리를 위해 셀을 만들 것입니다. 식별자는 모든 유형의 셀을 자체 큐에 유지하고 올바른 클래스가 새 셀을 만드는 데 사용되는지 확인하는 데 사용됩니다.
개발 과정에 가입하여 스위프트 5 와 엑스코드 12 와 함께 훌륭한 앱을 빌드하는 방법에 대해 알아보세요.
사용자 상호 작용에 응답
한 가지는 우리의 테이블 뷰 컨트롤러에서 누락:우리의 연락처 목록에있는 사람을 호출 할 수있는 기능! 우리가 그렇게하기 전에 그러나,당신은 또한 테이블 뷰 컨트롤러에서 연락처의 전화 번호를 볼 수 있는지 확인 할 수 있습니다.
기본UITableViewCell
클래스는UITableViewCellStyle
열거형에 표현된 대로 4 가지 유형이 있습니다. 당신은 선택할 수 있습니다:
-
.default
– 한 줄의 검은 색 텍스트가있는 간단한 뷰 -
.value1
– 왼쪽에 검은 색 텍스트 한 줄과 오른쪽에 작은 파란색 레이블(설정 앱에서 사용)이있는 간단한 보기) -
.value2
– 오른쪽에 검은 색 텍스트 한 줄과 왼쪽에 작은 파란색 레이블(연락처 앱에서 사용)이있는 간단한 보기) -
.subtitle
– 한 줄의 검정색 텍스트가있는 간단한 뷰와 그 아래에 작은 회색 텍스트 줄
대부분의 개발자는 요즘 사용자 정의 테이블 뷰 셀을 사용하므로 이러한 셀 유형을 자주 볼 수 없습니다. 그러나 그들은 거기에있다!
tableView(_:cellForRowAt:)
에서 코드를 약간 조정해야합니다. 함수의 첫 번째 줄을 다음 코드로 바꿉니다:
var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}
자세히 보면dequeueReusableCell(...)
호출의for: indexPath
부분을 제거한 것을 볼 수 있습니다. 대신,이 함수는 이제 선택 사항을 반환합니다. 셀을 큐를 해제할 수 없으면 함수는nil
를 반환합니다.
그런 다음nil
인 경우 셀을 만들기 위해 점프합니다. 코드의 두 번째 부분에서 볼 수 있습니다. 조건부if
문을 사용하여cell
이nil
와 같은지 확인하고,이 경우UITableViewCell(style:reuseIdentifier:)
이니셜라이저를 사용하여 셀을 만듭니다.
이니셜라이저는 셀 스타일.subtitle
와 이전에 사용한 식별자의 두 인수를 가져옵니다.
이 시점에서cell
이 선택 사항이기 때문에 문제가 있습니다! 그 유형은UITableViewCell?
이지만 함수 반환 유형은 비 선택적 유형UITableViewCell
로 인스턴스를 반환해야합니다.
다행히도,이것은 강제 래핑 해제를 사용하여 선택적 값을 안전하게 풀 수있는 인스턴스 중 하나입니다. 우리의 코드가 작성되는 방식 때문에cell
이nil
를 조건부로 넘어서는 것은 불가능합니다. cell
이if
문 뒤에nil
가 아님을 보장할 수 있습니다.
cell
에 대해 강제 래핑 해제를 사용하도록 함수를 업데이트해야 합니다. 또한cell!.textLabel ...
아래에 다음 코드 줄을 추가하여 셀의 자막을 설정하여 연락처의 전화 번호를 표시합니다.
cell!.detailTextLabel?.text = contacts
이제 전체 함수는 다음과 같습니다:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}
마지막으로viewDidLoad()
에서 다음 줄을 제거하십시오. 테이블 뷰가 잘못된 유형의 셀을 초기화하는 것을 방지합니다.
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
마이티 파인! 명령+아르 자형 또는 재생 버튼을 사용하여 응용 프로그램을 실행하고 작동하는지 확인. 당신은 이름과 전화 번호를 볼 수 있습니까? 좋아!
그런 다음,파이-드-아르 자형-저항,사용자 상호 작용 기능을 추가 할 수 있습니다. 이제 테이블 뷰 컨트롤러의 복잡함을 배웠으므로 이 다음 함수가 어떻게 작동하는지 이미 알고 있다고 생각합니다.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}
다시 말하지만tableView(_:didSelectRowAt:)
함수의 기본 구현을 재정의합니다. 이 함수는 사용자가 테이블 뷰의 셀을 탭할 때 호출되며UITableViewDelegate
프로토콜에 속합니다. 다른 기능과 마찬가지로 탭된 셀의 인덱스 경로를 제공합니다.
함수 본문에서는 단순히 전화 번호에서tel://
을 만듭니다. 이 번호로 전화를 걸 수 있습니다. 이 코드는 설명 목적으로 만 존재합니다. 이 아이폰 시뮬레이터에서 작동하지 않습니다,그리고 우리의 응용 프로그램의 숫자는 가짜입니다. (당신이 진짜 연락처 응용 프로그램을 만드는 경우 여전히,당신은이 코드를 사용하는 것입니다!)
작동 여부를 확인하려면 함수에 다음 코드를 추가할 수 있습니다.
print("\(#function) --- Calling: \(contacts)")
테이블 뷰의 셀을 탭하면 디버그 메시지가 출력됩니다.
추가 읽기
그리고 그게 전부입니다! 꽤 여행 이었지만 이제 테이블 뷰 컨트롤러가 어떻게 작동하는지 알 수 있습니다.