├── 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 | --------------------------------------------------------------------------------