Commit eb94bb7e by Daniel Dahan

added initial TextField sample project and moved Divider to a UIView extension

parent f00e3eee
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:TextField.xcodeproj">
</FileRef>
</Workspace>
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
import Material
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func applicationDidFinishLaunching(_ application: UIApplication) {
window = UIWindow(frame: Device.bounds)
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
}
}
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
import Material
class ViewController: UIViewController {
private var nameField: TextField!
private var emailField: ErrorTextField!
private var passwordField: TextField!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.white
prepareNameField()
prepareEmailField()
preparePasswordField()
prepareResignResponderButton()
}
/// Programmatic update for the textField as it rotates.
override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
emailField.width = view.bounds.height - 80
}
/// Prepares the resign responder button.
private func prepareResignResponderButton() {
let btn = RaisedButton(title: "Resign", titleColor: Color.blue.base)
btn.addTarget(self, action: #selector(handleResignResponderButton), for: .touchUpInside)
view.layout(btn).width(100).height(50).bottom(24).right(24)
}
/// Handle the resign responder button.
internal func handleResignResponderButton() {
nameField?.resignFirstResponder()
emailField?.resignFirstResponder()
passwordField?.resignFirstResponder()
}
/// Prepares the name TextField.
private func prepareNameField() {
nameField = TextField()
nameField.text = "Daniel Dahan"
nameField.placeholder = "Name"
nameField.detail = "Your given name"
nameField.textAlignment = .center
nameField.clearButtonMode = .whileEditing
// Size the TextField to the maximum width, less 40 pixels on either side
// with a top margin of 40 pixels.
view.layout(nameField).top(40).horizontally(left: 40, right: 40)
}
/// Prepares the email TextField.
private func prepareEmailField() {
emailField = ErrorTextField(frame: CGRect(x: 40, y: 120, width: view.width - 80, height: 32))
emailField.placeholder = "Email"
emailField.detail = "Error, incorrect email"
emailField.isClearIconButtonEnabled = true
emailField.delegate = self
emailField.placeholderColor = Color.amber.darken4
emailField.placeholderActiveColor = Color.pink.base
emailField.dividerColor = Color.cyan.base
view.addSubview(emailField)
}
/// Prepares the password TextField.
private func preparePasswordField() {
passwordField = TextField()
passwordField.placeholder = "Password"
passwordField.detail = "At least 8 characters"
passwordField.clearButtonMode = .whileEditing
passwordField.isVisibilityIconButtonEnabled = true
// Setting the visibilityFlatButton color.
passwordField.visibilityIconButton?.tintColor = Color.green.base.withAlphaComponent(passwordField.isSecureTextEntry ? 0.38 : 0.54)
// Size the TextField to the maximum width, less 40 pixels on either side
// with a top margin of 200 pixels.
view.layout(passwordField).top(200).horizontally(left: 40, right: 40)
}
}
extension UIViewController: TextFieldDelegate {
/// Executed when the 'return' key is pressed when using the emailField.
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
(textField as? ErrorTextField)?.isErrorRevealed = true
return true
}
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return true
}
public func textFieldDidBeginEditing(_ textField: UITextField) {
}
public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
return true
}
public func textFieldDidEndEditing(_ textField: UITextField) {
(textField as? ErrorTextField)?.isErrorRevealed = false
}
public func textFieldShouldClear(_ textField: UITextField) -> Bool {
(textField as? ErrorTextField)?.isErrorRevealed = false
return true
}
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
(textField as? ErrorTextField)?.isErrorRevealed = false
return true
}
}
......@@ -68,6 +68,9 @@
location = "group:Examples/Programmatic/TabBar/TabBar.xcodeproj">
</FileRef>
<FileRef
location = "group:Examples/Programmatic/TextField/TextField.xcodeproj">
</FileRef>
<FileRef
location = "group:Examples/Programmatic/ToolbarController/ToolbarController.xcodeproj">
</FileRef>
<FileRef
......
......@@ -37,41 +37,6 @@ public enum ContentViewAlignment: Int {
}
open class Bar: View {
/// Divider layer.
internal private(set) var divider: Divider!
/// Divider color.
@IBInspectable
open var dividerColor: UIColor? {
get {
return divider.color
}
set(value) {
divider.color = value
}
}
/// Divider animation.
open var dividerAlignment: DividerAlignment {
get {
return divider.alignment
}
set(value) {
divider.alignment = value
}
}
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat {
get {
return divider.height
}
set(value) {
divider.height = value
}
}
/// Should center the contentView.
open var contentViewAlignment = ContentViewAlignment.any {
didSet {
......@@ -265,16 +230,10 @@ open class Bar: View {
open override func prepare() {
super.prepare()
prepareContentView()
prepareDivider()
}
/// Prepares the contentView.
private func prepareContentView() {
contentView.backgroundColor = nil
}
/// Prepares the divider.
private func prepareDivider() {
divider = Divider(view: self)
}
}
......@@ -131,53 +131,3 @@ open class BottomTabBar: UITabBar {
backgroundImage = image
}
}
/// A memory reference to the TabBarItem instance.
private var TabBarKey: UInt8 = 0
extension UITabBar {
/// TabBarItem reference.
internal private(set) var divider: Divider {
get {
return AssociatedObject(base: self, key: &TabBarKey) {
return Divider(view: self)
}
}
set(value) {
AssociateObject(base: self, key: &TabBarKey, value: value)
}
}
/// Divider color.
@IBInspectable
open var dividerColor: UIColor? {
get {
return divider.color
}
set(value) {
divider.color = value
}
}
/// Divider animation.
open var dividerAlignment: DividerAlignment {
get {
return divider.alignment
}
set(value) {
divider.alignment = value
}
}
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat {
get {
return divider.height
}
set(value) {
divider.height = value
}
}
}
......@@ -32,41 +32,6 @@ import UIKit
@objc(CollectionViewCell)
open class CollectionViewCell: UICollectionViewCell {
/// Divider layer.
internal private(set) var divider: Divider!
/// Divider color.
@IBInspectable
open var dividerColor: UIColor? {
get {
return divider.color
}
set(value) {
divider.color = value
}
}
/// Divider animation.
open var dividerAlignment: DividerAlignment {
get {
return divider.alignment
}
set(value) {
divider.alignment = value
}
}
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat {
get {
return divider.height
}
set(value) {
divider.height = value
}
}
/**
A CAShapeLayer used to manage elements that would be affected by
the clipToBounds property of the backing layer. For example, this
......@@ -331,7 +296,6 @@ open class CollectionViewCell: UICollectionViewCell {
open func prepare() {
contentScaleFactor = Device.scale
prepareVisualLayer()
prepareDivider()
}
/// Prepares the visualLayer property.
......@@ -346,9 +310,4 @@ open class CollectionViewCell: UICollectionViewCell {
visualLayer.frame = bounds
visualLayer.cornerRadius = cornerRadius
}
/// Prepares the divider.
private func prepareDivider() {
divider = Divider(view: self)
}
}
......@@ -103,3 +103,53 @@ open class Divider {
}
}
}
/// A memory reference to the Divider instance.
private var DividerKey: UInt8 = 0
extension UIView {
/// TabBarItem reference.
public private(set) var divider: Divider {
get {
return AssociatedObject(base: self, key: &DividerKey) {
return Divider(view: self)
}
}
set(value) {
AssociateObject(base: self, key: &DividerKey, value: value)
}
}
/// Divider color.
@IBInspectable
open var dividerColor: UIColor? {
get {
return divider.color
}
set(value) {
divider.color = value
}
}
/// Divider animation.
open var dividerAlignment: DividerAlignment {
get {
return divider.alignment
}
set(value) {
divider.alignment = value
}
}
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat {
get {
return divider.height
}
set(value) {
divider.height = value
}
}
}
......@@ -30,11 +30,12 @@
import UIKit
public class ErrorTextField: TextField {
open class ErrorTextField: TextField {
/// Controls the visibility of detailLabel
@IBInspectable public var revealError: Bool = false {
@IBInspectable
open var isErrorRevealed = false {
didSet {
detailLabel.isHidden = !revealError
detailLabel.isHidden = !isErrorRevealed
}
}
......@@ -45,9 +46,8 @@ public class ErrorTextField: TextField {
The super.prepare method should always be called immediately
when subclassing.
*/
override public func prepare() {
open override func prepare() {
super.prepare()
revealError = false
detailColor = Color.red.base
}
}
......@@ -39,41 +39,6 @@ public enum NavigationBarStyle: Int {
}
open class NavigationBar: UINavigationBar {
/// Divider layer.
internal private(set) var divider: Divider!
/// Divider color.
@IBInspectable
open var dividerColor: UIColor? {
get {
return divider.color
}
set(value) {
divider.color = value
}
}
/// Divider animation.
open var dividerAlignment: DividerAlignment {
get {
return divider.alignment
}
set(value) {
divider.alignment = value
}
}
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat {
get {
return divider.height
}
set(value) {
divider.height = value
}
}
open override var intrinsicContentSize: CGSize {
switch navigationBarStyle {
case .small:
......@@ -324,8 +289,6 @@ open class NavigationBar: UINavigationBar {
when subclassing.
*/
public func prepare() {
prepareDivider()
barStyle = .black
isTranslucent = false
depthPreset = .depth1
......@@ -358,9 +321,4 @@ open class NavigationBar: UINavigationBar {
}
item.titleView = UIView(frame: .zero)
}
/// Prepares the divider.
private func prepareDivider() {
divider = Divider(view: self)
}
}
......@@ -49,36 +49,37 @@ open class TextField: UITextField {
}
}
/// Reference to the divider.
open private(set) var divider: CAShapeLayer!
/// Divider height.
@IBInspectable
open var dividerHeight: CGFloat = 1
/// Divider active state height.
/// Divider active state height.
@IBInspectable
open var dividerActiveHeight: CGFloat = 2
/// Sets the divider.
@IBInspectable
open var dividerColor: UIColor = Color.darkText.dividers {
didSet {
if !isEditing {
divider.backgroundColor = dividerColor.cgColor
}
}
}
open override var dividerColor: UIColor? {
get {
return super.dividerColor
}
set(value) {
guard !isEditing else {
return
}
super.dividerColor = value
}
}
/// Sets the divider.
@IBInspectable
open var dividerActiveColor: UIColor? {
didSet {
if let v: UIColor = dividerActiveColor {
if isEditing {
divider.backgroundColor = v.cgColor
}
}
guard isEditing else {
return
}
guard let v = dividerActiveColor else {
return
}
dividerColor = v
}
}
......@@ -198,7 +199,7 @@ open class TextField: UITextField {
/// Enables the clearIconButton.
@IBInspectable
open var isClearIconButtonEnable: Bool {
open var isClearIconButtonEnabled: Bool {
get {
return nil != clearIconButton
}
......@@ -211,7 +212,7 @@ open class TextField: UITextField {
clearButtonMode = .never
rightViewMode = .whileEditing
rightView = clearIconButton
clearIconButtonAutoHandle = clearIconButtonAutoHandle ? true : false
isClearIconButtonAutoHandled = isClearIconButtonAutoHandled ? true : false
}
} else {
clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside)
......@@ -222,10 +223,10 @@ open class TextField: UITextField {
/// Enables the automatic handling of the clearIconButton.
@IBInspectable
open var clearIconButtonAutoHandle = true {
open var isClearIconButtonAutoHandled = true {
didSet {
clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside)
if clearIconButtonAutoHandle {
if isClearIconButtonAutoHandled {
clearIconButton?.addTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside)
}
}
......@@ -233,7 +234,7 @@ open class TextField: UITextField {
/// Enables the visibilityIconButton.
@IBInspectable
open var isVisibilityIconButtonEnable: Bool {
open var isVisibilityIconButtonEnabled: Bool {
get {
return nil != visibilityIconButton
}
......@@ -247,7 +248,7 @@ open class TextField: UITextField {
clearButtonMode = .never
rightViewMode = .whileEditing
rightView = visibilityIconButton
visibilityIconButtonAutoHandle = visibilityIconButtonAutoHandle ? true : false
isVisibilityIconButtonAutoHandled = isVisibilityIconButtonAutoHandled ? true : false
}
} else {
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside)
......@@ -258,10 +259,10 @@ open class TextField: UITextField {
/// Enables the automatic handling of the visibilityIconButton.
@IBInspectable
open var visibilityIconButtonAutoHandle: Bool = true {
open var isVisibilityIconButtonAutoHandled: Bool = true {
didSet {
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside)
if visibilityIconButtonAutoHandle {
if isVisibilityIconButtonAutoHandled {
visibilityIconButton?.addTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside)
}
}
......@@ -312,13 +313,13 @@ open class TextField: UITextField {
open override func layoutSubviews() {
super.layoutSubviews()
layoutToSize()
layoutDivider()
}
open override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
if self.layer == layer {
layoutShape()
layoutDivider()
}
}
......@@ -388,7 +389,7 @@ open class TextField: UITextField {
/// Layout the divider.
open func layoutDivider() {
divider.frame = CGRect(x: 0, y: height, width: width, height: isEditing ? dividerActiveHeight : dividerHeight)
divider.reload()
}
/// Layout the placeholderLabel.
......@@ -423,8 +424,11 @@ open class TextField: UITextField {
/// Layout the detailLabel.
open func layoutDetailLabel() {
let h: CGFloat = nil == detail ? 12 : detailLabel.font.stringSize(string: detail!, constrainedToWidth: Double(width)).height
detailLabel.frame = CGRect(x: 0, y: divider.y + detailVerticalOffset, width: width, height: h)
guard let v = divider.line else {
return
}
let h: CGFloat = nil == detail ? 12 : detailLabel.font.stringSize(string: detail!, constrainedToWidth: Double(width)).height
detailLabel.frame = CGRect(x: 0, y: v.y + detailVerticalOffset, width: width, height: h)
}
/// Layout the clearIconButton.
......@@ -448,13 +452,13 @@ open class TextField: UITextField {
/// The animation for the divider when editing begins.
open func dividerEditingDidBeginAnimation() {
dividerHeight = dividerActiveHeight
divider.backgroundColor = nil == dividerActiveColor ? placeholderActiveColor.cgColor : dividerActiveColor!.cgColor
dividerColor = dividerActiveColor ?? placeholderActiveColor
}
/// The animation for the divider when editing ends.
open func dividerEditingDidEndAnimation() {
divider.frame.size.height = dividerHeight
divider.backgroundColor = dividerColor.cgColor
// divider.frame.size.height = dividerHeight
// divider.color = dividerColor
}
/// The animation for the placeholder when editing begins.
......@@ -503,9 +507,7 @@ open class TextField: UITextField {
/// Prepares the divider.
private func prepareDivider() {
divider = CAShapeLayer()
dividerColor = Color.darkText.dividers
layer.addSublayer(divider)
dividerColor = Color.darkText.dividers
}
/// Prepares the placeholderLabel.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment