Closed namsoo5 closed 3 years ago
TableView를 구분하는 방법
=== 연산자 이용
==는 값을 비교하는것 ===는 두 인스턴스의 포인터의 참조값을 비교하기 때문에 더 정확
class ViewController: UIViewController {
var table1: UITableView!
var table2: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
table1 = makeTableView(frame: CGRect(x: 0, y: 0, width: 375, height: 200))
table2 = makeTableView(frame: CGRect(x: 0, y: 250, width: 375, height: 200))
view.addSubview(table1)
view.addSubview(table2)
}
func makeTableView(frame: CGRect) -> UITableView {
let tableView = UITableView(frame: frame)
tableView.dataSource = self
return tableView
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView === table1 {
return 5
}
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.backgroundColor = .brown
return cell
}
}
DataSource 클래스 만들어주기
UITableViewDataSource를 채택한 인스턴스를 만들고 적용시켜주는 방식
class ViewController: UIViewController {
var table1: UITableView!
var table2: UITableView!
let aDataSource = ATableController()
override func viewDidLoad() {
super.viewDidLoad()
...
table1.dataSource = aDataSource
}
...
}
class ATableController: NSObject, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.backgroundColor = .red
return cell
}
}
TableViewDatasource 프로토콜을 채택한 ViewController 내에서 tableView의 인스턴스를 직접 비교해서 각각의 데이터를 분기하는 방식
DataSource 커스텀 클래스를 여러 개 만들어서 각각 tableView datasource에 대입하는 방식
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
if tableView == table1 {
return cell
} else {
return cell
}
}
override func viewDidLoad() {
super.viewDidLoad()
table1.tag = 1
table2.tag = 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
if tableView.tag == 1 {
return cell
} else {
return cell
}
}
extension SwitchingViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// ==값비교 , === 인스턴스 주소 비교 if( tableView === self.tableView){ return 3 } if ( tableView === tableView2) { return 10 }
return 0 // 기본 return값 지정해주지 않으면 error
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
}
2. 다른 클래스를 만들어서 DataSource와 Delegate를 채택시킨다.
```swift
override func viewDidLoad(){
tableView.dataSource = self
//기존처럼 기존의 뷰컨에서 DataSource를 받아서 처리
tableView2.dataSource = subDataSource
//DataSource를 채택한 sub클래스를 만들어서 사용
}
class subTableViewDataSource: NSObject, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
}
let tableView1 = UITableView()
let tableView2 = UITableView()
Observable.from(["1234","2345"])
.asObservable()
.bind(to: tableView1.rx.items) {
~
}
Observable.from(["1234","2345"])
.asObservable()
.bind(to: tableView2.rx.items) {
~
}
이렇게 하면 하나의 뷰컨에서도 예쁘게 적용 가능할것 같다
cell의 Size는 아래처럼 TableViewDelegate에서 분기쳐서 나눠주거나
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if tableview == tableView1 {
}
else {
}
}
아니면 아예 클래스파일을 두개 둘 것 같다 (delegate 클래스를 따로 지정)
테이블뷰에서 제공하는 메소드에서 tableView를 이용해 비교해 구분할수가 있습니다.
간단한 예시!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == 첫번째 테이블뷰 {
return 첫번째 테이블 뷰 에 해당하는 셀
} else {
return 두번째 테이블 뷰 에 해당하는 셀
}
}
DataSouce나 Delegate 의 구현 함수에는 첫번째 parameter를 해당 메소드를 호출한 객체가 들어오게 된다. 따라서 다음과 같이 switch 문, if 문을 통해 분기처리를 하여 해당 동작을 구현해 줄 수 있다.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch collectionView {
case productFunctionCV:
return productFunctionCVExtensionData?.count ?? 0
case naverLowestPriceInfoCV:
return naverLowestPriceInfoCVExtensionData?.count ?? 0
default:
return 0
}
}
그 다음으로 직접적으로 UITableView의 Delegate나 DataSource 등을 채택한 다른 클래스를 구현하는 방법이다. 이 프로토콜들은ㄴ NSObject Protocoal의 상속을 받기 때문에 이 것들을 채택하여 사용하기 위해서는 NSObject에 대한 상속이 필요하다.
따라서
// MARK: - ProductFunctionCVExtension
class ProductFunctionCVExtension : NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
var data: [EfficacyName]?
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
…
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
…
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
…
}
}
다음과 같이 구현해 준 다음 해당 테이븗 뷰와 컬렉션뷰의 델리게이트와 데이터소스를 해당 뷰컨트롤러가 아닌 해당 객체에 위임하여 사용할 수 있다.
self.productFunctionCV.delegate = self.productFunctionCVExtension
self.productFunctionCV.dataSource = self.productFunctionCVExtension
첫번째 방법
UITableViewDelegate, UITableViewDataSource 등의 처리에서 if문 또는 switch문을 이용해서 테이블뷰를 분기처리해준다.
두번째 방법
TableView 별로 클래스를 따로 정의한다.