Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates-to-review #49

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//
// CustomTextField.swift
// Custom Transitions
//
// Created by Aaron Tredrea on 27/11/2018.
// Copyright © 2018 Stanwood GmbH. All rights reserved.
//

import UIKit


extension UIColor{
static var errorRed = UIColor(r: 208, g: 2, b: 27)
static var labelGrey = UIColor(r: 155, g: 155, b: 155)
}

enum CustomTextFieldType{
case email, name
}

protocol CustomTextFieldDelegate: class {
func textFieldShouldReturn(_ textField: UITextField) -> Bool
func textFieldDidChange(_ textField: UITextField)
}

class CustomTextField: UIView {


// MARK:- Public Properties


var text: String?{
get{
return textfield.text
}
}

weak var delegate: CustomTextFieldDelegate?


// MARK:- Private Properties


private var isValid = true {
didSet{
let image = (textfield.text?.isEmpty ?? true) ? nil : validIcon
validImageView.image = image
titleLabel.textColor = isValid ? .labelGrey : .errorRed
errorLabel.isHidden = isValid
}
}
private var hasText = false {
didSet{
UIView.animate(withDuration: .medium) {
self.titleCentredConstraint.priority = UILayoutPriority(rawValue: self.hasText ? 900 : 900)
self.layoutIfNeeded()
}
}
}
private var validIcon: UIImage {
get{
return isValid ? #imageLiteral(resourceName: "icCheckCircle") : #imageLiteral(resourceName: "icError")
}
}
private var hideErrorLabels = false
private var type: CustomTextFieldType = .email


// MARK:- Outlets


@IBOutlet private weak var validImageView: UIImageView!
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var errorLabel: UILabel!
@IBOutlet weak var textfield: UITextField!
@IBOutlet private weak var titleCentredConstraint: NSLayoutConstraint!


// MARK:- Init


required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)

loadFromOutlet()
layoutViews()
}


// MARK:- Private Functions


private func layoutViews(){
errorLabel.textColor = .errorRed
isValid = false
errorLabel.isHidden = hideErrorLabels
hasText = false
textfield.delegate = self
backgroundColor = .clear
isValid = true
}

private func validate(_ type: CustomTextFieldType){
switch type {
case .email:
isValid = textfield.text?.isValid(.email) ?? false
case .name:
isValid = textfield.text?.isValid(.name) ?? false
}
}


// MARK:- Public Functions


func configure(for type: CustomTextFieldType){

self.type = type

switch type {
case .email:
titleLabel.text = "Email"
errorLabel.text = "Invalid Email"
textfield.keyboardType = .emailAddress
textfield.autocapitalizationType = .none
textfield.placeholder = "[email protected]"
case .name:
titleLabel.text = "Name"
errorLabel.text = "Invalid Name"
textfield.keyboardType = .default
textfield.autocapitalizationType = .words
textfield.placeholder = "Jon S Wood"
}
}


// MARK:- Actions


@IBAction func textFieldChanged(_ sender: UITextField) {

guard sender.text?.count ?? 0 > 0 else {
isValid = true
return
}

hasText = !(sender.text?.isEmpty ?? true)
validate(type)
delegate?.textFieldDidChange(sender)
}
}


// MARK:- UITextFieldDelegate


extension CustomTextField: UITextFieldDelegate {

func textFieldDidBeginEditing(_ textField: UITextField) {
hasText = true
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return delegate?.textFieldShouldReturn(textField) ?? true
}

func textFieldDidEndEditing(_ textField: UITextField) {
hasText = textField.text?.trimmedLowerCase.count ?? 0 > 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CustomTextField" customModule="GLAMOUR" customModuleProvider="target">
<connections>
<outlet property="errorLabel" destination="fQl-KE-sF5" id="XPe-r9-ov8"/>
<outlet property="textfield" destination="P8y-2o-Md8" id="alz-qJ-j4r"/>
<outlet property="titleCentredConstraint" destination="O9x-xS-58m" id="PTm-1p-ibn"/>
<outlet property="titleLabel" destination="XTt-v8-UWd" id="5n1-m6-4zc"/>
<outlet property="validImageView" destination="ZAy-RA-dfi" id="WdR-bA-tmD"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="433" height="64"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Falsches E-Mail Format." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fQl-KE-sF5">
<rect key="frame" x="16" y="50" width="118.5" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="Q72-2y-GsF"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="P8y-2o-Md8">
<rect key="frame" x="16" y="25" width="379" height="34"/>
<color key="tintColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" enablesReturnKeyAutomatically="YES"/>
<connections>
<action selector="textFieldChanged:" destination="-1" eventType="editingChanged" id="0Du-kv-gl6"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="E-Mail" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XTt-v8-UWd">
<rect key="frame" x="16" y="34.5" width="37" height="15"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="mFm-Cn-vqy"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZAy-RA-dfi">
<rect key="frame" x="403" y="35" width="14" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="Q8o-eY-o8A"/>
<constraint firstAttribute="width" constant="14" id="vV1-eD-gcK"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="ZAy-RA-dfi" firstAttribute="leading" secondItem="P8y-2o-Md8" secondAttribute="trailing" constant="8" id="3E8-rF-fxZ"/>
<constraint firstItem="ZAy-RA-dfi" firstAttribute="centerY" secondItem="P8y-2o-Md8" secondAttribute="centerY" id="5Kr-Im-soM"/>
<constraint firstItem="XTt-v8-UWd" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="KsT-ge-1BU"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="fQl-KE-sF5" secondAttribute="bottom" constant="-1" id="L4s-Cd-9Ow"/>
<constraint firstItem="ZAy-RA-dfi" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" constant="10" id="N4N-Sa-ewl"/>
<constraint firstItem="XTt-v8-UWd" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" priority="999" constant="10" id="O9x-xS-58m"/>
<constraint firstItem="fQl-KE-sF5" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="QJl-UL-f4A"/>
<constraint firstAttribute="trailing" secondItem="ZAy-RA-dfi" secondAttribute="trailing" constant="16" id="X6z-3M-HHj"/>
<constraint firstItem="P8y-2o-Md8" firstAttribute="top" secondItem="XTt-v8-UWd" secondAttribute="bottom" priority="800" constant="-20.5" id="guq-Zl-bZ3"/>
<constraint firstItem="P8y-2o-Md8" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="16" id="lsk-jL-IDF"/>
<constraint firstItem="fQl-KE-sF5" firstAttribute="top" secondItem="P8y-2o-Md8" secondAttribute="bottom" constant="-9" id="ovU-DH-DnO"/>
<constraint firstItem="XTt-v8-UWd" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" priority="950" constant="8" id="vwZ-q2-eQb"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="173.59999999999999" y="53.973013493253376"/>
</view>
</objects>
</document>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Regex.swift
// Custom Transitions
//
// Created by Aaron Tredrea on 27/11/2018.
// Copyright © 2018 Stanwood. All rights reserved.
//

import Foundation


struct Regex {
static let email = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
static let name = "^(?=.{1,40}$)[a-zA-Z]+(?:[a-zA-Z]+)*$"
}


extension NSRegularExpression {

func isValid(for string: String) -> Bool {
return firstMatch(in: string, options: [], range: string.range) != nil
}
}

enum RegexType{
case email, name // TODO:- Password
}

extension String {

func isValid(_ type: RegexType) -> Bool{

switch type {
case .email:
return Regex.email.regularExpression?.isValid(for: self) ?? false
case .name:
return !(Regex.name.regularExpression?.isValid(for: self) ?? true) && isTwoOrMoreWords
}
}

var isTwoOrMoreWords: Bool {

let words = components(separatedBy:" ")

guard
words.count > 1,
words[1].count > 0
else{
return false
}

return true
}

var regularExpression: NSRegularExpression? {
return try? NSRegularExpression(pattern: self, options: .caseInsensitive)
}
}
Loading