Пишем собственный CustomStepper в Swift

от автора

Тут можно найти реализацию готового проекта

На сегодняшний день во многих приложениях мы можем наблюдать stepper, большинство из них кастомные. Несмотря на то, что Apple предоставляет уже реализацию готового степпера, иногда он не подходит по разным причинам. Это пример подхода к реализации кастомного степпера для кофейни.

Есть разные способы в достижение цели, но сегодня я вам покажу тот, которые не не нашел. В этой статье мы будем использовать верстку кодом, stackView с 2 кнопками (-,+) и лейбл.

Для того, чтобы многократно использовать наш степпер, сделаем его классом, который наследуется от UIView. По сути это полноценный UI-компонент, который можно будет потом взять в свои проекты.

Самое важное — логика, которая будет обрабатывать текущее значения нашего степпера. Для этого будет использовать переменную, которая будет отвечать за текущее значения степпера и обновлять текст лейбла.

final class CustomStepper: UIView {      private lazy var currentValue = 1 }

Дальше нам нужно создать 2 кнопки и лейбл, из которых и будет состоять наш степпер. Для того, чтобы отслеживать состояние степпера, мы будем использовать enum, который будет управлять состояниями кнопок. Мы использовали теги, для чтобы не делать 2 метода для обработки нажатия кнопок.

    private enum ButtonState: Int, CaseIterable {         case decrease = 0         case increase     }      private lazy var decreaseButton: UIButton = {         let button = UIButton()         button.tag = ButtonState.decrease.rawValue         button.setTitleColor(.black, for: .normal)         button.setTitle("-", for: .normal)         button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)         return button     }()              private lazy var currentStepValueLabel: UILabel = {         let label = UILabel()         label.textColor = .black         label.text = "\(currentValue)"         label.font = .systemFont(ofSize: 15)         return label     }()              private lazy var increaseButton: UIButton = {         let button = UIButton()         button.tag = ButtonState.increase.rawValue         button.setTitle("+", for: .normal)         button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)         button.setTitleColor(.black, for: .normal)         return button     }()

Имея все необходимые элементы, мы можем реализовать метод, который отвечает за логику нашего степпера и привязать его к нашим кнопкам.

    //MARK: - Actions     @objc private func buttonAction(_ sender: UIButton) {         let buttonState = ButtonState(rawValue: sender.tag)                  switch buttonState {         case .decrease:             currentValue = currentValue > 1 ? currentValue - 1 : currentValue         case .increase:             currentValue += 1         default:             return         }         currentStepValueLabel.text = "\(currentValue)"     }

Будем использовать паттерн делегирования, чтобы передать данные степпера в наш контроллер для дальнейшей логики проекта и обновления значения.

protocol CustomStepperOutput: AnyObject {     func customStepper(_ didChangeValue: Int) }  protocol CustomStepperInput: AnyObject {     func update(_ value:Int) }

Это внутренний интерфейс, через который мы можем проинициализировать счетчик (при необходимости)

//MARK: - CustomStepperInput extension CustomStepper: CustomStepperInput {     func update(_ value: Int) {         currentValue = value     } }

Внутри контроллера проинициализируем наш степпер. Контроллер подпишем под делегатом степпера, поэтому контроллер будет реализовывать метод делегата, где получать данные от степпера. С этими данными контроллер может дальше осуществлять логику.

import UIKit  final class MainVC: UIViewController {      private lazy var stepperView = CustomStepper()          //MARK: - Life Cycle     override func viewDidLoad() {         super.viewDidLoad()         setupViews()         setupConstraints()     }          //MARK: - Private     private func setupViews() {         view.backgroundColor = .white         view.addSubview(stepperView)         stepperView.delegate = self     }          private func setupConstraints() {         stepperView.snp.makeConstraints { make in             make.centerX.centerY.equalToSuperview()         }     } }  //MARK: - CustomStepperOutput extension MainVC: CustomStepperOutput {     func customStepper(_ didChangeValue: Int) {         print(didChangeValue)     } }

Готово! Вот конечный результат:


ссылка на оригинал статьи https://habr.com/ru/post/701202/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *