├── BondKeyboard
├── Controller
│ ├── MainVC.swift
│ ├── ProcessVC.swift
│ └── ResultVC.swift
├── Info.plist
└── KeyboardViewController.swift
├── Data&Utilities
├── Extensions.swift
└── Themes+Colors.swift
├── LeelaKrishnaKeyboard.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ ├── leelaprasad.xcuserdatad
│ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ │ └── xcschememanagement.plist
│ └── penumutchu.prasadgmail.com.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── SecNinjazKeyboard
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── RupeSoKey.imageset
│ │ ├── Contents.json
│ │ └── RupeSoKey.png
│ ├── backspace.imageset
│ │ ├── Contents.json
│ │ └── backspace.png
│ ├── captial.imageset
│ │ ├── Contents.json
│ │ └── captial.png
│ ├── captial1.imageset
│ │ ├── Contents.json
│ │ └── captial1.png
│ ├── captial2.imageset
│ │ ├── Contents.json
│ │ └── captial2.png
│ └── globe.imageset
│ │ ├── Contents.json
│ │ └── globe.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
└── ViewController.swift
└── View
└── KeyboardButton.swift
/BondKeyboard/Controller/MainVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainVC.swift
3 | // BondKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MainVC: UIViewController {
12 |
13 | var dataArray1 = ["Prasad","Praveen","Ram","Dipesh","Abhishek","Gourav"]
14 | var dataArray2 = ["Name1","Name2","Name3","Name4","Name5","Name6"]
15 |
16 |
17 | lazy var segmntedContrl: UISegmentedControl = {
18 | let sgContrl = UISegmentedControl.init(items: ["Contacts","Wallet IDs"])
19 | sgContrl.tintColor = .orange
20 | sgContrl.selectedSegmentIndex = 0
21 | return sgContrl
22 | }()
23 |
24 | let cellId = "cellId"
25 |
26 | lazy var tableView: UITableView = {
27 | let tv = UITableView()
28 | tv.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
29 | tv.delegate = self
30 | tv.dataSource = self
31 | return tv
32 | }()
33 |
34 |
35 | override func viewDidLoad() {
36 | super.viewDidLoad()
37 |
38 | self.createSegmentedControl()
39 | self.createTableView()
40 | }
41 |
42 |
43 | override func viewWillAppear(_ animated: Bool) {
44 | super.viewWillAppear(animated)
45 |
46 |
47 | }
48 |
49 | override func viewWillDisappear(_ animated: Bool) {
50 |
51 | super.viewWillDisappear(animated)
52 | self.removeViewControllerAsChildViewController(childViewController: self)
53 |
54 | }
55 |
56 |
57 | func createSegmentedControl() {
58 | self.segmntedContrl.addTarget(self, action: #selector(onChangeOfSegments(segmntedControl:)), for: .valueChanged)
59 | self.view.addSubview(segmntedContrl)
60 | self.view.addConstraintsWithFormatString(formate: "H:|[v0]|", views: segmntedContrl)
61 | self.view.addConstraintsWithFormatString(formate: "V:|[v0(35)]", views: segmntedContrl)
62 | }
63 |
64 | @objc func onChangeOfSegments(segmntedControl: UISegmentedControl) {
65 | self.tableView.reloadData()
66 | }
67 |
68 | func createTableView() {
69 |
70 | self.view.addSubview(tableView)
71 |
72 | self.view.addConstraintsWithFormatString(formate: "H:|[v0]|", views: tableView)
73 | self.view.addConstraintsWithFormatString(formate: "V:|-35.5-[v0]|", views: tableView)
74 |
75 | }
76 |
77 | private func addViewControllerAsChildViewController(childViewController: UIViewController) {
78 |
79 | addChildViewController(childViewController)
80 | view.addSubview(childViewController.view)
81 | childViewController.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
82 | childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
83 | childViewController.didMove(toParentViewController: self)
84 |
85 | }
86 |
87 | private func removeViewControllerAsChildViewController(childViewController: UIViewController) {
88 |
89 | childViewController.willMove(toParentViewController: nil)
90 | childViewController.view.removeFromSuperview()
91 | childViewController.removeFromParentViewController()
92 |
93 | }
94 |
95 |
96 |
97 | }
98 |
99 |
100 |
101 | extension MainVC: UITableViewDelegate, UITableViewDataSource {
102 |
103 | func numberOfSections(in tableView: UITableView) -> Int {
104 | return 1
105 | }
106 |
107 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
108 | if segmntedContrl.selectedSegmentIndex == 0 {
109 | return dataArray1.count
110 | } else {
111 | return dataArray2.count
112 | }
113 | }
114 |
115 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
116 | let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
117 |
118 | if segmntedContrl.selectedSegmentIndex == 0 {
119 | cell.textLabel?.text = dataArray1[indexPath.row]
120 | } else {
121 | cell.textLabel?.text = dataArray2[indexPath.row]
122 | }
123 | return cell
124 | }
125 |
126 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
127 |
128 | let vc1 = ProcessVC()
129 | self.view.addSubview(vc1.view)
130 | self.addViewControllerAsChildViewController(childViewController: vc1)
131 |
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/BondKeyboard/Controller/ProcessVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProcessVC.swift
3 | // BondKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ProcessVC: UIViewController {
12 |
13 | var amountTF: UITextField!
14 | var nextButton: UIButton!
15 |
16 |
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 |
21 | self.amountTF = UITextField.init()
22 | amountTF.placeholder = "Enter Amount"
23 | amountTF.backgroundColor = .white
24 | view.addSubview(amountTF)
25 |
26 | self.nextButton = UIButton.init(type: .system)
27 | nextButton.setTitle("Next", for: .normal)
28 | nextButton.backgroundColor = .yellow
29 | nextButton.addTarget(self, action: #selector(onNext(sender:)), for: .touchUpInside)
30 | self.view.addSubview(nextButton)
31 |
32 | self.view.addConstraintsWithFormatString(formate: "H:|-35-[v0]-35-|", views: amountTF)
33 | self.view.addConstraintsWithFormatString(formate: "V:|-12-[v0(35)]", views: amountTF)
34 | self.view.addConstraintsWithFormatString(formate: "H:[v0(75)]-8-|", views: nextButton)
35 | self.view.addConstraintsWithFormatString(formate: "V:[v0(50)]-8-|", views: nextButton)
36 | }
37 |
38 |
39 | override func viewWillAppear(_ animated: Bool) {
40 | super.viewWillAppear(animated)
41 |
42 | //Make Text nil, as it is appeaaring first time...
43 |
44 | NotificationCenter.default.post(name: .textProxyNilNotification, object: nil)
45 | NotificationCenter.default.post(name: .childVCInformation, object: self)
46 | self.view.backgroundColor = #colorLiteral(red: 1, green: 0.8980991223, blue: 0.8880640628, alpha: 1)
47 | NotificationCenter.default.addObserver(self, selector: #selector(handleText(notf:)), name: .textProxyForContainer, object: nil)
48 |
49 | }
50 |
51 | override func viewDidAppear(_ animated: Bool) {
52 | super.viewDidAppear(animated)
53 |
54 | self.amountTF.becomeFirstResponder()
55 |
56 | }
57 |
58 | override func viewWillDisappear(_ animated: Bool) {
59 |
60 | super.viewWillDisappear(animated)
61 |
62 | NotificationCenter.default.removeObserver(self, name: .textProxyNilNotification, object: nil)
63 | self.removeViewControllerAsChildViewController(childViewController: vc2)
64 |
65 | }
66 |
67 |
68 |
69 |
70 | @objc func handleText(notf: Notification) {
71 |
72 | if let txttttt = notf.userInfo?["txt"] as? String {
73 | self.amountTF.text = txttttt
74 | }
75 |
76 | }
77 |
78 | let vc2 = ResultVC()
79 |
80 | @objc func onNext(sender: UIButton) {
81 |
82 | self.view.addSubview(vc2.view)
83 | self.addViewControllerAsChildViewController(childViewController: vc2)
84 |
85 | }
86 |
87 | private func addViewControllerAsChildViewController(childViewController: UIViewController) {
88 |
89 | addChildViewController(childViewController)
90 | view.addSubview(childViewController.view)
91 | childViewController.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
92 | childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
93 | childViewController.didMove(toParentViewController: self)
94 |
95 | }
96 |
97 | private func removeViewControllerAsChildViewController(childViewController: UIViewController) {
98 |
99 | childViewController.willMove(toParentViewController: nil)
100 | childViewController.view.removeFromSuperview()
101 | childViewController.removeFromParentViewController()
102 |
103 | }
104 |
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/BondKeyboard/Controller/ResultVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResultVC.swift
3 | // BondKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ResultVC: UIViewController {
12 |
13 |
14 | var passCodeTF: UITextField!
15 |
16 | var payButton: UIButton!
17 |
18 | var originalPassCode: String = ""
19 |
20 |
21 | override func viewDidLoad() {
22 | super.viewDidLoad()
23 |
24 | view.backgroundColor = UIColor.white
25 |
26 | self.passCodeTF = UITextField.init()
27 | passCodeTF.placeholder = "Enter Passcode"
28 | passCodeTF.textAlignment = .center
29 | passCodeTF.backgroundColor = #colorLiteral(red: 0.955975412, green: 0.8367665422, blue: 1, alpha: 1)
30 | view.addSubview(passCodeTF)
31 |
32 |
33 | self.payButton = UIButton.init(type: .system)
34 | payButton.setTitle("Pay", for: .normal)
35 | payButton.addTarget(self, action: #selector(onPay(sender:)), for: .touchUpInside)
36 | payButton.backgroundColor = .yellow
37 | self.view.addSubview(payButton)
38 |
39 | self.view.addConstraintsWithFormatString(formate: "H:|-65-[v0]-65-|", views: self.passCodeTF)
40 | self.view.addConstraintsWithFormatString(formate: "V:|-12-[v0(35)]", views: self.passCodeTF)
41 |
42 | self.view.addConstraintsWithFormatString(formate: "H:[v0(75)]-8-|", views: payButton)
43 | self.view.addConstraintsWithFormatString(formate: "V:[v0(50)]-8-|", views: payButton)
44 |
45 | }
46 |
47 | override func viewWillAppear(_ animated: Bool) {
48 | super.viewWillAppear(animated)
49 |
50 | NotificationCenter.default.post(name: .textProxyNilNotification, object: nil)
51 | NotificationCenter.default.post(name: .childVCInformation, object: self)
52 |
53 | NotificationCenter.default.addObserver(self, selector: #selector(handleText(notf:)), name: .textProxyForContainer, object: nil)
54 |
55 | }
56 |
57 | override func viewDidAppear(_ animated: Bool) {
58 | super.viewDidAppear(animated)
59 |
60 | self.passCodeTF.becomeFirstResponder()
61 |
62 | }
63 |
64 | override func viewWillDisappear(_ animated: Bool) {
65 | super.viewWillDisappear(animated)
66 |
67 | NotificationCenter.default.removeObserver(self, name: .textProxyNilNotification, object: nil)
68 |
69 | }
70 |
71 | var passcode = ""
72 |
73 | @objc func handleText(notf: Notification) {
74 |
75 | if let txttttt = notf.userInfo?["txt"] as? String {
76 |
77 | self.originalPassCode = txttttt
78 |
79 | passcode.removeAll()
80 |
81 | for _ in self.originalPassCode {
82 |
83 | passcode.append("*")
84 | }
85 | self.passCodeTF.text = passcode
86 |
87 | }
88 |
89 | }
90 |
91 | @objc func onPay(sender: UIButton) {
92 |
93 | print("Your PassCode is: \(originalPassCode)")
94 | NotificationCenter.default.post(name: .containerShowAndHideNotification, object: nil)
95 |
96 |
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/BondKeyboard/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | BondKeyboard
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | NSExtension
24 |
25 | NSExtensionAttributes
26 |
27 | IsASCIICapable
28 |
29 | PrefersRightToLeft
30 |
31 | PrimaryLanguage
32 | en-US
33 | RequestsOpenAccess
34 |
35 |
36 | NSExtensionPointIdentifier
37 | com.apple.keyboard-service
38 | NSExtensionPrincipalClass
39 | $(PRODUCT_MODULE_NAME).KeyboardViewController
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/BondKeyboard/KeyboardViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KeyboardViewController.swift
3 | // BondKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class KeyboardViewController: UIInputViewController {
12 |
13 |
14 | var capButton: KeyboardButton!
15 | var numericButton: KeyboardButton!
16 | var deleteButton: KeyboardButton!
17 | var nextKeyboardButton: KeyboardButton!
18 | var rupeSoButton: KeyboardButton!
19 | var returnButton: KeyboardButton!
20 |
21 | var isCapitalsShowing = false
22 |
23 | var areLettersShowing = true {
24 |
25 | didSet{
26 |
27 | if areLettersShowing {
28 | for view in mainStackView.arrangedSubviews {
29 | view.removeFromSuperview()
30 | }
31 | self.addKeyboardButtons()
32 |
33 | }else{
34 | displayNumericKeys()
35 | }
36 |
37 | }
38 |
39 | }
40 |
41 | var isContainerShowing = false {
42 |
43 | didSet{
44 | if isContainerShowing {
45 | self.childVCsNotif()
46 | }else {
47 | NotificationCenter.default.removeObserver(self, name: .childVCInformation, object: nil)
48 | }
49 | }
50 |
51 | }
52 |
53 | var allTextButtons = [KeyboardButton]()
54 |
55 | var keyboardHeight: CGFloat = 225
56 | var KeyboardVCHeightConstraint: NSLayoutConstraint!
57 | var containerViewHeight: CGFloat = 0
58 |
59 | var userLexicon: UILexicon?
60 |
61 | var notificationDictionary = [String: Any]()
62 |
63 | var containerText: String = "" {
64 |
65 | didSet{
66 | self.notificationDictionary["txt"] = self.containerText
67 | NotificationCenter.default.post(name: .textProxyForContainer, object: nil, userInfo: self.notificationDictionary)
68 | }
69 |
70 | }
71 |
72 |
73 | var currentWord: String? {
74 | var lastWord: String?
75 | // 1
76 | if let stringBeforeCursor = textDocumentProxy.documentContextBeforeInput {
77 | // 2
78 | stringBeforeCursor.enumerateSubstrings(in: stringBeforeCursor.startIndex...,
79 | options: .byWords)
80 | { word, _, _, _ in
81 | // 3
82 | if let word = word {
83 | lastWord = word
84 | }
85 | }
86 | }
87 | return lastWord
88 | }
89 |
90 | var isNumberPadNeeded: Bool = false {
91 |
92 | didSet{
93 |
94 | if isNumberPadNeeded {
95 | // Show Number Pad
96 | self.showNumberPad()
97 | }else {
98 | // Show Default Keyboard
99 | for view in mainStackView.arrangedSubviews {
100 | view.removeFromSuperview()
101 | }
102 | self.addKeyboardButtons()
103 | }
104 |
105 | }
106 |
107 | }
108 |
109 |
110 | override func viewDidLoad() {
111 | super.viewDidLoad()
112 |
113 | self.addKeyboardButtons()
114 | self.setNextKeyboardVisible(needsInputModeSwitchKey)
115 | self.KeyboardVCHeightConstraint = NSLayoutConstraint(item: self.view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: keyboardHeight+containerViewHeight)
116 | self.view.addConstraint(self.KeyboardVCHeightConstraint)
117 | self.requestSupplementaryLexicon { (lexicon) in
118 | self.userLexicon = lexicon
119 | }
120 | self.createObeservers()
121 |
122 | }
123 |
124 | override func viewWillAppear(_ animated: Bool) {
125 | super.viewWillAppear(animated)
126 | self.view.removeConstraint(KeyboardVCHeightConstraint)
127 | self.view.addConstraint(self.KeyboardVCHeightConstraint)
128 | }
129 |
130 | override func updateViewConstraints() {
131 | super.updateViewConstraints()
132 | // Add custom view sizing constraints here
133 | }
134 |
135 | override func textWillChange(_ textInput: UITextInput?) {
136 | // The app is about to change the document's contents. Perform any preparation here.
137 | }
138 |
139 | override func textDidChange(_ textInput: UITextInput?) {
140 | // The app has just changed the document's contents, the document context has been updated.
141 | let colorScheme: KBColorScheme
142 | if textDocumentProxy.keyboardAppearance == .dark {
143 | colorScheme = .dark
144 | } else {
145 | colorScheme = .light
146 | }
147 | self.setColorScheme(colorScheme)
148 | //Sets return key title on keyboard...
149 | if let returnTitle = self.textDocumentProxy.returnKeyType {
150 | let type = UIReturnKeyType(rawValue: returnTitle.rawValue)
151 | guard let retTitle = type?.get(rawValue: (type?.rawValue)!) else {return}
152 | self.returnButton.setTitle(retTitle, for: .normal)
153 | }
154 | }
155 |
156 | //Handles NextKeyBoard Button Appearance..
157 |
158 | func setNextKeyboardVisible(_ visible: Bool) {
159 | nextKeyboardButton.isHidden = !visible
160 | }
161 |
162 | //Set color scheme For keyboard appearance...
163 | func setColorScheme(_ colorScheme: KBColorScheme) {
164 |
165 | let themeColor = KBColors(colorScheme: colorScheme)
166 |
167 | self.capButton.defaultBackgroundColor = themeColor.buttonHighlightColor
168 | self.deleteButton.defaultBackgroundColor = themeColor.buttonHighlightColor
169 | self.numericButton.defaultBackgroundColor = themeColor.buttonHighlightColor
170 | self.rupeSoButton.defaultBackgroundColor = themeColor.buttonHighlightColor
171 | self.nextKeyboardButton.defaultBackgroundColor = themeColor.buttonHighlightColor
172 | self.returnButton.defaultBackgroundColor = themeColor.buttonHighlightColor
173 |
174 | self.capButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
175 | self.deleteButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
176 | self.nextKeyboardButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
177 | self.returnButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
178 | self.numericButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
179 | self.rupeSoButton.highlightBackgroundColor = themeColor.buttonBackgroundColor
180 |
181 | for button in allTextButtons {
182 | button.tintColor = themeColor.buttonTintColor
183 | button.defaultBackgroundColor = themeColor.buttonBackgroundColor
184 | button.highlightBackgroundColor = themeColor.buttonHighlightColor
185 | button.setTitleColor(themeColor.buttonTextColor, for: .normal)
186 |
187 | }
188 |
189 | }
190 |
191 | var mainStackView: UIStackView!
192 |
193 | private func addKeyboardButtons() {
194 | //My Custom Keys...
195 |
196 | let firstRowView = addRowsOnKeyboard(kbKeys: ["q","w","e","r","t","y","u","i","o","p"])
197 | let secondRowView = addRowsOnKeyboard(kbKeys: ["a","s","d","f","g","h","j","k","l"])
198 |
199 | let thirdRowkeysView = addRowsOnKeyboard(kbKeys: ["z","x","c","v","b","n","m"])
200 |
201 | let (thirdRowSV,fourthRowSV) = serveiceKeys(midRow: thirdRowkeysView)
202 |
203 | // Add Row Views on Keyboard View... With a Single Stack View..
204 |
205 | self.mainStackView = UIStackView(arrangedSubviews: [firstRowView,secondRowView,thirdRowSV,fourthRowSV])
206 | mainStackView.axis = .vertical
207 | mainStackView.spacing = 3.0
208 | mainStackView.distribution = .fillEqually
209 | mainStackView.alignment = .fill
210 | mainStackView.translatesAutoresizingMaskIntoConstraints = false
211 | view.addSubview(mainStackView)
212 |
213 | mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 2).isActive = true
214 | mainStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 2).isActive = true
215 | mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -2).isActive = true
216 | mainStackView.heightAnchor.constraint(equalToConstant: keyboardHeight).isActive = true
217 |
218 | // secondRowView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.90, constant: 1).isActive = true
219 | // secondRowView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
220 |
221 | }
222 |
223 | func serveiceKeys(midRow: UIView)->(UIStackView, UIStackView) {
224 | self.capButton = accessoryButtons(title: nil, img: #imageLiteral(resourceName: "captial1"), tag: 1)
225 | self.deleteButton = accessoryButtons(title: nil, img: #imageLiteral(resourceName: "backspace"), tag: 2)
226 |
227 | let thirdRowSV = UIStackView(arrangedSubviews: [self.capButton,midRow,self.deleteButton])
228 | thirdRowSV.distribution = .fillProportionally
229 | thirdRowSV.spacing = 5
230 |
231 | self.numericButton = accessoryButtons(title: "123", img: nil, tag: 3)
232 | self.nextKeyboardButton = accessoryButtons(title: nil, img: #imageLiteral(resourceName: "globe"), tag: 4)
233 | self.rupeSoButton = accessoryButtons(title: nil, img: #imageLiteral(resourceName: "RupeSoKey"), tag: 5)
234 | let spaceKey = accessoryButtons(title: "space", img: nil, tag: 6)
235 | self.returnButton = accessoryButtons(title: "return", img: nil, tag: 7)
236 |
237 | let fourthRowSV = UIStackView(arrangedSubviews: [self.numericButton,self.nextKeyboardButton,self.rupeSoButton,spaceKey,self.returnButton])
238 | fourthRowSV.distribution = .fillProportionally
239 | fourthRowSV.spacing = 5
240 |
241 | return (thirdRowSV,fourthRowSV)
242 | }
243 |
244 |
245 | // Adding Keys on UIView with UIStack View..
246 | func addRowsOnKeyboard(kbKeys: [String]) -> UIView {
247 |
248 | let RowStackView = UIStackView.init()
249 | RowStackView.spacing = 5
250 | RowStackView.axis = .horizontal
251 | RowStackView.alignment = .fill
252 | RowStackView.distribution = .fillEqually
253 |
254 | for key in kbKeys {
255 | RowStackView.addArrangedSubview(createButtonWithTitle(title: key))
256 | }
257 |
258 | let keysView = UIView()
259 | keysView.backgroundColor = .clear
260 | keysView.addSubview(RowStackView)
261 | keysView.addConstraintsWithFormatString(formate: "H:|[v0]|", views: RowStackView)
262 | keysView.addConstraintsWithFormatString(formate: "V:|[v0]|", views: RowStackView)
263 | return keysView
264 | }
265 |
266 | // Creates Buttons on Keyboard...
267 | func createButtonWithTitle(title: String) -> KeyboardButton {
268 |
269 | let button = KeyboardButton(type: .system)
270 | button.setTitle(title, for: .normal)
271 | button.sizeToFit()
272 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
273 | button.translatesAutoresizingMaskIntoConstraints = false
274 | // button.backgroundColor = UIColor(white: 1.0, alpha: 1.0)
275 | // button.setTitleColor(UIColor.darkGray, for: .normal)
276 | button.addTarget(self, action: #selector(didTapButton(sender:)), for: .touchUpInside)
277 | allTextButtons.append(button)
278 |
279 | return button
280 | }
281 |
282 | @objc func didTapButton(sender: UIButton) {
283 |
284 | let button = sender as UIButton
285 | // self.manageShadowsOnKeys(button: button, isShadowsNeeded: false)
286 | guard let title = button.titleLabel?.text else { return }
287 | let proxy = self.textDocumentProxy
288 |
289 | UIView.animate(withDuration: 0.25, animations: {
290 | button.transform = CGAffineTransform(scaleX: 1.20, y: 1.20)
291 | self.inputView?.playInputClick()
292 | if self.isContainerShowing {
293 | self.containerText = self.containerText + title
294 |
295 | }else{
296 | if !self.isContainerShowing {
297 | proxy.insertText(title)
298 | }
299 | }
300 |
301 | }) { (_) in
302 | UIView.animate(withDuration: 0.10, animations: {
303 | button.transform = CGAffineTransform.identity
304 | // self.manageShadowsOnKeys(button: button, isShadowsNeeded: true)
305 | })
306 | }
307 |
308 | }
309 |
310 | // Accesory Buttons On Keyboard...
311 |
312 | func accessoryButtons(title: String?, img: UIImage?, tag: Int) -> KeyboardButton {
313 |
314 | let button = KeyboardButton.init(type: .system)
315 |
316 | if let buttonTitle = title {
317 | button.setTitle(buttonTitle, for: .normal)
318 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
319 | }
320 |
321 | if let buttonImage = img {
322 | button.setImage(buttonImage.withRenderingMode(.alwaysOriginal), for: .normal)
323 | }
324 |
325 | button.sizeToFit()
326 | button.translatesAutoresizingMaskIntoConstraints = false
327 | button.tag = tag
328 |
329 | //For Capitals...
330 | if button.tag == 1 {
331 | button.addTarget(self, action: #selector(handleCapitalsAndLowerCase(sender:)), for: .touchUpInside)
332 | button.widthAnchor.constraint(equalToConstant: 45).isActive = true
333 | return button
334 | }
335 | //For BackDelete Key // Install Once Only..
336 | if button.tag == 2 {
337 | let longPrssRcngr = UILongPressGestureRecognizer.init(target: self, action: #selector(onLongPressOfBackSpaceKey(longGestr:)))
338 |
339 | //if !(button.gestureRecognizers?.contains(longPrssRcngr))! {
340 | longPrssRcngr.minimumPressDuration = 0.5
341 | longPrssRcngr.numberOfTouchesRequired = 1
342 | longPrssRcngr.allowableMovement = 0.1
343 | button.addGestureRecognizer(longPrssRcngr)
344 | //}
345 | button.widthAnchor.constraint(equalToConstant: 45).isActive = true
346 | }
347 | //Switch to and From Letters & Numeric Keys
348 | if button.tag == 3 {
349 | button.addTarget(self, action: #selector(handleSwitchingNumericsAndLetters(sender:)), for: .touchUpInside)
350 | button.widthAnchor.constraint(equalToConstant: 50).isActive = true
351 |
352 | return button
353 | }
354 | //Next Keyboard Button... Globe Button Usually...
355 | if button.tag == 4 {
356 | button.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
357 | button.widthAnchor.constraint(equalToConstant: 50).isActive = true
358 |
359 | return button
360 | }
361 | //Handle Rupee Button// For Showing Payment Container...
362 | if button.tag == 5 {
363 |
364 | button.addTarget(self, action: #selector(HandlePaymentContainer), for: .touchUpInside)
365 | button.widthAnchor.constraint(equalToConstant: 50).isActive = true
366 | return button
367 | }
368 | //White Space Button...
369 | if button.tag == 6 {
370 |
371 | button.addTarget(self, action: #selector(insertWhiteSpace), for: .touchUpInside)
372 | button.widthAnchor.constraint(equalToConstant: 100).isActive = true
373 |
374 | return button
375 | }
376 | //Handle return Button...//Usually depends on Texyfiled'd return Type...
377 | if button.tag == 7 {
378 | button.addTarget(self, action: #selector(handleReturnKey(sender:)), for: .touchUpInside)
379 | return button
380 | }
381 | //Else Case... For Others
382 | button.addTarget(self, action: #selector(manualAction(sender:)), for: .touchUpInside)
383 | return button
384 |
385 | }
386 |
387 | @objc func onLongPressOfBackSpaceKey(longGestr: UILongPressGestureRecognizer) {
388 |
389 | switch longGestr.state {
390 | case .began:
391 | if isContainerShowing {
392 |
393 | self.containerText = String.init((self.containerText.dropLast()))
394 |
395 | } else {
396 | self.textDocumentProxy.deleteBackward()
397 | // deleteLastWord()
398 | }
399 |
400 | case .ended:
401 | print("Ended")
402 | return
403 | default:
404 | self.textDocumentProxy.deleteBackward()
405 | //deleteLastWord()
406 | }
407 |
408 | }
409 |
410 | @objc func handleCapitalsAndLowerCase(sender: UIButton) {
411 | for button in allTextButtons {
412 |
413 | if let title = button.currentTitle {
414 | button.setTitle(isCapitalsShowing ? title.lowercased() : title.uppercased(), for: .normal)
415 | }
416 | }
417 | isCapitalsShowing = !isCapitalsShowing
418 | }
419 |
420 | @objc func handleSwitchingNumericsAndLetters(sender: UIButton) {
421 |
422 | areLettersShowing = !areLettersShowing
423 | print("Switching To and From Numeric and Alphabets")
424 | }
425 |
426 | @objc func HandlePaymentContainer() {
427 | isContainerShowing = !isContainerShowing
428 | self.handleContainerDisplay()
429 | }
430 |
431 | @objc func insertWhiteSpace() {
432 |
433 | attemptToReplaceCurrentWord()
434 | let proxy = self.textDocumentProxy
435 | proxy.insertText(" ")
436 | print("white space")
437 | }
438 |
439 | @objc func handleReturnKey(sender: UIButton) {
440 | // if let _ = self.textDocumentProxy.documentContextBeforeInput {
441 | self.textDocumentProxy.insertText("\n")
442 | // }
443 |
444 | // print("Return Type is handled here...")
445 | }
446 |
447 |
448 | @objc func manualAction(sender: UIButton) {
449 | let proxy = self.textDocumentProxy
450 |
451 | if isContainerShowing {
452 |
453 | self.containerText = String.init((self.containerText.dropLast()))
454 |
455 | } else {
456 | proxy.deleteBackward()
457 | }
458 | print("Else Case... Remaining Keys")
459 | }
460 |
461 |
462 |
463 | deinit {
464 | NotificationCenter.default.removeObserver(self)
465 | }
466 |
467 |
468 | func createObeservers() {
469 | NotificationCenter.default.addObserver(self, selector: #selector(handleNotifs(notf:)), name: .containerShowAndHideNotification, object: nil)
470 | NotificationCenter.default.addObserver(self, selector: #selector(handleNotifs(notf:)), name: .textProxyNilNotification, object: nil)
471 | }
472 |
473 |
474 | @objc func handleNotifs(notf: Notification) {
475 | if notf.name == .textProxyNilNotification {
476 | self.containerText = ""
477 | return
478 | }
479 | if notf.name == .containerShowAndHideNotification {
480 | resignFirstResponder()
481 | self.HandlePaymentContainer()
482 |
483 | OperationQueue.current?.addOperation {
484 | self.textDocumentProxy.insertText("The amount Rs.100 has been credited to your wallet...")
485 | }
486 | //self.textDocumentProxy.insertText("The amount Rs.100 has been credited to your wallet...")
487 | }
488 | }
489 |
490 | //Show Payments Container as needed...
491 | func handleContainerDisplay() {
492 | self.KeyboardVCHeightConstraint.isActive = false
493 |
494 | UIView.animate(withDuration: 0.35) {
495 | self.KeyboardVCHeightConstraint.isActive = true
496 |
497 | if self.isContainerShowing {
498 | self.containerViewHeight = 150
499 | self.KeyboardVCHeightConstraint.constant = self.keyboardHeight+self.containerViewHeight
500 | self.presentContainerVC()
501 | return
502 | } else {
503 | self.isNumberPadNeeded = false
504 | self.containerViewHeight = 0
505 | self.KeyboardVCHeightConstraint.constant = self.keyboardHeight
506 | if self.view.subviews.contains(self.mainVC.view) {
507 | // self.view.addConstraintsWithFormatString(formate: "H:|[v0]|", views: self.mainVC.view)
508 | // self.view.addConstraintsWithFormatString(formate: "V:|[v0(0)]", views: self.mainVC.view)
509 | self.removeViewControllerAsChildViewController(childViewController: self.mainVC)
510 | }
511 | return
512 | }
513 | }
514 | self.view.layoutIfNeeded()
515 |
516 | }
517 |
518 |
519 | // Add Child VC as container...
520 |
521 | lazy var mainVC: MainVC = {
522 | var viewController = MainVC()
523 | return viewController
524 | }()
525 |
526 | func presentContainerVC() {
527 | self.addViewControllerAsChildViewController(childViewController: mainVC)
528 | }
529 |
530 |
531 | private func addViewControllerAsChildViewController(childViewController: UIViewController) {
532 |
533 | addChildViewController(childViewController)
534 | view.addSubview(childViewController.view)
535 | childViewController.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height-keyboardHeight)
536 | childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
537 | childViewController.didMove(toParentViewController: self)
538 |
539 | }
540 |
541 | private func removeViewControllerAsChildViewController(childViewController: UIViewController) {
542 |
543 | childViewController.willMove(toParentViewController: nil)
544 | childViewController.view.removeFromSuperview()
545 | childViewController.removeFromParentViewController()
546 |
547 | }
548 |
549 | func childVCsNotif() {
550 |
551 | NotificationCenter.default.addObserver(self, selector: #selector(handleChildVCNotifs(notf:)), name: .childVCInformation, object: nil)
552 |
553 | }
554 |
555 | @objc func handleChildVCNotifs(notf: Notification) {
556 |
557 | if let _ = notf.object as? ProcessVC {
558 | // Show Number Pad on View
559 | isNumberPadNeeded = true
560 | return
561 | }
562 |
563 | if let _ = notf.object as? ResultVC {
564 | // Show Number Pad on View
565 | isNumberPadNeeded = true
566 | return
567 | }
568 |
569 | isNumberPadNeeded = false
570 |
571 | }
572 |
573 |
574 | func showNumberPad() {
575 |
576 | for view in mainStackView.arrangedSubviews {
577 | view.removeFromSuperview()
578 | }
579 | let firstRow = [".","0"]
580 | let secRow = ["1","2","3"]
581 | let thirdRow = ["4","5","6"]
582 | let fourthRow = ["7","8","9"]
583 |
584 | self.deleteButton = accessoryButtons(title: nil, img: #imageLiteral(resourceName: "backspace"), tag: 2)
585 |
586 | let first = addRowsOnKeyboard(kbKeys: firstRow)
587 | let second = addRowsOnKeyboard(kbKeys: secRow)
588 | let third = addRowsOnKeyboard(kbKeys: thirdRow)
589 | let fourth = addRowsOnKeyboard(kbKeys: fourthRow)
590 |
591 | let fsv = UIStackView(arrangedSubviews: [first, deleteButton])
592 | fsv.alignment = .fill
593 | fsv.distribution = .fill
594 | fsv.spacing = 5
595 |
596 | deleteButton.widthAnchor.constraint(equalTo: fsv.widthAnchor, multiplier: 1.0/3.0, constant: -5.0).isActive = true
597 |
598 | mainStackView.addArrangedSubview(fourth)
599 | mainStackView.addArrangedSubview(third)
600 | mainStackView.addArrangedSubview(second)
601 | mainStackView.addArrangedSubview(fsv)
602 |
603 | }
604 |
605 | func displayNumericKeys() {
606 |
607 | for view in mainStackView.arrangedSubviews {
608 | view.removeFromSuperview()
609 | }
610 |
611 | let nums = ["1","2","3","4","5","6","7","8","9","0"]
612 | let splChars1 = ["-","/",":",";","(",")","\u{20B9}","&","@","*"]
613 | let splChars2 = [".",",","?","!","#"]
614 |
615 | let numsRow = self.addRowsOnKeyboard(kbKeys: nums)
616 | let splChars1Row = self.addRowsOnKeyboard(kbKeys: splChars1)
617 | let splChars2Row = self.addRowsOnKeyboard(kbKeys: splChars2)
618 |
619 | let (thirdRowSV,fourthRowSV) = serveiceKeys(midRow: splChars2Row)
620 |
621 | mainStackView.addArrangedSubview(numsRow)
622 | mainStackView.addArrangedSubview(splChars1Row)
623 | mainStackView.addArrangedSubview(thirdRowSV)
624 | mainStackView.addArrangedSubview(fourthRowSV)
625 |
626 | }
627 |
628 |
629 |
630 | }
631 |
632 |
633 | private extension KeyboardViewController {
634 | func attemptToReplaceCurrentWord() {
635 | // 1
636 | guard let entries = userLexicon?.entries,
637 | let currentWord = currentWord?.lowercased() else {
638 | return
639 | }
640 |
641 | // 2
642 | let replacementEntries = entries.filter {
643 | $0.userInput.lowercased() == currentWord
644 | }
645 |
646 | if let replacement = replacementEntries.first {
647 | // 3
648 | for _ in 0.. UIColor {
50 |
51 | return UIColor.init(red: red/255, green: green/255, blue: blue/255, alpha: 1.0)
52 | }
53 |
54 | /**Gives Color from HEX Value, If there is more than 6 characters in HEX String, it returns "Magenta Color". If the HEX String is Correct, it returns it's Color*/
55 | static func colorFromHexValue(_ hex: String) -> UIColor {
56 |
57 | var hexString = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
58 |
59 | if hexString.hasPrefix("#") {
60 |
61 | hexString.remove(at: hexString.startIndex)
62 | }
63 |
64 | if hexString.count != 6 {
65 |
66 | return UIColor.magenta
67 | }
68 |
69 | var rgb: UInt32 = 0
70 | Scanner.init(string: hexString).scanHexInt32(&rgb)
71 |
72 | return UIColor.init(red: CGFloat((rgb & 0xFF0000) >> 16)/255,
73 | green: CGFloat((rgb & 0x00FF00) >> 8)/255,
74 | blue: CGFloat(rgb & 0x0000FF)/255,
75 | alpha: 1.0)
76 | }
77 |
78 | }
79 |
80 |
81 | extension UIInputView: UIInputViewAudioFeedback {
82 |
83 | public var enableInputClicksWhenVisible: Bool {
84 | get {
85 | return true
86 | }
87 | }
88 |
89 | func playInputClick() {
90 | UIDevice.current.playInputClick()
91 | }
92 |
93 | }
94 |
95 | extension String {
96 |
97 | var length : Int {
98 | get{
99 | return self.count
100 | }
101 | }
102 | }
103 |
104 |
105 |
106 | extension Notification.Name {
107 |
108 | static var containerShowAndHideNotification = Notification.Name.init("containerShowAndHideNotification")
109 |
110 | static var textProxyForContainer = Notification.Name.init("HandleContainerText")
111 |
112 | static var textProxyNilNotification = Notification.Name.init("TextProxyNilNotification")
113 |
114 | // For notifying From Child View Controllers
115 |
116 | static var childVCInformation = Notification.Name.init("ChildVC Information")
117 |
118 | }
119 |
120 |
121 | extension UIReturnKeyType {
122 |
123 | func get (rawValue: Int)-> String {
124 |
125 | switch self.rawValue {
126 | case UIReturnKeyType.default.rawValue:
127 | return "Return"
128 | case UIReturnKeyType.continue.rawValue:
129 | return "Continue"
130 | case UIReturnKeyType.google.rawValue:
131 | return "google"
132 | case UIReturnKeyType.done.rawValue:
133 | return "Done"
134 | case UIReturnKeyType.search.rawValue:
135 | return "Search"
136 | case UIReturnKeyType.join.rawValue:
137 | return "Join"
138 | case UIReturnKeyType.next.rawValue:
139 | return "Next"
140 | case UIReturnKeyType.emergencyCall.rawValue:
141 | return "Emg Call"
142 | case UIReturnKeyType.route.rawValue:
143 | return "Route"
144 | case UIReturnKeyType.send.rawValue:
145 | return "Send"
146 | case UIReturnKeyType.yahoo.rawValue:
147 | return "search"
148 |
149 | default:
150 | return "Default"
151 | }
152 |
153 | }
154 |
155 | }
156 |
157 |
158 |
159 | extension UIViewController {
160 |
161 | // /**Adds View controoler as a child view controller, on current View */
162 | // func addViewControllerAsChildViewController(childViewController: UIViewController) {
163 | //
164 | // addChildViewController(childViewController)
165 | // view.addSubview(childViewController.view)
166 | // childViewController.view.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height-225)
167 | // childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
168 | // childViewController.didMove(toParentViewController: self)
169 | //
170 | // }
171 | //
172 | // /**Removes View controoler from child view controller, on current View */
173 | // func removeViewControllerAsChildViewController(childViewController: UIViewController) {
174 | //
175 | // childViewController.willMove(toParentViewController: nil)
176 | // childViewController.view.removeFromSuperview()
177 | // childViewController.removeFromParentViewController()
178 | //
179 | // }
180 |
181 |
182 | }
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
--------------------------------------------------------------------------------
/Data&Utilities/Themes+Colors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Themes+Colors.swift
3 | // SecNinjazKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum KBColorScheme {
12 | case dark
13 | case light
14 | }
15 |
16 | struct KBColors {
17 |
18 | let buttonTextColor: UIColor
19 | let buttonBackgroundColor: UIColor
20 | let buttonHighlightColor: UIColor
21 | let backgroundColor: UIColor
22 | let previewTextColor: UIColor
23 | let previewBackgroundColor: UIColor
24 | let buttonTintColor: UIColor
25 |
26 | init(colorScheme: KBColorScheme) {
27 | switch colorScheme {
28 | case .light:
29 | buttonTextColor = .black
30 | buttonTintColor = .black
31 | buttonBackgroundColor = .white
32 | buttonHighlightColor = UIColor(red: 174/255, green: 179/255, blue: 190/255, alpha: 1.0)
33 | backgroundColor = UIColor(red: 210/255, green: 213/255, blue: 219/255, alpha: 1.0)
34 | previewTextColor = .white
35 | previewBackgroundColor = UIColor(red: 186/255, green: 191/255, blue: 200/255, alpha: 1.0)
36 | case .dark:
37 | buttonTextColor = .white
38 | buttonTintColor = .white
39 | buttonBackgroundColor = UIColor(white: 138/255, alpha: 1.0)
40 | buttonHighlightColor = UIColor(white: 104/255, alpha: 1.0)
41 | backgroundColor = UIColor(white:89/255, alpha: 1.0)
42 | previewTextColor = .white
43 | previewBackgroundColor = UIColor(white: 80/255, alpha: 1.0)
44 | }
45 | }
46 |
47 | }
48 |
49 |
50 | //MARK: Color Constatnts
51 |
52 | let containerPrimaryViewColor = UIColor.white
53 | let containerSubViewBackgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
54 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5A4FAE352096F2270052E81A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE342096F2270052E81A /* AppDelegate.swift */; };
11 | 5A4FAE372096F2270052E81A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE362096F2270052E81A /* ViewController.swift */; };
12 | 5A4FAE3A2096F2270052E81A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5A4FAE382096F2270052E81A /* Main.storyboard */; };
13 | 5A4FAE3C2096F22B0052E81A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A4FAE3B2096F22B0052E81A /* Assets.xcassets */; };
14 | 5A4FAE3F2096F22B0052E81A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5A4FAE3D2096F22B0052E81A /* LaunchScreen.storyboard */; };
15 | 5A4FAE4A2096F2AA0052E81A /* Themes+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE492096F2AA0052E81A /* Themes+Colors.swift */; };
16 | 5A4FAE4C2096F3B10052E81A /* KeyboardButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE4B2096F3B10052E81A /* KeyboardButton.swift */; };
17 | 5A4FAE542096F5460052E81A /* KeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE532096F5460052E81A /* KeyboardViewController.swift */; };
18 | 5A4FAE582096F5460052E81A /* BondKeyboard.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5A4FAE512096F5460052E81A /* BondKeyboard.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
19 | 5A4FAE5D2096F6E00052E81A /* KeyboardButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE4B2096F3B10052E81A /* KeyboardButton.swift */; };
20 | 5A4FAE5E2096F6E40052E81A /* Themes+Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE492096F2AA0052E81A /* Themes+Colors.swift */; };
21 | 5A4FAE602096F7340052E81A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE5F2096F7340052E81A /* Extensions.swift */; };
22 | 5A4FAE612096F73A0052E81A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE5F2096F7340052E81A /* Extensions.swift */; };
23 | 5A4FAE622096FBCD0052E81A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A4FAE3B2096F22B0052E81A /* Assets.xcassets */; };
24 | 5A4FAE65209700C00052E81A /* MainVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE64209700C00052E81A /* MainVC.swift */; };
25 | 5A4FAE67209700DD0052E81A /* ProcessVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE66209700DD0052E81A /* ProcessVC.swift */; };
26 | 5A4FAE69209700EC0052E81A /* ResultVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A4FAE68209700EC0052E81A /* ResultVC.swift */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | 5A4FAE562096F5460052E81A /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 5A4FAE292096F2270052E81A /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 5A4FAE502096F5460052E81A;
35 | remoteInfo = BondKeyboard;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXCopyFilesBuildPhase section */
40 | 5A4FAE5C2096F5460052E81A /* Embed App Extensions */ = {
41 | isa = PBXCopyFilesBuildPhase;
42 | buildActionMask = 2147483647;
43 | dstPath = "";
44 | dstSubfolderSpec = 13;
45 | files = (
46 | 5A4FAE582096F5460052E81A /* BondKeyboard.appex in Embed App Extensions */,
47 | );
48 | name = "Embed App Extensions";
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | /* End PBXCopyFilesBuildPhase section */
52 |
53 | /* Begin PBXFileReference section */
54 | 5A4FAE312096F2270052E81A /* LeelaKrishnaKeyboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LeelaKrishnaKeyboard.app; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 5A4FAE342096F2270052E81A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
56 | 5A4FAE362096F2270052E81A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
57 | 5A4FAE392096F2270052E81A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
58 | 5A4FAE3B2096F22B0052E81A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
59 | 5A4FAE3E2096F22B0052E81A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
60 | 5A4FAE402096F22B0052E81A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
61 | 5A4FAE492096F2AA0052E81A /* Themes+Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Themes+Colors.swift"; sourceTree = ""; };
62 | 5A4FAE4B2096F3B10052E81A /* KeyboardButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardButton.swift; sourceTree = ""; };
63 | 5A4FAE512096F5460052E81A /* BondKeyboard.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = BondKeyboard.appex; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 5A4FAE532096F5460052E81A /* KeyboardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardViewController.swift; sourceTree = ""; };
65 | 5A4FAE552096F5460052E81A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
66 | 5A4FAE5F2096F7340052E81A /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
67 | 5A4FAE64209700C00052E81A /* MainVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainVC.swift; sourceTree = ""; };
68 | 5A4FAE66209700DD0052E81A /* ProcessVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessVC.swift; sourceTree = ""; };
69 | 5A4FAE68209700EC0052E81A /* ResultVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultVC.swift; sourceTree = ""; };
70 | /* End PBXFileReference section */
71 |
72 | /* Begin PBXFrameworksBuildPhase section */
73 | 5A4FAE2E2096F2270052E81A /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | 5A4FAE4E2096F5460052E81A /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | /* End PBXFrameworksBuildPhase section */
88 |
89 | /* Begin PBXGroup section */
90 | 5A4FAE282096F2270052E81A = {
91 | isa = PBXGroup;
92 | children = (
93 | 5A4FAE332096F2270052E81A /* SecNinjazKeyboard */,
94 | 5A4FAE482096F2610052E81A /* Data&Utilities */,
95 | 5A4FAE472096F2580052E81A /* View */,
96 | 5A4FAE462096F24A0052E81A /* Model */,
97 | 5A4FAE522096F5460052E81A /* BondKeyboard */,
98 | 5A4FAE322096F2270052E81A /* Products */,
99 | );
100 | sourceTree = "";
101 | };
102 | 5A4FAE322096F2270052E81A /* Products */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 5A4FAE312096F2270052E81A /* LeelaKrishnaKeyboard.app */,
106 | 5A4FAE512096F5460052E81A /* BondKeyboard.appex */,
107 | );
108 | name = Products;
109 | sourceTree = "";
110 | };
111 | 5A4FAE332096F2270052E81A /* SecNinjazKeyboard */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 5A4FAE342096F2270052E81A /* AppDelegate.swift */,
115 | 5A4FAE362096F2270052E81A /* ViewController.swift */,
116 | 5A4FAE382096F2270052E81A /* Main.storyboard */,
117 | 5A4FAE3B2096F22B0052E81A /* Assets.xcassets */,
118 | 5A4FAE3D2096F22B0052E81A /* LaunchScreen.storyboard */,
119 | 5A4FAE402096F22B0052E81A /* Info.plist */,
120 | );
121 | path = SecNinjazKeyboard;
122 | sourceTree = "";
123 | };
124 | 5A4FAE462096F24A0052E81A /* Model */ = {
125 | isa = PBXGroup;
126 | children = (
127 | );
128 | path = Model;
129 | sourceTree = "";
130 | };
131 | 5A4FAE472096F2580052E81A /* View */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 5A4FAE4B2096F3B10052E81A /* KeyboardButton.swift */,
135 | );
136 | path = View;
137 | sourceTree = "";
138 | };
139 | 5A4FAE482096F2610052E81A /* Data&Utilities */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 5A4FAE5F2096F7340052E81A /* Extensions.swift */,
143 | 5A4FAE492096F2AA0052E81A /* Themes+Colors.swift */,
144 | );
145 | path = "Data&Utilities";
146 | sourceTree = "";
147 | };
148 | 5A4FAE522096F5460052E81A /* BondKeyboard */ = {
149 | isa = PBXGroup;
150 | children = (
151 | 5A4FAE63209700A80052E81A /* Controller */,
152 | 5A4FAE532096F5460052E81A /* KeyboardViewController.swift */,
153 | 5A4FAE552096F5460052E81A /* Info.plist */,
154 | );
155 | path = BondKeyboard;
156 | sourceTree = "";
157 | };
158 | 5A4FAE63209700A80052E81A /* Controller */ = {
159 | isa = PBXGroup;
160 | children = (
161 | 5A4FAE64209700C00052E81A /* MainVC.swift */,
162 | 5A4FAE66209700DD0052E81A /* ProcessVC.swift */,
163 | 5A4FAE68209700EC0052E81A /* ResultVC.swift */,
164 | );
165 | path = Controller;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | 5A4FAE302096F2270052E81A /* LeelaKrishnaKeyboard */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 5A4FAE432096F22B0052E81A /* Build configuration list for PBXNativeTarget "LeelaKrishnaKeyboard" */;
174 | buildPhases = (
175 | 5A4FAE2D2096F2270052E81A /* Sources */,
176 | 5A4FAE2E2096F2270052E81A /* Frameworks */,
177 | 5A4FAE2F2096F2270052E81A /* Resources */,
178 | 5A4FAE5C2096F5460052E81A /* Embed App Extensions */,
179 | );
180 | buildRules = (
181 | );
182 | dependencies = (
183 | 5A4FAE572096F5460052E81A /* PBXTargetDependency */,
184 | );
185 | name = LeelaKrishnaKeyboard;
186 | productName = SecNinjazKeyboard;
187 | productReference = 5A4FAE312096F2270052E81A /* LeelaKrishnaKeyboard.app */;
188 | productType = "com.apple.product-type.application";
189 | };
190 | 5A4FAE502096F5460052E81A /* BondKeyboard */ = {
191 | isa = PBXNativeTarget;
192 | buildConfigurationList = 5A4FAE592096F5460052E81A /* Build configuration list for PBXNativeTarget "BondKeyboard" */;
193 | buildPhases = (
194 | 5A4FAE4D2096F5460052E81A /* Sources */,
195 | 5A4FAE4E2096F5460052E81A /* Frameworks */,
196 | 5A4FAE4F2096F5460052E81A /* Resources */,
197 | );
198 | buildRules = (
199 | );
200 | dependencies = (
201 | );
202 | name = BondKeyboard;
203 | productName = BondKeyboard;
204 | productReference = 5A4FAE512096F5460052E81A /* BondKeyboard.appex */;
205 | productType = "com.apple.product-type.app-extension";
206 | };
207 | /* End PBXNativeTarget section */
208 |
209 | /* Begin PBXProject section */
210 | 5A4FAE292096F2270052E81A /* Project object */ = {
211 | isa = PBXProject;
212 | attributes = {
213 | LastSwiftUpdateCheck = 0930;
214 | LastUpgradeCheck = 0930;
215 | ORGANIZATIONNAME = "Leela Prasad";
216 | TargetAttributes = {
217 | 5A4FAE302096F2270052E81A = {
218 | CreatedOnToolsVersion = 9.3;
219 | };
220 | 5A4FAE502096F5460052E81A = {
221 | CreatedOnToolsVersion = 9.3;
222 | };
223 | };
224 | };
225 | buildConfigurationList = 5A4FAE2C2096F2270052E81A /* Build configuration list for PBXProject "LeelaKrishnaKeyboard" */;
226 | compatibilityVersion = "Xcode 9.3";
227 | developmentRegion = en;
228 | hasScannedForEncodings = 0;
229 | knownRegions = (
230 | en,
231 | Base,
232 | );
233 | mainGroup = 5A4FAE282096F2270052E81A;
234 | productRefGroup = 5A4FAE322096F2270052E81A /* Products */;
235 | projectDirPath = "";
236 | projectRoot = "";
237 | targets = (
238 | 5A4FAE302096F2270052E81A /* LeelaKrishnaKeyboard */,
239 | 5A4FAE502096F5460052E81A /* BondKeyboard */,
240 | );
241 | };
242 | /* End PBXProject section */
243 |
244 | /* Begin PBXResourcesBuildPhase section */
245 | 5A4FAE2F2096F2270052E81A /* Resources */ = {
246 | isa = PBXResourcesBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | 5A4FAE3F2096F22B0052E81A /* LaunchScreen.storyboard in Resources */,
250 | 5A4FAE3C2096F22B0052E81A /* Assets.xcassets in Resources */,
251 | 5A4FAE3A2096F2270052E81A /* Main.storyboard in Resources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | 5A4FAE4F2096F5460052E81A /* Resources */ = {
256 | isa = PBXResourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | 5A4FAE622096FBCD0052E81A /* Assets.xcassets in Resources */,
260 | );
261 | runOnlyForDeploymentPostprocessing = 0;
262 | };
263 | /* End PBXResourcesBuildPhase section */
264 |
265 | /* Begin PBXSourcesBuildPhase section */
266 | 5A4FAE2D2096F2270052E81A /* Sources */ = {
267 | isa = PBXSourcesBuildPhase;
268 | buildActionMask = 2147483647;
269 | files = (
270 | 5A4FAE602096F7340052E81A /* Extensions.swift in Sources */,
271 | 5A4FAE4C2096F3B10052E81A /* KeyboardButton.swift in Sources */,
272 | 5A4FAE4A2096F2AA0052E81A /* Themes+Colors.swift in Sources */,
273 | 5A4FAE372096F2270052E81A /* ViewController.swift in Sources */,
274 | 5A4FAE352096F2270052E81A /* AppDelegate.swift in Sources */,
275 | );
276 | runOnlyForDeploymentPostprocessing = 0;
277 | };
278 | 5A4FAE4D2096F5460052E81A /* Sources */ = {
279 | isa = PBXSourcesBuildPhase;
280 | buildActionMask = 2147483647;
281 | files = (
282 | 5A4FAE67209700DD0052E81A /* ProcessVC.swift in Sources */,
283 | 5A4FAE5E2096F6E40052E81A /* Themes+Colors.swift in Sources */,
284 | 5A4FAE65209700C00052E81A /* MainVC.swift in Sources */,
285 | 5A4FAE5D2096F6E00052E81A /* KeyboardButton.swift in Sources */,
286 | 5A4FAE69209700EC0052E81A /* ResultVC.swift in Sources */,
287 | 5A4FAE542096F5460052E81A /* KeyboardViewController.swift in Sources */,
288 | 5A4FAE612096F73A0052E81A /* Extensions.swift in Sources */,
289 | );
290 | runOnlyForDeploymentPostprocessing = 0;
291 | };
292 | /* End PBXSourcesBuildPhase section */
293 |
294 | /* Begin PBXTargetDependency section */
295 | 5A4FAE572096F5460052E81A /* PBXTargetDependency */ = {
296 | isa = PBXTargetDependency;
297 | target = 5A4FAE502096F5460052E81A /* BondKeyboard */;
298 | targetProxy = 5A4FAE562096F5460052E81A /* PBXContainerItemProxy */;
299 | };
300 | /* End PBXTargetDependency section */
301 |
302 | /* Begin PBXVariantGroup section */
303 | 5A4FAE382096F2270052E81A /* Main.storyboard */ = {
304 | isa = PBXVariantGroup;
305 | children = (
306 | 5A4FAE392096F2270052E81A /* Base */,
307 | );
308 | name = Main.storyboard;
309 | sourceTree = "";
310 | };
311 | 5A4FAE3D2096F22B0052E81A /* LaunchScreen.storyboard */ = {
312 | isa = PBXVariantGroup;
313 | children = (
314 | 5A4FAE3E2096F22B0052E81A /* Base */,
315 | );
316 | name = LaunchScreen.storyboard;
317 | sourceTree = "";
318 | };
319 | /* End PBXVariantGroup section */
320 |
321 | /* Begin XCBuildConfiguration section */
322 | 5A4FAE412096F22B0052E81A /* Debug */ = {
323 | isa = XCBuildConfiguration;
324 | buildSettings = {
325 | ALWAYS_SEARCH_USER_PATHS = NO;
326 | CLANG_ANALYZER_NONNULL = YES;
327 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
329 | CLANG_CXX_LIBRARY = "libc++";
330 | CLANG_ENABLE_MODULES = YES;
331 | CLANG_ENABLE_OBJC_ARC = YES;
332 | CLANG_ENABLE_OBJC_WEAK = YES;
333 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
334 | CLANG_WARN_BOOL_CONVERSION = YES;
335 | CLANG_WARN_COMMA = YES;
336 | CLANG_WARN_CONSTANT_CONVERSION = YES;
337 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
338 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
339 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
340 | CLANG_WARN_EMPTY_BODY = YES;
341 | CLANG_WARN_ENUM_CONVERSION = YES;
342 | CLANG_WARN_INFINITE_RECURSION = YES;
343 | CLANG_WARN_INT_CONVERSION = YES;
344 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
345 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
346 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
348 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
349 | CLANG_WARN_STRICT_PROTOTYPES = YES;
350 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
351 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
352 | CLANG_WARN_UNREACHABLE_CODE = YES;
353 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
354 | CODE_SIGN_IDENTITY = "iPhone Developer";
355 | COPY_PHASE_STRIP = NO;
356 | DEBUG_INFORMATION_FORMAT = dwarf;
357 | ENABLE_STRICT_OBJC_MSGSEND = YES;
358 | ENABLE_TESTABILITY = YES;
359 | GCC_C_LANGUAGE_STANDARD = gnu11;
360 | GCC_DYNAMIC_NO_PIC = NO;
361 | GCC_NO_COMMON_BLOCKS = YES;
362 | GCC_OPTIMIZATION_LEVEL = 0;
363 | GCC_PREPROCESSOR_DEFINITIONS = (
364 | "DEBUG=1",
365 | "$(inherited)",
366 | );
367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
369 | GCC_WARN_UNDECLARED_SELECTOR = YES;
370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
371 | GCC_WARN_UNUSED_FUNCTION = YES;
372 | GCC_WARN_UNUSED_VARIABLE = YES;
373 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
374 | MTL_ENABLE_DEBUG_INFO = YES;
375 | ONLY_ACTIVE_ARCH = YES;
376 | SDKROOT = iphoneos;
377 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
378 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
379 | };
380 | name = Debug;
381 | };
382 | 5A4FAE422096F22B0052E81A /* Release */ = {
383 | isa = XCBuildConfiguration;
384 | buildSettings = {
385 | ALWAYS_SEARCH_USER_PATHS = NO;
386 | CLANG_ANALYZER_NONNULL = YES;
387 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
388 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
389 | CLANG_CXX_LIBRARY = "libc++";
390 | CLANG_ENABLE_MODULES = YES;
391 | CLANG_ENABLE_OBJC_ARC = YES;
392 | CLANG_ENABLE_OBJC_WEAK = YES;
393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
394 | CLANG_WARN_BOOL_CONVERSION = YES;
395 | CLANG_WARN_COMMA = YES;
396 | CLANG_WARN_CONSTANT_CONVERSION = YES;
397 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
398 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
399 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
400 | CLANG_WARN_EMPTY_BODY = YES;
401 | CLANG_WARN_ENUM_CONVERSION = YES;
402 | CLANG_WARN_INFINITE_RECURSION = YES;
403 | CLANG_WARN_INT_CONVERSION = YES;
404 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
405 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
406 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
408 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
409 | CLANG_WARN_STRICT_PROTOTYPES = YES;
410 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
411 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
412 | CLANG_WARN_UNREACHABLE_CODE = YES;
413 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
414 | CODE_SIGN_IDENTITY = "iPhone Developer";
415 | COPY_PHASE_STRIP = NO;
416 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
417 | ENABLE_NS_ASSERTIONS = NO;
418 | ENABLE_STRICT_OBJC_MSGSEND = YES;
419 | GCC_C_LANGUAGE_STANDARD = gnu11;
420 | GCC_NO_COMMON_BLOCKS = YES;
421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
423 | GCC_WARN_UNDECLARED_SELECTOR = YES;
424 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
425 | GCC_WARN_UNUSED_FUNCTION = YES;
426 | GCC_WARN_UNUSED_VARIABLE = YES;
427 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
428 | MTL_ENABLE_DEBUG_INFO = NO;
429 | SDKROOT = iphoneos;
430 | SWIFT_COMPILATION_MODE = wholemodule;
431 | SWIFT_OPTIMIZATION_LEVEL = "-O";
432 | VALIDATE_PRODUCT = YES;
433 | };
434 | name = Release;
435 | };
436 | 5A4FAE442096F22B0052E81A /* Debug */ = {
437 | isa = XCBuildConfiguration;
438 | buildSettings = {
439 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
440 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
441 | CODE_SIGN_STYLE = Automatic;
442 | DEVELOPMENT_TEAM = "";
443 | INFOPLIST_FILE = SecNinjazKeyboard/Info.plist;
444 | LD_RUNPATH_SEARCH_PATHS = (
445 | "$(inherited)",
446 | "@executable_path/Frameworks",
447 | );
448 | PRODUCT_BUNDLE_IDENTIFIER = ssss.SecNinjazKeyboard;
449 | PRODUCT_NAME = "$(TARGET_NAME)";
450 | SWIFT_VERSION = 4.0;
451 | TARGETED_DEVICE_FAMILY = "1,2";
452 | };
453 | name = Debug;
454 | };
455 | 5A4FAE452096F22B0052E81A /* Release */ = {
456 | isa = XCBuildConfiguration;
457 | buildSettings = {
458 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
459 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
460 | CODE_SIGN_STYLE = Automatic;
461 | DEVELOPMENT_TEAM = "";
462 | INFOPLIST_FILE = SecNinjazKeyboard/Info.plist;
463 | LD_RUNPATH_SEARCH_PATHS = (
464 | "$(inherited)",
465 | "@executable_path/Frameworks",
466 | );
467 | PRODUCT_BUNDLE_IDENTIFIER = ssss.SecNinjazKeyboard;
468 | PRODUCT_NAME = "$(TARGET_NAME)";
469 | SWIFT_VERSION = 4.0;
470 | TARGETED_DEVICE_FAMILY = "1,2";
471 | };
472 | name = Release;
473 | };
474 | 5A4FAE5A2096F5460052E81A /* Debug */ = {
475 | isa = XCBuildConfiguration;
476 | buildSettings = {
477 | CODE_SIGN_STYLE = Automatic;
478 | DEVELOPMENT_TEAM = 5LC376D52F;
479 | INFOPLIST_FILE = BondKeyboard/Info.plist;
480 | LD_RUNPATH_SEARCH_PATHS = (
481 | "$(inherited)",
482 | "@executable_path/Frameworks",
483 | "@executable_path/../../Frameworks",
484 | );
485 | PRODUCT_BUNDLE_IDENTIFIER = ssss.SecNinjazKeyboard.BondKeyboard;
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | SKIP_INSTALL = YES;
488 | SWIFT_VERSION = 4.0;
489 | TARGETED_DEVICE_FAMILY = "1,2";
490 | };
491 | name = Debug;
492 | };
493 | 5A4FAE5B2096F5460052E81A /* Release */ = {
494 | isa = XCBuildConfiguration;
495 | buildSettings = {
496 | CODE_SIGN_STYLE = Automatic;
497 | DEVELOPMENT_TEAM = 5LC376D52F;
498 | INFOPLIST_FILE = BondKeyboard/Info.plist;
499 | LD_RUNPATH_SEARCH_PATHS = (
500 | "$(inherited)",
501 | "@executable_path/Frameworks",
502 | "@executable_path/../../Frameworks",
503 | );
504 | PRODUCT_BUNDLE_IDENTIFIER = ssss.SecNinjazKeyboard.BondKeyboard;
505 | PRODUCT_NAME = "$(TARGET_NAME)";
506 | SKIP_INSTALL = YES;
507 | SWIFT_VERSION = 4.0;
508 | TARGETED_DEVICE_FAMILY = "1,2";
509 | };
510 | name = Release;
511 | };
512 | /* End XCBuildConfiguration section */
513 |
514 | /* Begin XCConfigurationList section */
515 | 5A4FAE2C2096F2270052E81A /* Build configuration list for PBXProject "LeelaKrishnaKeyboard" */ = {
516 | isa = XCConfigurationList;
517 | buildConfigurations = (
518 | 5A4FAE412096F22B0052E81A /* Debug */,
519 | 5A4FAE422096F22B0052E81A /* Release */,
520 | );
521 | defaultConfigurationIsVisible = 0;
522 | defaultConfigurationName = Release;
523 | };
524 | 5A4FAE432096F22B0052E81A /* Build configuration list for PBXNativeTarget "LeelaKrishnaKeyboard" */ = {
525 | isa = XCConfigurationList;
526 | buildConfigurations = (
527 | 5A4FAE442096F22B0052E81A /* Debug */,
528 | 5A4FAE452096F22B0052E81A /* Release */,
529 | );
530 | defaultConfigurationIsVisible = 0;
531 | defaultConfigurationName = Release;
532 | };
533 | 5A4FAE592096F5460052E81A /* Build configuration list for PBXNativeTarget "BondKeyboard" */ = {
534 | isa = XCConfigurationList;
535 | buildConfigurations = (
536 | 5A4FAE5A2096F5460052E81A /* Debug */,
537 | 5A4FAE5B2096F5460052E81A /* Release */,
538 | );
539 | defaultConfigurationIsVisible = 0;
540 | defaultConfigurationName = Release;
541 | };
542 | /* End XCConfigurationList section */
543 | };
544 | rootObject = 5A4FAE292096F2270052E81A /* Project object */;
545 | }
546 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/xcuserdata/leelaprasad.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/xcuserdata/leelaprasad.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | BondKeyboard.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | SecNinjazKeyboard.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LeelaKrishnaKeyboard.xcodeproj/xcuserdata/penumutchu.prasadgmail.com.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | BondKeyboard.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | LeelaKrishnaKeyboard.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 | SecNinjazKeyboard.xcscheme
18 |
19 | orderHint
20 | 0
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SecNinjazKeyboard/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SecNinjazKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/RupeSoKey.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "RupeSoKey.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/RupeSoKey.imageset/RupeSoKey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/RupeSoKey.imageset/RupeSoKey.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/backspace.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "backspace.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/backspace.imageset/backspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/backspace.imageset/backspace.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "captial.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial.imageset/captial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/captial.imageset/captial.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "captial1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial1.imageset/captial1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/captial1.imageset/captial1.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "captial2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/captial2.imageset/captial2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/captial2.imageset/captial2.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/globe.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "globe.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Assets.xcassets/globe.imageset/globe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/penumutchuprasad/CustKeyboardTutorial/77b74b5eff703f6c25fd7c778f77579b9c308088/SecNinjazKeyboard/Assets.xcassets/globe.imageset/globe.png
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/SecNinjazKeyboard/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/SecNinjazKeyboard/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SecNinjazKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController, UITextFieldDelegate {
12 |
13 |
14 |
15 |
16 | @IBOutlet weak var searchTF: UITextField!
17 | @IBOutlet weak var doneTF: UITextField!
18 | @IBOutlet weak var nextTF: UITextField!
19 | @IBOutlet weak var defTF: UITextField!
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | override func viewDidLoad() {
29 | super.viewDidLoad()
30 |
31 | searchTF.delegate = self
32 | doneTF.delegate = self
33 | nextTF.delegate = self
34 | defTF.delegate = self
35 | searchTF.enablesReturnKeyAutomatically = true
36 |
37 | }
38 |
39 |
40 |
41 |
42 | func textFieldShouldReturn(_ textField: UITextField) -> Bool {
43 |
44 | if textField == searchTF {
45 |
46 | if (textField.text?.count)! >= 3 {
47 | textField.enablesReturnKeyAutomatically = false
48 | }
49 |
50 | }
51 |
52 | switch textField {
53 | case searchTF:
54 | textField.backgroundColor = .cyan
55 | case doneTF:
56 | returnAction()
57 | case nextTF:
58 | textField.backgroundColor = .green
59 | default:
60 | textField.backgroundColor = .magenta
61 | }
62 |
63 |
64 |
65 | return true
66 | }
67 |
68 |
69 |
70 |
71 | func returnAction() {
72 |
73 | print("Configure The Return Action Here...")
74 | resignFirstResponder()
75 | self.view.backgroundColor = .blue
76 | self.view.endEditing(true)
77 |
78 | }
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/View/KeyboardButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // KeyboardButton.swift
3 | // SecNinjazKeyboard
4 | //
5 | // Created by Leela Prasad on 30/04/18.
6 | // Copyright © 2018 Leela Prasad. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class KeyboardButton: UIButton {
12 |
13 | var defaultBackgroundColor: UIColor = .white
14 | var highlightBackgroundColor: UIColor = .lightGray
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | commonInit()
19 | }
20 |
21 | required init?(coder aDecoder: NSCoder) {
22 | super.init(coder: aDecoder)
23 | commonInit()
24 | }
25 |
26 | override func layoutSubviews() {
27 | super.layoutSubviews()
28 | backgroundColor = isHighlighted ? highlightBackgroundColor : defaultBackgroundColor
29 | }
30 |
31 |
32 | }
33 |
34 |
35 | // MARK: - Private Methods
36 | private extension KeyboardButton {
37 | func commonInit() {
38 | layer.cornerRadius = 5.0
39 | layer.masksToBounds = false
40 | layer.shadowOffset = CGSize(width: 0, height: 1.0)
41 | layer.shadowRadius = 0.0
42 | layer.shadowOpacity = 0.35
43 | }
44 | }
45 |
--------------------------------------------------------------------------------