• Swift 5.0
  • UITableView

What’s new in Swift 5.0?

isNumber

check there is numbers in string

let testString = "Swift 5.0"
var countOfNumbers = 0

for character in testString {
    if character.isNumber {
        countOfNumbers += 1
    }
}

print(countOfNumbers)

활용

let countOfNumbers2 = testString.reduce(into: 0) { (result, char) in
    if char.isNumber {
        return result += 1
    }
}

print(countOfNumbers2)
testString.map { (char) -> Void in
    if char.isNumber {
        countOfNumbers += 1
    }
}

print(countOfNumbers)

isAlphabetic, isLowercase, isUppercase

var numberOfAlphabets = 0, numberOflowercases = 0, numberOfUppercases = 0
for unicode in testString.unicodeScalars {
    if unicode.properties.isLowercase {
        numberOflowercases += 1
    }
    
    if unicode.properties.isUppercase {
        numberOfUppercases += 1
    }
    
    if unicode.properties.isAlphabetic {
        numberOfAlphabets += 1
    }
}

print(testString)
print("\(numberOflowercases), \(numberOfUppercases), \(numberOfAlphabets)")

Refactoring header section

    let header: UIView = {
        let header = UIView()
        header.addSubview(image1Button)
        let padding: CGFloat = 16
        image1Button.anchor(top: header.topAnchor, leading: header.leadingAnchor, bottom: header.bottomAnchor, trailing: nil, padding: UIEdgeInsets.init(top: padding, left: padding, bottom: padding, right: 0))
        image1Button.widthAnchor.constraint(equalTo: header.widthAnchor, multiplier: 0.45).isActive = true
        
        let stackView = UIStackView(arrangedSubviews: [image2Button, image3Button])
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.spacing = padding
        
        header.addSubview(stackView)
        stackView.anchor(top: header.topAnchor, leading: image1Button.trailingAnchor, bottom: header.bottomAnchor, trailing: header.trailingAnchor, padding: .init(top: padding, left: padding, bottom: padding, right: padding))
        return header
    }()
    
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        
        return header
    }

we have to use lazy var to header it means the header would be created after imageButtons are created!


Building cells Steps in Table VIew

set number of sections

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 5
    }

only first section’s header’s height is 300

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        
        if section == 0 {
            return 300
        }
        return 40
    }

other sections header is just UILabel

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 {
            return header
        }
        
        let headerLabel = UILabel()
        headerLabel.text = "Name"
        return headerLabel
    }

numberOfRowsInSection

call override func with numrowsin~

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

cellForRowAt

call override func with cellforrow

create cell with UITableViewCell

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        cell.textLabel?.text = "TEST TEST TEST"
        return cell
    }

the first section doesn’t need any rows

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return section == 0 ? 0 : 1
    }

UI 요소들 확장시키기

extend UILabel with ` class`

    class HeaderLabel: UILabel {
        override func drawText(in rect: CGRect) {
            super.drawText(in: rect.insetBy(dx: 16, dy: 0))
        }
    }
    
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 {
            return header
        }
        
        let headerLabel = HeaderLabel()
        headerLabel.text = "Name"
        return headerLabel
    }

SettingsCell.swift

초기값 설정

        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
class SettingsCell: UITableViewCell {
    
    // default initializer
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

}
    let textField: UITextField = {
        let tf = UITextField()
        tf.placeholder = "Enter Name"
        return tf
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        addSubview(textField)
        textField.fillSuperview()
    }
// SettingsController.swift

override func tableVIew(---)
        let cell = SettingsCell(style: .default, reuseIdentifier: nil)

따로 SettingCell을 만들어서 SettignCell 내부에서 textFieldsubview로 추가해주지 않으면 cellForRowAt에서 일일히 추가해줘야한다.

keyboardDismissMode

scroll에 따라 keyboard가 dimiss하게 해준다.

        tableView.keyboardDismissMode = .interactive

TextField Size

// SettingsCell.swift
    class SettingsTextField: UITextField {
        override var intrinsicContentSize: CGSize {
            return .init(width: 0, height: 44)
        }
    }

여기서 width는 어떤 값을 주어도 꽉차게 나온다. TableViewCell이여서 그런 듯 하다.

placeholder inset

placeholder는 항상 기본 textRect의 inset과 editingRect inset을 모두 수정해줘야한다.

    class SettingsTextField: UITextField {
        
        override func textRect(forBounds bounds: CGRect) -> CGRect {
            return bounds.insetBy(dx: 24, dy: 0)
        }
        
        override func editingRect(forBounds bounds: CGRect) -> CGRect {
            return bounds.insetBy(dx: 24, dy: 0)
        }

change the title of header(UILabel) according to section

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 {
            return header
        }
        
        let headerLabel = HeaderLabel()
        switch section {
        case 1:
            headerLabel.text = "Name"
        case 2:
            headerLabel.text = "Profession"
        case 3:
            headerLabel.text = "Age"
        default:
            headerLabel.text = "Bio"
        }
        headerLabel.font = UIFont.boldSystemFont(ofSize: headerLabel.font.pointSize)
        return headerLabel
    }

change placeholder of each cell in rows

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = SettingsCell(style: .default, reuseIdentifier: nil)
        
        switch indexPath.section {
        case 1:
            cell.textField.placeholder = "Enter Name"
        case 2:
            cell.textField.placeholder = "Enter Profession"
        case 3:
            cell.textField.placeholder = "Enter Age"
        default:
            cell.textField.placeholder = "Enter Your Bio"
        }
        return cell
    }

Dimiss Keyboard

    fileprivate func setupTapGesture() {
        tableView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTapDismiss)))
    }
    
    @objc fileprivate func handleTapDismiss() {
        tableView.endEditing(true)
    }

태그: ,

카테고리:

업데이트:

댓글남기기