Swift | Вопросы собесов
2.15K subscribers
29 photos
959 links
Download Telegram
🤔 Что такое gitflow?

В основе Git Flow – несколько веток с разными ролями, чтобы команда могла параллельно разрабатывать новые фичи, исправлять баги и выпускать релизы.

🚩Как работает Git Flow?

🟠Основные ветки (`main` и `develop`)
- main – содержит только стабильные версии.
- developосновная ветка разработки, в неё вливаются все новые фичи.

🟠Разработка новых фич (feature branches)
- Каждая новая фича создаётся в отдельной ветке feature/*.
- После завершения сливается в develop.
git checkout develop
git checkout -b feature/new-cool-feature
# Разработка...
git checkout develop
git merge feature/new-cool-feature
git branch -d feature/new-cool-feature


🟠Подготовка к релизу (release branches)
- Когда код стабилен, создаётся ветка release/* от develop.
- Здесь можно тестировать и исправлять баги.
- После финального теста сливается в main и develop.
git checkout develop
git checkout -b release/1.0
# Фиксим баги, тестируем...
git checkout main
git merge release/1.0
git tag -a v1.0 -m "Release 1.0"
git checkout develop
git merge release/1.0
git branch -d release/1.0


🟠Горячие фиксы (hotfix branches)
- Если критический баг в main, создаём hotfix/*.
- После исправления вливаем в main и в develop.
git checkout main
git checkout -b hotfix/urgent-bugfix
# Фиксим баг...
git checkout main
git merge hotfix/urgent-bugfix
git checkout develop
git merge hotfix/urgent-bugfix
git branch -d hotfix/urgent-bugfix


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Объяснение NSOperation?

NSOperation — это объектно-ориентированный способ организации задач в iOS/macOS. Он позволяет управлять очередями задач с возможностью их приостановки, отмены, приоритезации и установления зависимостей между операциями. Работает в связке с NSOperationQueue. В отличие от GCD, даёт больше контроля и читаемости, особенно при работе со сложными асинхронными цепочками.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В чём разница между вью и леером?

В iOS и macOS приложениях, разработанных с использованием Swift или Objective-C, UIView и CALayer играют ключевые роли в управлении и отображении пользовательского интерфейса. Несмотря на то, что они тесно связаны, между ними есть важные различия. Давайте рассмотрим их подробнее.

🚩UIView

UIView — это базовый класс для всех элементов пользовательского интерфейса в iOS. Он представляет собой прямоугольную область на экране, которая может отображать контент и реагировать на события пользователя, такие как нажатия, жесты и касания.
UIView предоставляет множество свойств и методов для управления внешним видом, положением и поведением представления. Примеры включают frame, bounds, center, backgroundColor, alpha, isHidden, и subviews. UIView также поддерживает анимации, автолэйаут и работу с событийной системой.
UIView обрабатывает пользовательские события, такие как касания и жесты. Он предоставляет методы, такие как touchesBegan, touchesMoved, и touchesEnded, для обработки этих событий.
   let myView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myView.backgroundColor = .blue
view.addSubview(myView)


🚩CALayer

CALayer — это базовый класс для всех графических слоев, используемых в Core Animation. Он обеспечивает низкоуровневую поддержку для рендеринга, анимации и композиции графики.
CALayer предоставляет свойства для управления внешним видом, такими как backgroundColor, borderWidth, cornerRadius, shadowOpacity, contents (для отображения изображений), и transform. CALayer также поддерживает анимации, используя ключевые кадры и основные анимации. CALayer не обрабатывает пользовательские события напрямую. Эти задачи оставлены на UIView, который может содержать один или несколько слоев.
   let myLayer = CALayer()
myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
myLayer.backgroundColor = UIColor.blue.cgColor
view.layer.addSublayer(myLayer)


🚩Основные различия между UIView и CALayer

🟠По уровеню абстракции
UIView
— это более высокий уровень абстракции, предназначенный для работы с пользовательским интерфейсом и обработкой событий. CALayer — более низкоуровневый элемент, который фокусируется на рендеринге и анимации графики.

🟠Реакция на события
UIView обрабатывает события пользовательского интерфейса. CALayer не обрабатывает события, но предоставляет возможности для рендеринга и анимации.

🟠Иерархия
UIView может содержать другие представления (subviews) и управлять их иерархией. CALayer может содержать другие слои (sublayers) и управлять их иерархией.

🟠Анимации
UIView использует UIView.animate для создания анимаций, которые высокоуровневые и просты в использовании. CALayer использует CAAnimation и его подклассы для создания анимаций, которые более гибкие и мощные, но требуют большего количества кода.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 В чём разница между var и let?

- var — переменная, её значение можно изменить.
- let — константа, значение нельзя переопределить после инициализации.
Это помогает контролировать изменяемость данных в коде.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔2
🤔 Какие есть способы верстать?

В iOS существует несколько способов вёрстки пользовательского интерфейса. Каждый из них имеет свои плюсы и минусы в зависимости от проекта.

🟠Interface Builder (Storyboard & XIB)
Используется: визуальный редактор в Xcode.
Storyboard
- Позволяет создавать весь UI в одном файле .storyboard.
- Поддерживает Auto Layout и Size Classes для адаптивного дизайна.
- Можно настраивать Segue (переходы между экранами).

🟠Верстка кодом (без Storyboard)
Используется: Полностью программная вёрстка без использования Interface Builder.
let button = UIButton()
button.setTitle("Нажми", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)

NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])


🟠SwiftUI – декларативный подход
Используется: Современный способ верстки с декларативным синтаксисом.
struct ContentView: View {
var body: some View {
VStack {
Text("Привет, SwiftUI!")
.font(.largeTitle)
Button("Нажми меня") {
print("Кнопка нажата")
}
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Зачем нужны свойства "Content Hugging Priority"?

1. Свойства управляют тем, как сильно элемент интерфейса сопротивляется увеличению своего размера.
2. Высокий приоритет указывает, что элемент предпочитает оставаться минимального размера, основываясь на содержимом.
3. Используется для разрешения конфликтов автолейаута, чтобы определять, какой элемент должен изменяться.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Inam относится ли к value тайпам?

enum (перечисления) относится к типам значений (value types). Это означает, что при передаче перечисления функции или при его присвоении переменной создается новая копия этого перечисления. Это работает аналогично другим типам значений, таким как struct и базовые типы данных (Int, String, Double и т.д.).

🚩Особенности

🟠Копирование при присвоении
Когда переменной перечисления присваивается значение другой переменной перечисления, создается независимая копия этого значения.

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

🟠Связанные значения
enum может хранить связанные значения различных типов.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}


🟠Методы
enum может иметь методы, которые предоставляют функциональность, связанную с перечислением.
enum Planet {
case earth, mars, venus

func isHabitable() -> Bool {
switch self {
case .earth:
return true
default:
return false
}
}
}


Пример
enum TrafficLight {
case red, yellow, green
}

var light = TrafficLight.red
var lightCopy = light
lightCopy = .green

print(light) // Выводит "red"
print(lightCopy) // Выводит "green"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊7🤔2
🤔 Какие ситуации могут быть с isUserInteractionEnabled = false, когда UIView не может обработать тач?

Если isUserInteractionEnabled == false, то:
- Вью не участвует в hit-тестировании.
- Касания игнорируются, и управление не передаётся даже в её subviews.
- Это может использоваться для пропуска вью при касаниях, например для декоративных вьюшек или контейнеров.
Ситуации:
- Кнопка, которая кажется активной, но isUserInteractionEnabled = false — не реагирует.
- Обёртка вокруг интерактивной вью с отключенным взаимодействием — вложенные вью тоже не реагируют.
Чтобы вложенные вью реагировали, при этом контейнер не мешал, можно либо оставить userInteractionEnabled = true, либо использовать прозрачный hitTest.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
🤔 Как устроена память?

Память устройства можно представить в виде нескольких уровней, каждый из которых имеет свою скорость доступа, размер и назначение:

🟠Регистры процессора
Это самая быстрая память, непосредственно встроенная в процессор. Регистры хранят те данные, с которыми процессор работает в данный момент времени.

🟠Кэш-память
Она находится непосредственно на процессоре или рядом с ним. Кэш-память используется для временного хранения копий часто используемых данных из основной памяти для ускорения доступа к ним. Кэш-память делится на несколько уровней (L1, L2, и иногда L3), где L1 — самый быстрый и обычно самый маленький.

🟠Оперативная память (ОЗУ)
Здесь хранятся данные и программы, с которыми компьютер работает в данный момент. Доступ к ОЗУ быстрый, но оно является временным хранилищем: при выключении устройства данные в ОЗУ теряются.

🟠Постоянная память (ПЗУ, SSD, HDD)
Это память для долговременного хранения данных. Она сохраняет информацию даже при выключении питания. HDD (жесткие диски) использовались ранее и работают на принципе магнитного записывания данных, в то время как SSD (твердотельные накопители) работают на основе флеш-памяти и обеспечивают более быстрый доступ к данным.

🟠Виртуальная память
Это техника, которая позволяет операционной системе использовать часть жесткого диска (или SSD) как дополнительную оперативную память. Когда ОЗУ заполнено, операционная система может перемещать редко используемые данные из ОЗУ на диск в специальный файл подкачки (swap file), освобождая ОЗУ для других задач.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Существует 2 типа queue?

Да, существуют два основных типа dispatch-очередей:
- Serial queue — задачи выполняются строго по одной, по порядку.
- Concurrent queue — задачи могут выполняться одновременно, в зависимости от доступных ресурсов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие виды диспетчеризации существуют в свифт?

В Swift существует несколько видов диспетчеризации, которые определяют, как и когда вызываются методы или функции. Основные виды диспетчеризации включают статическую диспетчеризацию (static dispatch), диспетчеризацию по таблице виртуальных функций (vtable dispatch), диспетчеризацию по свидетелю (witness table dispatch) и динамическую диспетчеризацию (dynamic dispatch). Рассмотрим их подробнее:

🟠Статическая диспетчеризация (Static Dispatch)
Вызов функции или метода определяется на этапе компиляции. Используется для функций и методов, которые не переопределяются в подклассах или не являются динамическими. Для структур, перечислений и final классов.
     struct MyStruct {
func printMessage() {
print("Hello from MyStruct")
}
}

let instance = MyStruct()
instance.printMessage() // Вызов определяется на этапе компиляции


🟠Диспетчеризация по таблице виртуальных функций (Vtable Dispatch)
Используется для вызова методов класса, которые могут быть переопределены в подклассах. Виртуальная таблица (vtable) используется для определения, какой метод вызывать. Для классов и их подклассов.
     class BaseClass {
func printMessage() {
print("Hello from BaseClass")
}
}

class SubClass: BaseClass {
override func printMessage() {
print("Hello from SubClass")
}
}

let instance: BaseClass = SubClass()
instance.printMessage() // Вызов определяется в runtime с использованием vtable


🟠Диспетчеризация по свидетелю (Witness Table Dispatch)
Используется для вызова методов протоколов, реализованных типами. Таблица свидетелей (witness table) используется для определения, какой метод вызывать. Для типов, соответствующих протоколам.
     protocol MyProtocol {
func printMessage()
}

struct MyStruct: MyProtocol {
func printMessage() {
print("Hello from MyStruct")
}
}

let instance: MyProtocol = MyStruct()
instance.printMessage() // Вызов определяется в runtime с использованием witness table


🟠Динамическая диспетчеризация (Dynamic Dispatch)
Используется для вызова методов, отмеченных как dynamic или методов Objective-C. Метод определяется в runtime с использованием Objective-C runtime. Для методов, которые должны быть динамически разрешены в runtime, обычно для взаимодействия с Objective-C.
     import Foundation

class MyClass: NSObject {
@objc dynamic func printMessage() {
print("Hello from MyClass")
}
}

let instance = MyClass()
instance.printMessage() // Вызов определяется в runtime с использованием Objective-C runtime


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔 К какому типу относится замыкание?

Замыкание — это референсный тип. Оно является объектом и передаётся по ссылке. При захвате переменных — сохраняет их в памяти до завершения использования.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
🤔 Что такое Satisfiable?

В контексте Swift термин Satisfiable (удовлетворяемый) относится к тому, может ли конкретный тип соответствовать (удовлетворять) требованиям протокола.

🚩Что значит, что протокол satisfiable?
Протокол считается satisfiable, если его можно реализовать без противоречий. Например, если в протоколе указаны требования, которые могут быть выполнены в классе или структуре.
protocol Animal {
var name: String { get }
func speak()
}

struct Dog: Animal {
var name = "Барсик"

func speak() {
print("Гав-гав")
}
}

let dog = Dog()
dog.speak() // "Гав-гав"


🚩Когда протокол не satisfiable?

Протокол не может быть удовлетворён (то есть, не satisfiable), если он содержит требования, которые невозможно реализовать в конкретном типе.
protocol Impossible {
var value: Self { get } // Self требует, чтобы свойство содержало сам тип
}

struct Example: Impossible {
var value: Example // ОШИБКА: бесконечная рекурсия!
}


🚩Проверка satisfiability в Swift

Если вы видите ошибку Protocol 'X' cannot be satisfied, значит, Swift не может найти способ правильно реализовать все его требования.
Проверьте ассоциированные типы и Self – они должны корректно ссылаться на реализуемый тип.
Проверьте требования протокола – убедитесь, что все свойства и методы могут быть реализованы в классе/структуре.
Попробуйте использовать any Protocol – если Self создаёт проблемы, возможно, нужно использовать any:
   func test(value: any Impossible) { } // Позволяет работать с протоколом без строгого Self


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что будет, если сделать копию массива?

Зависит от языка:
- В Python или Swift, копирование изменяемого массива создаёт новый массив, но если элементы — ссылки на объекты, то копируются ссылки, а не сами объекты (поверхностная копия).
- В других языках может быть как поверхностная, так и глубокая копия, в зависимости от реализации. Копия — это независимая структура, но её элементы могут по-прежнему ссылаться на одни и те же объекты.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2
🤔 Что такое runLoop?

RunLoop — это фундаментальный механизм в iOS и macOS, который управляет циклом обработки событий в приложении. Он отслеживает и обрабатывает входящие события, такие как нажатия клавиш, касания экрана, таймеры и сетевые запросы, и поддерживает приложение в активном состоянии, пока оно не завершится.

🚩Основные аспекты `RunLoop`

🟠Цикл обработки событий
RunLoop постоянно выполняет цикл, ожидая входящие события и обрабатывая их по мере поступления. Этот цикл состоит из нескольких этапов: ожидание события, обработка события и повтор цикла.

🟠Режимы (Modes)
RunLoop может работать в разных режимах, которые определяют, какие источники событий будут отслеживаться и обрабатываться. Основные режимы включают default и tracking (для событий отслеживания, таких как прокрутка). В каждой итерации RunLoop обрабатывает события только для текущего режима.
RunLoop.current.run(mode: .default, before: Date.distantFuture)     


🟠Источники событий (Event Sources)
RunLoop может отслеживать различные источники событий, такие как таймеры (Timer), порты (Port), ввод пользователей (такие как касания экрана и клики мыши), а также пользовательские источники (Input Source).

🟠Таймеры
RunLoop может управлять таймерами, которые выполняют задачи через определенные интервалы времени.
     let timer = Timer(timeInterval: 1.0, repeats: true) { _ in
print("Timer fired!")
}
RunLoop.current.add(timer, forMode: .default)


🟠Обработка событий
RunLoop используется для обработки событий в основном потоке (main thread) приложения. Это особенно важно для поддержания отзывчивости пользовательского интерфейса, поскольку все взаимодействия с UI происходят в основном потоке.

🚩Пример использования `RunLoop`

import Foundation

class Example {
var timer: Timer?

func startRunLoop() {
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
RunLoop.current.run()
}

@objc func timerFired() {
print("Timer fired!")
}
}

let example = Example()
example.startRunLoop()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что такое matchedGeometryEffect?

Это механизм анимации в SwiftUI, позволяющий плавно анимировать переходы между представлениями, сохраняя визуальную взаимосвязь между элементами, которые логически одинаковые, но физически находятся в разных частях UI.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Какие есть варианты обезопасить работу с историей images?

Обеспечение безопасности работы с историей изображений в iOS-приложениях может включать несколько уровней защиты:

🟠Контроль доступа к изображениям
- Используйте Privacy Settings (NSPhotoLibraryUsageDescription, NSCameraUsageDescription) для контроля доступа к фотоальбому.
- Для ограниченного доступа в iOS 14+ используйте PHPickerViewController.
let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
if status == .authorized {
// Доступ есть
} else {
// Запросить разрешение
PHPhotoLibrary.requestAuthorization { newStatus in
if newStatus == .authorized {
print("Доступ получен")
}
}
}


🟠Шифрование изображений
- Если изображения сохраняются локально, используйте AES-шифрование.
- Можно хранить ключ в Keychain или использовать Secure Enclave.
import CommonCrypto

func encryptImage(data: Data, key: Data) -> Data? {
var buffer = Data(count: data.count + kCCBlockSizeAES128)
var numBytesEncrypted: size_t = 0

let status = CCCrypt(
CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding), key.bytes, key.count,
nil, data.bytes, data.count, &buffer, buffer.count, &numBytesEncrypted
)

return status == kCCSuccess ? buffer.prefix(numBytesEncrypted) : nil
}


🟠Безопасное хранение изображений
Core Data с Encrypted Store – можно использовать зашифрованные базы данных, такие как SQLCipher.
FileManager + Data Protection – файлы можно хранить в Application Support с флагом .completeFileProtection.
Keychain – если нужно хранить ссылки на изображения или ключи.
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("secure_image.jpg")
try? imageData.write(to: fileURL, options: .completeFileProtection)


🟠Ограничение кеширования изображений
- Если изображение чувствительное, отключите кеширование в URLSession:
let config = URLSessionConfiguration.default
config.urlCache = nil // Отключаем кеш
let session = URLSession(configuration: config)


🟠Защита от утечек в памяти
- Убедитесь, что ссылки на изображения не создают retain cycle.
- Используйте weak ссылки в кэше изображений.
class ImageCache {
private let cache = NSCache<NSString, UIImage>()

func store(image: UIImage, forKey key: String) {
cache.setObject(image, forKey: key as NSString)
}

func retrieve(forKey key: String) -> UIImage? {
return cache.object(forKey: key as NSString)
}
}


🟠Безопасная загрузка изображений (защита от MITM)
- Используйте HTTPS вместо HTTP.
- Включите App Transport Security (ATS) в Info.plist.
- Верифицируйте SSL-сертификаты при загрузке.
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if let serverTrust = challenge.protectionSpace.serverTrust {
let credential = URLCredential(trust: serverTrust)
completionHandler(.useCredential, credential)
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В чём разница между static и final?

static используется для определения методов и свойств, которые принадлежат типу, а не экземпляру. Внутри классов static по сути означает final, так как такие методы нельзя переопределить в подклассах.
final, в свою очередь, может применяться к классам, методам и свойствам, чтобы запретить наследование или переопределение, но не обязательно делает метод или свойство статическим.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔 Что относится к типам данных?

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

🤔 Основные типы данных

🟠Примитивные типы данных
Представляют целые числа. Int, UIn
       let age: Int = 25


Представляют дробные числа. Float, Double
       let pi: Double = 3.14159


Представляют логические значения true или false. Bool
       let isActive: Bool = true


Представляют отдельные символы. Character
       let letter: Character = "A"


🟠Составные типы данных (Composite data types)
Представляют последовательности символов. String
       let greeting: String = "Hello, World!"


Представляют упорядоченные коллекции элементов одного типа. Array<T>
       let numbers: [Int] = [1, 2, 3, 4, 5]


Представляют коллекции пар ключ-значение. Dictionary<Key, Value>
       let user: [String: String] = ["name": "Alice", "age": "30"]


Представляют коллекции уникальных элементов. Set<T>
       let uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5]


🟠Пользовательские типы данных (User-defined data types)
Представляют тип данных с набором связанных значений. enum
       enum CompassPoint {
case north
case south
case east
case west
}


Представляют группы связанных значений. struct
       struct Person {
var name: String
var age: Int
}
let person = Person(name: "Alice", age: 30)


Представляют объекты с состоянием и поведением. class
       class Car {
var model: String
var year: Int

init(model: String, year: Int) {
self.model = model
self.year = year
}
}
let car = Car(model: "Tesla", year: 2021)


🟠Специальные типы данных
Представляют группы нескольких значений различных типов. (Type1, Type2, ...)
       let coordinates: (Int, Int) = (10, 20)


Представляют значение, которое может быть либо некоторым значением, либо nil. Optional<T>
       var optionalName: String? = "Alice"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что происходит с вьюшками, которые лежат в Scroll View?

- Эти вьюшки не двигаются физически — они находятся в contentView, которая движется вместе с contentOffset.
- Относительно ScrollView они могут визуально выходить за пределы видимости, но физически остаются на месте внутри большого contentSize.
Если вью ушла за пределы видимой области, она не рендерится до тех пор, пока не попадёт в видимую область (оптимизация).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2