Files
ScrollingContentViewController/Examples/CodeExample/SignUpViewController.swift
T
Drew Olbrich 8e6c9b5a23 Fix bug: Content view isn't sized correctly when it doesn't fill the screen
This commit addresses an error in the earlier commit 04b4f8e, which did
not the case when shouldResizeContentViewForKeyboard was false.
2019-03-21 20:46:42 -07:00

188 lines
8.4 KiB
Swift

//
// SignUpViewController.swift
// CodeExample
//
// Created by Drew Olbrich on 12/29/18.
// Copyright 2019 Oath Inc.
//
// Licensed under the terms of the MIT License. See the file LICENSE for the full terms.
//
import UIKit
import ScrollingContentViewController
/// A class that demonstrates configuring `ScrollingContentViewController`
/// programmatically. This view controller is instantiated in `AppDelegate` and
/// installed as the window's root view controller.
class SignUpViewController: ScrollingContentViewController {
/// Helper object that encapsulates code common to all
/// `ScrollingContentViewController` example applications.
private var signUpController: SignUpController?
private let logoImageView = UIImageView(image: UIImage(named: "Lorem-Ipsum-Logo"))
private let nameTextField = PillTextField()
private let emailTextField = PillTextField()
private let passwordTextField = PillTextField()
private let signUpButton = PillButton(type: .system)
private let signInButton = UIButton(type: .system)
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func loadView() {
// Assign a gradient as the root view.
view = GradientBackgroundView()
}
override func viewDidLoad() {
super.viewDidLoad()
// Create the content view.
createContentView()
// Allow the content view to shrink vertically when the keyboard is presented.
shouldResizeContentViewForKeyboard = true
// Allow the user to dismiss the keyboard by dragging from the scroll view to the
// bottom of the screen.
scrollView.keyboardDismissMode = .interactive
signUpController = SignUpController(logoImageView: logoImageView, nameTextField: nameTextField, emailTextField: emailTextField, passwordTextField: passwordTextField, signUpButton: signUpButton, signInButton: signInButton, delegate: self)
}
/// Creates the content view.
private func createContentView() {
// When ScrollingContentViewController.contentView is assigned for the first time,
// this has the side effect of adding a scroll view to the view controller's root
// view, and adding the content view to the scroll view. If a new view was assigned
// to this property later, it would replace the existing content view in the scroll
// view, and leave the scroll view unchanged.
contentView = UIView()
// Assign the content view's background color to transparent so it can be seen
// through it to the gradient background view. This is the default value, but the
// intent here is to be explicit for example code.
contentView.backgroundColor = nil
logoImageView.tintColor = .white
configureTextFields()
signUpButton.setTitle("Sign Up", for: .normal)
signUpButton.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
addConstraints()
}
private func configureTextFields() {
configureTextField(nameTextField, placeholder: "Name", textContentType: .name, autocapitalizationType: .words, returnKeyType: .next, keyboardType: .default, isSecureTextEntry: false)
configureTextField(emailTextField, placeholder: "Email", textContentType: .emailAddress, autocapitalizationType: .none, returnKeyType: .next, keyboardType: .emailAddress, isSecureTextEntry: false)
configureTextField(passwordTextField, placeholder: "Password", textContentType: nil, autocapitalizationType: .none, returnKeyType: .done, keyboardType: .default, isSecureTextEntry: true)
}
// swiftlint:disable:next function_parameter_count
private func configureTextField(_ textField: UITextField, placeholder: String?, textContentType: UITextContentType?, autocapitalizationType: UITextAutocapitalizationType, returnKeyType: UIReturnKeyType, keyboardType: UIKeyboardType, isSecureTextEntry: Bool) {
textField.placeholder = placeholder
textField.textContentType = textContentType
textField.autocapitalizationType = autocapitalizationType
textField.autocorrectionType = .no
textField.smartDashesType = .no
textField.smartInsertDeleteType = .no
textField.smartQuotesType = .no
textField.spellCheckingType = .no
textField.returnKeyType = returnKeyType
textField.keyboardType = keyboardType
textField.enablesReturnKeyAutomatically = true
textField.isSecureTextEntry = isSecureTextEntry
}
// swiftlint:disable:next function_body_length
private func addConstraints() {
logoImageView.translatesAutoresizingMaskIntoConstraints = false
nameTextField.translatesAutoresizingMaskIntoConstraints = false
emailTextField.translatesAutoresizingMaskIntoConstraints = false
passwordTextField.translatesAutoresizingMaskIntoConstraints = false
signUpButton.translatesAutoresizingMaskIntoConstraints = false
signInButton.translatesAutoresizingMaskIntoConstraints = false
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 16
stackView.addArrangedSubview(nameTextField)
stackView.addArrangedSubview(emailTextField)
stackView.addArrangedSubview(passwordTextField)
addPillViewConstraints(to: nameTextField)
addPillViewConstraints(to: emailTextField)
addPillViewConstraints(to: passwordTextField)
addPillViewConstraints(to: signUpButton)
contentView.addSubview(logoImageView)
contentView.addSubview(stackView)
contentView.addSubview(signUpButton)
contentView.addSubview(signInButton)
let logoImageTopLayoutGuide = UILayoutGuide()
let logoImageBottomLayoutGuide = UILayoutGuide()
let signUpButtonBottomLayoutGuide = UILayoutGuide()
contentView.addLayoutGuide(logoImageTopLayoutGuide)
contentView.addLayoutGuide(logoImageBottomLayoutGuide)
contentView.addLayoutGuide(signUpButtonBottomLayoutGuide)
let constraints: [NSLayoutConstraint] = [
contentView.centerXAnchor.constraint(equalTo: logoImageView.centerXAnchor),
contentView.centerXAnchor.constraint(equalTo: stackView.centerXAnchor),
contentView.centerXAnchor.constraint(equalTo: signUpButton.centerXAnchor),
contentView.centerXAnchor.constraint(equalTo: signInButton.centerXAnchor),
contentView.topAnchor.constraint(equalTo: logoImageTopLayoutGuide.topAnchor),
logoImageView.topAnchor.constraint(equalTo: logoImageTopLayoutGuide.bottomAnchor),
logoImageView.bottomAnchor.constraint(equalTo: logoImageBottomLayoutGuide.topAnchor),
stackView.topAnchor.constraint(equalTo: logoImageBottomLayoutGuide.bottomAnchor),
signUpButton.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 48),
signUpButton.bottomAnchor.constraint(equalTo: signUpButtonBottomLayoutGuide.topAnchor),
signInButton.topAnchor.constraint(equalTo: signUpButtonBottomLayoutGuide.bottomAnchor),
contentView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 30),
logoImageTopLayoutGuide.heightAnchor.constraint(equalTo: logoImageBottomLayoutGuide.heightAnchor),
logoImageBottomLayoutGuide.heightAnchor.constraint(equalTo: signUpButtonBottomLayoutGuide.heightAnchor, multiplier: 2, constant: 0),
signUpButtonBottomLayoutGuide.heightAnchor.constraint(greaterThanOrEqualToConstant: 16)
]
logoImageView.setContentHuggingPriority(.required, for: .vertical)
logoImageView.setContentHuggingPriority(.required, for: .horizontal)
NSLayoutConstraint.activate(constraints)
}
private func addPillViewConstraints(to pillView: UIView) {
let widthConstraint = pillView.widthAnchor.constraint(equalToConstant: 280)
widthConstraint.priority = UILayoutPriority.defaultLow - 10
let heightConstraint = pillView.heightAnchor.constraint(equalToConstant: 44)
heightConstraint.priority = .required
pillView.addConstraints([widthConstraint, heightConstraint])
}
}
extension SignUpViewController: SignUpControllerDelegate {
func signUpControllerScrollFirstResponderToVisible(_ signUpController: SignUpController) {
scrollView.scrollFirstResponderToVisible(animated: true)
}
}