Files
LCEssentials/Documentation/UIKit.md
2026-08-29 19:31:43 -03:00

8.5 KiB

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; SwiftUI helpers in SwiftUI.md.

Every section is a collapsible block — click a heading to expand it.

Contents


Layout & Constraints

UIView — programmatic constraints, chainable anchors

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+).

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.

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.

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.

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).

UIView — hierarchy, appearance, effects

static var className: String

String(describing: self).

UIButton.className   // "UIButton"

func addSubview(_ subview:, translatesAutoresizingMaskIntoConstraints: Bool = false) / addSubviews(_ subviews: [UIView], …)

Add a view (or many) and set translatesAutoresizingMaskIntoConstraints in one call.

view.addSubviews([header, body, footer])   // all ready for Auto Layout

func subviews<T>(ofType _: T.Type) -> [T]

All descendants of a type, recursively.

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).

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.

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.

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).

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.)

overlay.fadeOut { _ in overlay.removeFromSuperview() }

var viewReference: UIView?

Scratch reference used internally by the chained setConstraintsTo calls.

GradientOrientation / EnumBorderSide

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.

UIStackView — convenience init, bulk arranged-subview ops (iOS 9+)

convenience init(arrangedSubviews: [UIView]? = nil, axis: = .vertical, spacing: = 0, alignment: = .fill, distribution: = .fill, layoutMargins: = .zero, isMarginsRelative: Bool = true)

One-call configured stack view.

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.

stack.addArrangedSubviews([row1, row2])
stack.addSpace(24)
stack.addArrangedSubview(row3)

NSLayoutConstraint helpers (constraintWithMultiplier, matches(view:anchor:)) and [NSLayoutConstraint].filtered(view:anchor:) are internal — used by the UIView.constraints(on:) accessors above, not called directly.

Views & Controls

Navigation & Controllers

Collections & Tables

Media & Components