FormViewController

open class FormViewController : UIViewController

A view controller with a scrollable content area that will automatically avoid the keyboard for you. A good choice for views that have inputs (e.g. login or onboarding).

  • The top-level scrollview. Its edges are pinned to the view controller’s view. Don’t add subviews directly to scrollView but rather to contentView instead. This view is publicly exposed to assist with layout constraints.

    Declaration

    Swift

    public let scrollView: UIScrollView
  • The content view. This is where you would want to add your subviews. This view is already inset from all edges so you can constrain your subviews directly to the edges without additional insets.

    Declaration

    Swift

    public let contentView: UIView
  • Default vertical spacing used in the default implementation of contentInsets (16 points)

    Declaration

    Swift

    public static let defaultVerticalSpacing: CGFloat
  • The content insets to apply to contentView.

    Horizontally contentView is pinned to the view’s margins not edges, so for system default behavior you probably want to leave the horizontal values at 0.

    Vertically contentView is pinned to the top and bottom of scrollView, so you probably want some padding for a nice appearance.

    Default implementation returns {16, 0, 16, 0}. Override to return different insets.

    Declaration

    Swift

    open var contentInsets: NSDirectionalEdgeInsets { get }
  • The (optional) gesture recognizer for handling taps on the scrollview outside of any controls.

    Declaration

    Swift

    public private(set) var tapOutsideGesture: UITapGestureRecognizer? { get }
  • Whether to add a gesture recognizer to responds to taps on the scrollView (i.e. those that fall outside of the input fields) to dismiss the keyboard. If you will embed any UIScrollView-derived view withincontentView (e.g. UITableView), then you must return false.

    Default implementation returns true. Override and return false if you don’t want this behavior.

    Declaration

    Swift

    open var useTapOutsideRecognizer: Bool { get }
  • Configures the various subviews. The base method configures the scroll and content views and registers to listen for keyboard notifications. Override to add additional functionality, but you will need to call super.

    Declaration

    Swift

    open func configureSubviews()
  • Handles the tap outside gesture recognizer (see useTapOutsideRecognizer). Override to add custom functionality

    Declaration

    Swift

    open func handleTapOutside()

Autolayout Helpers

  • Attempts to stretch the content to fit the screen’s height (but does nothing if content height already equals or exceeds screen height).

    This contrains contentView.height >= screen height. Primary use case: pin a CTA button to the bottom of the screen. To achieve this you would want to constrain the button’s topAnchor to be >= previous control’s bottomAnchor. Use button.constrain(below: previousControl, relatedBy: .greaterThanOrEqual, offset: gap)

    Declaration

    Swift

    @discardableResult
    func fitContentToScreen() -> NSLayoutConstraint

    Return Value

    The created height constraint

  • Attempts to compress the content to fit the screen’s height (but does nothing if content height cannot be compressed below screen height).

    Primary use case: a view with a resizable graphic that you would rather compress so that the entire view fits rather than have it scroll vertically. Also works when you would rather tighten up vertical spacing between elements rather than have the view scroll. In order for your layout to work in a deterministic manner, you will need to set constraints and/or compression resistance with the proper priorities.

    Declaration

    Swift

    @discardableResult
    func compressContentToScreen(priority: UILayoutPriority) -> NSLayoutConstraint

    Parameters

    priority

    priority of compressing contentView to fit the screen height

    Return Value

    The created height constraint