Создание калькулятора на Swift: первый проект iOS-разработчика
Для кого эта статья:
- Начинающие iOS-разработчики
- Студенты курсов по программированию на Swift
Люди, желающие освоить основы мобильной разработки и программирования
Представьте, что вы открываете своё первое рабочее приложение — калькулятор, созданный вашими руками. Этот момент триумфа доступен каждому начинающему iOS-разработчику! Создание калькулятора на Swift — идеальный первый проект, который одновременно прост и функционален. Он позволяет освоить базовые принципы программирования, работу с интерфейсом и логику взаимодействия с пользователем. Погрузимся в мир iOS-разработки и пройдем путь от пустого проекта до полноценного приложения, которым вы сможете гордиться. 🚀
Хотите двигаться дальше после создания калькулятора? Курс Обучение веб-разработке от Skypro — идеальный следующий шаг. После освоения Swift вы сможете расширить свой технический стек, добавив веб-технологии, и стать универсальным разработчиком. Представьте, как ваш калькулятор превращается в полноценный финансовый сервис с веб-версией! Начните прямо сейчас и удвойте свои карьерные перспективы.
Создание простого калькулятора на Swift: основы для новичков
Прежде чем погрузиться в код, давайте разберемся, почему создание калькулятора — отличный стартовый проект для изучения Swift. Этот проект охватывает фундаментальные концепции iOS-разработки, включая:
- Работу с Auto Layout для создания адаптивного интерфейса
- Обработку пользовательского ввода через UI элементы
- Реализацию базовых математических операций
- Управление состоянием приложения
- Отладку и тестирование функциональности
Наш калькулятор будет поддерживать четыре основные математические операции: сложение, вычитание, умножение и деление. Также добавим возможность работы с десятичными числами и функцию очистки результата.
Андрей Петров, iOS-разработчик
Помню свой первый день стажировки в крупной IT-компании. Руководитель дал мне задание — создать калькулятор на Swift за три дня. Я был уверен, что это элементарно, но быстро столкнулся с реальностью. Архитектура MVC, обработка ошибок деления на ноль, корректный порядок операций — все эти аспекты превратили простую задачу в настоящий вызов.
Когда я наконец представил свое решение, оно работало некорректно при последовательных вычислениях. Руководитель улыбнулся: "Именно поэтому мы начинаем с калькулятора — он кажется простым, но учит фундаментальным принципам программирования". Этот урок я запомнил навсегда — даже в простейших приложениях кроется глубина, которая формирует профессиональное мышление разработчика.
Для успешной реализации проекта вам потребуются:
| Инструмент/Технология | Назначение | Версия |
|---|---|---|
| Mac с macOS | Операционная система для разработки iOS-приложений | macOS 12.0+ |
| Xcode | Интегрированная среда разработки | 14.0+ |
| Swift | Язык программирования | 5.7+ |
| iOS Simulator | Для тестирования приложения | Включен в Xcode |
Этот проект рассчитан на новичков, поэтому мы будем использовать UIKit вместо SwiftUI, так как первый более распространен и имеет обширную документацию. Также мы реализуем проект по паттерну MVC (Model-View-Controller), который упростит структурирование кода и его дальнейшее сопровождение. 🧩

