TOPasscodeButtonLabel.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //
  2. // TOPasscodeButtonLabel.m
  3. //
  4. // Copyright 2017 Timothy Oliver. All rights reserved.
  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
  8. // deal in the Software without restriction, including without limitation the
  9. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. // sell 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
  17. // OR 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 LIABILITY,
  20. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
  21. // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. #import "TOPasscodeButtonLabel.h"
  23. @interface TOPasscodeButtonLabel ()
  24. @property (nonatomic, strong, readwrite) UILabel *numberLabel;
  25. @property (nonatomic, strong, readwrite) UILabel *letteringLabel;
  26. @end
  27. @implementation TOPasscodeButtonLabel
  28. #pragma mark - View Setup -
  29. - (instancetype)initWithFrame:(CGRect)frame
  30. {
  31. if (self = [super initWithFrame:frame]) {
  32. _letteringVerticalSpacing = 6.0f;
  33. _letteringCharacterSpacing = 3.0f;
  34. _letteringHorizontalSpacing = 5.0f;
  35. _numberLabelFont = [UIFont systemFontOfSize:37.5f weight:UIFontWeightThin];
  36. _letteringLabelFont = [UIFont systemFontOfSize:9.0f weight:UIFontWeightThin];
  37. [self setUpViews];
  38. }
  39. return self;
  40. }
  41. - (void)setUpViews
  42. {
  43. if (!self.numberLabel) {
  44. self.numberLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  45. self.numberLabel.text = self.numberString;
  46. self.numberLabel.textColor = self.textColor;
  47. self.numberLabel.font = self.numberLabelFont;
  48. [self.numberLabel sizeToFit];
  49. [self addSubview:self.numberLabel];
  50. }
  51. // Create the lettering string only if we have a lettering value for it
  52. if (!self.letteringLabel && self.letteringString.length > 0) {
  53. self.letteringLabel = [[UILabel alloc] initWithFrame:CGRectZero];
  54. self.letteringLabel.textColor = self.textColor;
  55. self.letteringLabel.font = self.letteringLabelFont;
  56. [self.letteringLabel sizeToFit];
  57. [self addSubview:self.letteringLabel];
  58. [self updateLetteringLabelText];
  59. }
  60. }
  61. #pragma mark - View Layout -
  62. - (void)updateLetteringLabelText
  63. {
  64. if (self.letteringString.length == 0) {
  65. return;
  66. }
  67. NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString:self.letteringString];
  68. [attrStr addAttribute:NSKernAttributeName value:@(_letteringCharacterSpacing) range:NSMakeRange(0, attrStr.length-1)];
  69. self.letteringLabel.attributedText = attrStr;
  70. }
  71. - (void)layoutSubviews
  72. {
  73. [super layoutSubviews];
  74. CGSize viewSize = self.bounds.size;
  75. [self.numberLabel sizeToFit];
  76. [self.letteringLabel sizeToFit];
  77. CGFloat numberVerticalHeight = self.numberLabelFont.capHeight;
  78. CGFloat letteringVerticalHeight = self.letteringLabelFont.capHeight;
  79. CGFloat textTotalHeight = (numberVerticalHeight+2.0f) + self.letteringVerticalSpacing + (letteringVerticalHeight+2.0f);
  80. CGRect frame = self.numberLabel.frame;
  81. frame.size.height = ceil(numberVerticalHeight) + 2.0f;
  82. frame.origin.x = ceilf((viewSize.width - frame.size.width) * 0.5f);
  83. if (!self.horizontalLayout && !self.verticallyCenterNumberLabel) {
  84. frame.origin.y = floorf((viewSize.height - textTotalHeight) * 0.5f);
  85. }
  86. else {
  87. frame.origin.y = floorf((viewSize.height - frame.size.height) * 0.5f);
  88. }
  89. self.numberLabel.frame = CGRectIntegral(frame);
  90. if (self.letteringLabel) {
  91. CGFloat y = CGRectGetMaxY(frame);
  92. y += self.letteringVerticalSpacing;
  93. frame = self.letteringLabel.frame;
  94. frame.size.height = ceil(letteringVerticalHeight) + 2.0f;
  95. if (!self.horizontalLayout) {
  96. frame.origin.y = floorf(y);
  97. frame.origin.x = (viewSize.width - frame.size.width) * 0.5f;
  98. }
  99. else {
  100. frame.origin.y = floorf((viewSize.height - frame.size.height) * 0.5f);
  101. frame.origin.x = CGRectGetMaxX(self.numberLabel.frame) + self.letteringHorizontalSpacing;
  102. }
  103. self.letteringLabel.frame = CGRectIntegral(frame);
  104. }
  105. }
  106. #pragma mark - Accessors -
  107. - (void)setTextColor:(UIColor *)textColor
  108. {
  109. if (textColor == _textColor) { return; }
  110. _textColor = textColor;
  111. self.numberLabel.textColor = _textColor;
  112. self.letteringLabel.textColor = _textColor;
  113. }
  114. /***********************************************************/
  115. - (void)setNumberString:(NSString *)numberString
  116. {
  117. self.numberLabel.text = numberString;
  118. [self setNeedsLayout];
  119. }
  120. - (NSString *)numberString { return self.numberLabel.text; }
  121. /***********************************************************/
  122. - (void)setLetteringString:(NSString *)letteringString
  123. {
  124. _letteringString = [letteringString copy];
  125. [self setUpViews];
  126. [self updateLetteringLabelText];
  127. [self setNeedsLayout];
  128. }
  129. /***********************************************************/
  130. - (void)setLetteringCharacterSpacing:(CGFloat)letteringCharacterSpacing
  131. {
  132. _letteringCharacterSpacing = letteringCharacterSpacing;
  133. [self updateLetteringLabelText];
  134. }
  135. /***********************************************************/
  136. - (void)setNumberLabelFont:(UIFont *)numberLabelFont
  137. {
  138. if (_numberLabelFont == numberLabelFont) { return; }
  139. _numberLabelFont = numberLabelFont;
  140. self.numberLabel.font = _numberLabelFont;
  141. }
  142. /***********************************************************/
  143. - (void)setLetteringLabelFont:(UIFont *)letteringLabelFont
  144. {
  145. if (_letteringLabelFont == letteringLabelFont) { return; }
  146. _letteringLabelFont = letteringLabelFont;
  147. self.letteringLabel.font = letteringLabelFont;
  148. }
  149. @end