MMAlertView.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. //
  2. // MMAlertView.m
  3. // MMPopupView
  4. //
  5. // Created by Ralph Li on 9/6/15.
  6. // Copyright © 2015 LJC. All rights reserved.
  7. //
  8. #import "MMAlertView.h"
  9. #import "MMPopupItem.h"
  10. #import "MMPopupCategory.h"
  11. #import "MMPopupDefine.h"
  12. #import <Masonry/Masonry.h>
  13. @interface MMAlertView()
  14. @property (nonatomic, strong) UILabel *titleLabel;
  15. @property (nonatomic, strong) UILabel *detailLabel;
  16. @property (nonatomic, strong) UITextField *inputView;
  17. @property (nonatomic, strong) UIView *buttonView;
  18. @property (nonatomic, strong) NSArray *actionItems;
  19. @property (nonatomic, copy) MMPopupInputHandler inputHandler;
  20. @end
  21. @implementation MMAlertView
  22. - (instancetype) initWithInputTitle:(NSString *)title
  23. detail:(NSString *)detail
  24. placeholder:(NSString *)inputPlaceholder
  25. keyboardType:(UIKeyboardType)keyboardType
  26. items:(NSArray*)items
  27. handler:(MMPopupInputHandler)inputHandler
  28. {
  29. return [self initWithTitle:title detail:detail items:items inputPlaceholder:inputPlaceholder keyboardType:keyboardType inputHandler:inputHandler];
  30. }
  31. - (instancetype) initWithConfirmTitle:(NSString*)title
  32. detail:(NSString*)detail
  33. {
  34. MMAlertViewConfig *config = [MMAlertViewConfig globalConfig];
  35. NSArray *items =@[
  36. MMItemMake(config.defaultTextOK, MMItemTypeNormal, nil)
  37. ];
  38. return [self initWithTitle:title detail:detail items:items inputPlaceholder:nil keyboardType:UIKeyboardTypeDefault inputHandler:nil];
  39. }
  40. - (instancetype) initWithTitle:(NSString*)title
  41. detail:(NSString*)detail
  42. items:(NSArray*)items
  43. {
  44. return [self initWithTitle:title detail:detail items:items inputPlaceholder:nil keyboardType:UIKeyboardTypeDefault inputHandler:nil];
  45. }
  46. - (instancetype)initWithTitle:(NSString *)title
  47. detail:(NSString *)detail
  48. items:(NSArray *)items
  49. inputPlaceholder:(NSString *)inputPlaceholder
  50. keyboardType:(UIKeyboardType)keyboardType
  51. inputHandler:(MMPopupInputHandler)inputHandler
  52. {
  53. self = [super init];
  54. if ( self )
  55. {
  56. NSAssert(items.count>0, @"Could not find any items.");
  57. MMAlertViewConfig *config = [MMAlertViewConfig globalConfig];
  58. self.type = MMPopupTypeAlert;
  59. self.withKeyboard = (inputHandler!=nil);
  60. self.inputHandler = inputHandler;
  61. self.actionItems = items;
  62. self.layer.cornerRadius = config.cornerRadius;
  63. self.clipsToBounds = YES;
  64. self.backgroundColor = config.backgroundColor;
  65. self.layer.borderWidth = MM_SPLIT_WIDTH;
  66. self.layer.borderColor = config.splitColor.CGColor;
  67. [self mas_makeConstraints:^(MASConstraintMaker *make) {
  68. make.width.mas_equalTo(config.width);
  69. }];
  70. [self setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
  71. [self setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisVertical];
  72. MASViewAttribute *lastAttribute = self.mas_top;
  73. if ( title.length > 0 )
  74. {
  75. self.titleLabel = [UILabel new];
  76. [self addSubview:self.titleLabel];
  77. [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  78. make.top.equalTo(lastAttribute).offset(config.innerMargin);
  79. make.left.right.equalTo(self).insets(UIEdgeInsetsMake(0, config.innerMargin, 0, config.innerMargin));
  80. }];
  81. self.titleLabel.textColor = config.titleColor;
  82. self.titleLabel.textAlignment = NSTextAlignmentCenter;
  83. self.titleLabel.font = [UIFont boldSystemFontOfSize:config.titleFontSize];
  84. self.titleLabel.numberOfLines = 0;
  85. self.titleLabel.backgroundColor = self.backgroundColor;
  86. self.titleLabel.text = title;
  87. lastAttribute = self.titleLabel.mas_bottom;
  88. }
  89. else
  90. {
  91. self.titleLabel = [UILabel new];
  92. [self addSubview:self.titleLabel];
  93. [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  94. make.top.equalTo(lastAttribute).offset(config.innerMargin);
  95. make.left.right.equalTo(self).insets(UIEdgeInsetsMake(0, 5, 0, 5));
  96. }];
  97. lastAttribute = self.titleLabel.mas_bottom;
  98. }
  99. if ( detail.length > 0 )
  100. {
  101. self.detailLabel = [UILabel new];
  102. [self addSubview:self.detailLabel];
  103. [self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  104. make.top.equalTo(lastAttribute).offset(10);
  105. make.left.right.equalTo(self).insets(UIEdgeInsetsMake(0, config.innerMargin, 0, config.innerMargin));
  106. }];
  107. self.detailLabel.textColor = config.detailColor;
  108. self.detailLabel.textAlignment = NSTextAlignmentCenter;
  109. self.detailLabel.font = [UIFont systemFontOfSize:config.detailFontSize];
  110. self.detailLabel.numberOfLines = 0;
  111. self.detailLabel.backgroundColor = self.backgroundColor;
  112. self.detailLabel.text = detail;
  113. lastAttribute = self.detailLabel.mas_bottom;
  114. }
  115. if ( self.inputHandler )
  116. {
  117. self.inputView = [UITextField new];
  118. [self addSubview:self.inputView];
  119. [self.inputView mas_makeConstraints:^(MASConstraintMaker *make) {
  120. make.top.equalTo(lastAttribute).offset(10);
  121. make.left.right.equalTo(self).insets(UIEdgeInsetsMake(0, config.innerMargin, 0, config.innerMargin));
  122. make.height.mas_equalTo(40);
  123. }];
  124. self.inputView.backgroundColor = self.backgroundColor;
  125. self.inputView.layer.borderWidth = MM_SPLIT_WIDTH;
  126. self.inputView.layer.borderColor = config.splitColor.CGColor;
  127. self.inputView.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
  128. self.inputView.leftViewMode = UITextFieldViewModeAlways;
  129. self.inputView.clearButtonMode = UITextFieldViewModeWhileEditing;
  130. self.inputView.placeholder = inputPlaceholder;
  131. self.inputView.font = [UIFont systemFontOfSize:13.0];
  132. if (keyboardType)
  133. {
  134. self.inputView.keyboardType = keyboardType;
  135. }
  136. self.inputView.textAlignment = NSTextAlignmentCenter;
  137. lastAttribute = self.inputView.mas_bottom;
  138. }
  139. self.buttonView = [UIView new];
  140. [self addSubview:self.buttonView];
  141. [self.buttonView mas_makeConstraints:^(MASConstraintMaker *make) {
  142. make.top.equalTo(lastAttribute).offset(config.innerMargin);
  143. make.left.right.equalTo(self);
  144. }];
  145. __block UIButton *firstButton = nil;
  146. __block UIButton *lastButton = nil;
  147. for ( NSInteger i = 0 ; i < items.count; ++i )
  148. {
  149. MMPopupItem *item = items[i];
  150. UIButton *btn = [UIButton mm_buttonWithTarget:self action:@selector(actionButton:)];
  151. [self.buttonView addSubview:btn];
  152. btn.tag = i;
  153. [btn mas_makeConstraints:^(MASConstraintMaker *make) {
  154. if ( items.count <= 2)
  155. {
  156. make.top.bottom.equalTo(self.buttonView);
  157. make.height.mas_equalTo(config.buttonHeight);
  158. if ( !firstButton )
  159. {
  160. firstButton = btn;
  161. make.left.equalTo(self.buttonView.mas_left).offset(-MM_SPLIT_WIDTH);
  162. }
  163. else
  164. {
  165. make.left.equalTo(lastButton.mas_right).offset(-MM_SPLIT_WIDTH);
  166. make.width.equalTo(firstButton);
  167. }
  168. }
  169. else
  170. {
  171. make.left.right.equalTo(self.buttonView);
  172. make.height.mas_equalTo(config.buttonHeight);
  173. if ( !firstButton )
  174. {
  175. firstButton = btn;
  176. make.top.equalTo(self.buttonView.mas_top).offset(-MM_SPLIT_WIDTH);
  177. }
  178. else
  179. {
  180. make.top.equalTo(lastButton.mas_bottom).offset(-MM_SPLIT_WIDTH);
  181. make.width.equalTo(firstButton);
  182. }
  183. }
  184. lastButton = btn;
  185. }];
  186. [btn setBackgroundImage:[UIImage mm_imageWithColor:self.backgroundColor] forState:UIControlStateNormal];
  187. [btn setBackgroundImage:[UIImage mm_imageWithColor:config.itemPressedColor] forState:UIControlStateHighlighted];
  188. [btn setTitle:item.title forState:UIControlStateNormal];
  189. [btn setTitleColor:item.highlight?config.itemHighlightColor:config.itemNormalColor forState:UIControlStateNormal];
  190. btn.layer.borderWidth = MM_SPLIT_WIDTH;
  191. btn.layer.borderColor = config.splitColor.CGColor;
  192. btn.titleLabel.font = (item==items.lastObject)?[UIFont boldSystemFontOfSize:config.buttonFontSize]:[UIFont systemFontOfSize:config.buttonFontSize];
  193. }
  194. [lastButton mas_updateConstraints:^(MASConstraintMaker *make) {
  195. if ( items.count <= 2 )
  196. {
  197. make.right.equalTo(self.buttonView.mas_right).offset(MM_SPLIT_WIDTH);
  198. }
  199. else
  200. {
  201. make.bottom.equalTo(self.buttonView.mas_bottom).offset(MM_SPLIT_WIDTH);
  202. }
  203. }];
  204. [self mas_updateConstraints:^(MASConstraintMaker *make) {
  205. make.bottom.equalTo(self.buttonView.mas_bottom);
  206. }];
  207. }
  208. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyTextChange:) name:UITextFieldTextDidChangeNotification object:nil];
  209. return self;
  210. }
  211. - (void)dealloc
  212. {
  213. [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
  214. }
  215. - (void)actionButton:(UIButton*)btn
  216. {
  217. MMPopupItem *item = self.actionItems[btn.tag];
  218. if ( item.disabled )
  219. {
  220. return;
  221. }
  222. if ( self.withKeyboard && (btn.tag==1) )
  223. {
  224. if ( self.inputView.text.length > 0 )
  225. {
  226. [self hide];
  227. }
  228. }
  229. else
  230. {
  231. [self hide];
  232. }
  233. if ( self.inputHandler && (btn.tag>0) )
  234. {
  235. self.inputHandler(self.inputView.text);
  236. }
  237. else
  238. {
  239. if ( item.handler )
  240. {
  241. item.handler(btn.tag);
  242. }
  243. }
  244. }
  245. - (void)notifyTextChange:(NSNotification *)n
  246. {
  247. if ( self.maxInputLength == 0 )
  248. {
  249. return;
  250. }
  251. if ( n.object != self.inputView )
  252. {
  253. return;
  254. }
  255. UITextField *textField = self.inputView;
  256. NSString *toBeString = textField.text;
  257. UITextRange *selectedRange = [textField markedTextRange];
  258. //获取高亮部分
  259. UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
  260. // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
  261. if (!position) {
  262. if (toBeString.length > self.maxInputLength) {
  263. textField.text = [toBeString mm_truncateByCharLength:self.maxInputLength];
  264. }
  265. }
  266. }
  267. - (void)showKeyboard
  268. {
  269. [self.inputView becomeFirstResponder];
  270. }
  271. - (void)hideKeyboard
  272. {
  273. [self.inputView resignFirstResponder];
  274. }
  275. @end
  276. @interface MMAlertViewConfig()
  277. @end
  278. @implementation MMAlertViewConfig
  279. + (MMAlertViewConfig *)globalConfig
  280. {
  281. static MMAlertViewConfig *config;
  282. static dispatch_once_t onceToken;
  283. dispatch_once(&onceToken, ^{
  284. config = [MMAlertViewConfig new];
  285. });
  286. return config;
  287. }
  288. - (instancetype)init
  289. {
  290. self = [super init];
  291. if ( self )
  292. {
  293. self.width = 275.0f;
  294. self.buttonHeight = 50.0f;
  295. self.innerMargin = 25.0f;
  296. self.cornerRadius = 6.0f;
  297. self.titleFontSize = 16.0f;
  298. self.detailFontSize = 14.0f;
  299. self.buttonFontSize = 16.0f;
  300. self.backgroundColor = MMHexColor(0xFFFFFFFF);
  301. self.titleColor = MMHexColor(0x333333FF);
  302. self.detailColor = MMHexColor(0x333333FF);
  303. self.splitColor = MMHexColor(0xE7E7F1FF);
  304. self.itemNormalColor = MMHexColor(0x333333FF);
  305. self.itemHighlightColor = MMHexColor(0xE76153FF);
  306. self.itemPressedColor = MMHexColor(0xEFEDE7FF);
  307. self.defaultTextOK = ASLocalizedString(@"知道了");
  308. self.defaultTextCancel = ASLocalizedString(@"取消");
  309. self.defaultTextConfirm = ASLocalizedString(@"确定");
  310. }
  311. return self;
  312. }
  313. @end