iOS_ TableView(3)

longlivedrgn·2022년 11월 16일
0

iOS 스터디

목록 보기
8/8
post-thumbnail

Table Header View & Footer View

// iOS 13부터는 안됨?..
해더뷰에 검색창을 만들어보자

  • List Table View 안에 cell 위에 searchBar를 추가해주고, viewcontroller와 delegate으로 연결해준다.
  • 현재 아래와 같이 코드가 작성되어있다.
import UIKit

class HeaderFooterViewViewController: UIViewController {
    
    @IBOutlet weak var listTableView: UITableView!
    
    let list = ["iMac Pro", "iMac 5K", "Macbook Pro", "iPad Pro", "iPad", "iPad mini", "iPhone 8", "iPhone 8 Plus", "iPhone SE", "iPhone X", "Mac mini", "Apple TV", "Apple Watch"]
    var filteredList = ["iMac Pro", "iMac 5K", "Macbook Pro", "iPad Pro", "iPad", "iPad mini", "iPhone 8", "iPhone 8 Plus", "iPhone SE", "iPhone X", "Mac mini", "Apple TV", "Apple Watch"]
    
    
    lazy var resultLabel: UILabel = { [weak self] in
        var frame = self?.view.bounds ?? .zero
        frame.size.height = 50
        
        let lbl = UILabel(frame: frame)
        lbl.textAlignment = .center
        lbl.textColor = UIColor.white
        lbl.backgroundColor = UIColor.gray
        return lbl
    }()
    
    
    @objc func handle(notification: Notification) {
        switch notification.name {
        case NSNotification.Name.UIKeyboardWillShow:
            if let frame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect {
                var inset = listTableView.contentInset
                inset.bottom = frame.height
                listTableView.contentInset = inset
            }
        case NSNotification.Name.UIKeyboardWillHide:
            var inset = listTableView.contentInset
            inset.bottom = 0
            listTableView.contentInset = inset
        default:
            break
        }
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(handle(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handle(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }
}




extension HeaderFooterViewViewController: UISearchBarDelegate {
    func filter(with keyword: String) {
        if keyword.count > 0 {
            filteredList = list.filter { $0.contains(keyword) }
        } else {
            filteredList = list
        }
        
        listTableView.reloadData()
        resultLabel.text = "\(filteredList.count) result(s) found"
    }
    
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        filter(with: searchText)
    }
    
    
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        
    }
    
    
    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        
    }
    
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        filter(with: searchBar.text ?? "")
    }
    
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        filteredList = list
        listTableView.reloadData()
        
        searchBar.resignFirstResponder()
    }
}




extension HeaderFooterViewViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filteredList.count
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        let target = filteredList[indexPath.row]
        cell.textLabel?.text = target
        
        return cell
    }
}
  • 위코드에서 아래와 같이 searchBarDelegate을 설정해주면
extension HeaderFooterViewViewController: UISearchBarDelegate {
    func filter(with keyword: String) {
        if keyword.count > 0 {
            filteredList = list.filter { $0.contains(keyword) }
        } else {
            filteredList = list
        }
        
        listTableView.reloadData()
        resultLabel.text = "\(filteredList.count) result(s) found"
    }
    
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        filter(with: searchText)
    }
    
    
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        listTableView.tableFooterView = resultLabel
    }
    
    
    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        searchBar.text = nil
        resultLabel.text = "0 result(s) found"
        listTableView.tableFooterView = nil
    }
    
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        filter(with: searchBar.text ?? "")
    }
    
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        filteredList = list
        listTableView.reloadData()
        
        searchBar.resignFirstResponder()
    }
}

Managing Selection

  • cell을 몇개 선택할 수 있게 할 지를 내가 선택할 수 있다.

  • 셀을 선택시 셀 색깔을 어떻게 변화시킬지를 선택할 수 있다.

  • 코드를 통하여 셀이 선택되었을 때 하이라이트가 될 지, 어떻게 될 지를 선택할 수 있다.

extension SingleSelectionViewController: UITableViewDelegate {
    // 셀이 선택하기전에 호출이 된다. -> 특정 셀의 선택을 금지할 때 사용이된다.
    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        // indexPath를 넘겨주면 셀이 선택이 된다.
        
        // 첫번째 셀은 선택이 불가능하게 해보기
        if indexPath.row == 0 {
            return nil
        }
        return indexPath
    }
    
    // 셀이 선택된 직후에 호출이 된다.
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 선택된 셀의 데이터를 경고창에 띄어보자.
        let target = list[indexPath.section].countries[indexPath.row]
        showAlert(with: target)
        
        // 선택이 되면 색깔은 검은색으로 바꾸기
        tableView.cellForRow(at: indexPath)?.textLabel?.textColor = .black
        // highlight은 안되게 할 수 있다.
        tableView.cellForRow(at: indexPath)?.selectionStyle = .none
        
    }
    
    // 선택이 해제가 되기 전에 호출이 된다.
    func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
        return indexPath
    }
    
    // 선택이 해제되면 호출이 된다.
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        tableView.cellForRow(at: indexPath)?.textLabel?.textColor = .systemGray3
    }
    
    // 첫번째 cell은 Highlight이 안되게 설정해보자
    func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
        return indexPath.row != 0
    }
    
    func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
        tableView.cellForRow(at: indexPath)?.textLabel?.textColor = .black
    }
    
    func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
        return
    }
}

0개의 댓글