@@ -10,17 +10,15 @@ import UIKit
10
10
11
11
// MARK: - CustomKeyboardDelegate
12
12
@objc public protocol CustomKeyboardDelegate {
13
- optional func customKeyboardKeyButtonPressed( customKeyboard: CustomKeyboard , key: String )
13
+ optional func customKeyboard( customKeyboard: CustomKeyboard , keyboardButtonPressed keyboardButton: KeyboardButton )
14
+ optional func customKeyboard( customKeyboard: CustomKeyboard , keyButtonPressed key: String )
14
15
optional func customKeyboardSpaceButtonPressed( customKeyboard: CustomKeyboard )
15
16
optional func customKeyboardBackspaceButtonPressed( customKeyboard: CustomKeyboard )
16
17
optional func customKeyboardGlobeButtonPressed( customKeyboard: CustomKeyboard )
17
18
optional func customKeyboardReturnButtonPressed( customKeyboard: CustomKeyboard )
18
- optional func customKeyboardButtonPressed( customKeyboard: CustomKeyboard , keyboardButton: KeyboardButton )
19
19
}
20
20
21
21
// MARK: - CustomKeyboard
22
- public var CustomKeyboardKeyButtonPopupTag : Int = 101
23
-
24
22
public class CustomKeyboard: UIView , KeyboardLayoutDelegate {
25
23
public var keyButtonPopupContainer : UIView ?
26
24
@@ -34,6 +32,24 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
34
32
private var backspaceDeleteTimer : NSTimer ?
35
33
private var backspaceAutoDeleteModeTimer : NSTimer ?
36
34
35
+ public var keyMenuLocked : Bool = false
36
+ public var keyMenuOpenTimer : NSTimer ?
37
+ public var keyMenuOpenTimeInterval : NSTimeInterval = 1
38
+ public var keyMenuShowingKeyboardButton : KeyboardButton ? {
39
+ didSet {
40
+ oldValue? . showKeyPop ( show: false )
41
+ oldValue? . showKeyMenu ( show: false )
42
+ keyMenuShowingKeyboardButton? . showKeyPop ( show: false )
43
+ keyMenuShowingKeyboardButton? . showKeyMenu ( show: true )
44
+
45
+ dispatch_after (
46
+ dispatch_time ( DISPATCH_TIME_NOW, Int64 ( 0.1 * Double( NSEC_PER_SEC) ) ) ,
47
+ dispatch_get_main_queue ( ) ) { [ weak self] in
48
+ self ? . currentLayout. typingEnabled = self !. keyMenuShowingKeyboardButton == nil && self !. keyMenuLocked == false
49
+ }
50
+ }
51
+ }
52
+
37
53
public var uppercaseToggledLayout : KeyboardLayout ! {
38
54
didSet {
39
55
layoutDidChange (
@@ -74,7 +90,6 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
74
90
}
75
91
}
76
92
77
- private var lastLetterLayout : KeyboardLayout ?
78
93
private( set) var currentLayout : KeyboardLayout ! {
79
94
didSet {
80
95
oldValue? . delegate = nil
@@ -183,46 +198,64 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
183
198
repeats: false )
184
199
}
185
200
186
- public func invalidateShiftToggleTimer( ) {
201
+ internal func invalidateShiftToggleTimer( ) {
187
202
shiftToggleTimer? . invalidate ( )
188
203
shiftToggleTimer = nil
189
204
shiftCanBeToggled = false
190
205
}
191
206
192
- // MARK: Key popup in custom container
193
- public func addKeyPopup( forKey key: KeyboardButton ) {
194
- switch key. type {
195
- case . Key( _) :
196
- if let container = keyButtonPopupContainer {
197
- if container. viewWithTag ( CustomKeyboardKeyButtonPopupTag) == nil {
198
- let popup = key. createPopup ( )
199
- popup. tag = CustomKeyboardKeyButtonPopupTag
200
- popup. frame. origin = key. convertPoint ( popup. frame. origin, toView: container)
201
- container. addSubview ( popup)
202
- }
203
- }
204
- default :
205
- return
206
- }
207
+ // MARK: KeyMenu Toggle
208
+ private func startKeyMenuOpenTimer( forKeyboardButton keyboardButton: KeyboardButton ) {
209
+ keyMenuOpenTimer = NSTimer . scheduledTimerWithTimeInterval (
210
+ keyMenuOpenTimeInterval,
211
+ target: self ,
212
+ selector: #selector( CustomKeyboard . openKeyMenu ( _: ) ) ,
213
+ userInfo: keyboardButton,
214
+ repeats: false )
207
215
}
208
216
209
- public func removeKeyPopup( ) {
210
- if let container = keyButtonPopupContainer {
211
- if let popup = container. viewWithTag ( CustomKeyboardKeyButtonPopupTag) {
212
- popup. removeFromSuperview ( )
213
- }
217
+ private func invalidateKeyMenuOpenTimer( ) {
218
+ keyMenuOpenTimer? . invalidate ( )
219
+ keyMenuOpenTimer = nil
220
+ }
221
+
222
+ public func openKeyMenu( timer: NSTimer ) {
223
+ if let userInfo = timer. userInfo, keyboardButton = userInfo as? KeyboardButton {
224
+ keyMenuShowingKeyboardButton = keyboardButton
214
225
}
215
226
}
216
227
217
228
// MARK: KeyboardLayoutDelegate
218
- public func keyboardLayoutDidPressButton( keyboardLayout: KeyboardLayout , keyboardButton: KeyboardButton ) {
219
- delegate? . customKeyboardButtonPressed ? ( self , keyboardButton: keyboardButton)
229
+ public func keyboardLayout( keyboardLayout: KeyboardLayout , didKeyPressStart keyboardButton: KeyboardButton ) {
220
230
invalidateBackspaceAutoDeleteModeTimer ( )
221
231
invalidateBackspaceDeleteTimer ( )
232
+ invalidateKeyMenuOpenTimer ( )
233
+
234
+ if keyboardLayout == currentLayout {
235
+ // Backspace
236
+ if keyboardButton. identifier == CustomKeyboardIdentifier . Backspace. rawValue {
237
+ startBackspaceAutoDeleteModeTimer ( )
238
+ }
239
+
240
+ // KeyPop and KeyMenu
241
+ if keyboardButton. style. keyPopType != nil {
242
+ keyboardButton. showKeyPop ( show: true )
243
+ if keyboardButton. keyMenu != nil {
244
+ startKeyMenuOpenTimer ( forKeyboardButton: keyboardButton)
245
+ }
246
+ } else if keyboardButton. keyMenu != nil {
247
+ keyMenuShowingKeyboardButton = keyboardButton
248
+ keyMenuLocked = false
249
+ }
250
+ }
251
+ }
252
+
253
+ public func keyboardLayout( keyboardLayout: KeyboardLayout , didKeyPressEnd keyboardButton: KeyboardButton ) {
222
254
if keyboardLayout == currentLayout {
255
+ delegate? . customKeyboard ? ( self , keyboardButtonPressed: keyboardButton)
223
256
switch keyboardButton. type {
224
257
case . Key( let key) :
225
- delegate? . customKeyboardKeyButtonPressed ? ( self , key : key)
258
+ delegate? . customKeyboard ? ( self , keyButtonPressed : key)
226
259
if uppercaseOnce {
227
260
uppercaseOnce = false
228
261
currentLayout = lowercaseLayout
@@ -231,23 +264,23 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
231
264
if let id = keyboardButton. identifier,
232
265
let identifier = CustomKeyboardIdentifier ( rawValue: id) {
233
266
switch identifier {
267
+ case . Numbers:
268
+ currentLayout = numbersLayout
269
+ case . Symbols:
270
+ currentLayout = symbolsLayout
271
+ case . Letters:
272
+ currentLayout = uppercaseLayout
273
+ uppercaseOnce = true
274
+ case . Globe:
275
+ delegate? . customKeyboardGlobeButtonPressed ? ( self )
276
+ case . Return:
277
+ delegate? . customKeyboardReturnButtonPressed ? ( self )
234
278
case . Space:
235
279
delegate? . customKeyboardSpaceButtonPressed ? ( self )
236
280
uppercaseOnce = false
237
281
case . Backspace:
238
282
delegate? . customKeyboardBackspaceButtonPressed ? ( self )
239
283
uppercaseOnce = false
240
- case . Globe:
241
- delegate? . customKeyboardGlobeButtonPressed ? ( self )
242
- case . Return:
243
- delegate? . customKeyboardReturnButtonPressed ? ( self )
244
- case . Letters:
245
- currentLayout = uppercaseLayout
246
- uppercaseOnce = true
247
- case . Numbers:
248
- currentLayout = numbersLayout
249
- case . Symbols:
250
- currentLayout = symbolsLayout
251
284
case . Shift:
252
285
if shiftCanBeToggled {
253
286
currentLayout = uppercaseToggledLayout
@@ -258,9 +291,6 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
258
291
uppercaseOnce = true
259
292
startShiftToggleTimer ( )
260
293
}
261
- case . ShiftToggled:
262
- currentLayout = lowercaseLayout
263
- uppercaseOnce = false
264
294
case . ShiftToggledOnce:
265
295
if shiftCanBeToggled {
266
296
currentLayout = uppercaseToggledLayout
@@ -271,30 +301,75 @@ public class CustomKeyboard: UIView, KeyboardLayoutDelegate {
271
301
currentLayout = lowercaseLayout
272
302
startShiftToggleTimer ( )
273
303
}
304
+ case . ShiftToggled:
305
+ currentLayout = lowercaseLayout
306
+ uppercaseOnce = false
274
307
}
275
308
}
276
- break
277
309
}
278
310
}
279
311
}
280
312
281
- public func keyboardLayoutDidStartPressingButton( keyboardLayout: KeyboardLayout , keyboardButton: KeyboardButton ) {
313
+ public func keyboardLayout( keyboardLayout: KeyboardLayout , didTouchesBegin touches: Set < UITouch > ) {
314
+ if let menu = keyMenuShowingKeyboardButton? . keyMenu, touch = touches. first {
315
+ menu. updateSelection ( touchLocation: touch. locationInView ( self ) , inView: self )
316
+ }
317
+ }
318
+
319
+ public func keyboardLayout( keyboardLayout: KeyboardLayout, didTouchesMove touches: Set < UITouch > ) {
320
+ if let menu = keyMenuShowingKeyboardButton? . keyMenu, touch = touches. first {
321
+ menu. updateSelection ( touchLocation: touch. locationInView ( self ) , inView: self )
322
+ }
323
+ }
324
+
325
+ public func keyboardLayout( keyboardLayout: KeyboardLayout, didTouchesEnd touches: Set < UITouch > ? ) {
282
326
invalidateBackspaceAutoDeleteModeTimer ( )
283
327
invalidateBackspaceDeleteTimer ( )
284
- addKeyPopup ( forKey: keyboardButton)
285
- if keyboardLayout == currentLayout {
286
- if keyboardButton. identifier == CustomKeyboardIdentifier . Backspace. rawValue {
287
- startBackspaceAutoDeleteModeTimer ( )
328
+ invalidateKeyMenuOpenTimer ( )
329
+
330
+ if let menu = keyMenuShowingKeyboardButton? . keyMenu, touch = touches? . first {
331
+ menu. updateSelection ( touchLocation: touch. locationInView ( self ) , inView: self )
332
+ // select item
333
+ if menu. selectedIndex >= 0 {
334
+ if let item = menu. items [ safe: menu. selectedIndex] {
335
+ item. action ? ( keyMenuItem: item)
336
+ }
337
+ keyMenuShowingKeyboardButton = nil
338
+ keyMenuLocked = false
339
+ } else {
340
+ if keyMenuLocked {
341
+ keyMenuShowingKeyboardButton = nil
342
+ keyMenuLocked = false
343
+ return
344
+ }
345
+ keyMenuLocked = true
288
346
}
289
347
}
290
348
}
291
349
292
- public func keyboardLayoutDidDraggedInButton( keyboardLayout: KeyboardLayout , keyboardButton: KeyboardButton ) {
293
- removeKeyPopup ( )
294
- addKeyPopup ( forKey: keyboardButton)
295
- }
296
-
297
- public func keyboardLayoutDidEndTouches( keyboardLayout: KeyboardLayout ) {
298
- removeKeyPopup ( )
350
+ public func keyboardLayout( keyboardLayout: KeyboardLayout, didTouchesCancel touches: Set < UITouch > ? ) {
351
+ invalidateBackspaceAutoDeleteModeTimer ( )
352
+ invalidateBackspaceDeleteTimer ( )
353
+ invalidateKeyMenuOpenTimer ( )
354
+
355
+ if let menu = keyMenuShowingKeyboardButton? . keyMenu, touch = touches? . first {
356
+ menu. updateSelection ( touchLocation: touch. locationInView ( self ) , inView: self )
357
+ // select item
358
+ if menu. selectedIndex >= 0 {
359
+ if let item = menu. items [ safe: menu. selectedIndex] {
360
+ item. action ? ( keyMenuItem: item)
361
+ }
362
+ keyMenuShowingKeyboardButton = nil
363
+ keyMenuLocked = false
364
+ } else {
365
+ if keyMenuLocked {
366
+ keyMenuShowingKeyboardButton = nil
367
+ keyMenuLocked = false
368
+ currentLayout. typingEnabled = true
369
+ return
370
+ }
371
+ keyMenuLocked = true
372
+ }
373
+ }
299
374
}
300
375
}
0 commit comments