) {
9 | guard let urlContext = URLContexts.first else { return }
10 | do {
11 | let importedMap = try FileStorage().copyFile(at: urlContext.url)
12 | // present imported content
13 | guard let windowScene = (scene as? UIWindowScene) else { return }
14 | self.window = UIWindow(windowScene: windowScene)
15 |
16 | guard let rootVC = UIStoryboard(name: "Home", bundle: nil).instantiateViewController(identifier: "HomeViewController") as? HomeViewController else { return }
17 | let rootNC = UINavigationController(rootViewController: rootVC)
18 | rootNC.navigationBar.topItem?.title = " "
19 | self.window?.rootViewController = rootNC
20 | self.window?.makeKeyAndVisible()
21 |
22 | guard let mapVC = UIStoryboard(name: "Home", bundle: nil).instantiateViewController(withIdentifier: "MapViewController") as? MapViewController else { return }
23 | let state = importedMap.state
24 | mapVC.mapFile = importedMap
25 | mapVC.state = state
26 |
27 | if state == .locked {
28 | let context = LAContext()
29 | context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Protect with Touch ID") { success, error in
30 | if success {
31 | //show locked file
32 | DispatchQueue.main.async {
33 | rootNC.pushViewController(mapVC, animated: true)
34 | }
35 | } else {
36 | ErrorReporting.showMessage(title: "Error", message: "This file is private! ❌")
37 | }
38 | }
39 | } else {
40 | rootNC.pushViewController(mapVC, animated: true)
41 | }
42 | } catch {
43 | ErrorReporting.showMessage(title: "Error", message: "Import unsuccessful")
44 | }
45 | }
46 |
47 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
48 | self.scene(scene, openURLContexts: connectionOptions.urlContexts)
49 | }
50 |
51 | func sceneDidDisconnect(_ scene: UIScene) {
52 | // Called as the scene is being released by the system.
53 | // This occurs shortly after the scene enters the background, or when its session is discarded.
54 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
55 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
56 | }
57 |
58 | func sceneDidBecomeActive(_ scene: UIScene) {
59 | // Called when the scene has moved from an inactive state to an active state.
60 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
61 | hidePrivacyProtectionWindow()
62 | }
63 |
64 | func sceneWillResignActive(_ scene: UIScene) {
65 | // Called when the scene will move from an active state to an inactive state.
66 | // This may occur due to temporary interruptions (ex. an incoming phone call).
67 | if UserDefaults.standard.bool(forKey: String.isFileLocked) {
68 | showPrivacyProtectionWindow()
69 | }
70 | }
71 |
72 | func sceneWillEnterForeground(_ scene: UIScene) {
73 | // Called as the scene transitions from the background to the foreground.
74 | // Use this method to undo the changes made on entering the background.
75 | hidePrivacyProtectionWindow()
76 | }
77 |
78 | func sceneDidEnterBackground(_ scene: UIScene) {
79 | // Called as the scene transitions from the foreground to the background.
80 | // Use this method to save data, release shared resources, and store enough scene-specific state information
81 | // to restore the scene back to its current state.
82 | if UserDefaults.standard.bool(forKey: String.isFileLocked) {
83 | showPrivacyProtectionWindow()
84 | }
85 | }
86 |
87 | // MARK: Privacy Protection
88 | private var privacyProtectionWindow: UIWindow?
89 |
90 | private func showPrivacyProtectionWindow() {
91 | guard let windowScene = self.window?.windowScene else {
92 | return
93 | }
94 | privacyProtectionWindow = UIWindow(windowScene: windowScene)
95 | privacyProtectionWindow?.windowLevel = .alert + 1
96 | privacyProtectionWindow?.makeKeyAndVisible()
97 |
98 | let blurEffect = UIBlurEffect(style: .light)
99 | let blurEffectView = UIVisualEffectView(effect: blurEffect)
100 | blurEffectView.frame = window!.frame
101 | blurEffectView.tag = 1221
102 | privacyProtectionWindow?.addSubview(blurEffectView)
103 | }
104 |
105 | private func hidePrivacyProtectionWindow() {
106 | privacyProtectionWindow?.isHidden = true
107 | privacyProtectionWindow = nil
108 | privacyProtectionWindow?.viewWithTag(1221)?.removeFromSuperview()
109 | }
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/MindMap/Services/Storage/FileStorage.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | class FileStorage {
4 |
5 | // MARK: Stored properties
6 | private let fileManager: FileManager
7 |
8 | // MARK: Initialize
9 | init(fileManager: FileManager = FileManager.default) {
10 | self.fileManager = fileManager
11 | }
12 |
13 | // MARK: Functions
14 | func documentDirectoryPath(_ appendingPath: String) -> URL {
15 | guard let url = self.fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
16 | fatalError("\(#function) `documentDirectory` not found")
17 | }
18 | return url.appendingPathComponent(appendingPath)
19 | }
20 |
21 | func getFile(atPath path: String) throws -> Data {
22 | let url = self.documentDirectoryPath(path)
23 | return try Data(contentsOf: url, options: .mappedIfSafe)
24 | }
25 |
26 | func writeFile(_ data: Data, atPath path: String) throws {
27 | let url = self.documentDirectoryPath(path)
28 | try data.write(to: url)
29 | }
30 |
31 | func deleteFile(atPath path: String) throws {
32 | let url = self.documentDirectoryPath(path)
33 | try self.fileManager.removeItem(at: url)
34 | }
35 |
36 | func copyFile(at url: URL) throws -> MapFile {
37 | let encodedMapFile = try Data(contentsOf: url, options: .mappedIfSafe)
38 | // import file
39 | let mapData = try JSONDecoder().decode(MapFile.self, from: encodedMapFile)
40 | try writeFile(encodedMapFile, atPath: "\(mapData.rootNode.name)\(String.mmdExtension)")
41 | return mapData
42 | }
43 |
44 | func getAllFiles(with type: String) -> [String] {
45 | let directory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
46 | if let urlArray = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: [.contentModificationDateKey], options:.skipsHiddenFiles) {
47 | return urlArray.map { url in
48 | (url.lastPathComponent, (try? url.resourceValues(forKeys: [.contentModificationDateKey]))?.contentModificationDate ?? Date.distantPast)
49 | }.filter({ $0.0.hasSuffix(type)}).map { $0.0 }
50 | } else {
51 | return [String]()
52 | }
53 | }
54 |
55 | func getRecentFiles(with type: String) -> [String] {
56 | let directory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
57 | if let urlArray = try? FileManager.default.contentsOfDirectory(at: directory,includingPropertiesForKeys: [.contentModificationDateKey], options:.skipsHiddenFiles) {
58 | return urlArray.map { url in
59 | (url.lastPathComponent, (try? url.resourceValues(forKeys: [.contentModificationDateKey]))?.contentModificationDate ?? Date.distantPast)
60 | }.filter({ $0.0.hasSuffix(type)})
61 | .sorted(by: { $0.1 > $1.1 })
62 | .map { $0.0 }
63 | } else {
64 | return [String]()
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/MindMap/View/AlertView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | protocol AlertViewDelegate: AnyObject {
4 | func addNode(name: String)
5 | func closeAlert()
6 | }
7 |
8 | class AlertView: UIView {
9 |
10 | let alertHeight = 150.0
11 |
12 | private var backgroundView = { () -> UIView in
13 | let container = UIView()
14 | container.translatesAutoresizingMaskIntoConstraints = false
15 | container.backgroundColor = UIColor.black.withAlphaComponent(0.3)
16 | return container
17 | }()
18 |
19 | private var containerView = { () -> UIView in
20 | let container = UIView()
21 | container.translatesAutoresizingMaskIntoConstraints = false
22 | container.backgroundColor = UIColor.backgroundViolet
23 | container.layer.cornerRadius = 8
24 | return container
25 | }()
26 |
27 | private lazy var stackView = { () -> UIStackView in
28 | let stackView = UIStackView(arrangedSubviews: [textField, addButtonContainer])
29 | stackView.translatesAutoresizingMaskIntoConstraints = false
30 | stackView.axis = .horizontal
31 | stackView.alignment = .fill
32 | stackView.distribution = .fill
33 | stackView.backgroundColor = .clear
34 | stackView.spacing = 8.0
35 | return stackView
36 | }()
37 |
38 | private var titleLabel = { () -> UILabel in
39 | let label = UILabel()
40 | label.text = "Create your map 💡"
41 | label.numberOfLines = 0
42 | label.lineBreakMode = .byWordWrapping
43 | label.textAlignment = .center
44 | label.textColor = UIColor.white
45 | label.translatesAutoresizingMaskIntoConstraints = false
46 | return label
47 | }()
48 |
49 | private var errorLabel = { () -> UILabel in
50 | let label = UILabel()
51 | label.text = " "
52 | label.textAlignment = .center
53 | label.font = .systemFont(ofSize: 10)
54 | label.textColor = UIColor.error
55 | label.translatesAutoresizingMaskIntoConstraints = false
56 | return label
57 | }()
58 |
59 | private var textField = { () -> CustomRoundedTextField in
60 | let textfield = CustomRoundedTextField()
61 | textfield.textColor = .white
62 | textfield.attributedPlaceholder = NSAttributedString(string: "Your idea...", attributes: [NSAttributedString.Key.foregroundColor: UIColor.regularLight])
63 | textfield.translatesAutoresizingMaskIntoConstraints = false
64 | return textfield
65 | }()
66 |
67 | private var addButtonContainer = { () -> UIView in
68 | let container = UIView()
69 | container.translatesAutoresizingMaskIntoConstraints = false
70 | return container
71 | }()
72 |
73 | private var addButton = { () -> UIButton in
74 | let button = UIButton()
75 | button.setImage(UIImage(named: "send"), for: .normal)
76 | button.translatesAutoresizingMaskIntoConstraints = false
77 | button.addTarget(self, action: #selector(addButtonDidTap), for: .touchUpInside)
78 | return button
79 | }()
80 |
81 | private var closeButton = { () -> UIButton in
82 | let button = UIButton()
83 | button.setImage(UIImage(named: "close"), for: .normal)
84 | button.translatesAutoresizingMaskIntoConstraints = false
85 | button.addTarget(self, action: #selector(closeButtonDidTap), for: .touchUpInside)
86 | return button
87 | }()
88 |
89 | weak var delegate: AlertViewDelegate?
90 |
91 | // MARK: Initialize
92 | override init(frame: CGRect) {
93 | super.init(frame: frame)
94 |
95 | configureUI()
96 | }
97 |
98 | required init?(coder: NSCoder) {
99 | fatalError("init(coder:) has not been implemented")
100 | }
101 |
102 | func configureUI() {
103 | // adding shadow
104 | layer.shadowColor = UIColor.white.cgColor
105 | layer.shadowOpacity = 0.5
106 | layer.shadowOffset = .zero
107 | layer.shadowRadius = 4
108 |
109 | // adding subviews
110 | addSubview(backgroundView)
111 | addButtonContainer.addSubview(addButton)
112 | backgroundView.addSubview(containerView)
113 |
114 | containerView.addSubview(titleLabel)
115 | containerView.addSubview(errorLabel)
116 | containerView.addSubview(stackView)
117 | containerView.addSubview(closeButton)
118 |
119 | setupConstraints()
120 | }
121 |
122 | @objc func addButtonDidTap() {
123 | addButton.rotate()
124 | // validating map's name
125 | if let text = textField.text, !text.isEmpty, !text.trimmingCharacters(in: .whitespaces).isEmpty {
126 | if mapWithThisNameExist(name: text) {
127 | shakeTextField()
128 | errorLabel.text = "This map already exist"
129 | } else {
130 | textField.text = ""
131 | errorLabel.text = ""
132 | delegate?.addNode(name: text)
133 | }
134 | } else {
135 | shakeTextField()
136 | errorLabel.text = "Map name shouldn't be empty"
137 | }
138 | }
139 |
140 | func mapWithThisNameExist(name: String) -> Bool {
141 | do {
142 | let _ = try FileStorage().getFile(atPath: "\(name)\(String.mmdExtension)")
143 | return true
144 | } catch {
145 | return false
146 | }
147 | }
148 |
149 |
150 | @objc func closeButtonDidTap() {
151 | textField.text = ""
152 | delegate?.closeAlert()
153 | }
154 |
155 | private func shakeTextField() {
156 | let midX = textField.center.x
157 | let midY = textField.center.y
158 | let animation = CABasicAnimation(keyPath: "position")
159 | animation.duration = 0.06
160 | animation.repeatCount = 3
161 | animation.autoreverses = true
162 | animation.fromValue = CGPoint(x: midX - 6, y: midY)
163 | animation.toValue = CGPoint(x: midX + 6, y: midY)
164 | textField.layer.add(animation, forKey: "position")
165 | }
166 |
167 | // MARK: Constraints
168 | private func setupConstraints() {
169 | //background view
170 | backgroundView.topAnchor.constraint(equalTo: topAnchor).isActive = true
171 | backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
172 | backgroundView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
173 | backgroundView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
174 |
175 | //container View
176 | containerView.centerXAnchor.constraint(equalTo: backgroundView.centerXAnchor).isActive = true
177 | containerView.centerYAnchor.constraint(equalTo: backgroundView.centerYAnchor).isActive = true
178 | containerView.heightAnchor.constraint(equalToConstant: alertHeight).isActive = true
179 |
180 | // add button
181 | addButtonContainer.widthAnchor.constraint(equalToConstant: 30.0).isActive = true
182 | addButton.leftAnchor.constraint(equalTo: addButtonContainer.leftAnchor).isActive = true
183 | addButton.centerYAnchor.constraint(equalTo: addButtonContainer.centerYAnchor).isActive = true
184 | addButton.widthAnchor.constraint(equalToConstant: 30.0).isActive = true
185 | addButton.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
186 |
187 | // title label
188 | titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16).isActive = true
189 | titleLabel.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 16).isActive = true
190 | titleLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -16).isActive = true
191 |
192 | // error label
193 | errorLabel.topAnchor.constraint(equalTo: titleLabel.topAnchor, constant: 24).isActive = true
194 | errorLabel.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 16).isActive = true
195 | errorLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -16).isActive = true
196 |
197 | // stackView
198 | stackView.topAnchor.constraint(equalTo: errorLabel.bottomAnchor, constant: 24).isActive = true
199 | stackView.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 16).isActive = true
200 | stackView.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -16).isActive = true
201 | stackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -16).isActive = true
202 | stackView.widthAnchor.constraint(equalToConstant: 310).isActive = true
203 |
204 | // close button
205 | closeButton.widthAnchor.constraint(equalToConstant: 16.0).isActive = true
206 | closeButton.heightAnchor.constraint(equalToConstant: 16.0).isActive = true
207 | closeButton.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -16).isActive = true
208 | closeButton.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor).isActive = true
209 | }
210 |
211 | }
212 |
213 |
--------------------------------------------------------------------------------
/MindMap/View/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 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/MindMap/View/CustomTextField.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | class CustomRoundedTextField: UITextField {
4 |
5 | // MARK: Initialize
6 | override init(frame: CGRect) {
7 | super.init(frame: frame)
8 | sharedInit()
9 | }
10 |
11 | required init?(coder aDecoder: NSCoder) {
12 | super.init(coder: aDecoder)
13 | sharedInit()
14 | }
15 |
16 | // MARK: Functions
17 | private func sharedInit() {
18 | borderStyle = .none
19 |
20 | backgroundColor = UIColor.regularLight.withAlphaComponent(0.1)
21 | layer.borderColor = UIColor.regularLight.cgColor
22 | layer.borderWidth = 0.5
23 | layer.cornerRadius = 4
24 | }
25 |
26 | override var intrinsicContentSize: CGSize {
27 | return CGSize(width: UIView.noIntrinsicMetric, height: 50)
28 | }
29 |
30 | override func textRect(forBounds bounds: CGRect) -> CGRect {
31 | return super.textRect(forBounds: bounds).insetBy(dx: 8, dy: 0)
32 | }
33 |
34 | override func editingRect(forBounds bounds: CGRect) -> CGRect {
35 | return super.editingRect(forBounds: bounds).insetBy(dx: 8, dy: 0)
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/MindMap/View/HomePageCollectionViewCell/FileCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | enum MapState: Codable {
4 | case locked
5 | case regular
6 | }
7 |
8 | protocol FileCollectionViewCellDelegate: AnyObject {
9 | func deleteMap(with name: String)
10 | func lockMap(state: MapState, with name: String)
11 | }
12 |
13 | class FileCollectionViewCell: UICollectionViewCell {
14 |
15 | var mapName: String?
16 | var state: MapState?
17 | weak var delegate: FileCollectionViewCellDelegate?
18 |
19 | @IBOutlet weak var containerView: UIView!
20 | @IBOutlet weak var previewImageView: UIImageView!
21 | @IBOutlet weak var nameButton: UIButton!
22 | @IBOutlet weak var editView: UIView!
23 | @IBOutlet weak var lockButton: UIButton!
24 | @IBOutlet weak var stateImageView: UIImageView!
25 |
26 | func configureUI(name: String, image: UIImage, state: MapState) {
27 | mapName = name
28 | self.state = state
29 | containerView.backgroundColor = UIColor.backgroundLight
30 |
31 | // adding shadow
32 | containerView.layer.shadowColor = UIColor.white.cgColor
33 | containerView.layer.shadowOpacity = 0.5
34 | containerView.layer.shadowOffset = .zero
35 | containerView.layer.shadowRadius = 4
36 |
37 | nameButton.setTitle(name, for: .normal)
38 | editView.isHidden = true
39 |
40 | stateImageView.isHidden = state == .regular ? true : false
41 | previewImageView.image = state == .regular ? image : UIImage(named: "folder")
42 | lockButton.setTitle(state == .regular ? "Lock map" : "Unlock map", for: .normal)
43 | }
44 |
45 | @IBAction func editDidTap(_ sender: Any) {
46 | UIView.transition(with: self.editView, duration: 0.4, options: .transitionCrossDissolve, animations: {
47 | self.editView.isHidden = !self.editView.isHidden
48 | })
49 | }
50 |
51 | @IBAction func deleteDidTap(_ sender: Any) {
52 | if let mapName = mapName {
53 | delegate?.deleteMap(with: mapName)
54 | editView.isHidden = !editView.isHidden
55 | }
56 | }
57 |
58 | @IBAction func lockDidTap(_ sender: Any) {
59 | state = state == .regular ? .locked : .regular
60 | if let mapName = mapName, let state = state {
61 | delegate?.lockMap(state: state, with: mapName)
62 | editView.isHidden = !editView.isHidden
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/MindMap/View/HomePageCollectionViewCell/HeaderCollectionView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | class HeaderCollectionView: UICollectionReusableView {
4 |
5 | @IBOutlet weak var titleLabel: UILabel!
6 |
7 | func configure(title: String) {
8 | titleLabel.text = title
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/MindMap/View/NodeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MegaView.swift
3 | // Mega Mindmap
4 | //
5 | // Created by Markus Karlsson on 2019-04-10.
6 | // Copyright © 2019 The App Factory AB. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum Direction {
12 | case top
13 | case bottom
14 | case left
15 | case right
16 | }
17 |
18 | protocol NodeViewDelegate {
19 | func addChildNode(parentNodeView: NodeView, at location: CGPoint)
20 | func didEditText(view: NodeView, text: String)
21 | func delete(view: NodeView)
22 | func expandView(direction: Direction)
23 | }
24 |
25 | class NodeView: UIView {
26 | // MARK: Stored properties
27 | var delegate: NodeViewDelegate?
28 | var splines = [SplineView]()
29 | var node: Node?
30 | var isRoot: Bool?
31 |
32 | let viewHeight: CGFloat = 120
33 | let minWidth: CGFloat = 120
34 | let maxWidth: CGFloat = 350
35 | let padding: CGFloat = 16
36 |
37 | lazy var textView: UITextView = {
38 | let label = UITextView()
39 | label.textAlignment = NSTextAlignment.center
40 | label.textColor = .lightGray
41 | label.text = "Type your idea here..."
42 | label.isEditable = true
43 | label.textColor = UIColor.white
44 | label.delegate = self
45 | label.backgroundColor = .clear
46 | label.font = .systemFont(ofSize: 16)
47 | label.autocorrectionType = .no
48 | return label
49 | }()
50 |
51 | // MARK: Initialize
52 | init(at position: CGPoint, name: String, node: Node, isRoot: Bool) {
53 | let size: CGFloat = 120
54 | let frame = CGRect(x: position.x - size / 2, y: position.y - size / 2, width: size, height: size)
55 | super.init(frame: frame)
56 |
57 | textView.frame = self.bounds
58 | textView.text = name
59 | addSubview(textView)
60 |
61 | self.node = node
62 | self.isRoot = isRoot
63 |
64 | // adding shadow
65 | layer.shadowColor = UIColor.white.cgColor
66 | layer.shadowOpacity = 0.5
67 | layer.shadowOffset = .zero
68 | layer.shadowRadius = 4
69 |
70 | backgroundColor = UIColor.clear
71 |
72 | // adding child
73 | addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:))))
74 |
75 | // moving view
76 | let pan = UIPanGestureRecognizer(target: self, action: #selector(twoFingerPan(_:)))
77 | pan.minimumNumberOfTouches = 2
78 | pan.maximumNumberOfTouches = 2
79 | pan.delaysTouchesBegan = true
80 | addGestureRecognizer(pan)
81 |
82 | // contextMenu (editing + removing)
83 | let interaction = UIContextMenuInteraction(delegate: self)
84 | self.addInteraction(interaction)
85 |
86 | update()
87 | }
88 |
89 | required init?(coder aDecoder: NSCoder) {
90 | super.init(coder: aDecoder)
91 | }
92 |
93 | //MARK: - Functions
94 | func delete() {
95 | DispatchQueue.main.async {
96 | self.splines.forEach({ $0.removeFromSuperview() })
97 | self.removeFromSuperview()
98 | }
99 | }
100 |
101 | func update() {
102 | let textSize = textView.sizeThatFits(CGSize(width: maxWidth - 2 * padding, height: viewHeight - 2 * padding))
103 | let width = max(minWidth, textSize.width + 2 * padding)
104 |
105 | let labelSize = textView.getSize(constrainedWidth: width)
106 |
107 | textView.frame = CGRect(x: padding, y: padding, width: width - 2 * padding, height: labelSize.height )
108 | frame = CGRect(x: center.x - width / 2, y: frame.origin.y, width: width, height: labelSize.height + 2 * padding)
109 |
110 | setNeedsDisplay()
111 | }
112 |
113 | override func draw(_ rect: CGRect) {
114 | let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.allCorners], cornerRadii: CGSize(width: 8, height: 8))
115 | UIColor.backgroundViolet.setFill()
116 | path.fill()
117 | }
118 |
119 | @objc func didPan(gesture: UIPanGestureRecognizer) {
120 | switch gesture.state {
121 | case.changed:
122 | if let contentView = superview {
123 | needsExpand(location: gesture.location(in: contentView))
124 | }
125 | case .ended:
126 | delegate?.addChildNode(parentNodeView: self, at: gesture.location(in: self.superview))
127 | default:
128 | break
129 | }
130 | }
131 |
132 | @objc func twoFingerPan(_ gesture: UIPanGestureRecognizer) {
133 | // moving view & splines
134 | switch gesture.state {
135 | case .changed:
136 | self.center = gesture.location(in: self.superview)
137 | splines.forEach({ $0.update() })
138 | if let contentView = superview {
139 | needsExpand(location: gesture.location(in: contentView))
140 | }
141 | case .began:
142 | superview?.bringSubviewToFront(self)
143 | default:
144 | break
145 | }
146 | }
147 |
148 | func needsExpand(location: CGPoint) {
149 | if let contentView = superview {
150 | if contentView.frame.width - location.x <= 100 {
151 | delegate?.expandView(direction: .right)
152 | }
153 |
154 | if location.x <= 100 {
155 | delegate?.expandView(direction: .left)
156 | }
157 |
158 | if contentView.frame.height - location.y <= 100 {
159 | delegate?.expandView(direction: .bottom)
160 | }
161 |
162 | if location.y <= 100 {
163 | delegate?.expandView(direction: .top)
164 | }
165 | }
166 | }
167 | }
168 |
169 | //MARK: - UIContextMenuInteractionDelegate
170 | extension NodeView: UIContextMenuInteractionDelegate {
171 |
172 | func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
173 | let removeIcon = UIImage(named: "delete")
174 | let editIcon = UIImage(named: "edit")
175 |
176 | return UIContextMenuConfiguration(identifier: "id" as NSCopying, previewProvider: nil, actionProvider: { _ in
177 | let editAction = UIAction(title: "Edit", image: editIcon, identifier: nil, discoverabilityTitle: nil) { _ in
178 | self.textView.becomeFirstResponder()
179 | }
180 |
181 | let removeAction = UIAction(title: "Remove", image: removeIcon, identifier: nil, discoverabilityTitle: nil, attributes: .destructive, handler: { _ in
182 | self.delegate?.delete(view: self)
183 | })
184 |
185 | return UIMenu(title: "Edit", image: nil, options: [.displayInline], children: [editAction, removeAction])
186 | })
187 | }
188 |
189 |
190 | //MARK: - Stolen from https://kylebashour.com/posts/context-menu-guide
191 | // improved UI behaviour
192 | private func makeTargetedPreview(for configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
193 | let visiblePath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 16)
194 | let parameters = UIPreviewParameters()
195 | parameters.visiblePath = visiblePath
196 | parameters.backgroundColor = .clear
197 | return UITargetedPreview(view: self, parameters: parameters)
198 | }
199 |
200 | func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
201 | return self.makeTargetedPreview(for: configuration)
202 | }
203 |
204 | func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForDismissingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
205 | return self.makeTargetedPreview(for: configuration)
206 | }
207 | }
208 |
209 | //MARK: - UITextViewDelegate
210 | extension NodeView: UITextViewDelegate {
211 | func textViewDidBeginEditing(_ textView: UITextView) {
212 | if textView.textColor != .white && textView.isFirstResponder {
213 | textView.text = nil
214 | textView.textColor = .white
215 | }
216 | }
217 |
218 | func textViewDidEndEditing(_ textView: UITextView) {
219 | if textView.text.isEmpty || textView.text == "" {
220 | textView.textColor = .lightGray
221 | textView.text = "Type your idea here..."
222 | }
223 | update()
224 | delegate?.didEditText(view: self, text: textView.text)
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/MindMap/View/SplineView.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | class SplineView: UIView {
4 |
5 | // MARK: Stored properties
6 | var parentView: NodeView?
7 | var childView: NodeView?
8 |
9 | var color: UIColor = .white
10 |
11 | // MARK: Initialize
12 | init(parentView: NodeView, childView: NodeView, color: UIColor) {
13 | super.init(frame: CGRect.zero)
14 |
15 | self.parentView = parentView
16 | self.childView = childView
17 | self.color = color
18 |
19 | backgroundColor = UIColor.clear
20 | }
21 |
22 | required init?(coder aDecoder: NSCoder) {
23 | super.init(coder: aDecoder)
24 | }
25 |
26 | // MARK: Functions
27 | func update() {
28 | if let parentView = parentView, let childView = childView {
29 | self.frame = parentView.frame.union(childView.frame)
30 | self.setNeedsDisplay()
31 | }
32 | }
33 |
34 | override func draw(_ rect: CGRect) {
35 | let path = UIBezierPath()
36 | path.lineWidth = 1.5
37 |
38 | self.color.setStroke()
39 |
40 | if let parentView = parentView, let childView = childView {
41 | let parentCenter = CGPoint(x: parentView.center.x - frame.origin.x, y: parentView.center.y - frame.origin.y)
42 | let childCenter = CGPoint(x: childView.center.x - frame.origin.x, y: childView.center.y - frame.origin.y)
43 |
44 | path.move(to: parentCenter)
45 |
46 | let point1 = CGPoint(x: parentCenter.x + (childCenter.x - parentCenter.x) / 2, y: parentCenter.y)
47 | let point2 = CGPoint(x: childCenter.x - (childCenter.x - parentCenter.x) / 2, y: childCenter.y)
48 |
49 | path.addCurve(to: childCenter, controlPoint1: point1, controlPoint2: point2)
50 | path.stroke()
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'MindMap' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for MindMap
9 | pod 'IQKeyboardManagerSwift'
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - IQKeyboardManagerSwift (6.5.6)
3 |
4 | DEPENDENCIES:
5 | - IQKeyboardManagerSwift
6 |
7 | SPEC REPOS:
8 | trunk:
9 | - IQKeyboardManagerSwift
10 |
11 | SPEC CHECKSUMS:
12 | IQKeyboardManagerSwift: c7df9d2deb356c04522f5c4b7b6e4ce4d8ed94fe
13 |
14 | PODFILE CHECKSUM: 9a6633194abfb806a44f4f824f06803bc7123faa
15 |
16 | COCOAPODS: 1.11.2
17 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQNSArray+Sort.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 | import UIKit
26 |
27 | /**
28 | UIView.subviews sorting category.
29 | */
30 | internal extension Array where Element: UIView {
31 |
32 | ///--------------
33 | /// MARK: Sorting
34 | ///--------------
35 |
36 | /**
37 | Returns the array by sorting the UIView's by their tag property.
38 | */
39 | func sortedArrayByTag() -> [Element] {
40 |
41 | return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
42 |
43 | return (obj1.tag < obj2.tag)
44 | })
45 | }
46 |
47 | /**
48 | Returns the array by sorting the UIView's by their tag property.
49 | */
50 | func sortedArrayByPosition() -> [Element] {
51 |
52 | return sorted(by: { (obj1: Element, obj2: Element) -> Bool in
53 | if obj1.frame.minY != obj2.frame.minY {
54 | return obj1.frame.minY < obj2.frame.minY
55 | } else {
56 | return obj1.frame.minX < obj2.frame.minX
57 | }
58 | })
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQUIScrollView+Additions.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 | import UIKit
26 |
27 | private var kIQShouldIgnoreScrollingAdjustment = "kIQShouldIgnoreScrollingAdjustment"
28 | private var kIQShouldIgnoreContentInsetAdjustment = "kIQShouldIgnoreContentInsetAdjustment"
29 | private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollViewContentOffset"
30 |
31 | @objc public extension UIScrollView {
32 |
33 | /**
34 | If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO.
35 | */
36 | @objc var shouldIgnoreScrollingAdjustment: Bool {
37 | get {
38 |
39 | if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment) as? Bool {
40 | return aValue
41 | } else {
42 | return false
43 | }
44 | }
45 | set(newValue) {
46 | objc_setAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
47 | }
48 | }
49 |
50 | /**
51 | If YES, then scrollview will ignore content inset adjustment (simply not updating it) when keyboard is shown. Default is NO.
52 | */
53 | @objc var shouldIgnoreContentInsetAdjustment: Bool {
54 | get {
55 |
56 | if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment) as? Bool {
57 | return aValue
58 | } else {
59 | return false
60 | }
61 | }
62 | set(newValue) {
63 | objc_setAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
64 | }
65 | }
66 |
67 | /**
68 | To set customized distance from keyboard for textField/textView. Can't be less than zero
69 | */
70 | @objc var shouldRestoreScrollViewContentOffset: Bool {
71 | get {
72 |
73 | if let aValue = objc_getAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset) as? Bool {
74 | return aValue
75 | } else {
76 | return false
77 | }
78 | }
79 | set(newValue) {
80 | objc_setAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
81 | }
82 | }
83 | }
84 |
85 | internal extension UITableView {
86 |
87 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
88 | var previousRow = indexPath.row - 1
89 | var previousSection = indexPath.section
90 |
91 | //Fixing indexPath
92 | if previousRow < 0 {
93 | previousSection -= 1
94 |
95 | if previousSection >= 0 {
96 | previousRow = self.numberOfRows(inSection: previousSection) - 1
97 | }
98 | }
99 |
100 | if previousRow >= 0 && previousSection >= 0 {
101 | return IndexPath(row: previousRow, section: previousSection)
102 | } else {
103 | return nil
104 | }
105 | }
106 | }
107 |
108 | internal extension UICollectionView {
109 |
110 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? {
111 | var previousRow = indexPath.row - 1
112 | var previousSection = indexPath.section
113 |
114 | //Fixing indexPath
115 | if previousRow < 0 {
116 | previousSection -= 1
117 |
118 | if previousSection >= 0 {
119 | previousRow = self.numberOfItems(inSection: previousSection) - 1
120 | }
121 | }
122 |
123 | if previousRow >= 0 && previousSection >= 0 {
124 | return IndexPath(item: previousRow, section: previousSection)
125 | } else {
126 | return nil
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQUITextFieldView+Additions.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 | import UIKit
26 |
27 | /**
28 | Uses default keyboard distance for textField.
29 | */
30 | public let kIQUseDefaultKeyboardDistance = CGFloat.greatestFiniteMagnitude
31 |
32 | private var kIQKeyboardDistanceFromTextField = "kIQKeyboardDistanceFromTextField"
33 | private var kIQKeyboardEnableMode = "kIQKeyboardEnableMode"
34 | private var kIQShouldResignOnTouchOutsideMode = "kIQShouldResignOnTouchOutsideMode"
35 | private var kIQIgnoreSwitchingByNextPrevious = "kIQIgnoreSwitchingByNextPrevious"
36 |
37 | /**
38 | UIView category for managing UITextField/UITextView
39 | */
40 | @objc public extension UIView {
41 |
42 | /**
43 | To set customized distance from keyboard for textField/textView. Can't be less than zero
44 | */
45 | @objc var keyboardDistanceFromTextField: CGFloat {
46 | get {
47 |
48 | if let aValue = objc_getAssociatedObject(self, &kIQKeyboardDistanceFromTextField) as? CGFloat {
49 | return aValue
50 | } else {
51 | return kIQUseDefaultKeyboardDistance
52 | }
53 | }
54 | set(newValue) {
55 | objc_setAssociatedObject(self, &kIQKeyboardDistanceFromTextField, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
56 | }
57 | }
58 |
59 | /**
60 | If shouldIgnoreSwitchingByNextPrevious is true then library will ignore this textField/textView while moving to other textField/textView using keyboard toolbar next previous buttons. Default is false
61 | */
62 | @objc var ignoreSwitchingByNextPrevious: Bool {
63 | get {
64 |
65 | if let aValue = objc_getAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious) as? Bool {
66 | return aValue
67 | } else {
68 | return false
69 | }
70 | }
71 | set(newValue) {
72 | objc_setAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
73 | }
74 | }
75 |
76 | // /**
77 | // Override Enable/disable managing distance between keyboard and textField behaviour for this particular textField.
78 | // */
79 | @objc var enableMode: IQEnableMode {
80 | get {
81 |
82 | if let savedMode = objc_getAssociatedObject(self, &kIQKeyboardEnableMode) as? IQEnableMode {
83 | return savedMode
84 | } else {
85 | return .default
86 | }
87 | }
88 | set(newValue) {
89 | objc_setAssociatedObject(self, &kIQKeyboardEnableMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
90 | }
91 | }
92 |
93 | /**
94 | Override resigns Keyboard on touching outside of UITextField/View behaviour for this particular textField.
95 | */
96 | @objc var shouldResignOnTouchOutsideMode: IQEnableMode {
97 | get {
98 |
99 | if let savedMode = objc_getAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode) as? IQEnableMode {
100 | return savedMode
101 | } else {
102 | return .default
103 | }
104 | }
105 | set(newValue) {
106 | objc_setAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQUIView+Hierarchy.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | /**
27 | UIView hierarchy category.
28 | */
29 | @objc public extension UIView {
30 |
31 | ///----------------------
32 | /// MARK: viewControllers
33 | ///----------------------
34 |
35 | /**
36 | Returns the UIViewController object that manages the receiver.
37 | */
38 | @objc func viewContainingController() -> UIViewController? {
39 |
40 | var nextResponder: UIResponder? = self
41 |
42 | repeat {
43 | nextResponder = nextResponder?.next
44 |
45 | if let viewController = nextResponder as? UIViewController {
46 | return viewController
47 | }
48 |
49 | } while nextResponder != nil
50 |
51 | return nil
52 | }
53 |
54 | /**
55 | Returns the topMost UIViewController object in hierarchy.
56 | */
57 | @objc func topMostController() -> UIViewController? {
58 |
59 | var controllersHierarchy = [UIViewController]()
60 |
61 | if var topController = window?.rootViewController {
62 | controllersHierarchy.append(topController)
63 |
64 | while let presented = topController.presentedViewController {
65 |
66 | topController = presented
67 |
68 | controllersHierarchy.append(presented)
69 | }
70 |
71 | var matchController: UIResponder? = viewContainingController()
72 |
73 | while let mController = matchController as? UIViewController, controllersHierarchy.contains(mController) == false {
74 |
75 | repeat {
76 | matchController = matchController?.next
77 |
78 | } while matchController != nil && matchController is UIViewController == false
79 | }
80 |
81 | return matchController as? UIViewController
82 |
83 | } else {
84 | return viewContainingController()
85 | }
86 | }
87 |
88 | /**
89 | Returns the UIViewController object that is actually the parent of this object. Most of the time it's the viewController object which actually contains it, but result may be different if it's viewController is added as childViewController of another viewController.
90 | */
91 | @objc func parentContainerViewController() -> UIViewController? {
92 |
93 | var matchController = viewContainingController()
94 | var parentContainerViewController: UIViewController?
95 |
96 | if var navController = matchController?.navigationController {
97 |
98 | while let parentNav = navController.navigationController {
99 | navController = parentNav
100 | }
101 |
102 | var parentController: UIViewController = navController
103 |
104 | while let parent = parentController.parent,
105 | (parent.isKind(of: UINavigationController.self) == false &&
106 | parent.isKind(of: UITabBarController.self) == false &&
107 | parent.isKind(of: UISplitViewController.self) == false) {
108 |
109 | parentController = parent
110 | }
111 |
112 | if navController == parentController {
113 | parentContainerViewController = navController.topViewController
114 | } else {
115 | parentContainerViewController = parentController
116 | }
117 | } else if let tabController = matchController?.tabBarController {
118 |
119 | if let navController = tabController.selectedViewController as? UINavigationController {
120 | parentContainerViewController = navController.topViewController
121 | } else {
122 | parentContainerViewController = tabController.selectedViewController
123 | }
124 | } else {
125 | while let parentController = matchController?.parent,
126 | (parentController.isKind(of: UINavigationController.self) == false &&
127 | parentController.isKind(of: UITabBarController.self) == false &&
128 | parentController.isKind(of: UISplitViewController.self) == false) {
129 |
130 | matchController = parentController
131 | }
132 |
133 | parentContainerViewController = matchController
134 | }
135 |
136 | let finalController = parentContainerViewController?.parentIQContainerViewController() ?? parentContainerViewController
137 |
138 | return finalController
139 |
140 | }
141 |
142 | ///-----------------------------------
143 | /// MARK: Superviews/Subviews/Siglings
144 | ///-----------------------------------
145 |
146 | /**
147 | Returns the superView of provided class type.
148 |
149 |
150 | @param classType class type of the object which is to be search in above hierarchy and return
151 |
152 | @param belowView view object in upper hierarchy where method should stop searching and return nil
153 | */
154 | @objc func superviewOfClassType(_ classType: UIView.Type, belowView: UIView? = nil) -> UIView? {
155 |
156 | var superView = superview
157 |
158 | while let unwrappedSuperView = superView {
159 |
160 | if unwrappedSuperView.isKind(of: classType) {
161 |
162 | //If it's UIScrollView, then validating for special cases
163 | if unwrappedSuperView.isKind(of: UIScrollView.self) {
164 |
165 | let classNameString = NSStringFromClass(type(of: unwrappedSuperView.self))
166 |
167 | // If it's not UITableViewWrapperView class, this is internal class which is actually manage in UITableview. The speciality of this class is that it's superview is UITableView.
168 | // If it's not UITableViewCellScrollView class, this is internal class which is actually manage in UITableviewCell. The speciality of this class is that it's superview is UITableViewCell.
169 | //If it's not _UIQueuingScrollView class, actually we validate for _ prefix which usually used by Apple internal classes
170 | if unwrappedSuperView.superview?.isKind(of: UITableView.self) == false &&
171 | unwrappedSuperView.superview?.isKind(of: UITableViewCell.self) == false &&
172 | classNameString.hasPrefix("_") == false {
173 | return superView
174 | }
175 | } else {
176 | return superView
177 | }
178 | } else if unwrappedSuperView == belowView {
179 | return nil
180 | }
181 |
182 | superView = unwrappedSuperView.superview
183 | }
184 |
185 | return nil
186 | }
187 |
188 | /**
189 | Returns all siblings of the receiver which canBecomeFirstResponder.
190 | */
191 | internal func responderSiblings() -> [UIView] {
192 |
193 | //Array of (UITextField/UITextView's).
194 | var tempTextFields = [UIView]()
195 |
196 | // Getting all siblings
197 | if let siblings = superview?.subviews {
198 |
199 | for textField in siblings {
200 |
201 | if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
202 | tempTextFields.append(textField)
203 | }
204 | }
205 | }
206 |
207 | return tempTextFields
208 | }
209 |
210 | /**
211 | Returns all deep subViews of the receiver which canBecomeFirstResponder.
212 | */
213 | internal func deepResponderViews() -> [UIView] {
214 |
215 | //Array of (UITextField/UITextView's).
216 | var textfields = [UIView]()
217 |
218 | for textField in subviews {
219 |
220 | if (textField == self || textField.ignoreSwitchingByNextPrevious == false) && textField.IQcanBecomeFirstResponder() == true {
221 | textfields.append(textField)
222 | }
223 | //Sometimes there are hidden or disabled views and textField inside them still recorded, so we added some more validations here (Bug ID: #458)
224 | //Uncommented else (Bug ID: #625)
225 | else if textField.subviews.count != 0 && isUserInteractionEnabled == true && isHidden == false && alpha != 0.0 {
226 | for deepView in textField.deepResponderViews() {
227 | textfields.append(deepView)
228 | }
229 | }
230 | }
231 |
232 | //subviews are returning in opposite order. Sorting according the frames 'y'.
233 | return textfields.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
234 |
235 | let frame1 = view1.convert(view1.bounds, to: self)
236 | let frame2 = view2.convert(view2.bounds, to: self)
237 |
238 | if frame1.minY != frame2.minY {
239 | return frame1.minY < frame2.minY
240 | } else {
241 | return frame1.minX < frame2.minX
242 | }
243 | })
244 | }
245 |
246 | private func IQcanBecomeFirstResponder() -> Bool {
247 |
248 | var IQcanBecomeFirstResponder = false
249 |
250 | if self.conforms(to: UITextInput.self) {
251 | // Setting toolbar to keyboard.
252 | if let textView = self as? UITextView {
253 | IQcanBecomeFirstResponder = textView.isEditable
254 | } else if let textField = self as? UITextField {
255 | IQcanBecomeFirstResponder = textField.isEnabled
256 | }
257 | }
258 |
259 | if IQcanBecomeFirstResponder == true {
260 | IQcanBecomeFirstResponder = isUserInteractionEnabled == true && isHidden == false && alpha != 0.0 && isAlertViewTextField() == false && textFieldSearchBar() == nil
261 | }
262 |
263 | return IQcanBecomeFirstResponder
264 | }
265 |
266 | ///-------------------------
267 | /// MARK: Special TextFields
268 | ///-------------------------
269 |
270 | /**
271 | Returns searchBar if receiver object is UISearchBarTextField, otherwise return nil.
272 | */
273 | internal func textFieldSearchBar() -> UISearchBar? {
274 |
275 | var responder: UIResponder? = self.next
276 |
277 | while let bar = responder {
278 |
279 | if let searchBar = bar as? UISearchBar {
280 | return searchBar
281 | } else if bar is UIViewController {
282 | break
283 | }
284 |
285 | responder = bar.next
286 | }
287 |
288 | return nil
289 | }
290 |
291 | /**
292 | Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO.
293 | */
294 | internal func isAlertViewTextField() -> Bool {
295 |
296 | var alertViewController: UIResponder? = viewContainingController()
297 |
298 | var isAlertViewTextField = false
299 |
300 | while let controller = alertViewController, isAlertViewTextField == false {
301 |
302 | if controller.isKind(of: UIAlertController.self) {
303 | isAlertViewTextField = true
304 | break
305 | }
306 |
307 | alertViewController = controller.next
308 | }
309 |
310 | return isAlertViewTextField
311 | }
312 |
313 | private func depth() -> Int {
314 | var depth: Int = 0
315 |
316 | if let superView = superview {
317 | depth = superView.depth()+1
318 | }
319 |
320 | return depth
321 | }
322 |
323 | }
324 |
325 | extension NSObject {
326 |
327 | internal func _IQDescription() -> String {
328 | return "<\(self) \(Unmanaged.passUnretained(self).toOpaque())>"
329 | }
330 | }
331 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQUIViewController+Additions.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | private var kIQLayoutGuideConstraint = "kIQLayoutGuideConstraint"
27 |
28 | @objc public extension UIViewController {
29 |
30 | /**
31 | This method is provided to override by viewController's if the library lifts a viewController which you doesn't want to lift . This may happen if you have implemented side menu feature in your app and the library try to lift the side menu controller. Overriding this method in side menu class to return correct controller should fix the problem.
32 | */
33 | func parentIQContainerViewController() -> UIViewController? {
34 | return self
35 | }
36 |
37 | /**
38 | To set customized distance from keyboard for textField/textView. Can't be less than zero
39 |
40 | @deprecated Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview
41 | */
42 | @available(*, deprecated, message: "Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview.")
43 | @IBOutlet @objc var IQLayoutGuideConstraint: NSLayoutConstraint? {
44 | get {
45 |
46 | return objc_getAssociatedObject(self, &kIQLayoutGuideConstraint) as? NSLayoutConstraint
47 | }
48 |
49 | set(newValue) {
50 | objc_setAssociatedObject(self, &kIQLayoutGuideConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQKeyboardManagerConstants.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 |
26 | ///-----------------------------------
27 | /// MARK: IQAutoToolbarManageBehaviour
28 | ///-----------------------------------
29 |
30 | /**
31 | `IQAutoToolbarBySubviews`
32 | Creates Toolbar according to subview's hirarchy of Textfield's in view.
33 |
34 | `IQAutoToolbarByTag`
35 | Creates Toolbar according to tag property of TextField's.
36 |
37 | `IQAutoToolbarByPosition`
38 | Creates Toolbar according to the y,x position of textField in it's superview coordinate.
39 | */
40 | @objc public enum IQAutoToolbarManageBehaviour: Int {
41 | case bySubviews
42 | case byTag
43 | case byPosition
44 | }
45 |
46 | /**
47 | `IQPreviousNextDisplayModeDefault`
48 | Show NextPrevious when there are more than 1 textField otherwise hide.
49 |
50 | `IQPreviousNextDisplayModeAlwaysHide`
51 | Do not show NextPrevious buttons in any case.
52 |
53 | `IQPreviousNextDisplayModeAlwaysShow`
54 | Always show nextPrevious buttons, if there are more than 1 textField then both buttons will be visible but will be shown as disabled.
55 | */
56 | @objc public enum IQPreviousNextDisplayMode: Int {
57 | case `default`
58 | case alwaysHide
59 | case alwaysShow
60 | }
61 |
62 | /**
63 | `IQEnableModeDefault`
64 | Pick default settings.
65 |
66 | `IQEnableModeEnabled`
67 | setting is enabled.
68 |
69 | `IQEnableModeDisabled`
70 | setting is disabled.
71 | */
72 | @objc public enum IQEnableMode: Int {
73 | case `default`
74 | case enabled
75 | case disabled
76 | }
77 |
78 | /*
79 | /---------------------------------------------------------------------------------------------------\
80 | \---------------------------------------------------------------------------------------------------/
81 | | iOS Notification Mechanism |
82 | /---------------------------------------------------------------------------------------------------\
83 | \---------------------------------------------------------------------------------------------------/
84 |
85 | ------------------------------------------------------------
86 | When UITextField become first responder
87 | ------------------------------------------------------------
88 | - UITextFieldTextDidBeginEditingNotification (UITextField)
89 | - UIKeyboardWillShowNotification
90 | - UIKeyboardDidShowNotification
91 |
92 | ------------------------------------------------------------
93 | When UITextView become first responder
94 | ------------------------------------------------------------
95 | - UIKeyboardWillShowNotification
96 | - UITextViewTextDidBeginEditingNotification (UITextView)
97 | - UIKeyboardDidShowNotification
98 |
99 | ------------------------------------------------------------
100 | When switching focus from UITextField to another UITextField
101 | ------------------------------------------------------------
102 | - UITextFieldTextDidEndEditingNotification (UITextField1)
103 | - UITextFieldTextDidBeginEditingNotification (UITextField2)
104 | - UIKeyboardWillShowNotification
105 | - UIKeyboardDidShowNotification
106 |
107 | ------------------------------------------------------------
108 | When switching focus from UITextView to another UITextView
109 | ------------------------------------------------------------
110 | - UITextViewTextDidEndEditingNotification: (UITextView1)
111 | - UIKeyboardWillShowNotification
112 | - UITextViewTextDidBeginEditingNotification: (UITextView2)
113 | - UIKeyboardDidShowNotification
114 |
115 | ------------------------------------------------------------
116 | When switching focus from UITextField to UITextView
117 | ------------------------------------------------------------
118 | - UITextFieldTextDidEndEditingNotification (UITextField)
119 | - UIKeyboardWillShowNotification
120 | - UITextViewTextDidBeginEditingNotification (UITextView)
121 | - UIKeyboardDidShowNotification
122 |
123 | ------------------------------------------------------------
124 | When switching focus from UITextView to UITextField
125 | ------------------------------------------------------------
126 | - UITextViewTextDidEndEditingNotification (UITextView)
127 | - UITextFieldTextDidBeginEditingNotification (UITextField)
128 | - UIKeyboardWillShowNotification
129 | - UIKeyboardDidShowNotification
130 |
131 | ------------------------------------------------------------
132 | When opening/closing UIKeyboard Predictive bar
133 | ------------------------------------------------------------
134 | - UIKeyboardWillShowNotification
135 | - UIKeyboardDidShowNotification
136 |
137 | ------------------------------------------------------------
138 | On orientation change
139 | ------------------------------------------------------------
140 | - UIApplicationWillChangeStatusBarOrientationNotification
141 | - UIKeyboardWillHideNotification
142 | - UIKeyboardDidHideNotification
143 | - UIApplicationDidChangeStatusBarOrientationNotification
144 | - UIKeyboardWillShowNotification
145 | - UIKeyboardDidShowNotification
146 | - UIKeyboardWillShowNotification
147 | - UIKeyboardDidShowNotification
148 |
149 | */
150 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQKeyboardManagerConstantsInternal.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQTextView.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | /** @abstract UITextView with placeholder support */
27 | open class IQTextView: UITextView {
28 |
29 | @objc required public init?(coder aDecoder: NSCoder) {
30 | super.init(coder: aDecoder)
31 |
32 | #if swift(>=4.2)
33 | let UITextViewTextDidChange = UITextView.textDidChangeNotification
34 | #else
35 | let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange
36 | #endif
37 |
38 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
39 | }
40 |
41 | @objc override public init(frame: CGRect, textContainer: NSTextContainer?) {
42 | super.init(frame: frame, textContainer: textContainer)
43 |
44 | #if swift(>=4.2)
45 | let notificationName = UITextView.textDidChangeNotification
46 | #else
47 | let notificationName = Notification.Name.UITextViewTextDidChange
48 | #endif
49 |
50 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: notificationName, object: self)
51 | }
52 |
53 | @objc override open func awakeFromNib() {
54 | super.awakeFromNib()
55 |
56 | #if swift(>=4.2)
57 | let UITextViewTextDidChange = UITextView.textDidChangeNotification
58 | #else
59 | let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange
60 | #endif
61 |
62 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self)
63 | }
64 |
65 | deinit {
66 | IQ_PlaceholderLabel.removeFromSuperview()
67 | NotificationCenter.default.removeObserver(self)
68 | }
69 |
70 | private var placeholderInsets: UIEdgeInsets {
71 | return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding)
72 | }
73 |
74 | private var placeholderExpectedFrame: CGRect {
75 | let placeholderInsets = self.placeholderInsets
76 | let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right
77 | let expectedSize = IQ_PlaceholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom))
78 |
79 | return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height)
80 | }
81 |
82 | lazy var IQ_PlaceholderLabel: UILabel = {
83 | let label = UILabel()
84 |
85 | label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
86 | label.lineBreakMode = .byWordWrapping
87 | label.numberOfLines = 0
88 | label.font = self.font
89 | label.textAlignment = self.textAlignment
90 | label.backgroundColor = UIColor.clear
91 | #if swift(>=5.1)
92 | label.textColor = UIColor.systemGray
93 | #else
94 | label.textColor = UIColor.lightText
95 | #endif
96 | label.alpha = 0
97 | self.addSubview(label)
98 |
99 | return label
100 | }()
101 |
102 | /** @abstract To set textView's placeholder text color. */
103 | @IBInspectable open var placeholderTextColor: UIColor? {
104 |
105 | get {
106 | return IQ_PlaceholderLabel.textColor
107 | }
108 |
109 | set {
110 | IQ_PlaceholderLabel.textColor = newValue
111 | }
112 | }
113 |
114 | /** @abstract To set textView's placeholder text. Default is nil. */
115 | @IBInspectable open var placeholder: String? {
116 |
117 | get {
118 | return IQ_PlaceholderLabel.text
119 | }
120 |
121 | set {
122 | IQ_PlaceholderLabel.text = newValue
123 | refreshPlaceholder()
124 | }
125 | }
126 |
127 | /** @abstract To set textView's placeholder attributed text. Default is nil. */
128 | open var attributedPlaceholder: NSAttributedString? {
129 | get {
130 | return IQ_PlaceholderLabel.attributedText
131 | }
132 |
133 | set {
134 | IQ_PlaceholderLabel.attributedText = newValue
135 | refreshPlaceholder()
136 | }
137 | }
138 |
139 | @objc override open func layoutSubviews() {
140 | super.layoutSubviews()
141 |
142 | IQ_PlaceholderLabel.frame = placeholderExpectedFrame
143 | }
144 |
145 | @objc internal func refreshPlaceholder() {
146 |
147 | if !text.isEmpty || !attributedText.string.isEmpty {
148 | IQ_PlaceholderLabel.alpha = 0
149 | } else {
150 | IQ_PlaceholderLabel.alpha = 1
151 | }
152 | }
153 |
154 | @objc override open var text: String! {
155 |
156 | didSet {
157 | refreshPlaceholder()
158 | }
159 | }
160 |
161 | open override var attributedText: NSAttributedString! {
162 |
163 | didSet {
164 | refreshPlaceholder()
165 | }
166 | }
167 |
168 | @objc override open var font: UIFont? {
169 |
170 | didSet {
171 |
172 | if let unwrappedFont = font {
173 | IQ_PlaceholderLabel.font = unwrappedFont
174 | } else {
175 | IQ_PlaceholderLabel.font = UIFont.systemFont(ofSize: 12)
176 | }
177 | }
178 | }
179 |
180 | @objc override open var textAlignment: NSTextAlignment {
181 | didSet {
182 | IQ_PlaceholderLabel.textAlignment = textAlignment
183 | }
184 | }
185 |
186 | @objc override weak open var delegate: UITextViewDelegate? {
187 |
188 | get {
189 | refreshPlaceholder()
190 | return super.delegate
191 | }
192 |
193 | set {
194 | super.delegate = newValue
195 | }
196 | }
197 |
198 | @objc override open var intrinsicContentSize: CGSize {
199 | guard !hasText else {
200 | return super.intrinsicContentSize
201 | }
202 |
203 | var newSize = super.intrinsicContentSize
204 | let placeholderInsets = self.placeholderInsets
205 | newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom
206 |
207 | return newSize
208 | }
209 | }
210 |
211 | //#if swift(>=5.1)
212 | //import SwiftUI
213 | //
214 | //struct IQTextViewSwiftUI: UIViewRepresentable {
215 | // func makeUIView(context: Context) -> IQTextView {
216 | // IQTextView(frame: .zero)
217 | // }
218 | //
219 | // func updateUIView(_ view: IQTextView, context: Context) {
220 | // }
221 | //}
222 | //
223 | //struct IQTextViewSwiftUI_Preview: PreviewProvider {
224 | // static var previews: some View {
225 | // IQTextViewSwiftUI()
226 | // }
227 | //}
228 | //
229 | //#endif
230 | //
231 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQBarButtonItem.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 | import Foundation
26 |
27 | open class IQBarButtonItem: UIBarButtonItem {
28 |
29 | private static var _classInitialize: Void = classInitialize()
30 |
31 | @objc public override init() {
32 | _ = IQBarButtonItem._classInitialize
33 | super.init()
34 | }
35 |
36 | @objc public required init?(coder aDecoder: NSCoder) {
37 | _ = IQBarButtonItem._classInitialize
38 | super.init(coder: aDecoder)
39 | }
40 |
41 | private class func classInitialize() {
42 |
43 | let appearanceProxy = self.appearance()
44 |
45 | #if swift(>=4.2)
46 | let states: [UIControl.State]
47 | #else
48 | let states: [UIControlState]
49 | #endif
50 |
51 | states = [.normal, .highlighted, .disabled, .selected, .application, .reserved]
52 |
53 | for state in states {
54 |
55 | appearanceProxy.setBackgroundImage(nil, for: state, barMetrics: .default)
56 | appearanceProxy.setBackgroundImage(nil, for: state, style: .done, barMetrics: .default)
57 | appearanceProxy.setBackgroundImage(nil, for: state, style: .plain, barMetrics: .default)
58 | appearanceProxy.setBackButtonBackgroundImage(nil, for: state, barMetrics: .default)
59 | }
60 |
61 | appearanceProxy.setTitlePositionAdjustment(UIOffset(), for: .default)
62 | appearanceProxy.setBackgroundVerticalPositionAdjustment(0, for: .default)
63 | appearanceProxy.setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default)
64 | }
65 |
66 | @objc override open var tintColor: UIColor? {
67 | didSet {
68 |
69 | #if swift(>=4.2)
70 | var textAttributes = [NSAttributedString.Key: Any]()
71 | let foregroundColorKey = NSAttributedString.Key.foregroundColor
72 | #elseif swift(>=4)
73 | var textAttributes = [NSAttributedStringKey: Any]()
74 | let foregroundColorKey = NSAttributedStringKey.foregroundColor
75 | #else
76 | var textAttributes = [String: Any]()
77 | let foregroundColorKey = NSForegroundColorAttributeName
78 | #endif
79 |
80 | textAttributes[foregroundColorKey] = tintColor
81 |
82 | #if swift(>=4)
83 |
84 | if let attributes = titleTextAttributes(for: .normal) {
85 |
86 | for (key, value) in attributes {
87 | #if swift(>=4.2)
88 | textAttributes[key] = value
89 | #else
90 | textAttributes[NSAttributedStringKey.init(key)] = value
91 | #endif
92 | }
93 | }
94 |
95 | #else
96 |
97 | if let attributes = titleTextAttributes(for: .normal) {
98 | textAttributes = attributes
99 | }
100 | #endif
101 |
102 | setTitleTextAttributes(textAttributes, for: .normal)
103 | }
104 | }
105 |
106 | /**
107 | Boolean to know if it's a system item or custom item, we are having a limitation that we cannot override a designated initializer, so we are manually setting this property once in initialization
108 | */
109 | @objc internal var isSystemItem = false
110 |
111 | /**
112 | Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback.
113 |
114 | @param target Target object.
115 | @param action Target Selector.
116 | */
117 | @objc open func setTarget(_ target: AnyObject?, action: Selector?) {
118 | if let target = target, let action = action {
119 | invocation = IQInvocation(target, action)
120 | } else {
121 | invocation = nil
122 | }
123 | }
124 |
125 | /**
126 | Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method.
127 | */
128 | @objc open var invocation: IQInvocation?
129 |
130 | deinit {
131 | target = nil
132 | invocation = nil
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQInvocation.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | @objc public class IQInvocation: NSObject {
27 | @objc public weak var target: AnyObject?
28 | @objc public var action: Selector
29 |
30 | @objc public init(_ target: AnyObject, _ action: Selector) {
31 | self.target = target
32 | self.action = action
33 | }
34 |
35 | @objc public func invoke(from: Any) {
36 | if let target = target {
37 | UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent())
38 | }
39 | }
40 |
41 | deinit {
42 | target = nil
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQPreviousNextView.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | @objc public class IQPreviousNextView: UIView {
27 |
28 | }
29 |
30 | //#if swift(>=5.1)
31 | //import SwiftUI
32 | //
33 | //struct IQPreviousNextViewSwiftUI: UIViewRepresentable {
34 | // func makeUIView(context: Context) -> IQPreviousNextView {
35 | // IQPreviousNextView(frame: .zero)
36 | // }
37 | //
38 | // func updateUIView(_ view: IQPreviousNextView, context: Context) {
39 | // }
40 | //}
41 | //
42 | //struct IQTextViewSwiftUI_Preview: PreviewProvider {
43 | // static var previews: some View {
44 | // IQPreviousNextViewSwiftUI()
45 | // }
46 | //}
47 | //
48 | //#endif
49 |
50 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQTitleBarButtonItem.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 | import UIKit
26 |
27 | open class IQTitleBarButtonItem: IQBarButtonItem {
28 |
29 | @objc open var titleFont: UIFont? {
30 |
31 | didSet {
32 | if let unwrappedFont = titleFont {
33 | titleButton?.titleLabel?.font = unwrappedFont
34 | } else {
35 | titleButton?.titleLabel?.font = UIFont.systemFont(ofSize: 13)
36 | }
37 | }
38 | }
39 |
40 | @objc override open var title: String? {
41 | didSet {
42 | titleButton?.setTitle(title, for: .normal)
43 | }
44 | }
45 |
46 | /**
47 | titleColor to be used for displaying button text when displaying title (disabled state).
48 | */
49 | @objc open var titleColor: UIColor? {
50 |
51 | didSet {
52 |
53 | if let color = titleColor {
54 | titleButton?.setTitleColor(color, for: .disabled)
55 | } else {
56 | titleButton?.setTitleColor(UIColor.lightGray, for: .disabled)
57 | }
58 | }
59 | }
60 |
61 | /**
62 | selectableTitleColor to be used for displaying button text when button is enabled.
63 | */
64 | @objc open var selectableTitleColor: UIColor? {
65 |
66 | didSet {
67 |
68 | if let color = selectableTitleColor {
69 | titleButton?.setTitleColor(color, for: .normal)
70 | } else {
71 | #if swift(>=5.1)
72 | titleButton?.setTitleColor(UIColor.systemBlue, for: .normal)
73 | #else
74 | titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal)
75 | #endif
76 | }
77 | }
78 | }
79 |
80 | /**
81 | Customized Invocation to be called on title button action. titleInvocation is internally created using setTitleTarget:action: method.
82 | */
83 | @objc override open var invocation: IQInvocation? {
84 |
85 | didSet {
86 |
87 | if let target = invocation?.target, let action = invocation?.action {
88 | self.isEnabled = true
89 | titleButton?.isEnabled = true
90 | titleButton?.addTarget(target, action: action, for: .touchUpInside)
91 | } else {
92 | self.isEnabled = false
93 | titleButton?.isEnabled = false
94 | titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)
95 | }
96 | }
97 | }
98 |
99 | internal var titleButton: UIButton?
100 | private var _titleView: UIView?
101 |
102 | override init() {
103 | super.init()
104 | }
105 |
106 | @objc public convenience init(title: String?) {
107 |
108 | self.init(title: nil, style: .plain, target: nil, action: nil)
109 |
110 | _titleView = UIView()
111 | _titleView?.backgroundColor = UIColor.clear
112 |
113 | titleButton = UIButton(type: .system)
114 | titleButton?.isEnabled = false
115 | titleButton?.titleLabel?.numberOfLines = 3
116 | titleButton?.setTitleColor(UIColor.lightGray, for: .disabled)
117 | #if swift(>=5.1)
118 | titleButton?.setTitleColor(UIColor.systemBlue, for: .normal)
119 | #else
120 | titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal)
121 | #endif
122 | titleButton?.backgroundColor = UIColor.clear
123 | titleButton?.titleLabel?.textAlignment = .center
124 | titleButton?.setTitle(title, for: .normal)
125 | titleFont = UIFont.systemFont(ofSize: 13.0)
126 | titleButton?.titleLabel?.font = self.titleFont
127 | _titleView?.addSubview(titleButton!)
128 |
129 | if #available(iOS 11, *) {
130 |
131 | var layoutDefaultLowPriority: UILayoutPriority
132 | var layoutDefaultHighPriority: UILayoutPriority
133 |
134 | #if swift(>=4.0)
135 | let layoutPriorityLowValue = UILayoutPriority.defaultLow.rawValue-1
136 | let layoutPriorityHighValue = UILayoutPriority.defaultHigh.rawValue-1
137 | layoutDefaultLowPriority = UILayoutPriority(rawValue: layoutPriorityLowValue)
138 | layoutDefaultHighPriority = UILayoutPriority(rawValue: layoutPriorityHighValue)
139 | #else
140 | layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1
141 | layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1
142 | #endif
143 |
144 | _titleView?.translatesAutoresizingMaskIntoConstraints = false
145 | _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
146 | _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
147 | _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
148 | _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
149 |
150 | titleButton?.translatesAutoresizingMaskIntoConstraints = false
151 | titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical)
152 | titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal)
153 | titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical)
154 | titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal)
155 |
156 | let top = NSLayoutConstraint.init(item: titleButton!, attribute: .top, relatedBy: .equal, toItem: _titleView, attribute: .top, multiplier: 1, constant: 0)
157 | let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0)
158 | let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0)
159 | let trailing = NSLayoutConstraint.init(item: titleButton!, attribute: .trailing, relatedBy: .equal, toItem: _titleView, attribute: .trailing, multiplier: 1, constant: 0)
160 |
161 | _titleView?.addConstraints([top, bottom, leading, trailing])
162 | } else {
163 | _titleView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
164 | titleButton?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
165 | }
166 |
167 | customView = _titleView
168 | }
169 |
170 | @objc required public init?(coder aDecoder: NSCoder) {
171 | super.init(coder: aDecoder)
172 | }
173 |
174 | deinit {
175 | customView = nil
176 | titleButton?.removeTarget(nil, action: nil, for: .touchUpInside)
177 | _titleView = nil
178 | titleButton = nil
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IQToolbar.swift
3 | // https://github.com/hackiftekhar/IQKeyboardManager
4 | // Copyright (c) 2013-16 Iftekhar Qurashi.
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | /** @abstract IQToolbar for IQKeyboardManager. */
27 | open class IQToolbar: UIToolbar, UIInputViewAudioFeedback {
28 |
29 | private static var _classInitialize: Void = classInitialize()
30 |
31 | private class func classInitialize() {
32 |
33 | let appearanceProxy = self.appearance()
34 |
35 | appearanceProxy.barTintColor = nil
36 |
37 | let positions: [UIBarPosition] = [.any, .bottom, .top, .topAttached]
38 |
39 | for position in positions {
40 |
41 | appearanceProxy.setBackgroundImage(nil, forToolbarPosition: position, barMetrics: .default)
42 | appearanceProxy.setShadowImage(nil, forToolbarPosition: .any)
43 | }
44 |
45 | //Background color
46 | appearanceProxy.backgroundColor = nil
47 | }
48 |
49 | /**
50 | Previous bar button of toolbar.
51 | */
52 | private var privatePreviousBarButton: IQBarButtonItem?
53 | @objc open var previousBarButton: IQBarButtonItem {
54 | get {
55 | if privatePreviousBarButton == nil {
56 | privatePreviousBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
57 | }
58 | return privatePreviousBarButton!
59 | }
60 |
61 | set (newValue) {
62 | privatePreviousBarButton = newValue
63 | }
64 | }
65 |
66 | /**
67 | Next bar button of toolbar.
68 | */
69 | private var privateNextBarButton: IQBarButtonItem?
70 | @objc open var nextBarButton: IQBarButtonItem {
71 | get {
72 | if privateNextBarButton == nil {
73 | privateNextBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
74 | }
75 | return privateNextBarButton!
76 | }
77 |
78 | set (newValue) {
79 | privateNextBarButton = newValue
80 | }
81 | }
82 |
83 | /**
84 | Title bar button of toolbar.
85 | */
86 | private var privateTitleBarButton: IQTitleBarButtonItem?
87 | @objc open var titleBarButton: IQTitleBarButtonItem {
88 | get {
89 | if privateTitleBarButton == nil {
90 | privateTitleBarButton = IQTitleBarButtonItem(title: nil)
91 | privateTitleBarButton?.accessibilityLabel = "Title"
92 | }
93 | return privateTitleBarButton!
94 | }
95 |
96 | set (newValue) {
97 | privateTitleBarButton = newValue
98 | }
99 | }
100 |
101 | /**
102 | Done bar button of toolbar.
103 | */
104 | private var privateDoneBarButton: IQBarButtonItem?
105 | @objc open var doneBarButton: IQBarButtonItem {
106 | get {
107 | if privateDoneBarButton == nil {
108 | privateDoneBarButton = IQBarButtonItem(title: nil, style: .done, target: nil, action: nil)
109 | }
110 | return privateDoneBarButton!
111 | }
112 |
113 | set (newValue) {
114 | privateDoneBarButton = newValue
115 | }
116 | }
117 |
118 | /**
119 | Fixed space bar button of toolbar.
120 | */
121 | private var privateFixedSpaceBarButton: IQBarButtonItem?
122 | @objc open var fixedSpaceBarButton: IQBarButtonItem {
123 | get {
124 | if privateFixedSpaceBarButton == nil {
125 | privateFixedSpaceBarButton = IQBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
126 | }
127 | privateFixedSpaceBarButton!.isSystemItem = true
128 |
129 | if #available(iOS 10, *) {
130 | privateFixedSpaceBarButton!.width = 6
131 | } else {
132 | privateFixedSpaceBarButton!.width = 20
133 | }
134 |
135 | return privateFixedSpaceBarButton!
136 | }
137 |
138 | set (newValue) {
139 | privateFixedSpaceBarButton = newValue
140 | }
141 | }
142 |
143 | override init(frame: CGRect) {
144 | _ = IQToolbar._classInitialize
145 | super.init(frame: frame)
146 |
147 | sizeToFit()
148 |
149 | autoresizingMask = .flexibleWidth
150 | self.isTranslucent = true
151 | }
152 |
153 | @objc required public init?(coder aDecoder: NSCoder) {
154 | _ = IQToolbar._classInitialize
155 | super.init(coder: aDecoder)
156 |
157 | sizeToFit()
158 |
159 | autoresizingMask = .flexibleWidth
160 | self.isTranslucent = true
161 | }
162 |
163 | @objc override open func sizeThatFits(_ size: CGSize) -> CGSize {
164 | var sizeThatFit = super.sizeThatFits(size)
165 | sizeThatFit.height = 44
166 | return sizeThatFit
167 | }
168 |
169 | @objc override open var tintColor: UIColor! {
170 |
171 | didSet {
172 | if let unwrappedItems = items {
173 | for item in unwrappedItems {
174 | item.tintColor = tintColor
175 | }
176 | }
177 | }
178 | }
179 |
180 | @objc override open func layoutSubviews() {
181 |
182 | super.layoutSubviews()
183 |
184 | if #available(iOS 11, *) {
185 | return
186 | } else if let customTitleView = titleBarButton.customView {
187 | var leftRect = CGRect.null
188 | var rightRect = CGRect.null
189 | var isTitleBarButtonFound = false
190 |
191 | let sortedSubviews = self.subviews.sorted(by: { (view1: UIView, view2: UIView) -> Bool in
192 | if view1.frame.minX != view2.frame.minX {
193 | return view1.frame.minX < view2.frame.minX
194 | } else {
195 | return view1.frame.minY < view2.frame.minY
196 | }
197 | })
198 |
199 | for barButtonItemView in sortedSubviews {
200 |
201 | if isTitleBarButtonFound == true {
202 | rightRect = barButtonItemView.frame
203 | break
204 | } else if barButtonItemView === customTitleView {
205 | isTitleBarButtonFound = true
206 | //If it's UIToolbarButton or UIToolbarTextButton (which actually UIBarButtonItem)
207 | } else if barButtonItemView.isKind(of: UIControl.self) == true {
208 | leftRect = barButtonItemView.frame
209 | }
210 | }
211 |
212 | let titleMargin: CGFloat = 16
213 |
214 | let maxWidth: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
215 | let maxHeight = self.frame.height
216 |
217 | let sizeThatFits = customTitleView.sizeThatFits(CGSize(width: maxWidth, height: maxHeight))
218 |
219 | var titleRect: CGRect
220 |
221 | if sizeThatFits.width > 0 && sizeThatFits.height > 0 {
222 | let width = min(sizeThatFits.width, maxWidth)
223 | let height = min(sizeThatFits.height, maxHeight)
224 |
225 | var xPosition: CGFloat
226 |
227 | if leftRect.isNull == false {
228 | xPosition = titleMargin + leftRect.maxX + ((maxWidth - width)/2)
229 | } else {
230 | xPosition = titleMargin
231 | }
232 |
233 | let yPosition = (maxHeight - height)/2
234 |
235 | titleRect = CGRect(x: xPosition, y: yPosition, width: width, height: height)
236 | } else {
237 |
238 | var xPosition: CGFloat
239 |
240 | if leftRect.isNull == false {
241 | xPosition = titleMargin + leftRect.maxX
242 | } else {
243 | xPosition = titleMargin
244 | }
245 |
246 | let width: CGFloat = self.frame.width - titleMargin*2 - (leftRect.isNull ? 0 : leftRect.maxX) - (rightRect.isNull ? 0 : self.frame.width - rightRect.minX)
247 |
248 | titleRect = CGRect(x: xPosition, y: 0, width: width, height: maxHeight)
249 | }
250 |
251 | customTitleView.frame = titleRect
252 | }
253 | }
254 |
255 | @objc open var enableInputClicksWhenVisible: Bool {
256 | return true
257 | }
258 |
259 | deinit {
260 |
261 | items = nil
262 | privatePreviousBarButton = nil
263 | privateNextBarButton = nil
264 | privateTitleBarButton = nil
265 | privateDoneBarButton = nil
266 | privateFixedSpaceBarButton = nil
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2013-2017 Iftekhar Qurashi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Pods/IQKeyboardManagerSwift/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | IQKeyboardManager
5 |
6 |
8 |
9 |
10 | [](https://travis-ci.org/hackiftekhar/IQKeyboardManager)
11 |
12 |
13 | While developing iOS apps, we often run into issues where the iPhone keyboard slides up and covers the `UITextField/UITextView`. `IQKeyboardManager` allows you to prevent this issue of keyboard sliding up and covering `UITextField/UITextView` without needing you to write any code or make any additional setup. To use `IQKeyboardManager` you simply need to add source files to your project.
14 |
15 |
16 | #### Key Features
17 |
18 | 1) `**CODELESS**, Zero Lines of Code`
19 |
20 | 2) `Works Automatically`
21 |
22 | 3) `No More UIScrollView`
23 |
24 | 4) `No More Subclasses`
25 |
26 | 5) `No More Manual Work`
27 |
28 | 6) `No More #imports`
29 |
30 | `IQKeyboardManager` works on all orientations, and with the toolbar. It also has nice optional features allowing you to customize the distance from the text field, behaviour of previous, next and done buttons in the keyboard toolbar, play sound when the user navigates through the form and more.
31 |
32 |
33 | ## Screenshot
34 | [](http://youtu.be/6nhLw6hju2A)
35 | [](http://youtu.be/6nhLw6hju2A)
36 |
37 | ## GIF animation
38 | [](http://youtu.be/6nhLw6hju2A)
39 |
40 | ## Video
41 |
42 |
44 |
45 | ## Tutorial video by @rebeloper ([#1135](https://github.com/hackiftekhar/IQKeyboardManager/issues/1135))
46 |
47 | @rebeloper demonstrated two videos on how to implement **IQKeyboardManager** at it's core:
48 |
49 |
51 |
52 | https://www.youtube.com/playlist?list=PL_csAAO9PQ8aTL87XnueOXi3RpWE2m_8v
53 |
54 | ## Warning
55 |
56 | - **If you're planning to build SDK/library/framework and want to handle UITextField/UITextView with IQKeyboardManager then you're totally going the wrong way.** I would never suggest to add **IQKeyboardManager** as **dependency/adding/shipping** with any third-party library. Instead of adding **IQKeyboardManager** you should implement your own solution to achieve same kind of results. **IQKeyboardManager** is totally designed for projects to help developers for their convenience, it's not designed for **adding/dependency/shipping** with any **third-party library**, because **doing this could block adoption by other developers for their projects as well (who are not using IQKeyboardManager and have implemented their custom solution to handle UITextField/UITextView in the project).**
57 | - If **IQKeyboardManager** conflicts with other **third-party library**, then it's **developer responsibility** to **enable/disable IQKeyboardManager** when **presenting/dismissing** third-party library UI. Third-party libraries are not responsible to handle IQKeyboardManager.
58 |
59 | ## Requirements
60 | []()
61 |
62 | | | Language | Minimum iOS Target | Minimum Xcode Version |
63 | |------------------------|----------|--------------------|-----------------------|
64 | | IQKeyboardManager | Obj-C | iOS 8.0 | Xcode 9 |
65 | | IQKeyboardManagerSwift | Swift | iOS 8.0 | Xcode 9 |
66 | | Demo Project | | | Xcode 11 |
67 |
68 | #### Swift versions support
69 |
70 | | Swift | Xcode | IQKeyboardManagerSwift |
71 | |-------------------|-------|------------------------|
72 | | 5.1, 5.0, 4.2, 4.0, 3.2, 3.0| 11 | >= 6.5.0 |
73 | | 5.0,4.2, 4.0, 3.2, 3.0| 10.2 | >= 6.2.1 |
74 | | 4.2, 4.0, 3.2, 3.0| 10.0 | >= 6.0.4 |
75 | | 4.0, 3.2, 3.0 | 9.0 | 5.0.0 |
76 |
77 | Installation
78 | ==========================
79 |
80 | #### Installation with CocoaPods
81 |
82 | [](http://cocoadocs.org/docsets/IQKeyboardManager)
83 |
84 | ***IQKeyboardManager (Objective-C):*** IQKeyboardManager is available through [CocoaPods](http://cocoapods.org). To install
85 | it, simply add the following line to your Podfile: ([#9](https://github.com/hackiftekhar/IQKeyboardManager/issues/9))
86 |
87 | ```ruby
88 | pod 'IQKeyboardManager' #iOS8 and later
89 | ```
90 |
91 | ***IQKeyboardManager (Swift):*** IQKeyboardManagerSwift is available through [CocoaPods](http://cocoapods.org). To install
92 | it, simply add the following line to your Podfile: ([#236](https://github.com/hackiftekhar/IQKeyboardManager/issues/236))
93 |
94 | *Swift 5.1, 5.0, 4.2, 4.0, 3.2, 3.0 (Xcode 11)*
95 |
96 | ```ruby
97 | pod 'IQKeyboardManagerSwift'
98 | ```
99 |
100 | *Or you can choose the version you need based on Swift support table from [Requirements](README.md#requirements)*
101 |
102 | ```ruby
103 | pod 'IQKeyboardManagerSwift', '6.3.0'
104 | ```
105 |
106 | In AppDelegate.swift, just import IQKeyboardManagerSwift framework and enable IQKeyboardManager.
107 |
108 | ```swift
109 | import IQKeyboardManagerSwift
110 |
111 | @UIApplicationMain
112 | class AppDelegate: UIResponder, UIApplicationDelegate {
113 |
114 | var window: UIWindow?
115 |
116 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
117 |
118 | IQKeyboardManager.shared.enable = true
119 |
120 | return true
121 | }
122 | }
123 | ```
124 |
125 | #### Installation with Carthage
126 |
127 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
128 |
129 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
130 |
131 | ```bash
132 | $ brew update
133 | $ brew install carthage
134 | ```
135 |
136 | To integrate `IQKeyboardManger` or `IQKeyboardManagerSwift` into your Xcode project using Carthage, add the following line to your `Cartfile`:
137 |
138 | ```ogdl
139 | github "hackiftekhar/IQKeyboardManager"
140 | ```
141 |
142 | Run `carthage` to build the frameworks and drag the appropriate framework (`IQKeyboardManager.framework` or `IQKeyboardManagerSwift.framework`) into your Xcode project based on your need. Make sure to add only one framework and not both.
143 |
144 |
145 | #### Installation with Source Code
146 |
147 | []()
148 |
149 |
150 |
151 | ***IQKeyboardManager (Objective-C):*** Just ***drag and drop*** `IQKeyboardManager` directory from demo project to your project. That's it.
152 |
153 | ***IQKeyboardManager (Swift):*** ***Drag and drop*** `IQKeyboardManagerSwift` directory from demo project to your project
154 |
155 | In AppDelegate.swift, just enable IQKeyboardManager.
156 |
157 | ```swift
158 | @UIApplicationMain
159 | class AppDelegate: UIResponder, UIApplicationDelegate {
160 |
161 | var window: UIWindow?
162 |
163 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
164 |
165 | IQKeyboardManager.shared.enable = true
166 |
167 | return true
168 | }
169 | }
170 | ```
171 |
172 | #### Installation with Swift Package Manager
173 |
174 | [Swift Package Manager(SPM)](https://swift.org/package-manager/) is Apple's dependency manager tool. It is now supported in Xcode 11. So it can be used in all appleOS types of projects. It can be used alongside other tools like CocoaPods and Carthage as well.
175 |
176 | To install IQKeyboardManager package into your packages, add a reference to IQKeyboardManager and a targeting release version in the dependencies section in `Package.swift` file:
177 |
178 | ```swift
179 | import PackageDescription
180 |
181 | let package = Package(
182 | name: "YOUR_PROJECT_NAME",
183 | products: [],
184 | dependencies: [
185 | .package(url: "https://github.com/hackiftekhar/IQKeyboardManager.git", from: "6.5.0")
186 | ]
187 | )
188 | ```
189 |
190 | To install IQKeyboardManager package via Xcode
191 |
192 | * Go to File -> Swift Packages -> Add Package Dependency...
193 | * Then search for https://github.com/hackiftekhar/IQKeyboardManager.git
194 | * And choose the version you want
195 |
196 | Migration Guide
197 | ==========================
198 | - [IQKeyboardManager 6.0.0 Migration Guide](https://github.com/hackiftekhar/IQKeyboardManager/wiki/IQKeyboardManager-6.0.0-Migration-Guide)
199 |
200 | Other Links
201 | ==========================
202 |
203 | - [Known Issues](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Known-Issues)
204 | - [Manual Management Tweaks](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Manual-Management)
205 | - [Properties and functions usage](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Properties-&-Functions)
206 |
207 | ## Flow Diagram
208 | [](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Screenshot/IQKeyboardManagerFlowDiagram.jpg)
209 |
210 | If you would like to see detailed Flow diagram then check [Detailed Flow Diagram](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManagerCFD.jpg).
211 |
212 |
213 | LICENSE
214 | ---
215 | Distributed under the MIT License.
216 |
217 | Contributions
218 | ---
219 | Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub.
220 |
221 | Author
222 | ---
223 | If you wish to contact me, email at: hack.iftekhar@gmail.com
224 |
--------------------------------------------------------------------------------
/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - IQKeyboardManagerSwift (6.5.6)
3 |
4 | DEPENDENCIES:
5 | - IQKeyboardManagerSwift
6 |
7 | SPEC REPOS:
8 | trunk:
9 | - IQKeyboardManagerSwift
10 |
11 | SPEC CHECKSUMS:
12 | IQKeyboardManagerSwift: c7df9d2deb356c04522f5c4b7b6e4ce4d8ed94fe
13 |
14 | PODFILE CHECKSUM: 9a6633194abfb806a44f4f824f06803bc7123faa
15 |
16 | COCOAPODS: 1.11.2
17 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/alina.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/alina.xcuserdatad/xcschemes/Pods-MindMap.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/alina.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IQKeyboardManagerSwift.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 0
13 |
14 | Pods-MindMap.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 1
20 |
21 |
22 | SuppressBuildableAutocreation
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 6.5.6
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_IQKeyboardManagerSwift : NSObject
3 | @end
4 | @implementation PodsDummy_IQKeyboardManagerSwift
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double IQKeyboardManagerSwiftVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char IQKeyboardManagerSwiftVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
5 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit"
6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift
11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
13 | SKIP_INSTALL = YES
14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
15 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap:
--------------------------------------------------------------------------------
1 | framework module IQKeyboardManagerSwift {
2 | umbrella header "IQKeyboardManagerSwift-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
5 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit"
6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift
11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
13 | SKIP_INSTALL = YES
14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
15 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## IQKeyboardManagerSwift
5 |
6 | MIT License
7 |
8 | Copyright (c) 2013-2017 Iftekhar Qurashi
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
28 | Generated by CocoaPods - https://cocoapods.org
29 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | MIT License
18 |
19 | Copyright (c) 2013-2017 Iftekhar Qurashi
20 |
21 | Permission is hereby granted, free of charge, to any person obtaining a copy
22 | of this software and associated documentation files (the "Software"), to deal
23 | in the Software without restriction, including without limitation the rights
24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25 | copies of the Software, and to permit persons to whom the Software is
26 | furnished to do so, subject to the following conditions:
27 |
28 | The above copyright notice and this permission notice shall be included in all
29 | copies or substantial portions of the Software.
30 |
31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 | SOFTWARE.
38 |
39 | License
40 | MIT
41 | Title
42 | IQKeyboardManagerSwift
43 | Type
44 | PSGroupSpecifier
45 |
46 |
47 | FooterText
48 | Generated by CocoaPods - https://cocoapods.org
49 | Title
50 |
51 | Type
52 | PSGroupSpecifier
53 |
54 |
55 | StringsTable
56 | Acknowledgements
57 | Title
58 | Acknowledgements
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_MindMap : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_MindMap
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks-Debug-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks-Debug-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks-Release-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks-Release-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | function on_error {
7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
8 | }
9 | trap 'on_error $LINENO' ERR
10 |
11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
13 | # frameworks to, so exit 0 (signalling the script phase was successful).
14 | exit 0
15 | fi
16 |
17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
19 |
20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
22 | BCSYMBOLMAP_DIR="BCSymbolMaps"
23 |
24 |
25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
28 |
29 | # Copies and strips a vendored framework
30 | install_framework()
31 | {
32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
33 | local source="${BUILT_PRODUCTS_DIR}/$1"
34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
36 | elif [ -r "$1" ]; then
37 | local source="$1"
38 | fi
39 |
40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
41 |
42 | if [ -L "${source}" ]; then
43 | echo "Symlinked..."
44 | source="$(readlink "${source}")"
45 | fi
46 |
47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
50 | echo "Installing $f"
51 | install_bcsymbolmap "$f" "$destination"
52 | rm "$f"
53 | done
54 | rmdir "${source}/${BCSYMBOLMAP_DIR}"
55 | fi
56 |
57 | # Use filter instead of exclude so missing patterns don't throw errors.
58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
60 |
61 | local basename
62 | basename="$(basename -s .framework "$1")"
63 | binary="${destination}/${basename}.framework/${basename}"
64 |
65 | if ! [ -r "$binary" ]; then
66 | binary="${destination}/${basename}"
67 | elif [ -L "${binary}" ]; then
68 | echo "Destination binary is symlinked..."
69 | dirname="$(dirname "${binary}")"
70 | binary="${dirname}/$(readlink "${binary}")"
71 | fi
72 |
73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
75 | strip_invalid_archs "$binary"
76 | fi
77 |
78 | # Resign the code if required by the build settings to avoid unstable apps
79 | code_sign_if_enabled "${destination}/$(basename "$1")"
80 |
81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
83 | local swift_runtime_libs
84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
85 | for lib in $swift_runtime_libs; do
86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
88 | code_sign_if_enabled "${destination}/${lib}"
89 | done
90 | fi
91 | }
92 | # Copies and strips a vendored dSYM
93 | install_dsym() {
94 | local source="$1"
95 | warn_missing_arch=${2:-true}
96 | if [ -r "$source" ]; then
97 | # Copy the dSYM into the targets temp dir.
98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
100 |
101 | local basename
102 | basename="$(basename -s .dSYM "$source")"
103 | binary_name="$(ls "$source/Contents/Resources/DWARF")"
104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
105 |
106 | # Strip invalid architectures from the dSYM.
107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
108 | strip_invalid_archs "$binary" "$warn_missing_arch"
109 | fi
110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
111 | # Move the stripped file into its final destination.
112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
114 | else
115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
116 | mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
117 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
118 | fi
119 | fi
120 | }
121 |
122 | # Used as a return value for each invocation of `strip_invalid_archs` function.
123 | STRIP_BINARY_RETVAL=0
124 |
125 | # Strip invalid architectures
126 | strip_invalid_archs() {
127 | binary="$1"
128 | warn_missing_arch=${2:-true}
129 | # Get architectures for current target binary
130 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
131 | # Intersect them with the architectures we are building for
132 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
133 | # If there are no archs supported by this binary then warn the user
134 | if [[ -z "$intersected_archs" ]]; then
135 | if [[ "$warn_missing_arch" == "true" ]]; then
136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
137 | fi
138 | STRIP_BINARY_RETVAL=1
139 | return
140 | fi
141 | stripped=""
142 | for arch in $binary_archs; do
143 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
144 | # Strip non-valid architectures in-place
145 | lipo -remove "$arch" -output "$binary" "$binary"
146 | stripped="$stripped $arch"
147 | fi
148 | done
149 | if [[ "$stripped" ]]; then
150 | echo "Stripped $binary of architectures:$stripped"
151 | fi
152 | STRIP_BINARY_RETVAL=0
153 | }
154 |
155 | # Copies the bcsymbolmap files of a vendored framework
156 | install_bcsymbolmap() {
157 | local bcsymbolmap_path="$1"
158 | local destination="${BUILT_PRODUCTS_DIR}"
159 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
160 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
161 | }
162 |
163 | # Signs a framework with the provided identity
164 | code_sign_if_enabled() {
165 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
166 | # Use the current code_sign_identity
167 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
168 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
169 |
170 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
171 | code_sign_cmd="$code_sign_cmd &"
172 | fi
173 | echo "$code_sign_cmd"
174 | eval "$code_sign_cmd"
175 | fi
176 | }
177 |
178 | if [[ "$CONFIGURATION" == "Debug" ]]; then
179 | install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework"
180 | fi
181 | if [[ "$CONFIGURATION" == "Release" ]]; then
182 | install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework"
183 | fi
184 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
185 | wait
186 | fi
187 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_MindMapVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_MindMapVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers"
6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
8 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "QuartzCore" -framework "UIKit"
9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
10 | PODS_BUILD_DIR = ${BUILD_DIR}
11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
13 | PODS_ROOT = ${SRCROOT}/Pods
14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_MindMap {
2 | umbrella header "Pods-MindMap-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-MindMap/Pods-MindMap.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers"
6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
8 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "QuartzCore" -framework "UIKit"
9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
10 | PODS_BUILD_DIR = ${BUILD_DIR}
11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
13 | PODS_ROOT = ${SRCROOT}/Pods
14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MindMap
2 | An iOS application for creating Mind Maps with clean/intuitive UI and MVC architecture.
3 |
4 | ## About the project
5 | - Check recently edited mind maps
6 | - Privacy (Lock mind maps)
7 | - Share with your friends
8 |
9 |
10 |
|
11 | --- | ---
12 |
13 |
14 | ## Languages / Frameworks Used
15 | - Swift 5
16 | - UIKit
17 | - LocalAuthentication
18 |
19 |
20 | ## How to run the project ?
21 | * Fork the project.
22 | * Switch to the `main` branch.
23 | * Run the project using Xcode.
24 |
--------------------------------------------------------------------------------