TBKeyboardToolbar.m 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //
  2. // TBKeyboardToolbar.m
  3. //
  4. // Created by Rudd Fawcett on 12/3/13.
  5. // Copyright (c) 2013 Rudd Fawcett. All rights reserved.
  6. //
  7. #import "TBKeyboardToolbar.h"
  8. #define kToolbarHeight 44
  9. @interface TBKeyboardToolbar ()
  10. /// The fake top border to replicate the toolbar.
  11. @property (nonatomic) CALayer *topBorder;
  12. @property (nonatomic) UIView *toolbarView;
  13. @property (nonatomic) UIScrollView *scrollView;
  14. @property (nonatomic) UIVisualEffectView *blurView;
  15. @end
  16. @implementation TBKeyboardToolbar
  17. + (instancetype)toolbarWithButtons:(NSArray *)buttons {
  18. return [[self alloc] initWithButtons:buttons];
  19. }
  20. - (id)initWithButtons:(NSArray *)buttons {
  21. self = [super initWithFrame:CGRectMake(0, 0, self.window.rootViewController.view.bounds.size.width, kToolbarHeight)];
  22. if (self) {
  23. _buttons = [buttons copy];
  24. self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
  25. self.appearance = UIKeyboardAppearanceLight;
  26. }
  27. return self;
  28. }
  29. - (void)setAppearance:(UIKeyboardAppearance)appearance {
  30. _appearance = appearance;
  31. if (self.toolbarView) {
  32. [self.toolbarView removeFromSuperview];
  33. }
  34. [self addSubview:self.inputAccessoryView];
  35. }
  36. - (void)layoutSubviews {
  37. CGRect frame = _toolbarView.bounds;
  38. frame.size.height = 0.5f;
  39. _topBorder.frame = frame;
  40. }
  41. - (UIView *)inputAccessoryView {
  42. _topBorder = [CALayer layer];
  43. _topBorder.frame = CGRectMake(0.0f, 0.0f, self.bounds.size.width, 0.5f);
  44. switch (_appearance) {
  45. case UIKeyboardAppearanceDefault:
  46. case UIKeyboardAppearanceLight: {
  47. _toolbarView = [UIView new];
  48. _toolbarView.backgroundColor = [UIColor colorWithRed:0.799 green:0.814 blue:0.847 alpha:1.000];
  49. _topBorder.backgroundColor = [UIColor clearColor].CGColor;
  50. [_toolbarView.layer addSublayer:_topBorder];
  51. [_toolbarView addSubview:[self fakeToolbar]];
  52. break;
  53. }
  54. case UIKeyboardAppearanceDark: {
  55. UIVisualEffect *darkBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
  56. _blurView = [[UIVisualEffectView alloc] initWithEffect:darkBlur];
  57. _toolbarView = _blurView;
  58. _topBorder.backgroundColor = [UIColor colorWithWhite:0.100 alpha:1.000].CGColor;
  59. [_blurView.contentView.layer addSublayer:_topBorder];
  60. [_blurView.contentView addSubview:[self fakeToolbar]];
  61. break;
  62. }
  63. }
  64. _toolbarView.frame = CGRectMake(0, 0, self.bounds.size.width, kToolbarHeight);
  65. _toolbarView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  66. return _toolbarView;
  67. }
  68. - (UIScrollView *)fakeToolbar {
  69. _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, kToolbarHeight)];
  70. _scrollView.backgroundColor = [UIColor clearColor];
  71. _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  72. _scrollView.contentInset = UIEdgeInsetsMake(8.0f, 0.0f, 4.0f, 6.0f);
  73. _scrollView.showsHorizontalScrollIndicator = NO;
  74. [self addButtons];
  75. return _scrollView;
  76. }
  77. - (void)addButtons {
  78. NSUInteger spacing = 6;
  79. NSUInteger originX = spacing;
  80. CGRect originFrame;
  81. CGFloat top = _scrollView.contentInset.top;
  82. CGFloat bottom = _scrollView.contentInset.bottom;
  83. for (TBToolbarButton *button in _buttons) {
  84. button.appearance = self.appearance;
  85. originFrame = button.frame;
  86. originFrame.origin.x = originX;
  87. originFrame.origin.y = 0;
  88. originFrame.size.height = kToolbarHeight - (top + bottom);
  89. button.frame = originFrame;
  90. [_scrollView addSubview:button];
  91. originX += button.bounds.size.width + spacing;
  92. }
  93. CGSize contentSize = _scrollView.contentSize;
  94. contentSize.width = originX - spacing;
  95. _scrollView.contentSize = contentSize;
  96. }
  97. - (void)setButtons:(NSArray<TBToolbarButton*> *)buttons {
  98. [_buttons makeObjectsPerformSelector:@selector(removeFromSuperview)];
  99. _buttons = buttons.copy;
  100. [self addButtons];
  101. }
  102. - (void)setButtons:(NSArray<TBToolbarButton*> *)buttons animated:(BOOL)animated {
  103. if (!animated) {
  104. self.buttons = buttons;
  105. return;
  106. }
  107. NSMutableSet *buttonstoRemove = [NSMutableSet setWithArray:_buttons];
  108. [buttonstoRemove minusSet:[NSSet setWithArray:buttons]];
  109. NSMutableSet *buttonsToAdd = [NSMutableSet setWithArray:buttons];
  110. [buttonsToAdd minusSet:[NSSet setWithArray:_buttons]];
  111. if (!buttonstoRemove.count && !buttonsToAdd.count) {
  112. return;
  113. }
  114. // New buttons are invisible at first
  115. for (TBToolbarButton *button in buttons) {
  116. button.alpha = 0;
  117. }
  118. [UIView animateWithDuration:0.1 animations:^{
  119. // Fade out old buttons
  120. for (TBToolbarButton *button in _buttons) {
  121. button.alpha = 0;
  122. }
  123. } completion:^(BOOL finished) {
  124. // Remove old, add new
  125. self.buttons = buttons;
  126. [UIView animateWithDuration:0.1 animations:^{
  127. // Fade in new buttons
  128. for (TBToolbarButton *button in buttons) {
  129. button.alpha = 1;
  130. }
  131. }];
  132. }];
  133. }
  134. @end