Swift 스터디. 4번째
테이블뷰 코드로 만들기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import UIKit internal var data: [String] = ["1", "2", "3"] // 커스텀에 코드 넣을 수 있음 internal class TableViewCell: UITableViewCell { private var didUpdateConstraints: Bool = false private var label: UILabel = { let label: UILabel = UILabel() label.translatesAutoresizingMaskIntoConstraints = false label.text = "abc" label.textColor = .blue return label }() func setTitle(text: String) { label.text = text } override func updateConstraints() { if !didUpdateConstraints { NSLayoutConstraint.activate([ label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10), label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15), label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10) ]) didUpdateConstraints = true } super.updateConstraints() } override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(label) contentView.setNeedsUpdateConstraints() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder: ) not been implemented") } } class ViewController: UIViewController { @IBAction func addAction(_ sender: Any) { data.append("\(data.count + 1)") tableView.reloadData() // 스크롤 마지막으로 let indexPath = IndexPath(row: data.count - 1, section: 0) tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) } var didUpdateConstraints: Bool = false lazy var tableView: UITableView = { let tableView: UITableView = UITableView.init(frame: .zero, style: .grouped) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell") tableView.delegate = self tableView.dataSource = self // tableView.isEditing = true // Delete 버튼 나타남 return tableView }() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. view.addSubview(tableView) // 뷰에 넣기 view.updateConstraintsIfNeeded() // 넣은 테이블뷰 업데이트 } override func updateViewConstraints() { if !didUpdateConstraints { NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) didUpdateConstraints = true } // 마지막에 넣기 super.updateViewConstraints() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } extension ViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // as? 하지 않으면 UITableViewCell 로 받아옴. ㅠㅠ // guard let 으로 처리 guard let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as? TableViewCell else {return UITableViewCell() } cell.setTitle(text: "\(data[indexPath.row])") return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) tableView.deselectRow(at: indexPath, animated: true) cell?.accessoryType = .checkmark } } | cs |
새로 배운 점
1. internal
정의 된 모듈 어디에서든 사용할 수 있다. 그러나 그 모듈이 아닌 파일에서는 사용할 수 없다.
2. 클로저로 객체들을 생성하는 법
UITableView와 UILabel을 생성할 때, 클로저 안에서 여러 속성들을 적용한 객체를 저장하고 있다.
UITableView 를 생성할 때, lazy 키워드를 붙이지 않으면 self 키워드를 ViewController 로 인식을 하지 못한다.
3. 코드로 Constraint 제약 주는 법
updateViewConstraints() 메소드를 오버라이딩한다. 그 안에서
NSLayoutConstraint.activate([...]) 으로 Constraint 속성을 설정한다. 한 번만 실행하기 위해 플래그 변수도 설정한다.
4. 새 프로토콜의 구현할 메소드들을 Extension 으로 코드 분리하기
UIViewController 를 구현한 ViewController 에서 프로토콜을 추가해 구현할 수 있다.
extension 을 이용해 ViewController 에 프로토콜을 추가해 코드를 분리시켰다.
5. TableCell의 accessoryType
.checkmark 로 설정하면, 흔히 기본 iOS 앱에서 볼 수 있는 삭제 UI를 볼 수 있다.
6. 코드로 View 넣기
7. 테이블뷰
테이블뷰는 셀들을 identifier 로 구분해 재사용 할 수 있다. 새 셀 양식을 테이블뷰에 저장할 때는 register() 메소드로 저장한다.
꺼낼 때는 dequeueReusableCell() 메소드로 identifier 에 맞는 셀을 가져온다. 이 때 형식 변환을 하지 않으면 dequeueReusableCell() 반환 형식인 UITableViewCell 으로 들어온다.
as? TableViewCell 으로 변환한다. 변환에 실패할 때를 처리해주기 위해, guard let 구문을 사용한다.
'iOS > iOS 자료실' 카테고리의 다른 글
[오류] Could not insert new outlet connection 해결법 (2) | 2018.08.03 |
---|---|
Swift(iOS) 스터디. 5번째 SQLite (0) | 2018.06.03 |
Swift 스터디. 3번째 (0) | 2018.05.19 |
Swift 스터디. 4월 둘째주 (0) | 2018.04.15 |
Swift 스터디. 4월 첫째주 (0) | 2018.04.08 |
댓글