pt — points, логическая единица измерения в iOS и macOS, абстрагирующая интерфейс от физического разрешения экрана. Один point соответствует одному пикселю на экране без Retina (@1x) и двум или трём пикселям на Retina (@2x, @3x). Статья объясняет принцип работы pt, масштабирование на разных экранах, использование CGPoint и UIFont.pointSize.
Главное
pt (point) — логическая единица измерения в iOS, которая позволяет разработчику описывать интерфейс в абстрактных координатах, не зависящих от физического разрешения дисплея. Apple ввела понятие points с выходом iPhone 4 и Retina-дисплея в 2010 году. До Retina разработчики использовали пиксели напрямую — один пиксель UI равнялся одному физическому пикселю.
Система координат iOS построена на точках: точка (0,0) находится в левом верхнем углу экрана, ось X направлена вправо, ось Y — вниз. Размер экрана в точках остаётся постоянным для каждого класса устройств: iPhone SE — 375×667 pt, iPhone 15 Pro — 393×852 pt, iPad — 768×1024 pt (портрет), 1024×768 pt (ландшафт). Физическое разрешение при этом может быть 1179×2556 px (iPhone 15 Pro) — но разработчик работает с точками.
По данным Apple Human Interface Guidelines, точки — фундаментальная абстракция UIKit. Все фреймворки — UIKit, SwiftUI, Core Graphics, SpriteKit — оперируют точками. Конвертация в пиксели происходит автоматически на этапе рендеринга через UIScreen.nativeScale.
Коэффициент масштаба (scale factor) определяет, сколько физических пикселей соответствует одной логической точке. Apple использует три уровня: @1x — 1 pt = 1 px (iPad mini без Retina, старые модели), @2x — 1 pt = 2 px (большинство iPhone до 2020 года, iPad Retina), @3x — 1 pt = 3 px (iPhone X и новее, включая iPhone 15 Pro).
| Устройство | Размер в pt | Размер в px | Scale |
|---|---|---|---|
| iPhone SE (3rd gen) | 375 × 667 | 750 × 1334 | @2x |
| iPhone 14 | 390 × 844 | 1170 × 2532 | @3x |
| iPhone 15 Pro Max | 430 × 932 | 1290 × 2796 | @3x |
| iPad Pro 12.9" | 1024 × 1366 | 2048 × 2732 | @2x |
| iPad mini (6th gen) | 744 × 1133 | 1488 × 2266 | @2x |
Значение scale factor доступно через UIScreen.main.scale (для UIKit) и @Environment(\.displayScale) (для SwiftUI). Используется при загрузке ассетов: система автоматически выбирает изображение с суффиксом @2x или @3x из Assets.xcassets. Разработчик не загружает @1x-изображения на устройствах с Retina — это снижает производительность и качество.
Структура CGPoint — базовый тип для представления координат в iOS и macOS. Содержит два поля: x (CGFloat) и y (CGFloat), значения задаются в точках. CGPoint используется во всех фреймворках Apple: UIKit (frame.origin), Core Graphics (CGContext), SpriteKit (SKNode.position), Core Animation (CALayer.position).
// CGPoint — работа с координатами в точках
import UIKit
// Создание точки
let point = CGPoint(x: 100.0, y: 200.0)
print("Координаты: \(point.x), \(point.y)")
// Математические операции
let offset = CGPoint(x: 16.0, y: 8.0)
let translated = CGPoint(
x: point.x + offset.x,
y: point.y + offset.y
)
// Расстояние между точками
func distance(from a: CGPoint, to b: CGPoint) -> CGFloat {
let dx = b.x - a.x
let dy = b.y - a.y
return sqrt(dx * dx + dy * dy)
}
// Преобразование точки в пиксели
extension CGPoint {
func toPixels(scale: CGFloat) -> CGPoint {
CGPoint(x: x * scale, y: y * scale)
}
}Метод toPixels в примере демонстрирует конвертацию точек в физические пиксели через UIScreen.main.scale. В UIKit эта конвертация происходит автоматически при рендеринге, но в Core Graphics и при работе с Metal разработчику может потребоваться явный перевод в пиксели. Все расчёты анимаций, collision detection и layout выполняются в точках.
Свойство UIFont.pointSize возвращает размер шрифта в точках — это стандартная единица типографики в iOS, унаследованная из полиграфии (1 pt = 1/72 дюйма). Apple использует pt для шрифтов с первых версий Mac OS. В iOS размер шрифта задаётся в точках через UIFont.systemFont(ofSize:) или через SwiftUI Font.system(size:).
// Работа с UIFont.pointSize в Swift
import UIKit
// Создание шрифта с размером в pt
let titleFont = UIFont.systemFont(ofSize: 28.0, weight: .bold)
let bodyFont = UIFont.systemFont(ofSize: 17.0)
let captionFont = UIFont.systemFont(ofSize: 12.0)
// Чтение pointSize
print("Размер заголовка: \(titleFont.pointSize) pt")
// Динамический тип — автоматическое масштабирование
let scaledFont = UIFontMetrics.default.scaledFont(for: bodyFont)
print("Масштабированный: \(scaledFont.pointSize) pt")
// Сравнение размеров шрифтов
func font(from size: CGFloat, weight: UIFont.Weight) -> UIFont {
UIFont.systemFont(ofSize: size, weight: weight)
}UIFontMetrics — механизм динамического масштабирования шрифтов, добавленный в iOS 11. Он автоматически корректирует pointSize в зависимости от настроек доступности пользователя (Settings > Display & Brightness > Text Size). Без использования UIFontMetrics шрифты не масштабируются, что нарушает требования WCAG к доступности.
Разница между pt и px критична для понимания iOS-разработки. pt — логическая единица, px — физическая. Одна точка может соответствовать 1, 2 или 3 пикселям в зависимости от scale factor. Разработчик оперирует точками, система преобразует их в пиксели на этапе растеризации.
| Характеристика | pt | px |
|---|---|---|
| Тип единицы | Логическая (device-independent) | Физическая (hardware pixel) |
| Зависит от разрешения | Нет | Да |
| Где используется | UIKit, SwiftUI, Core Graphics, layout | Изображения, Metal, raw buffer |
| Конвертация | 1 pt = scale × px (scale от 1 до 3) | 1 px = pt / scale |
| Пример (iPhone 15 Pro) | 393 × 852 pt | 1179 × 2556 px |
Ключевое следствие: размер интерфейса в точках одинаков на всех устройствах одного класса. Экран 375 pt шириной — это и iPhone SE, и iPhone 14 (базовая модель). Разница только в том, сколько физических пикселей умещается в эти 375 pt. Это обеспечивает единообразный UI без ручной адаптации под каждое устройство.
В SwiftUI разработчик не оперирует точками явно — все размеры задаются через Dp (device-independent points, эквивалент pt). SwiftUI автоматически применяет scale factor при рендеринге, но предоставляет доступ к нему через environment value displayScale.
// SwiftUI — работа с точками и scale factor
import SwiftUI
struct ContentView: View {
@Environment(\.displayScale) private var displayScale
var body: some View {
VStack(spacing: 16) {
Text("Заголовок")
.font(.system(size: 28, weight: .bold))
Text("Основной текст примера")
.font(.body)
HStack {
Text("Scale factor:")
.font(.caption)
Text("\(displayScale, specifier: "%.1f")")
.font(.caption.weight(.bold))
}
}
.padding(20)
.frame(width: 300)
}
}SwiftUI абстрагирует pt на уровне фреймворка. .font(.body) автоматически использует Dynamic Type — размер шрифта подстраивается под настройки пользователя. SwiftUI не позволяет задать размер шрифта в пикселях — только через Font и систему типографики. Это гарантирует доступность интерфейса без дополнительных усилий разработчика.
Часто задаваемые вопросы
pt — логическая точка iOS, не зависящая от разрешения экрана. px — физический пиксель дисплея. Одна точка на iPhone 15 Pro равна трём пикселям (@3x), на iPad Pro — двум (@2x). Разработчик всегда оперирует точками.
В UIKit: UIScreen.main.scale. В SwiftUI: @Environment(\.displayScale). Типичные значения: 1.0 (@1x), 2.0 (@2x), 3.0 (@3x). На iPhone 15 Pro Max значение — 3.0.
Apple рекомендует 17 pt для основного текста (UIFontTextStyle.body). Для заголовков — 28–34 pt. Для подписей — 12–13 pt. Стили Dynamic Type автоматически масштабируются под настройки доступности пользователя.
Dynamic Type — система автоматического масштабирования шрифтов iOS, представленная в iOS 7. Позволяет тексту адаптироваться под системные настройки размера шрифта (Text Size) и параметры доступности (Bold Text, Larger Text). Реализуется через UIFontMetrics или стили SwiftUI Font.
Нет. Современные устройства Apple используют Retina-дисплеи с @2x или @3x. @1x изображения нужны только для совместимости с iPad без Retina (iPad 2, iPad mini 1st gen). Начиная с iOS 13, все устройства поддерживают как минимум @2x.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.