New file |
| | |
| | | // |
| | | // JXTAlertController.h |
| | | // JXTAlertManager |
| | | // |
| | | // Created by JXT on 2016/12/22. |
| | | // Copyright © 2016年 JXT. All rights reserved. |
| | | // |
| | | |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | |
| | | NS_ASSUME_NONNULL_BEGIN |
| | | |
| | | #pragma mark - I.JXTAlertController构造 |
| | | |
| | | @class JXTAlertController; |
| | | /** |
| | | JXTAlertController: alertAction配置链 |
| | | |
| | | @param title 标题 |
| | | @return JXTAlertController对象 |
| | | */ |
| | | typedef JXTAlertController * _Nonnull (^JXTAlertActionTitle)(NSString *title); |
| | | |
| | | /** |
| | | JXTAlertController: alert按钮执行回调 |
| | | |
| | | @param buttonIndex 按钮index(根据添加action的顺序) |
| | | @param action UIAlertAction对象 |
| | | @param alertSelf 本类对象 |
| | | */ |
| | | typedef void (^JXTAlertActionBlock)(NSInteger buttonIndex, UIAlertAction *action, JXTAlertController *alertSelf); |
| | | |
| | | |
| | | /** |
| | | JXTAlertController 简介: |
| | | |
| | | 1.针对系统UIAlertController封装,支持iOS8及以上 |
| | | |
| | | 2.关于iOS9之后的`preferredAction`属性用法: |
| | | `alertController.preferredAction = alertController.actions[0];` |
| | | 效果为将已存在的某个action字体加粗,原cancel样式的加粗字体成为deafult样式,cancel样式的action仍然排列在最下 |
| | | 总体意义不大,且仅限于`UIAlertControllerStyleAlert`,actionSheet无效,功能略微鸡肋,不再单独封装 |
| | | |
| | | 3.关于`addTextFieldWithConfigurationHandler:`方法: |
| | | 该方法同样仅限于`UIAlertControllerStyleAlert`使用,使用场景较为局限,推荐直接调用,不再针对封装 |
| | | |
| | | 4.关于自定义按钮字体或者颜色,可以利用kvc间接访问这些私有属性,但是不推荐 |
| | | `[alertAction setValue:[UIColor grayColor] forKey:@"titleTextColor"]` |
| | | */ |
| | | NS_CLASS_AVAILABLE_IOS(8_0) @interface JXTAlertController : UIAlertController |
| | | |
| | | |
| | | /** |
| | | JXTAlertController: 禁用alert弹出动画,默认执行系统的默认弹出动画 |
| | | */ |
| | | - (void)alertAnimateDisabled; |
| | | |
| | | /** |
| | | JXTAlertController: alert弹出后,可配置的回调 |
| | | */ |
| | | @property (nullable, nonatomic, copy) void (^alertDidShown)(void); |
| | | |
| | | /** |
| | | JXTAlertController: alert关闭后,可配置的回调 |
| | | */ |
| | | @property (nullable, nonatomic, copy) void (^alertDidDismiss)(void); |
| | | |
| | | /** |
| | | JXTAlertController: 设置toast模式展示时间:如果alert未添加任何按钮,将会以toast样式展示,这里设置展示时间,默认1s |
| | | */ |
| | | @property (nonatomic, assign) NSTimeInterval toastStyleDuration; //deafult jxt_alertShowDurationDefault = 1s |
| | | |
| | | |
| | | /** |
| | | JXTAlertController: 链式构造alert视图按钮,添加一个alertAction按钮,默认样式,参数为标题 |
| | | |
| | | @return JXTAlertController对象 |
| | | */ |
| | | - (JXTAlertActionTitle)addActionDefaultTitle; |
| | | |
| | | /** |
| | | JXTAlertController: 链式构造alert视图按钮,添加一个alertAction按钮,取消样式,参数为标题(warning:一个alert该样式只能添加一次!!!) |
| | | |
| | | @return JXTAlertController对象 |
| | | */ |
| | | - (JXTAlertActionTitle)addActionCancelTitle; |
| | | |
| | | /** |
| | | JXTAlertController: 链式构造alert视图按钮,添加一个alertAction按钮,警告样式,参数为标题 |
| | | |
| | | @return JXTAlertController对象 |
| | | */ |
| | | - (JXTAlertActionTitle)addActionDestructiveTitle; |
| | | |
| | | @end |
| | | |
| | | |
| | | #pragma mark - II.UIViewController扩展使用JXTAlertController |
| | | |
| | | /** |
| | | JXTAlertController: alert构造块 |
| | | |
| | | @param alertMaker JXTAlertController配置对象 |
| | | */ |
| | | typedef void(^JXTAlertAppearanceProcess)(JXTAlertController *alertMaker); |
| | | |
| | | @interface UIViewController (JXTAlertController) |
| | | |
| | | /** |
| | | JXTAlertController: show-alert(iOS8) |
| | | |
| | | @param title title |
| | | @param message message |
| | | @param appearanceProcess alert配置过程 |
| | | @param actionBlock alert点击响应回调 |
| | | */ |
| | | - (void)jxt_showAlertWithTitle:(nullable NSString *)title |
| | | message:(nullable NSString *)message |
| | | appearanceProcess:(JXTAlertAppearanceProcess)appearanceProcess |
| | | actionsBlock:(nullable JXTAlertActionBlock)actionBlock NS_AVAILABLE_IOS(8_0); |
| | | |
| | | /** |
| | | JXTAlertController: show-actionSheet(iOS8) |
| | | |
| | | @param title title |
| | | @param message message |
| | | @param appearanceProcess actionSheet配置过程 |
| | | @param actionBlock actionSheet点击响应回调 |
| | | */ |
| | | - (void)jxt_showActionSheetWithTitle:(nullable NSString *)title |
| | | message:(nullable NSString *)message |
| | | appearanceProcess:(JXTAlertAppearanceProcess)appearanceProcess |
| | | actionsBlock:(nullable JXTAlertActionBlock)actionBlock NS_AVAILABLE_IOS(8_0); |
| | | |
| | | @end |
| | | |
| | | @interface UIAlertController (LMJ) |
| | | /** |
| | | JXTAlertController: show-alert(iOS8) |
| | | |
| | | @param title title |
| | | @param message message |
| | | @param appearanceProcess alert配置过程 |
| | | @param actionBlock alert点击响应回调 |
| | | */ |
| | | + (void)mj_showAlertWithTitle:(nullable NSString *)title |
| | | message:(nullable NSString *)message |
| | | appearanceProcess:(JXTAlertAppearanceProcess)appearanceProcess |
| | | actionsBlock:(nullable JXTAlertActionBlock)actionBlock NS_AVAILABLE_IOS(8_0); |
| | | |
| | | /** |
| | | JXTAlertController: show-actionSheet(iOS8) |
| | | |
| | | @param title title |
| | | @param message message |
| | | @param appearanceProcess actionSheet配置过程 |
| | | @param actionBlock actionSheet点击响应回调 |
| | | */ |
| | | + (void)mj_showActionSheetWithTitle:(nullable NSString *)title |
| | | message:(nullable NSString *)message |
| | | appearanceProcess:(JXTAlertAppearanceProcess)appearanceProcess |
| | | actionsBlock:(nullable JXTAlertActionBlock)actionBlock NS_AVAILABLE_IOS(8_0); |
| | | @end |
| | | |
| | | NS_ASSUME_NONNULL_END |
| | | /* |
| | | // |
| | | // ShowViewController.m |
| | | // JXTAlertManagerDemo |
| | | // |
| | | // Created by JXT on 2016/12/21. |
| | | // Copyright © 2016年 JXT. All rights reserved. |
| | | // |
| | | |
| | | #import "ShowViewController.h" |
| | | |
| | | #import "JXTAlertManagerHeader.h" |
| | | |
| | | static NSString *const cellId = @"CELLID"; |
| | | |
| | | @interface ShowViewController () <UITableViewDataSource, UITableViewDelegate> |
| | | @property (nonatomic, strong) UITableView * tableView; |
| | | @property (nonatomic, strong) NSArray * sectionViewArray; |
| | | @property (nonatomic, strong) NSArray * dataArray; |
| | | @end |
| | | |
| | | @implementation ShowViewController |
| | | |
| | | #pragma mark - LifeCycle |
| | | - (void)viewDidLoad |
| | | { |
| | | [super viewDidLoad]; |
| | | |
| | | self.navigationItem.title = @"JXTAlertManager"; |
| | | |
| | | self.dataArray = @[ |
| | | @[ |
| | | @"1.1.常规两个按钮alert", |
| | | @"1.2.简易调试使用alert,单按钮,标题默认为“确定”", |
| | | @"1.3.不定数量按钮alert", |
| | | @"1.4.无按钮toast样式", |
| | | @"1.5.单文字HUD", |
| | | @"1.6.带indicatorView的HUD", |
| | | @"1.7.带进度条的HUD,成功!", |
| | | @"1.8.带进度条的HUD,失败!", |
| | | ], |
| | | @[ |
| | | @"2.1.常规alertController-Alert", |
| | | @"2.2.常规alertController-ActionSheet", |
| | | @"2.3.无按钮alert-toast", |
| | | @"2.4.无按钮actionSheet-toast", |
| | | @"2.5.带输入框的alertController-Alert", |
| | | ] |
| | | ]; |
| | | |
| | | self.sectionViewArray = @[ |
| | | [self labelWithText:@"1.AlertView-推荐日常调试使用"], |
| | | [self labelWithText:@"2.AlertController-iOS8"] |
| | | ]; |
| | | |
| | | [self.view addSubview:self.tableView]; |
| | | } |
| | | |
| | | - (void)didReceiveMemoryWarning { |
| | | [super didReceiveMemoryWarning]; |
| | | } |
| | | |
| | | |
| | | #pragma mark - UI |
| | | - (UILabel *)labelWithText:(NSString *)text |
| | | { |
| | | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)]; |
| | | label.text = text; |
| | | label.font = [UIFont boldSystemFontOfSize:20]; |
| | | label.backgroundColor = [[self randomColor] colorWithAlphaComponent:0.5]; |
| | | label.textAlignment = NSTextAlignmentCenter; |
| | | |
| | | return label; |
| | | } |
| | | - (UITableView *)tableView |
| | | { |
| | | if (!_tableView) { |
| | | if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)]) { |
| | | self.automaticallyAdjustsScrollViewInsets = NO; |
| | | } |
| | | _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; |
| | | _tableView.delegate = self; |
| | | _tableView.dataSource = self; |
| | | _tableView.backgroundColor = [UIColor whiteColor]; |
| | | _tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); |
| | | _tableView.scrollIndicatorInsets = UIEdgeInsetsMake(64, 0, 0, 0); |
| | | } |
| | | return _tableView; |
| | | } |
| | | |
| | | |
| | | #pragma mark - UITableViewDataSource |
| | | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView |
| | | { |
| | | return self.dataArray.count; |
| | | } |
| | | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section |
| | | { |
| | | NSArray *sectionArray = self.dataArray[section]; |
| | | return sectionArray.count; |
| | | } |
| | | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath |
| | | { |
| | | UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId]; |
| | | if (!cell) { |
| | | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; |
| | | } |
| | | cell.backgroundColor = [self randomColor]; |
| | | cell.textLabel.text = self.dataArray[indexPath.section][indexPath.row]; |
| | | cell.textLabel.numberOfLines = 0; |
| | | |
| | | return cell; |
| | | } |
| | | //- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section |
| | | //{ |
| | | // return @"title"; |
| | | //} |
| | | |
| | | #pragma mark - UITableViewDelegate |
| | | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath |
| | | { |
| | | return 70; |
| | | } |
| | | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section |
| | | { |
| | | return 25; |
| | | } |
| | | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section |
| | | { |
| | | return 0.01; |
| | | } |
| | | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section |
| | | { |
| | | return self.sectionViewArray[section]; |
| | | } |
| | | |
| | | #pragma mark alert使用示例 |
| | | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath |
| | | { |
| | | [tableView deselectRowAtIndexPath:indexPath animated:YES]; |
| | | |
| | | if (indexPath.section == 0) |
| | | { |
| | | if (indexPath.row == 0) |
| | | { |
| | | //1. |
| | | // [JXTAlertView showAlertViewWithTitle:@"title" message:@"message" cancelButtonTitle:@"cancel" otherButtonTitle:@"other" cancelButtonBlock:^(NSInteger buttonIndex) { |
| | | // NSLog(@"cancel"); |
| | | // } otherButtonBlock:^(NSInteger buttonIndex) { |
| | | // NSLog(@"other"); |
| | | // }]; |
| | | //2. |
| | | jxt_showAlertTwoButton(@"常规两个按钮alert", @"支持按钮点击回调,支持C函数快速调用", @"cancel", ^(NSInteger buttonIndex) { |
| | | NSLog(@"cancel"); |
| | | }, @"other", ^(NSInteger buttonIndex) { |
| | | NSLog(@"other"); |
| | | }); |
| | | } |
| | | else if (indexPath.row == 1) |
| | | { |
| | | jxt_showAlertTitle(@"简易调试使用alert,单按钮,标题默认为“确定”"); |
| | | } |
| | | else if (indexPath.row == 2) |
| | | { |
| | | [JXTAlertView showAlertViewWithTitle:@"不定数量按钮alert" message:@"支持按钮点击回调,根据按钮index区分响应,有cancel按钮时,cancel的index默认0,无cancel时,按钮index根据添加顺序计算" cancelButtonTitle:@"cancel" buttonIndexBlock:^(NSInteger buttonIndex) { |
| | | if (buttonIndex == 0) { |
| | | NSLog(@"cancel"); |
| | | } |
| | | else if (buttonIndex == 1) { |
| | | NSLog(@"按钮1"); |
| | | } |
| | | else if (buttonIndex == 2) { |
| | | NSLog(@"按钮2"); |
| | | } |
| | | else if (buttonIndex == 3) { |
| | | NSLog(@"按钮3"); |
| | | } |
| | | else if (buttonIndex == 4) { |
| | | NSLog(@"按钮4"); |
| | | } |
| | | else if (buttonIndex == 5) { |
| | | NSLog(@"按钮5"); |
| | | } |
| | | } otherButtonTitles:@"按钮1", @"按钮2", @"按钮3", @"按钮4", @"按钮5", nil]; |
| | | } |
| | | else if (indexPath.row == 3) |
| | | { |
| | | //1. |
| | | [JXTAlertView showToastViewWithTitle:@"无按钮toast样式" message:@"可自定义展示延时时间,支持关闭回调" duration:2 dismissCompletion:^(NSInteger buttonIndex) { |
| | | NSLog(@"关闭"); |
| | | }]; |
| | | //2. |
| | | // jxt_showToastTitleDismiss(@"无按钮toast样式", 2, ^(NSInteger buttonIndex) { |
| | | // NSLog(@"关闭"); |
| | | // }); |
| | | //3. |
| | | // jxt_showToastMessage(@"无按钮toast样式", 0); |
| | | } |
| | | else if (indexPath.row == 4) |
| | | { |
| | | //1. |
| | | // jxt_showTextHUDTitle(@"单文字HUD"); |
| | | //2. |
| | | jxt_showTextHUDTitleMessage(@"单文字HUD", @"支持子标题,手动执行关闭,可改变显示状态"); |
| | | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ |
| | | jxt_dismissHUD(); |
| | | }); |
| | | } |
| | | else if (indexPath.row == 5) |
| | | { |
| | | jxt_showLoadingHUDTitleMessage(@"带indicatorView的HUD", @"支持子标题,手动执行关闭,可改变显示状态"); |
| | | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ |
| | | jxt_dismissHUD(); |
| | | }); |
| | | } |
| | | else if (indexPath.row == 6) |
| | | { |
| | | jxt_showProgressHUDTitleMessage(@"带进度条的HUD", @"支持子标题,手动执行关闭,可改变显示状态"); |
| | | __block float count = 0; |
| | | #warning timer block ios10 only |
| | | [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) { |
| | | count += 0.05; |
| | | jxt_setHUDProgress(count); |
| | | if (count > 1) { |
| | | [timer invalidate]; |
| | | jxt_setHUDSuccessTitle(@"加载成功!"); |
| | | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ |
| | | jxt_dismissHUD(); |
| | | }); |
| | | } |
| | | }]; |
| | | } |
| | | else if (indexPath.row == 7) |
| | | { |
| | | jxt_showProgressHUDTitleMessage(@"带进度条的HUD", @"支持子标题,手动执行关闭,可改变显示状态"); |
| | | __block float count = 0; |
| | | #warning timer block ios10 only |
| | | [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) { |
| | | count += 0.05; |
| | | jxt_setHUDProgress(count); |
| | | if (count > 1) { |
| | | [timer invalidate]; |
| | | jxt_setHUDFailMessage(@"加载失败!"); |
| | | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ |
| | | jxt_dismissHUD(); |
| | | }); |
| | | } |
| | | }]; |
| | | } |
| | | } |
| | | else if (indexPath.section == 1) |
| | | { |
| | | if (indexPath.row == 0) |
| | | { |
| | | [self jxt_showAlertWithTitle:@"常规alertController-Alert" message:@"基于系统UIAlertController封装,按钮以链式语法模式快捷添加,可根据按钮index区分响应,可根据action区分响应,支持配置弹出、关闭回调,可关闭弹出动画" appearanceProcess:^(JXTAlertController * _Nonnull alertMaker) { |
| | | alertMaker. |
| | | addActionCancelTitle(@"cancel"). |
| | | addActionDestructiveTitle(@"按钮1"); |
| | | } actionsBlock:^(NSInteger buttonIndex, UIAlertAction * _Nonnull action, JXTAlertController * _Nonnull alertSelf) { |
| | | if (buttonIndex == 0) { |
| | | NSLog(@"cancel"); |
| | | } |
| | | else if (buttonIndex == 1) { |
| | | NSLog(@"按钮1"); |
| | | } |
| | | NSLog(@"%@--%@", action.title, action); |
| | | }]; |
| | | } |
| | | else if (indexPath.row == 1) |
| | | { |
| | | [self jxt_showActionSheetWithTitle:@"常规alertController-ActionSheet" message:@"基于系统UIAlertController封装,按钮以链式语法模式快捷添加,可根据按钮index区分响应,可根据action区分响应,支持配置弹出、关闭回调,可关闭弹出动画" appearanceProcess:^(JXTAlertController * _Nonnull alertMaker) { |
| | | alertMaker. |
| | | addActionCancelTitle(@"cancel"). |
| | | addActionDestructiveTitle(@"按钮1"). |
| | | addActionDefaultTitle(@"按钮2"). |
| | | addActionDefaultTitle(@"按钮3"). |
| | | addActionDestructiveTitle(@"按钮4"); |
| | | } actionsBlock:^(NSInteger buttonIndex, UIAlertAction * _Nonnull action, JXTAlertController * _Nonnull alertSelf) { |
| | | |
| | | if ([action.title isEqualToString:@"cancel"]) { |
| | | NSLog(@"cancel"); |
| | | } |
| | | else if ([action.title isEqualToString:@"按钮1"]) { |
| | | NSLog(@"按钮1"); |
| | | } |
| | | else if ([action.title isEqualToString:@"按钮2"]) { |
| | | NSLog(@"按钮2"); |
| | | } |
| | | else if ([action.title isEqualToString:@"按钮3"]) { |
| | | NSLog(@"按钮3"); |
| | | } |
| | | else if ([action.title isEqualToString:@"按钮4"]) { |
| | | NSLog(@"按钮4"); |
| | | } |
| | | }]; |
| | | } |
| | | else if (indexPath.row == 2) |
| | | { |
| | | [self jxt_showAlertWithTitle:@"无按钮alert-toast" message:@"toast样式,可自定义展示延时时间,支持配置弹出、关闭回调,可关闭弹出动画" appearanceProcess:^(JXTAlertController * _Nonnull alertMaker) { |
| | | alertMaker.toastStyleDuration = 2; |
| | | [alertMaker setAlertDidShown:^{ |
| | | [self logMsg:@"alertDidShown"];//不用担心循环引用 |
| | | }]; |
| | | alertMaker.alertDidDismiss = ^{ |
| | | [self logMsg:@"alertDidDismiss"]; |
| | | }; |
| | | } actionsBlock:NULL]; |
| | | } |
| | | else if (indexPath.row == 3) |
| | | { |
| | | [self jxt_showActionSheetWithTitle:@"无按钮actionSheet-toast" message:@"toast样式,可自定义展示延时时间,支持配置弹出、关闭回调,可关闭弹出动画" appearanceProcess:^(JXTAlertController * _Nonnull alertMaker) { |
| | | alertMaker.toastStyleDuration = 3; |
| | | //关闭动画效果 |
| | | [alertMaker alertAnimateDisabled]; |
| | | |
| | | [alertMaker setAlertDidShown:^{ |
| | | NSLog(@"alertDidShown"); |
| | | }]; |
| | | alertMaker.alertDidDismiss = ^{ |
| | | NSLog(@"alertDidDismiss"); |
| | | }; |
| | | } actionsBlock:NULL]; |
| | | } |
| | | else if (indexPath.row == 4) |
| | | { |
| | | [self jxt_showAlertWithTitle:@"带输入框的alertController-Alert" message:@"点击按钮,控制台打印对应输入框的内容" appearanceProcess:^(JXTAlertController * _Nonnull alertMaker) { |
| | | alertMaker. |
| | | addActionDestructiveTitle(@"获取输入框1"). |
| | | addActionDestructiveTitle(@"获取输入框2"); |
| | | |
| | | [alertMaker addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { |
| | | textField.placeholder = @"输入框1-请输入"; |
| | | }]; |
| | | [alertMaker addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { |
| | | textField.placeholder = @"输入框2-请输入"; |
| | | }]; |
| | | } actionsBlock:^(NSInteger buttonIndex, UIAlertAction * _Nonnull action, JXTAlertController * _Nonnull alertSelf) { |
| | | if (buttonIndex == 0) { |
| | | UITextField *textField = alertSelf.textFields.firstObject; |
| | | [self logMsg:textField.text];//不用担心循环引用 |
| | | } |
| | | else if (buttonIndex == 1) { |
| | | UITextField *textField = alertSelf.textFields.lastObject; |
| | | [self logMsg:textField.text]; |
| | | } |
| | | }]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | #pragma mark - Methods |
| | | - (void)logMsg:(NSString *)msg |
| | | { |
| | | NSLog(@"%@", msg); |
| | | } |
| | | - (UIColor *)randomColor |
| | | { |
| | | CGFloat r = arc4random_uniform(255); |
| | | CGFloat g = arc4random_uniform(255); |
| | | CGFloat b = arc4random_uniform(255); |
| | | |
| | | return [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:0.3f]; |
| | | } |
| | | |
| | | @end |
| | | |
| | | */ |
| | | |