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
- Views & Controls
- Navigation & Controllers
- Collections & Tables
- Media & Components
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)
NSLayoutConstrainthelpers (constraintWithMultiplier,matches(view:anchor:)) and[NSLayoutConstraint].filtered(view:anchor:)areinternal— used by theUIView.constraints(on:)accessors above, not called directly.