• delegate pattern
  • custom UITableViewCell
  • How to access tableView Row

Delegate pattern

what is a protocol?

준수해야하는 약속, 서로간 지켜야할 규약

what is a delegate?

delegate : 대리자, 위임하는 역할, 대신 일을 해줄 수 있다.

delegate patternoop에서 하나의 객체가 모든 일을 처리하지 않고 다른 객체에게 할일을 넘기는 것을 뜻한다.

delegate를 사용하기 위해서는 채택작업이 필요하다. delegate를 쓰는데에는 과정이 존재, 위임자를 정해주는 과정

UITextFieldDelegate

textField의 위임자 역할은 self가 하겠다. self is ViewController

override func viewDidLoad() {
  super.viewDidLoad()
  textField.delegate = self
}

textFieldShoudReturn 함수는 UITextFieldDelegate에 정의되어있는 함수

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        ...
        return true
    }

textField에서 return을 누르면 이 함수가 호출된다.


Seeking Age Range in Setting

Make a custom UITableViewCell as AgeRangeCell

class AgeRangeCell: UITableViewCell {
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

custom UITableViewCell always inherits UITableViewCell, override init

As we want to add new cell in tableView

Change some tableView’s properties like numberOfSections, cellForRow, et cetera…

UIStackView skill in AgeRangeCell

UIStackView in UIStackView!

        let overallStackView = UIStackView(arrangedSubviews: [
            UIStackView(arrangedSubviews: [minLabel, minSlider]),
            UIStackView(arrangedSubviews: [maxLabel, maxSlider])
        ])

anchor 설정 주의

addSubview하기 전에 먼저 achor 설정을 해버리면 오류가 발생한다.

intrinsicContentSize

stackView로 넣었던 UILabel의 크기를 수동으로 설정해주기 위해서 intrinsicContentSize를 override한다.

    class AgeRangeLabel: UILabel {
        override var intrinsicContentSize: CGSize {
            return .init(width: 80, height: 0)
        }
    }

슬라이더 property 추가

    let minSlider: UISlider = {
        let slider = UISlider()
        slider.minimumValue = 18
        slider.maximumValue = 100
        return slider
    }()

cellForRow에서는 tableviewCell이 있기 때문에 바로 slider에 접근 가능, 그래서 slider에 selector를 target으로 추가

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 5 {
            let ageRangeCell = AgeRangeCell(style: .default, reuseIdentifier: nil)
            ageRangeCell.minSlider.addTarget(self, action: #selector(handleMinSlider), for: .valueChanged)
            ageRangeCell.maxSlider.addTarget(self, action: #selector(handleMaxSlider), for: .valueChanged)
            return ageRangeCell
        }

tableViewCell 접근 방법

tableView.cellForRow

    @objc fileprivate func handleMinSlider(slider: UISlider) {
        // I want to update the minLabel in my AgeRangeCell somehow...
        let indexPath = IndexPath(row: 0, section: 5)
        let ageRangeCell = tableView.cellForRow(at: indexPath) as! AgeRangeCell
        ageRangeCell.minLabel.text = "Min \(Int(slider.value))"
    }

As we added slider properties to User, we need to connect them to firebase

Update handle_MinOrMax_Sliders, cellForRow, handleSave …

+minSlider value can’t be greater than maxSlider value, maxSlider value can’t be less than minSlider value

    @objc fileprivate func handleMinSlider(slider: UISlider) {
        // I want to update the minLabel in my AgeRangeCell somehow...
        let indexPath = IndexPath(row: 0, section: 5)
        let ageRangeCell = tableView.cellForRow(at: indexPath) as! AgeRangeCell
        ageRangeCell.minLabel.text = "Min \(Int(slider.value))"
        user?.minSeekingAge = Int(slider.value)
        
        if slider.value >= ageRangeCell.maxSlider.value {
            ageRangeCell.maxSlider.value = slider.value
            ageRangeCell.maxLabel.text = "Max \(Int(slider.value))"
        }
    }
    
    @objc fileprivate func handleMaxSlider(slider: UISlider) {
        let indexPath = IndexPath(row: 0, section: 5)
        let ageRangeCell = tableView.cellForRow(at: indexPath) as! AgeRangeCell
        ageRangeCell.maxLabel.text = "Max \(Int(slider.value))"
        user?.maxSeekingAge = Int(slider.value)
        
        if slider.value <= ageRangeCell.minSlider.value {
            slider.value = ageRangeCell.minSlider.value
            ageRangeCell.maxLabel.text = "Max \(Int(slider.value))"
        }
    }

this is really fancy refactoring….

    fileprivate func evaluateMinMax() {
        guard let ageRangeCell = tableView.cellForRow(at: [5, 0]) as? AgeRangeCell else { return }
        let minValue = Int(ageRangeCell.minSlider.value)
        var maxValue = Int(ageRangeCell.maxSlider.value)
        maxValue = max(minValue, maxValue)
        ageRangeCell.minLabel.text = "Min \(minValue)"
        ageRangeCell.maxLabel.text = "Max \(maxValue)"
        
        user?.minSeekingAge = minValue
        user?.maxSeekingAge = maxValue
    }

태그: ,

카테고리:

업데이트:

댓글남기기