悟空记账

IQUIView+IQKeyboardToolbar.m 36KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. //
  2. // IQUIView+IQKeyboardToolbar.m
  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. #import "IQUIView+IQKeyboardToolbar.h"
  24. #import "IQKeyboardManagerConstantsInternal.h"
  25. #import "IQKeyboardManager.h"
  26. #import <objc/runtime.h>
  27. #import <UIKit/UIImage.h>
  28. #import <UIKit/UILabel.h>
  29. #import <UIKit/UIAccessibility.h>
  30. /*UIKeyboardToolbar Category implementation*/
  31. @implementation UIView (IQToolbarAddition)
  32. -(IQToolbar *)keyboardToolbar
  33. {
  34. IQToolbar *keyboardToolbar = nil;
  35. if ([[self inputAccessoryView] isKindOfClass:[IQToolbar class]])
  36. {
  37. keyboardToolbar = [self inputAccessoryView];
  38. }
  39. else
  40. {
  41. keyboardToolbar = objc_getAssociatedObject(self, @selector(keyboardToolbar));
  42. if (keyboardToolbar == nil)
  43. {
  44. keyboardToolbar = [[IQToolbar alloc] init];
  45. objc_setAssociatedObject(self, @selector(keyboardToolbar), keyboardToolbar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  46. }
  47. }
  48. return keyboardToolbar;
  49. }
  50. -(void)setShouldHideToolbarPlaceholder:(BOOL)shouldHideToolbarPlaceholder
  51. {
  52. objc_setAssociatedObject(self, @selector(shouldHideToolbarPlaceholder), @(shouldHideToolbarPlaceholder), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  53. self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder;
  54. }
  55. -(BOOL)shouldHideToolbarPlaceholder
  56. {
  57. NSNumber *shouldHideToolbarPlaceholder = objc_getAssociatedObject(self, @selector(shouldHideToolbarPlaceholder));
  58. return [shouldHideToolbarPlaceholder boolValue];
  59. }
  60. -(void)setShouldHidePlaceholderText:(BOOL)shouldHidePlaceholderText
  61. {
  62. [self setShouldHideToolbarPlaceholder:shouldHidePlaceholderText];
  63. }
  64. -(BOOL)shouldHidePlaceholderText
  65. {
  66. return [self shouldHideToolbarPlaceholder];
  67. }
  68. -(void)setToolbarPlaceholder:(NSString *)toolbarPlaceholder
  69. {
  70. objc_setAssociatedObject(self, @selector(toolbarPlaceholder), toolbarPlaceholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  71. self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder;
  72. }
  73. -(NSString *)toolbarPlaceholder
  74. {
  75. NSString *toolbarPlaceholder = objc_getAssociatedObject(self, @selector(toolbarPlaceholder));
  76. return toolbarPlaceholder;
  77. }
  78. -(void)setPlaceholderText:(NSString*)placeholderText
  79. {
  80. [self setToolbarPlaceholder:placeholderText];
  81. }
  82. -(NSString*)placeholderText
  83. {
  84. return [self toolbarPlaceholder];
  85. }
  86. -(NSString *)drawingToolbarPlaceholder
  87. {
  88. if (self.shouldHideToolbarPlaceholder)
  89. {
  90. return nil;
  91. }
  92. else if (self.toolbarPlaceholder.length != 0)
  93. {
  94. return self.toolbarPlaceholder;
  95. }
  96. else if ([self respondsToSelector:@selector(placeholder)])
  97. {
  98. return [(UITextField*)self placeholder];
  99. }
  100. else
  101. {
  102. return nil;
  103. }
  104. }
  105. -(NSString*)drawingPlaceholderText
  106. {
  107. return [self drawingToolbarPlaceholder];
  108. }
  109. #pragma mark - Private helper
  110. +(IQBarButtonItem*)flexibleBarButtonItem
  111. {
  112. static IQBarButtonItem *nilButton = nil;
  113. if (nilButton == nil)
  114. {
  115. nilButton = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
  116. }
  117. return nilButton;
  118. }
  119. #pragma mark - Toolbar on UIKeyboard
  120. - (void)addRightButtonOnKeyboardWithImage:(UIImage*)image target:(id)target action:(SEL)action titleText:(NSString*)titleText
  121. {
  122. // If can't set InputAccessoryView. Then return
  123. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  124. // Creating a toolBar for keyboard
  125. IQToolbar *toolbar = self.keyboardToolbar;
  126. if ([self respondsToSelector:@selector(keyboardAppearance)])
  127. {
  128. switch ([(UITextField*)self keyboardAppearance])
  129. {
  130. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  131. default: toolbar.barStyle = UIBarStyleDefault; break;
  132. }
  133. }
  134. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  135. //Flexible space
  136. [items addObject:[[self class] flexibleBarButtonItem]];
  137. //Title button
  138. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  139. #ifdef __IPHONE_11_0
  140. if (@available(iOS 11.0, *)) {}
  141. else
  142. #endif
  143. {
  144. toolbar.titleBarButton.customView.frame = CGRectZero;
  145. }
  146. [items addObject:toolbar.titleBarButton];
  147. //Flexible space
  148. [items addObject:[[self class] flexibleBarButtonItem]];
  149. //Right button
  150. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  151. if (doneButton.isSystemItem == NO)
  152. {
  153. doneButton.title = nil;
  154. doneButton.image = image;
  155. doneButton.target = target;
  156. doneButton.action = action;
  157. }
  158. else
  159. {
  160. doneButton = [[IQBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStyleDone target:target action:action];
  161. doneButton.invocation = toolbar.doneBarButton.invocation;
  162. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  163. toolbar.doneBarButton = doneButton;
  164. }
  165. [items addObject:doneButton];
  166. // Adding button to toolBar.
  167. [toolbar setItems:items];
  168. // Setting toolbar to keyboard.
  169. [(UITextField*)self setInputAccessoryView:toolbar];
  170. }
  171. - (void)addRightButtonOnKeyboardWithImage:(UIImage*)image target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  172. {
  173. NSString *title = nil;
  174. if (shouldShowPlaceholder)
  175. title = [self drawingToolbarPlaceholder];
  176. [self addRightButtonOnKeyboardWithImage:image target:target action:action titleText:title];
  177. }
  178. - (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action titleText:(NSString*)titleText
  179. {
  180. // If can't set InputAccessoryView. Then return
  181. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  182. // Creating a toolBar for keyboard
  183. IQToolbar *toolbar = self.keyboardToolbar;
  184. if ([self respondsToSelector:@selector(keyboardAppearance)])
  185. {
  186. switch ([(UITextField*)self keyboardAppearance])
  187. {
  188. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  189. default: toolbar.barStyle = UIBarStyleDefault; break;
  190. }
  191. }
  192. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  193. //Flexible space
  194. [items addObject:[[self class] flexibleBarButtonItem]];
  195. //Title button
  196. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  197. #ifdef __IPHONE_11_0
  198. if (@available(iOS 11.0, *)) {}
  199. else
  200. #endif
  201. {
  202. toolbar.titleBarButton.customView.frame = CGRectZero;
  203. }
  204. [items addObject:toolbar.titleBarButton];
  205. //Flexible space
  206. [items addObject:[[self class] flexibleBarButtonItem]];
  207. //Right button
  208. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  209. if (doneButton.isSystemItem == NO)
  210. {
  211. doneButton.title = text;
  212. doneButton.image = nil;
  213. doneButton.target = target;
  214. doneButton.action = action;
  215. }
  216. else
  217. {
  218. doneButton =[[IQBarButtonItem alloc] initWithTitle:text style:UIBarButtonItemStyleDone target:target action:action];
  219. doneButton.invocation = toolbar.doneBarButton.invocation;
  220. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  221. toolbar.doneBarButton = doneButton;
  222. }
  223. [items addObject:doneButton];
  224. // Adding button to toolBar.
  225. [toolbar setItems:items];
  226. // Setting toolbar to keyboard.
  227. [(UITextField*)self setInputAccessoryView:toolbar];
  228. }
  229. - (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  230. {
  231. NSString *title = nil;
  232. if (shouldShowPlaceholder)
  233. title = [self drawingToolbarPlaceholder];
  234. [self addRightButtonOnKeyboardWithText:text target:target action:action titleText:title];
  235. }
  236. - (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action
  237. {
  238. [self addRightButtonOnKeyboardWithText:text target:target action:action titleText:nil];
  239. }
  240. - (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action titleText:(NSString*)titleText
  241. {
  242. // If can't set InputAccessoryView. Then return
  243. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  244. // Creating a toolBar for keyboard
  245. IQToolbar *toolbar = self.keyboardToolbar;
  246. if ([self respondsToSelector:@selector(keyboardAppearance)])
  247. {
  248. switch ([(UITextField*)self keyboardAppearance])
  249. {
  250. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  251. default: toolbar.barStyle = UIBarStyleDefault; break;
  252. }
  253. }
  254. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  255. //Flexible space
  256. [items addObject:[[self class] flexibleBarButtonItem]];
  257. //Title button
  258. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  259. #ifdef __IPHONE_11_0
  260. if (@available(iOS 11.0, *)) {}
  261. else
  262. #endif
  263. {
  264. toolbar.titleBarButton.customView.frame = CGRectZero;
  265. }
  266. [items addObject:toolbar.titleBarButton];
  267. //Flexible space
  268. [items addObject:[[self class] flexibleBarButtonItem]];
  269. //Done button
  270. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  271. if (doneButton.isSystemItem == NO)
  272. {
  273. doneButton =[[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:target action:action];
  274. doneButton.invocation = toolbar.doneBarButton.invocation;
  275. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  276. toolbar.doneBarButton = doneButton;
  277. }
  278. else
  279. {
  280. doneButton.target = target;
  281. doneButton.action = action;
  282. }
  283. [items addObject:doneButton];
  284. // Adding button to toolBar.
  285. [toolbar setItems:items];
  286. // Setting toolbar to keyboard.
  287. [(UITextField*)self setInputAccessoryView:toolbar];
  288. }
  289. -(void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  290. {
  291. NSString *title = nil;
  292. if (shouldShowPlaceholder)
  293. title = [self drawingToolbarPlaceholder];
  294. [self addDoneOnKeyboardWithTarget:target action:action titleText:title];
  295. }
  296. -(void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action
  297. {
  298. [self addDoneOnKeyboardWithTarget:target action:action titleText:nil];
  299. }
  300. - (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction titleText:(NSString*)titleText
  301. {
  302. // If can't set InputAccessoryView. Then return
  303. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  304. // Creating a toolBar for keyboard
  305. IQToolbar *toolbar = self.keyboardToolbar;
  306. if ([self respondsToSelector:@selector(keyboardAppearance)])
  307. {
  308. switch ([(UITextField*)self keyboardAppearance])
  309. {
  310. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  311. default: toolbar.barStyle = UIBarStyleDefault; break;
  312. }
  313. }
  314. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  315. //Left button
  316. IQBarButtonItem *cancelButton = toolbar.previousBarButton;
  317. if (cancelButton.isSystemItem == NO)
  318. {
  319. cancelButton.title = leftTitle;
  320. cancelButton.image = nil;
  321. cancelButton.target = target;
  322. cancelButton.action = leftAction;
  323. }
  324. else
  325. {
  326. cancelButton = [[IQBarButtonItem alloc] initWithTitle:leftTitle style:UIBarButtonItemStylePlain target:target action:leftAction];
  327. cancelButton.invocation = toolbar.previousBarButton.invocation;
  328. cancelButton.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
  329. toolbar.previousBarButton = cancelButton;
  330. }
  331. [items addObject:cancelButton];
  332. //Flexible space
  333. [items addObject:[[self class] flexibleBarButtonItem]];
  334. //Title button
  335. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  336. #ifdef __IPHONE_11_0
  337. if (@available(iOS 11.0, *)) {}
  338. else
  339. #endif
  340. {
  341. toolbar.titleBarButton.customView.frame = CGRectZero;
  342. }
  343. [items addObject:toolbar.titleBarButton];
  344. //Flexible space
  345. [items addObject:[[self class] flexibleBarButtonItem]];
  346. //Right button
  347. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  348. if (doneButton.isSystemItem == NO)
  349. {
  350. doneButton.title = rightTitle;
  351. doneButton.image = nil;
  352. doneButton.target = target;
  353. doneButton.action = rightAction;
  354. }
  355. else
  356. {
  357. doneButton =[[IQBarButtonItem alloc] initWithTitle:rightTitle style:UIBarButtonItemStyleDone target:target action:rightAction];
  358. doneButton.invocation = toolbar.doneBarButton.invocation;
  359. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  360. toolbar.doneBarButton = doneButton;
  361. }
  362. [items addObject:doneButton];
  363. // Adding button to toolBar.
  364. [toolbar setItems:items];
  365. // Setting toolbar to keyboard.
  366. [(UITextField*)self setInputAccessoryView:toolbar];
  367. }
  368. - (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  369. {
  370. NSString *title = nil;
  371. if (shouldShowPlaceholder)
  372. title = [self drawingToolbarPlaceholder];
  373. [self addLeftRightOnKeyboardWithTarget:target leftButtonTitle:leftTitle rightButtonTitle:rightTitle leftButtonAction:leftAction rightButtonAction:rightAction titleText:title];
  374. }
  375. - (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction
  376. {
  377. [self addLeftRightOnKeyboardWithTarget:target leftButtonTitle:leftTitle rightButtonTitle:rightTitle leftButtonAction:leftAction rightButtonAction:rightAction titleText:nil];
  378. }
  379. - (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction titleText:(NSString*)titleText
  380. {
  381. // If can't set InputAccessoryView. Then return
  382. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  383. // Creating a toolBar for keyboard
  384. IQToolbar *toolbar = self.keyboardToolbar;
  385. if ([self respondsToSelector:@selector(keyboardAppearance)])
  386. {
  387. switch ([(UITextField*)self keyboardAppearance])
  388. {
  389. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  390. default: toolbar.barStyle = UIBarStyleDefault; break;
  391. }
  392. }
  393. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  394. //Cancel button
  395. IQBarButtonItem *cancelButton = toolbar.previousBarButton;
  396. if (cancelButton.isSystemItem == NO)
  397. {
  398. cancelButton =[[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:target action:cancelAction];
  399. cancelButton.invocation = toolbar.previousBarButton.invocation;
  400. cancelButton.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
  401. toolbar.previousBarButton = cancelButton;
  402. }
  403. else
  404. {
  405. cancelButton.target = target;
  406. cancelButton.action = cancelAction;
  407. }
  408. [items addObject:cancelButton];
  409. //Flexible space
  410. [items addObject:[[self class] flexibleBarButtonItem]];
  411. //Title button
  412. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  413. #ifdef __IPHONE_11_0
  414. if (@available(iOS 11.0, *)) {}
  415. else
  416. #endif
  417. {
  418. toolbar.titleBarButton.customView.frame = CGRectZero;
  419. }
  420. [items addObject:toolbar.titleBarButton];
  421. //Flexible space
  422. [items addObject:[[self class] flexibleBarButtonItem]];
  423. //Done button
  424. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  425. if (doneButton.isSystemItem == NO)
  426. {
  427. doneButton =[[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:target action:doneAction];
  428. doneButton.invocation = toolbar.doneBarButton.invocation;
  429. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  430. toolbar.doneBarButton = doneButton;
  431. }
  432. else
  433. {
  434. doneButton.target = target;
  435. doneButton.action = doneAction;
  436. }
  437. [items addObject:doneButton];
  438. // Adding button to toolBar.
  439. [toolbar setItems:items];
  440. // Setting toolbar to keyboard.
  441. [(UITextField*)self setInputAccessoryView:toolbar];
  442. }
  443. -(void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  444. {
  445. NSString *title = nil;
  446. if (shouldShowPlaceholder)
  447. title = [self drawingToolbarPlaceholder];
  448. [self addCancelDoneOnKeyboardWithTarget:target cancelAction:cancelAction doneAction:doneAction titleText:title];
  449. }
  450. -(void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction
  451. {
  452. [self addCancelDoneOnKeyboardWithTarget:target cancelAction:cancelAction doneAction:doneAction titleText:nil];
  453. }
  454. - (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction titleText:(NSString*)titleText
  455. {
  456. //If can't set InputAccessoryView. Then return
  457. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  458. // Creating a toolBar for phoneNumber keyboard
  459. IQToolbar *toolbar = self.keyboardToolbar;
  460. if ([self respondsToSelector:@selector(keyboardAppearance)])
  461. {
  462. switch ([(UITextField*)self keyboardAppearance])
  463. {
  464. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  465. default: toolbar.barStyle = UIBarStyleDefault; break;
  466. }
  467. }
  468. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  469. // Get the top level "bundle" which may actually be the framework
  470. NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
  471. // Check to see if the resource bundle exists inside the top level bundle
  472. NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
  473. if (resourcesBundle == nil) {
  474. resourcesBundle = mainBundle;
  475. }
  476. UIImage *imageLeftArrow = nil;
  477. UIImage *imageRightArrow = nil;
  478. #ifdef __IPHONE_11_0
  479. if (@available(iOS 10.0, *))
  480. #else
  481. if (IQ_IS_IOS10_OR_GREATER)
  482. #endif
  483. {
  484. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowUp" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  485. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowDown" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  486. }
  487. else
  488. {
  489. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowLeft" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  490. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowRight" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  491. }
  492. //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
  493. #ifdef __IPHONE_11_0
  494. if (@available(iOS 9.0, *)) {
  495. #endif
  496. if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
  497. {
  498. imageLeftArrow = [imageLeftArrow imageFlippedForRightToLeftLayoutDirection];
  499. imageRightArrow = [imageRightArrow imageFlippedForRightToLeftLayoutDirection];
  500. }
  501. #ifdef __IPHONE_11_0
  502. }
  503. #endif
  504. //Previous button
  505. IQBarButtonItem *prev = toolbar.previousBarButton;
  506. if (prev.isSystemItem == NO)
  507. {
  508. prev.title = nil;
  509. prev.image = imageLeftArrow;
  510. prev.target = target;
  511. prev.action = previousAction;
  512. }
  513. else
  514. {
  515. prev = [[IQBarButtonItem alloc] initWithImage:imageLeftArrow style:UIBarButtonItemStylePlain target:target action:previousAction];
  516. prev.invocation = toolbar.previousBarButton.invocation;
  517. prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
  518. toolbar.previousBarButton = prev;
  519. }
  520. [items addObject:prev];
  521. //Fixed space
  522. IQBarButtonItem *fixed = toolbar.fixedSpaceBarButton;
  523. #ifdef __IPHONE_11_0
  524. if (@available(iOS 10.0, *))
  525. #else
  526. if (IQ_IS_IOS10_OR_GREATER)
  527. #endif
  528. {
  529. [fixed setWidth:6];
  530. }
  531. else
  532. {
  533. [fixed setWidth:20];
  534. }
  535. [items addObject:fixed];
  536. //Next button
  537. IQBarButtonItem *next = toolbar.nextBarButton;
  538. if (next.isSystemItem == NO)
  539. {
  540. next.title = nil;
  541. next.image = imageRightArrow;
  542. next.target = target;
  543. next.action = nextAction;
  544. }
  545. else
  546. {
  547. next = [[IQBarButtonItem alloc] initWithImage:imageRightArrow style:UIBarButtonItemStylePlain target:target action:nextAction];
  548. next.invocation = toolbar.nextBarButton.invocation;
  549. next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
  550. toolbar.nextBarButton = next;
  551. }
  552. [items addObject:next];
  553. //Flexible space
  554. [items addObject:[[self class] flexibleBarButtonItem]];
  555. //Title button
  556. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  557. #ifdef __IPHONE_11_0
  558. if (@available(iOS 11.0, *)) {}
  559. else
  560. #endif
  561. {
  562. toolbar.titleBarButton.customView.frame = CGRectZero;
  563. }
  564. [items addObject:toolbar.titleBarButton];
  565. //Flexible space
  566. [items addObject:[[self class] flexibleBarButtonItem]];
  567. //Done button
  568. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  569. if (doneButton.isSystemItem == NO)
  570. {
  571. doneButton =[[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:target action:doneAction];
  572. doneButton.invocation = toolbar.doneBarButton.invocation;
  573. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  574. toolbar.doneBarButton = doneButton;
  575. }
  576. else
  577. {
  578. doneButton.target = target;
  579. doneButton.action = doneAction;
  580. }
  581. [items addObject:doneButton];
  582. // Adding button to toolBar.
  583. [toolbar setItems:items];
  584. // Setting toolbar to keyboard.
  585. [(UITextField*)self setInputAccessoryView:toolbar];
  586. }
  587. -(void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  588. {
  589. NSString *title = nil;
  590. if (shouldShowPlaceholder)
  591. title = [self drawingToolbarPlaceholder];
  592. [self addPreviousNextDoneOnKeyboardWithTarget:target previousAction:previousAction nextAction:nextAction doneAction:doneAction titleText:title];
  593. }
  594. -(void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction
  595. {
  596. [self addPreviousNextDoneOnKeyboardWithTarget:target previousAction:previousAction nextAction:nextAction doneAction:doneAction titleText:nil];
  597. }
  598. - (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonImage:(UIImage*)rightButtonImage previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText
  599. {
  600. //If can't set InputAccessoryView. Then return
  601. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  602. // Creating a toolBar for phoneNumber keyboard
  603. IQToolbar *toolbar = self.keyboardToolbar;
  604. if ([self respondsToSelector:@selector(keyboardAppearance)])
  605. {
  606. switch ([(UITextField*)self keyboardAppearance])
  607. {
  608. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  609. default: toolbar.barStyle = UIBarStyleDefault; break;
  610. }
  611. }
  612. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  613. // Get the top level "bundle" which may actually be the framework
  614. NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
  615. // Check to see if the resource bundle exists inside the top level bundle
  616. NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
  617. if (resourcesBundle == nil) {
  618. resourcesBundle = mainBundle;
  619. }
  620. UIImage *imageLeftArrow = nil;
  621. UIImage *imageRightArrow = nil;
  622. #ifdef __IPHONE_11_0
  623. if (@available(iOS 10.0, *))
  624. #else
  625. if (IQ_IS_IOS10_OR_GREATER)
  626. #endif
  627. {
  628. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowUp" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  629. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowDown" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  630. }
  631. else
  632. {
  633. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowLeft" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  634. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowRight" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  635. }
  636. //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
  637. #ifdef __IPHONE_11_0
  638. if (@available(iOS 9.0, *)) {
  639. #endif
  640. if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
  641. {
  642. imageLeftArrow = [imageLeftArrow imageFlippedForRightToLeftLayoutDirection];
  643. imageRightArrow = [imageRightArrow imageFlippedForRightToLeftLayoutDirection];
  644. }
  645. #ifdef __IPHONE_11_0
  646. }
  647. #endif
  648. //Previous button
  649. IQBarButtonItem *prev = toolbar.previousBarButton;
  650. if (prev.isSystemItem == NO)
  651. {
  652. prev.title = nil;
  653. prev.image = imageLeftArrow;
  654. prev.target = target;
  655. prev.action = previousAction;
  656. }
  657. else
  658. {
  659. prev = [[IQBarButtonItem alloc] initWithImage:imageLeftArrow style:UIBarButtonItemStylePlain target:target action:previousAction];
  660. prev.invocation = toolbar.previousBarButton.invocation;
  661. prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
  662. toolbar.previousBarButton = prev;
  663. }
  664. [items addObject:prev];
  665. //Fixed space
  666. IQBarButtonItem *fixed = toolbar.fixedSpaceBarButton;
  667. #ifdef __IPHONE_11_0
  668. if (@available(iOS 10.0, *))
  669. #else
  670. if (IQ_IS_IOS10_OR_GREATER)
  671. #endif
  672. {
  673. [fixed setWidth:6];
  674. }
  675. else
  676. {
  677. [fixed setWidth:20];
  678. }
  679. [items addObject:fixed];
  680. //Next button
  681. IQBarButtonItem *next = toolbar.nextBarButton;
  682. if (next.isSystemItem == NO)
  683. {
  684. next.title = nil;
  685. next.image = imageRightArrow;
  686. next.target = target;
  687. next.action = nextAction;
  688. }
  689. else
  690. {
  691. next = [[IQBarButtonItem alloc] initWithImage:imageRightArrow style:UIBarButtonItemStylePlain target:target action:nextAction];
  692. next.invocation = toolbar.nextBarButton.invocation;
  693. next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
  694. toolbar.nextBarButton = next;
  695. }
  696. [items addObject:next];
  697. //Flexible space
  698. [items addObject:[[self class] flexibleBarButtonItem]];
  699. //Title button
  700. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  701. #ifdef __IPHONE_11_0
  702. if (@available(iOS 11.0, *)) {}
  703. else
  704. #endif
  705. {
  706. toolbar.titleBarButton.customView.frame = CGRectZero;
  707. }
  708. [items addObject:toolbar.titleBarButton];
  709. //Flexible space
  710. [items addObject:[[self class] flexibleBarButtonItem]];
  711. //Right button
  712. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  713. if (doneButton.isSystemItem == NO)
  714. {
  715. doneButton.title = nil;
  716. doneButton.image = rightButtonImage;
  717. doneButton.target = target;
  718. doneButton.action = rightButtonAction;
  719. }
  720. else
  721. {
  722. doneButton = [[IQBarButtonItem alloc] initWithImage:rightButtonImage style:UIBarButtonItemStyleDone target:target action:rightButtonAction];
  723. doneButton.invocation = toolbar.doneBarButton.invocation;
  724. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  725. toolbar.doneBarButton = doneButton;
  726. }
  727. [items addObject:doneButton];
  728. // Adding button to toolBar.
  729. [toolbar setItems:items];
  730. // Setting toolbar to keyboard.
  731. [(UITextField*)self setInputAccessoryView:toolbar];
  732. }
  733. - (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  734. {
  735. NSString *title = nil;
  736. if (shouldShowPlaceholder)
  737. title = [self drawingToolbarPlaceholder];
  738. [self addPreviousNextRightOnKeyboardWithTarget:target rightButtonImage:rightButtonImage previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:title];
  739. }
  740. - (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText
  741. {
  742. //If can't set InputAccessoryView. Then return
  743. if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
  744. // Creating a toolBar for phoneNumber keyboard
  745. IQToolbar *toolbar = self.keyboardToolbar;
  746. if ([self respondsToSelector:@selector(keyboardAppearance)])
  747. {
  748. switch ([(UITextField*)self keyboardAppearance])
  749. {
  750. case UIKeyboardAppearanceAlert: toolbar.barStyle = UIBarStyleBlack; break;
  751. default: toolbar.barStyle = UIBarStyleDefault; break;
  752. }
  753. }
  754. NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
  755. // Get the top level "bundle" which may actually be the framework
  756. NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
  757. // Check to see if the resource bundle exists inside the top level bundle
  758. NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
  759. if (resourcesBundle == nil) {
  760. resourcesBundle = mainBundle;
  761. }
  762. UIImage *imageLeftArrow = nil;
  763. UIImage *imageRightArrow = nil;
  764. #ifdef __IPHONE_11_0
  765. if (@available(iOS 10.0, *))
  766. #else
  767. if (IQ_IS_IOS10_OR_GREATER)
  768. #endif
  769. {
  770. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowUp" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  771. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowDown" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  772. }
  773. else
  774. {
  775. imageLeftArrow = [UIImage imageNamed:@"IQButtonBarArrowLeft" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  776. imageRightArrow = [UIImage imageNamed:@"IQButtonBarArrowRight" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
  777. }
  778. //Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
  779. #ifdef __IPHONE_11_0
  780. if (@available(iOS 9.0, *)) {
  781. #endif
  782. if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
  783. {
  784. imageLeftArrow = [imageLeftArrow imageFlippedForRightToLeftLayoutDirection];
  785. imageRightArrow = [imageRightArrow imageFlippedForRightToLeftLayoutDirection];
  786. }
  787. #ifdef __IPHONE_11_0
  788. }
  789. #endif
  790. //Previous button
  791. IQBarButtonItem *prev = toolbar.previousBarButton;
  792. if (prev.isSystemItem == NO)
  793. {
  794. prev.title = nil;
  795. prev.image = imageLeftArrow;
  796. prev.target = target;
  797. prev.action = previousAction;
  798. }
  799. else
  800. {
  801. prev = [[IQBarButtonItem alloc] initWithImage:imageLeftArrow style:UIBarButtonItemStylePlain target:target action:previousAction];
  802. prev.invocation = toolbar.previousBarButton.invocation;
  803. prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
  804. toolbar.previousBarButton = prev;
  805. }
  806. [items addObject:prev];
  807. //Fixed space
  808. IQBarButtonItem *fixed = toolbar.fixedSpaceBarButton;
  809. #ifdef __IPHONE_11_0
  810. if (@available(iOS 10.0, *))
  811. #else
  812. if (IQ_IS_IOS10_OR_GREATER)
  813. #endif
  814. {
  815. [fixed setWidth:6];
  816. }
  817. else
  818. {
  819. [fixed setWidth:20];
  820. }
  821. [items addObject:fixed];
  822. //Next button
  823. IQBarButtonItem *next = toolbar.nextBarButton;
  824. if (next.isSystemItem == NO)
  825. {
  826. next.title = nil;
  827. next.image = imageRightArrow;
  828. next.target = target;
  829. next.action = nextAction;
  830. }
  831. else
  832. {
  833. next = [[IQBarButtonItem alloc] initWithImage:imageRightArrow style:UIBarButtonItemStylePlain target:target action:nextAction];
  834. next.invocation = toolbar.nextBarButton.invocation;
  835. next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
  836. toolbar.nextBarButton = next;
  837. }
  838. [items addObject:next];
  839. //Flexible space
  840. [items addObject:[[self class] flexibleBarButtonItem]];
  841. //Title button
  842. toolbar.titleBarButton.title = self.shouldHideToolbarPlaceholder?nil:titleText;
  843. #ifdef __IPHONE_11_0
  844. if (@available(iOS 11.0, *)) {}
  845. else
  846. #endif
  847. {
  848. toolbar.titleBarButton.customView.frame = CGRectZero;
  849. }
  850. [items addObject:toolbar.titleBarButton];
  851. //Flexible space
  852. [items addObject:[[self class] flexibleBarButtonItem]];
  853. //Right button
  854. IQBarButtonItem *doneButton = toolbar.doneBarButton;
  855. if (doneButton.isSystemItem == NO)
  856. {
  857. doneButton.title = rightButtonTitle;
  858. doneButton.image = nil;
  859. doneButton.target = target;
  860. doneButton.action = rightButtonAction;
  861. }
  862. else
  863. {
  864. doneButton =[[IQBarButtonItem alloc] initWithTitle:rightButtonTitle style:UIBarButtonItemStyleDone target:target action:rightButtonAction];
  865. doneButton.invocation = toolbar.doneBarButton.invocation;
  866. doneButton.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
  867. toolbar.doneBarButton = doneButton;
  868. }
  869. [items addObject:doneButton];
  870. // Adding button to toolBar.
  871. [toolbar setItems:items];
  872. // Setting toolbar to keyboard.
  873. [(UITextField*)self setInputAccessoryView:toolbar];
  874. }
  875. - (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
  876. {
  877. NSString *title = nil;
  878. if (shouldShowPlaceholder)
  879. title = [self drawingToolbarPlaceholder];
  880. [self addPreviousNextRightOnKeyboardWithTarget:target rightButtonTitle:rightButtonTitle previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:title];
  881. }
  882. - (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction
  883. {
  884. [self addPreviousNextRightOnKeyboardWithTarget:target rightButtonTitle:rightButtonTitle previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:nil];
  885. }
  886. @end