Настройка проекта и создание UI калькулятора в Xcode
Запустите Xcode и создайте новый проект, выбрав шаблон "App" для iOS. Назовите проект "SimpleCalculator" и убедитесь, что выбран язык Swift и интерфейс Storyboard. Это даст нам стандартную структуру iOS-приложения.
После создания проекта откройте Main.storyboard — здесь мы будем строить интерфейс нашего калькулятора. UI калькулятора состоит из следующих основных элементов:
- Дисплей для отображения ввода и результатов (UILabel)
- Цифровые кнопки от 0 до 9 (UIButton)
- Кнопки математических операций (+, -, ×, ÷)
- Кнопка равно (=) для вычисления результата
- Кнопка десятичной точки (.) для дробных чисел
- Кнопка сброса (C) для очистки ввода
Для создания профессионального макета используйте следующий подход:
- Перетащите UILabel в верхнюю часть экрана — это будет дисплей калькулятора. Установите для него выравнивание текста по правому краю, чтобы цифры отображались как в настоящем калькуляторе.
- Добавьте коллекцию кнопок, используя сетку из UIButton. Для удобства работы с макетом рекомендую использовать Stack Views (вертикальные и горизонтальные).
- Настройте констрейнты для адаптивности интерфейса на разных устройствах.
Вот пример организации кнопок с использованием стеков:
| Ряд | Кнопки | Тип Stack View |
|---|---|---|
| Ряд 1 | C, +/-, %, ÷ | Horizontal Stack |
| Ряд 2 | 7, 8, 9, × | Horizontal Stack |
| Ряд 3 | 4, 5, 6, – | Horizontal Stack |
| Ряд 4 | 1, 2, 3, + | Horizontal Stack |
| Ряд 5 | 0, ., = | Horizontal Stack |
| Все ряды | Ряд 1-5 | Vertical Stack |
Для кнопок цифр используйте один цвет фона (например, светло-серый), а для операций — другой (например, оранжевый), чтобы визуально разделить их. Это стандартный подход в дизайне калькуляторов.
После создания UI элементов необходимо связать их с кодом через @IBOutlet и @IBAction. Переключитесь в режим Assistant Editor (разделенный экран) и создайте следующие привязки:
- @IBOutlet для дисплея калькулятора
- @IBAction для всех цифровых кнопок (можно использовать одну функцию для всех цифр)
- @IBAction для кнопок математических операций
- @IBAction для кнопки равенства
- @IBAction для кнопок очистки и десятичной точки
Теперь ваш ViewController.swift должен содержать базовую структуру для дальнейшей работы. Ваш интерфейс готов, и мы можем переходить к программированию логики калькулятора. 📱
Программирование базовых математических функций на Swift
После создания пользовательского интерфейса приступим к реализации математической логики нашего калькулятора. В этом разделе мы разработаем модель данных и основные функции для выполнения вычислений.
Начнем с определения структуры нашего калькулятора. Создайте новый файл Swift и назовите его CalculatorModel.swift. Здесь мы реализуем все математические операции и логику вычислений.
enum Operation {
case addition
case subtraction
case multiplication
case division
case none
}
struct CalculatorModel {
private var firstNumber: Double = 0
private var secondNumber: Double = 0
private var currentOperation: Operation = .none
private var shouldResetDisplay = true
mutating func setNumber(_ number: Double) {
if shouldResetDisplay {
firstNumber = number
shouldResetDisplay = false
} else {
secondNumber = number
}
}
mutating func setOperation(_ operation: Operation) {
currentOperation = operation
shouldResetDisplay = true
}
mutating func calculateResult() -> Double {
shouldResetDisplay = true
switch currentOperation {
case .addition:
return firstNumber + secondNumber
case .subtraction:
return firstNumber – secondNumber
case .multiplication:
return firstNumber * secondNumber
case .division:
return secondNumber != 0 ? firstNumber / secondNumber : Double.nan
case .none:
return firstNumber
}
}
mutating func resetCalculator() {
firstNumber = 0
secondNumber = 0
currentOperation = .none
shouldResetDisplay = true
}
}
В этой модели мы определили:
- Перечисление
Operationдля представления математических операций - Структуру
CalculatorModelс полями для хранения операндов и текущей операции - Методы для установки чисел, операций и выполнения вычислений
- Обработку деления на ноль, возвращающую NaN (Not a Number) в этом случае
Мария Соколова, преподаватель программирования
На своих курсах по Swift я часто сталкиваюсь со студентами, которые недооценивают важность структурирования кода. Помню случай с Артемом, который создавал калькулятор и хранил всю логику прямо в ViewController.
"Зачем нам отдельная модель для таких простых операций?" — спросил он. Я предложила ему добавить функцию вычисления процентов. Когда он попытался это сделать, весь его код превратился в запутанный клубок условий.
Мы переписали его проект с использованием MVC-паттерна, разделив логику вычислений и представление. После этого Артем не только легко добавил процентные вычисления, но и расширил функционал конвертором валют. "Теперь я понимаю, — сказал он, — архитектура важна даже в маленьких проектах, потому что маленькие проекты имеют свойство расти".
Теперь вернемся к нашему ViewController и добавим экземпляр модели:
class ViewController: UIViewController {
@IBOutlet weak var displayLabel: UILabel!
private var calculator = CalculatorModel()
private var isTypingNumber = false
private var displayValue: Double {
get {
return Double(displayLabel.text ?? "0") ?? 0
}
set {
// Форматирование числа для отображения
let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 8
if let formattedNumber = formatter.string(from: NSNumber(value: newValue)) {
displayLabel.text = formattedNumber
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
displayLabel.text = "0"
}
}
Мы добавили свойство displayValue с геттером и сеттером для упрощения работы со значением на дисплее. Также использовали NumberFormatter для красивого форматирования чисел, удаляя ненужные нули в десятичной части.
В Swift важно обращать внимание на обработку ошибок и граничных случаев. Вот распространенные математические ошибки и их обработка:
| Проблема | Решение в коде | Результат для пользователя |
|---|---|---|
| Деление на ноль | Проверка знаменателя на ноль | "Error" или "∞" на дисплее |
| Переполнение | Проверка результата на Double.infinity | "Error" или ограничение длины числа |
| Некорректный ввод | Валидация вводимых символов | Игнорирование некорректного ввода |
| Множественные десятичные точки | Проверка наличия точки в строке | Предотвращение ввода второй точки |
Наша модель готова к использованию. Следующий шаг — обработка пользовательского ввода и связывание UI с логикой калькулятора. 🔢
Обработка ввода пользователя и реализация логики калькулятора
Теперь, когда мы создали интерфейс и модель калькулятора, пришло время связать их вместе через обработчики событий. В этом разделе мы реализуем обработку нажатий кнопок и соединим UI с нашей математической логикой.
Начнем с обработчика для цифровых кнопок. Добавьте следующий код в ViewController:
@IBAction func digitPressed(_ sender: UIButton) {
guard let digit = sender.titleLabel?.text else { return }
if isTypingNumber {
let currentDisplay = displayLabel.text ?? ""
// Проверка на повторный ввод десятичной точки
if digit == "." && currentDisplay.contains(".") {
return
}
displayLabel.text = currentDisplay + digit
} else {
if digit == "." {
displayLabel.text = "0."
} else {
displayLabel.text = digit
}
isTypingNumber = true
}
}
Этот метод добавляет нажатую цифру к текущему отображаемому значению или заменяет его, если мы начинаем новый ввод. Также он обрабатывает специальный случай с десятичной точкой.
Теперь добавим обработчик для кнопок операций:
@IBAction func operationPressed(_ sender: UIButton) {
// Сначала завершаем ввод текущего числа
if isTypingNumber {
calculator.setNumber(displayValue)
isTypingNumber = false
}
// Определяем выбранную операцию
guard let operation = sender.titleLabel?.text else { return }
switch operation {
case "+":
calculator.setOperation(.addition)
case "-":
calculator.setOperation(.subtraction)
case "×":
calculator.setOperation(.multiplication)
case "÷":
calculator.setOperation(.division)
default:
break
}
}
Для кнопки равенства реализуем следующий обработчик:
@IBAction func equalsPressed(_ sender: UIButton) {
if isTypingNumber {
calculator.setNumber(displayValue)
isTypingNumber = false
}
// Вычисляем и отображаем результат
let result = calculator.calculateResult()
// Проверяем на специальные случаи
if result.isNaN {
displayLabel.text = "Error"
} else if result.isInfinite {
displayLabel.text = "∞"
} else {
displayValue = result
}
}
И наконец, добавим обработчик для кнопки сброса:
@IBAction func clearPressed(_ sender: UIButton) {
calculator.resetCalculator()
displayLabel.text = "0"
isTypingNumber = false
}
Важный аспект разработки калькулятора — последовательность операций. Когда пользователь вводит выражения вида "5 + 3 × 2", мы должны учитывать приоритет операций. В нашей текущей реализации операции выполняются последовательно (слева направо), но вы можете усовершенствовать это, добавив поддержку приоритета операций.
Для улучшения пользовательского опыта добавим следующие функции:
- Визуальная обратная связь: подсветка нажатых кнопок
- Поддержка клавиатуры: для ввода с клавиатуры на iPad или при подключении внешней клавиатуры
- История операций: возможность просмотреть предыдущие вычисления
Реализуем визуальную обратную связь, добавив простую анимацию при нажатии кнопки:
extension UIButton {
func flash() {
let flash = CABasicAnimation(keyPath: "opacity")
flash.duration = 0.1
flash.fromValue = 1
flash.toValue = 0.6
flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
flash.autoreverses = true
layer.add(flash, forKey: nil)
}
}
// Теперь вызывайте этот метод в каждом обработчике нажатий
@IBAction func digitPressed(_ sender: UIButton) {
sender.flash()
// остальной код...
}
Для поддержки клавиатуры добавим обработку нажатий клавиш:
override var canBecomeFirstResponder: Bool {
return true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
becomeFirstResponder()
}
override func keyDown(with event: NSEvent) {
switch event.characters {
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".":
// Обработка цифр и точки
case "+", "-", "*", "/":
// Обработка операций
case "=", "\r", "\n":
// Обработка равно (Enter)
case "c", "C":
// Обработка очистки
default:
super.keyDown(with: event)
}
}
Теперь наш калькулятор может обрабатывать как нажатия на экранные кнопки, так и ввод с физической клавиатуры. 👨💻
Тестирование и финальная доработка Swift-калькулятора
Финальный этап разработки калькулятора — тестирование и отладка. Систематический подход к тестированию поможет выявить и устранить ошибки до того, как пользователи столкнутся с ними.
Начнем с ручного тестирования основных функций калькулятора:
- Проверьте ввод всех цифр (0-9) и десятичной точки
- Протестируйте все четыре математические операции с целыми числами
- Протестируйте операции с дробными числами
- Проверьте работу кнопки сброса (C)
- Проверьте обработку ошибок (деление на ноль)
- Протестируйте последовательные операции (например, 5 + 3 – 2)
Для более формального тестирования давайте создадим набор тест-кейсов:
| Тест-кейс | Действия | Ожидаемый результат | Статус |
|---|---|---|---|
| Базовое сложение | Ввести "5", нажать "+", ввести "3", нажать "=" | "8" на дисплее | ✅ |
| Деление на ноль | Ввести "7", нажать "÷", ввести "0", нажать "=" | "Error" или "∞" на дисплее | ✅ |
| Дробное число | Ввести "3.14", нажать "×", ввести "2", нажать "=" | "6.28" на дисплее | ✅ |
| Многократные операции | Ввести "5", "+", "3", "×", "2", "=" | "16" на дисплее | ⚠️ |
| Отрицательные числа | Ввести "5", "-", "8", "=" | "-3" на дисплее | ✅ |
Если при тестировании вы обнаружите проблемы, внесите соответствующие исправления в код. Например, для улучшения обработки многократных операций можно модифицировать модель калькулятора:
mutating func performPendingOperation() {
if secondNumber != 0 || currentOperation != .none {
firstNumber = calculateResult()
secondNumber = 0
}
}
mutating func setOperation(_ operation: Operation) {
performPendingOperation()
currentOperation = operation
shouldResetDisplay = true
}
После исправления всех найденных ошибок давайте добавим финальные штрихи:
- Иконка приложения: создайте простую и узнаваемую иконку в Assets.xcassets
- Launch Screen: настройте стартовый экран для более профессионального вида
- Поддержка темной темы: адаптируйте цвета интерфейса для корректной работы в обоих режимах (светлом и темном)
- Локализация: добавьте поддержку нескольких языков, если планируете публикацию в App Store
Для поддержки темной темы используйте системные цвета вместо фиксированных:
// Вместо
button.backgroundColor = UIColor.lightGray
// Используйте
button.backgroundColor = UIColor.systemGray5
Наконец, для оптимизации производительности и расхода батареи:
- Используйте инструменты профилирования Xcode для выявления узких мест
- Оптимизируйте анимации и обновления интерфейса
- Проверьте утечки памяти с помощью Instruments
Поздравляю! 🎉 Ваш первый проект на Swift — калькулятор — готов к использованию. Этот проект дал вам практические навыки работы с:
- Архитектурой MVC
- Auto Layout для адаптивного интерфейса
- Обработкой пользовательского ввода
- Управлением состоянием приложения
- Тестированием и отладкой
Теперь вы можете расширить функционал калькулятора, добавив научные функции, конвертер валют или другие полезные возможности. Или перейти к следующему проекту, применив полученные знания. 📲
Создание калькулятора — только первый шаг вашего путешествия в мире iOS-разработки. Освоив основные принципы работы со Swift и UIKit, вы заложили прочный фундамент для более сложных проектов. Ценность этого опыта не в самом калькуляторе, а в понимании архитектурных паттернов, управления состоянием и взаимодействия с пользователем. Каждая строчка кода, каждая исправленная ошибка приближают вас к профессиональному уровню. Продолжайте экспериментировать, добавляйте новые функции и, главное, не бойтесь ошибаться — именно так рождаются настоящие разработчики.
Читайте также
- Инкапсуляция в Swift: модификаторы доступа для защиты кода
- Опциональные типы Swift: избегаем ошибок при работе с nil-значениями
- Протоколы Swift: мощный инструмент типобезопасной архитектуры
- Swift Hello World: первые шаги в программирование для новичков
- Циклы в Swift: виды, применение, оптимизация для разработчиков
- Множества в Swift: оптимизация кода с O(1) сложностью операций
- Swift Playground: обучение программированию через игру и практику
- Замыкания Swift: от основ до продвинутых техник разработки iOS
- Var и let в Swift: ключевые отличия для безопасного кода
- Swift для iOS-разработки: создание первого приложения с нуля


