2026-08-29 19:22:12 -03:00
# LCEssentials — UIKit
UIKit-era helpers: programmatic layout & constraints, view/control extensions,
navigation, table/collection helpers, and drop-in components (image picker, image
zoom, snackbar, GIF loading).
Foundation/value-type helpers are in [Extensions.md ](Extensions.md ); SwiftUI
helpers in [SwiftUI.md ](SwiftUI.md ).
Every section is a collapsible block — click a heading to expand it.
## Contents
- [Layout & Constraints ](#layout--constraints )
- [Views & Controls ](#views--controls )
- [Navigation & Controllers ](#navigation--controllers )
- [Collections & Tables ](#collections--tables )
- [Media & Components ](#media--components )
---
## Layout & Constraints
2026-08-29 19:31:43 -03:00
<details>
<summary><b>UIView</b> — programmatic constraints, chainable anchors</summary>
### `enum AnchorType`
The anchor to pin when using `setConstraintsTo` . Cases: `all` , `top` , `bottom` ,
`leading` , `trailing` , `left` , `right` , `centerX` , `centerY` , `width` , `heigth`
*(sic)*, `topToBottom` , `bottomToTop` , `leadingToTrailing` , `trailingToLeading` ,
plus `…GreaterThanOrEqualTo` / `…LessThanOrEqualTo` variants.
### `@discardableResult func setConstraintsTo(parentView: UIView, anchorType: AnchorType, value: CGFloat, safeArea: Bool = false) -> Self`
Activate one constraint against `parentView` . Remembers `parentView` (in
`viewReference` ) so follow-up calls can omit it. `safeArea: true` pins top/bottom
to the safe-area guide (iOS 11+).
```swift
card.addSubview(label)
label.setConstraintsTo(parentView: card, anchorType: .top, value: 12, safeArea: false)
.setConstraints(.leading, 16)
.setConstraints(.trailing, -16)
```
### `@discardableResult func setConstraintsTo(_ parentView:_ anchorType:_ value:_ safeArea: Bool = false) -> Self`
Positional-argument shorthand for the above.
### `@discardableResult func setConstraintsTo(anchorType: AnchorType, value: CGFloat, safeArea: Bool = false) -> UIView`
Reuse the last `parentView` (`viewReference` ). **Traps ** with `fatalError` if no
`parentView` was set first.
### `@discardableResult func setConstraints(_ anchorType: AnchorType, _ value: CGFloat, _ safeArea: Bool = false) -> UIView`
Positional shorthand for the reuse form — the one you chain.
### `func setConstraints(_ toScrollView: UIScrollView, direction: UICollectionView.ScrollDirection = .vertical)`
Pin `self` as the single content view of a scroll view (edges + matching
width/height, with a low-priority constraint on the scroll axis). Traps if
`self` is itself a `UIScrollView` .
```swift
scrollView.addSubview(content)
content.setConstraints(scrollView, direction: .vertical)
```
### Constraint accessors
`widthConstraint` , `heightConstraint` , `leadingConstraint` , `trailingConstraint` ,
`topConstraint` , `bottomConstraint` , `centerXConstraints` , `centerYConstraints` —
the first matching `NSLayoutConstraint` found by walking up the hierarchy.
```swift
box.widthConstraint?.constant = 120
UIView.animate(withDuration: 0.2) { self.view.layoutIfNeeded() }
```
### `func findConstraint(attribute: NSLayoutConstraint.Attribute, for view: UIView) -> NSLayoutConstraint?`
Search self and ancestors for a constraint on `attribute` involving `view` .
### `func constraints(on anchor:) -> [NSLayoutConstraint]`
Constraints touching a given `NSLayoutYAxisAnchor` / `XAxisAnchor` / `Dimension` of `self` .
### `@discardableResult func setHeight(size:) -> Self` / `setHeight(min:)` / `setWidth(size:)` / `setWidth(min:)`
Activate a fixed or minimum dimension constraint.
```swift
avatar.setWidth(size: 44).setHeight(size: 44)
```
### `func setWidth(_ toView: UIView? = nil, constant: CGFloat, _ multiplier: CGFloat = 0) -> Self` / `setHeight(...)`
Dimension relative to another view (`multiplier` ) or fixed (`multiplier == 0` ).
### Frame setters
`setX(x:)` , `setY(y:)` , `setFrameWidth(width:)` , `setFrameHeight(height:)` — mutate
`self.frame` directly (manual layout, not Auto Layout).
</details>
<details>
<summary><b>UIView</b> — hierarchy, appearance, effects</summary>
### `static var className: String`
`String(describing: self)` .
```swift
UIButton.className // "UIButton"
```
### `func addSubview(_ subview:, translatesAutoresizingMaskIntoConstraints: Bool = false)` / `addSubviews(_ subviews: [UIView], …)`
Add a view (or many) and set `translatesAutoresizingMaskIntoConstraints` in one call.
```swift
view.addSubviews([header, body, footer]) // all ready for Auto Layout
```
### `func subviews<T>(ofType _: T.Type) -> [T]`
All descendants of a type, recursively.
```swift
formView.subviews(ofType: UITextField.self)
```
### `func findAView<T>(_ ofType: T.Type) -> T?`
First descendant of a type.
### `var parentViewController: UIViewController?`
Nearest owning view controller (walks the responder chain).
### `var borderColor: UIColor?` / `var borderWidth: CGFloat` / `var cornerRadius: CGFloat`
Layer border/corner shortcuts (`cornerRadius` also sets `masksToBounds` ).
```swift
card.cornerRadius = 12
card.borderWidth = 1
card.borderColor = .separator
```
### `func setRadius(top: Bool, bottom: Bool, radius: CGFloat = 8)`
Round only the top and/or bottom corners.
```swift
sheet.setRadius(top: true, bottom: false, radius: 16)
```
### `func applyShadow(color:offSet:radius:opacity:shouldRasterize: Bool = true, rasterizationScaleTo: = UIScreen.main.scale)` / `func removeShadow()`
Layer shadow with rasterisation on by default.
```swift
card.applyShadow(color: .black, offSet: CGSize(width: 0, height: 2),
radius: 6, opacity: 0.15)
```
### `func insertBlurView(style: UIBlurEffect.Style, color: UIColor = .black, alpha: CGFloat = 0.9)`
Insert a full-bleed `UIVisualEffectView` behind the content.
### `func drawCircle(inCoord x:y:with radius:strokeColor: = .red, fillColor: = .gray, isEmpty: Bool = false) -> [String: Any]`
Add a circular `CAShapeLayer` ; returns `["path": UIBezierPath, "layer": CAShapeLayer]` .
### `var isRightToLeft: Bool`
Effective RTL layout direction.
### `var screenshot: UIImage?` / `func asImage() -> UIImage`
Render the view to an image (`screenshot` via the legacy context, `asImage` via `UIGraphicsImageRenderer` ).
```swift
let png = chartView.asImage().pngData()
```
### `var globalPoint: CGPoint?` / `var globalFrame: CGRect?` / `var absolutePosition: CGRect`
Origin/frame converted to window coordinates.
### `func fadeIn(withDuration: TimeInterval = 1, withDelay: TimeInterval = 0, completionHandler: @escaping (Bool) -> Void)` / `func fadeOut(...)`
Animate `alpha` to 1 / 0. * (Completion-handler API — pre-dates async/await.) *
```swift
overlay.fadeOut { _ in overlay.removeFromSuperview() }
```
### `var viewReference: UIView?`
Scratch reference used internally by the chained `setConstraintsTo` calls.
</details>
<details>
<summary><b>GradientOrientation / EnumBorderSide</b></summary>
### `enum GradientOrientation`
`topRightBottomLeft` , `topLeftBottomRight` , `horizontal` , `vertical` — maps to a
`CAGradientLayer` start/end point pair. Passed to gradient helpers elsewhere in
the package.
### `enum EnumBorderSide`
`top` , `bottom` , `left` , `right` — which edge to draw a single-side border on.
</details>
<details>
<summary><b>UIStackView</b> — convenience init, bulk arranged-subview ops (iOS 9+)</summary>
### `convenience init(arrangedSubviews: [UIView]? = nil, axis: = .vertical, spacing: = 0, alignment: = .fill, distribution: = .fill, layoutMargins: = .zero, isMarginsRelative: Bool = true)`
One-call configured stack view.
```swift
let stack = UIStackView(arrangedSubviews: [title, subtitle],
axis: .vertical, spacing: 4)
```
### `func addArrangedSubviews(_ views: [UIView], translateAutoresizing: Bool = false)`
Add many arranged subviews, setting their autoresizing flag.
### `func removeAllArrangedSubviews(deactivateConstraints: Bool = true)`
Remove and dispose every arranged subview.
### `func removeSubview(view: UIView, deactivateConstraints: Bool = true)`
Remove one arranged subview (optionally deactivating its constraints and removing from the hierarchy).
### `func addSpace(_ size: CGFloat, backgroundColor: UIColor = .clear)`
Insert a fixed-size spacer view sized along the stack's axis.
```swift
stack.addArrangedSubviews([row1, row2])
stack.addSpace(24)
stack.addArrangedSubview(row3)
```
</details>
> `NSLayoutConstraint` helpers (`constraintWithMultiplier`, `matches(view:anchor:)`)
> and `[NSLayoutConstraint].filtered(view:anchor:)` are `internal` — used by the
> `UIView.constraints(on:)` accessors above, not called directly.
2026-08-29 19:22:12 -03:00
## Views & Controls
2026-08-29 19:32:31 -03:00
<details>
<summary><b>UIButton</b> — per-state accessors, all-state setters</summary>
### Per-state properties
`imageForNormal` / `imageForHighlighted` / `imageForSelected` / `imageForDisabled` ,
`titleForNormal` / `…Highlighted` / `…Selected` / `…Disabled` ,
`titleColorForNormal` / `…Highlighted` / `…Selected` / `…Disabled` — get/set
shortcuts for the matching `UIControl.State` (also `@IBInspectable` ).
```swift
button.titleForNormal = "Save"
button.titleColorForDisabled = .tertiaryLabel
```
### `func setTitleForAllStates(_:)` / `func setTitleColorForAllStates(_:)` / `func setImageForAllStates(_:)`
Apply one value to `.normal` , `.selected` , `.highlighted` , `.disabled` at once.
```swift
button.setTitleColorForAllStates(.white)
```
### `func centerTextAndImage(spacing: CGFloat)`
Balance title/image edge insets so text + icon sit centred with `spacing` between them.
```swift
button.centerTextAndImage(spacing: 8)
```
</details>
<details>
<summary><b>UILabel</b></summary>
### `func lineNumbers() -> Int`
Rendered line count at the current width.
```swift
if bodyLabel.lineNumbers() > 3 { showMoreButton() }
```
### `var getEstimatedHeight: CGFloat`
Height the label would need to show its full text/attributed text unclipped.
</details>
<details>
<summary><b>UITextField</b></summary>
### `var placeholderColor: UIColor`
Get/set the placeholder text colour (rebuilds `attributedPlaceholder` ; setter is a
no-op if no placeholder text is set).
```swift
field.placeholder = "Email"
field.placeholderColor = .secondaryLabel
```
### `func addPaddingLeft(_ padding: CGFloat)`
Inset the text from the left with an empty spacer view.
### `func addPaddingLeftIcon(_ image: UIImage, padding: CGFloat)`
Left view = an icon plus trailing padding.
```swift
field.addPaddingLeftIcon(UIImage(systemName: "magnifyingglass")!, padding: 8)
```
</details>
<details>
<summary><b>UIImageView</b> (<code>@MainActor </code>)</summary>
### `func changeColorOfImage(_ color: UIColor, image: UIImage?) -> UIImageView`
Set a template-rendered image tinted to `color` ; returns `self` .
```swift
iconView.changeColorOfImage(.systemBlue, image: UIImage(named: "star"))
```
### `var encodeToBase64: String?`
JPEG (quality 0.6) of the current image as a Base64 string.
### `func addAspectRatioConstraint()` / `func removeAspectRatioConstraint()`
Add / remove a width-to-height constraint matching the current image's ratio.
```swift
photoView.image = photo
photoView.addAspectRatioConstraint()
```
</details>
<details>
<summary><b>UIImage</b> — recolour, resize, thumbnails, masks, init</summary>
### `func imageWithColor(color: UIColor) -> UIImage` / `func tintImage(color: UIColor) -> UIImage`
Return a copy filled / tinted with `color` (keeps the alpha shape).
```swift
let redIcon = icon.tintImage(color: .systemRed)
```
### `func backgroundColorTransparent(initialColor: UIColor, finalColor: UIColor) -> UIImage?`
Make pixels in a colour range transparent.
### `class func outlinedEllipse(size: CGSize, color: UIColor, lineWidth: CGFloat = 1) -> UIImage?`
Generate a stroked-ellipse image.
```swift
UIImage.outlinedEllipse(size: CGSize(width: 24, height: 24), color: .label)
```
### `func resizeImage(newWidth: CGFloat) -> UIImage`
Scale to `newWidth` , keeping the aspect ratio.
### `func createThumbnail(_ maxPixelSize: UInt) -> UIImage`
Fast down-sampled thumbnail via `CGImageSource` .
```swift
let thumb = fullImage.createThumbnail(200)
```
### `func maskWithAlphaImage(maskImage: UIImage) -> UIImage`
Use another image's alpha as a mask.
### `func isAnimated() -> Bool`
Whether the image has more than one frame.
### `init?(base64String: String, scale: CGFloat = 1)`
Decode a Base64 string to an image.
### `init(view: UIView)` — *`@MainActor`*
Rasterise a view into an image.
```swift
let snapshot = UIImage(view: cardView)
```
</details>
<details>
<summary><b>UIColor</b> — hex, components</summary>
### `convenience init(hex: String)`
Parse `#RGB` , `#RGBA` , `#RRGGBB` , or `#RRGGBBAA` (with or without `#` ).
```swift
view.backgroundColor = UIColor(hex: "#1E88E5 ")
UIColor(hex: "FF0000CC") // red at 80% alpha
```
### `var hexString: String?`
`#RRGGBB` (or `#RRGGBBAA` when alpha < 1).
### `var redValue` / `var greenValue` / `var blueValue` / `var alphaValue`
Individual channel values (`CGFloat` , via `CIColor` ).
```swift
UIColor.systemBlue.redValue // 0.0…1.0
```
</details>
<details>
<summary><b>UIScrollView</b> — snapshot, visible rect, paged scrolling</summary>
### `var snapshot: UIImage?`
Image of the **entire ** content size (not just the visible part) — works on
`UITableView` / `UICollectionView` too.
### `var visibleRect: CGRect`
The currently visible content region.
### `var offsetInPage: CGFloat`
Fractional position within the current page height (`0.0` …`1.0` ).
### `func scrollUp(animated:)` / `scrollDown(animated:)` / `scrollLeft(animated:)` / `scrollRight(animated:)`
Move one page (respects `isPagingEnabled` ). `animated` defaults to `true` .
```swift
nextButton.onTap = { scrollView.scrollRight() }
```
### `enum orientation`
`horizontal` / `vertical` — helper enum used by scroll utilities.
</details>
<details>
<summary><b>UITapGestureRecognizer</b></summary>
### `func didTapAttributedTextInLabel(label: UILabel, textToTouch: String) -> Bool`
Whether the tap landed on a given substring of a label's attributed text — for
making part of a label tappable.
```swift
@objc func handleTap(_ g: UITapGestureRecognizer) {
if g.didTapAttributedTextInLabel(label: termsLabel, textToTouch: "Terms of Use") {
openTerms()
}
}
```
</details>
2026-08-29 19:22:12 -03:00
## Navigation & Controllers
2026-08-29 19:33:22 -03:00
<details>
<summary><b>UINavigationController</b> — completion-handler push/pop, transparent bar</summary>
### `func pushViewController(_:animated: Bool = true, completion: (() -> Void)? = nil)`
### `func popViewController(animated: Bool = true, _ completion: (() -> Void)? = nil)`
### `func popToViewController(_:animated: Bool = true, _ completion: (() -> Void)? = nil)`
The standard transitions with a completion block (wrapped in a `CATransaction` ).
```swift
navigationController?.pushViewController(detail) {
print("detail is on screen")
}
```
### `func pushViewController(_:hidesBottomBar: Bool = false, animated: Bool = true)` — *not tvOS*
Push while setting `hidesBottomBarWhenPushed` .
### `func makeTransparent(withTint tint: UIColor = .white)`
Clear background + shadow, translucent, tinted bar/title.
```swift
navigationController?.makeTransparent(withTint: .label)
```
</details>
<details>
<summary><b>UIViewController</b> — state, instantiation, dismissal, toasts, keyboard, observers</summary>
### `var isVisible: Bool` / `var isLoaded: Bool`
View is loaded **and ** in a window. (`isLoaded` is an alias.)
### `var isModal: Bool`
Whether the controller is presented modally (vs. pushed).
### `static var className: String` / `static var identifier: String` / `static var segueID: String`
`"MyVC"` , `"idMyVC"` , `"idSegueMyVC"` .
### `static func instantiate<T>(storyBoard: String, identifier: String? = nil, bundle: Bundle? = …) -> T`
Load a controller from a storyboard by (default) `T.identifier` .
```swift
let vc: ProfileVC = ProfileVC.instantiate(storyBoard: "Main")
```
### `static func instatiate<T>(nibName: String, bundle: Bundle? = nil) -> T` *(sic — "instatiate")*
Load from a nib and force an initial layout pass.
### `func present(viewControllerToPresent:completion: @escaping () -> Void)`
`present(_:animated:)` with a completion block.
### `func closeController(jumpToController: UIViewController? = nil, completion: @escaping () -> Void)`
Dismiss if modal, else pop (to `jumpToController` if given), then call `completion` .
```swift
closeController { self.refreshList() }
```
### `func show(toastWith message:, font: = system 12, toastPosition: ToastPosition, backgroundColor: = .black, textColor: = .white, duration: = 3)`
Show a temporary rounded toast label. `ToastPosition` is `.top` / `.down`
(notch-aware at the top).
```swift
show(toastWith: "Saved", toastPosition: .down)
```
### `func addNotificationObserver(name:selector:)` / `func removeNotificationObserver(name:)` / `func removeNotificationsObserver()`
`NotificationCenter` registration shortcuts (last one removes all).
### `@objc func dismissSystemKeyboard(_ sender: UITapGestureRecognizer)`
Ready-made selector for a tap-to-dismiss-keyboard gesture.
```swift
view.addGestureRecognizer(UITapGestureRecognizer(target: self,
action: #selector (dismissSystemKeyboard(_:))))
```
</details>
<details>
<summary><b>UITabBarController</b> — badges, animated tab switching</summary>
### `func setBadges(badgeValues: [Int], font: UIFont = Helvetica-Light 11)`
Set numeric badges for every tab at once (`0` = no badge). Custom-drawn
(`CustomTabBadge` label), so they position above each tab item.
```swift
tabBarController?.setBadges(badgeValues: [0, 3, 0, 12])
```
### `func addBadge(index:value:color:font:)`
Add a single custom badge.
### `func setSelectedView(atIndex:withAnimation: Bool = false, completion:)`
Select a tab (pops that tab's nav stack to root first).
### `func setSelectedView(withNoPop atIndex:withAnimation: Bool = false, completion:)`
Same, without popping to root.
### `func animateToTab(toIndex: Int)`
Slide-transition between tabs.
### `func changeViewControllerToItem(withViewController:Item:)`
Replace a tab's root controller then switch to that tab.
```swift
tabBarController?.changeViewControllerToItem(withViewController: NewHome(), Item: 0)
```
### `class CustomTabBadge: UILabel`
The badge label type used above (`init(font:)` ).
</details>
<details>
<summary><b>UIApplication</b> — environment, app info, open URL</summary>
### `enum Environment` + `static var inferredEnvironment: Environment`
`.debug` / `.testFlight` / `.appStore` , inferred from build config, simulator, and
the provisioning/receipt files.
```swift
if UIApplication.inferredEnvironment == .appStore { enableAnalytics() }
```
### `static var displayName: String?` / `static var buildNumber: String?` / `static var version: String?`
Bundle info values. (`LCEssentials.appVersion` etc. forward to these.)
### `static func openURL(urlStr: String)`
Open a URL string if it can be opened.
```swift
UIApplication.openURL(urlStr: "https://loverde.com.br")
```
</details>
<details>
<summary><b>UIResponder</b></summary>
### `var getParentViewController: UIViewController?`
Walk the responder chain to the owning view controller.
```swift
someView.getParentViewController?.present(alert, animated: true)
```
</details>
<details>
<summary><b>UIDevice</b> — notch metrics, model name</summary>
### `static var topNotch: CGFloat` / `static var bottomNotch: CGFloat` / `static var hasNotch: Bool`
Safe-area top/bottom insets and whether the device has a notch / Dynamic Island.
```swift
let headerY: CGFloat = UIDevice.hasNotch ? 44 : 20
```
### `var modelName: String`
Marketing name from the hardware identifier (`"iPhone 15 Pro"` , `"iPad Air (5th generation)"` , …); falls back to the raw identifier for unknown devices. Reads `SIMULATOR_MODEL_IDENTIFIER` on the simulator.
```swift
UIDevice.current.modelName // "iPhone 16 Pro"
```
</details>
2026-08-29 19:22:12 -03:00
## Collections & Tables
2026-08-29 19:33:59 -03:00
<details>
<summary><b>UITableView</b> — typed dequeue, safe indexing, cell animations</summary>
### `func dequeueReusableCell<T: UITableViewCell>(withClass name: T.Type) -> T` / `…(withClass:for indexPath:) -> T`
Dequeue a cell by its class name as the identifier. **Traps ** if the cell isn't registered.
```swift
let cell = tableView.dequeueReusableCell(withClass: OrderCell.self, for: indexPath)
```
### `func dequeueReusableHeaderFooterView<T: UITableViewHeaderFooterView>(withClass name: T.Type) -> T`
Same, for section header/footer views.
### `func dequeueCell<T: UITableViewCell>(indexPath: IndexPath) -> T`
Dequeue using `T.identifier` (`"id" + class name` ).
### `func reloadData(_ completion: @escaping () -> Void)`
`reloadData()` with a callback for when layout settles.
### `func isValidIndexPath(_:) -> Bool`
Bounds check against the current section/row counts.
### `func safeScrollToRow(at:at scrollPosition:animated:)`
`scrollToRow` that silently no-ops for an out-of-range index path.
### `func makeMoveUpWithFadeAnimation(rowHeight:duration:delayFactor:) -> UITableViewCellAnimation`
Build a staggered slide-up + fade-in cell animation closure.
```swift
let animator = UITableViewAnimator(
animation: tableView.makeMoveUpWithFadeAnimation(rowHeight: 64, duration: 0.35, delayFactor: 0.03)
)
func tableView(_ t: UITableView, willDisplay cell: UITableViewCell, forRowAt ip: IndexPath) {
animator.animate(cell: cell, at: ip, in: t)
}
```
### `typealias UITableViewCellAnimation = (UITableViewCell, IndexPath, UITableView) -> Void`
### `class UITableViewAnimator`
`init(animation:)` + `animate(cell:at:in:)` — runs a cell animation closure.
### `UITableViewCell.identifier` / `UITableViewCell.prepareDisclosureIndicator()`
`"id" + class name` ; and re-tint the disclosure chevron to a template image so it
picks up `tintColor` .
</details>
<details>
<summary><b>UICollectionView</b> — setup, counts, safe indexing, carousel layout</summary>
### `static var identifier: String`
`"id" + class name` .
### `func setupCollectionView(flowLayout: = UICollectionViewFlowLayout(), spacings: = 0, direction: = .horizontal, edgesInset: = .zero, allowMulpleSelection: Bool = false, automaticSize: CGSize? = nil)`
Configure layout spacing/direction/insets, multi-selection, and self-sizing in one call.
```swift
collectionView.setupCollectionView(spacings: 8, direction: .vertical,
edgesInset: .init(top: 12, left: 16, bottom: 12, right: 16))
```
### `func reloadData(_ completion: @escaping () -> Void)`
Reload with a completion callback.
### `func numberOfItems() -> Int`
Total items across all sections.
### `var lastSection: Int` / `var indexPathForLastItem: IndexPath?` / `func indexPathForLastItem(inSection:) -> IndexPath?`
Last section index; index path of the last item overall or in a section.
### `func isValidIndexPath(_:) -> Bool` / `func safeScrollToItem(at:at scrollPosition:animated:)`
Bounds check; scroll that no-ops on an invalid index path.
### `enum CollectionViewFlowLayoutSpacingMode`
`.fixed(spacing:)` / `.overlap(visibleOffset:)` — spacing strategy for the carousel layout below.
### `open class CollectionViewFlowLayout: UICollectionViewFlowLayout`
A centred, paginated "cover-flow" style layout: the centred item is full size,
side items scale and fade. Tunables: `sideItemScale` (0.6), `sideItemAlpha`
(0.6), `sideItemShift` (0), `spacingMode` (`.fixed(40)` ).
```swift
let layout = CollectionViewFlowLayout()
layout.itemSize = CGSize(width: 240, height: 320)
layout.sideItemScale = 0.7
layout.spacingMode = .overlap(visibleOffset: 30)
collectionView.collectionViewLayout = layout
```
</details>
2026-08-29 19:22:12 -03:00
## Media & Components
<!-- batch 13 -->