LXActionSheet.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. //
  2. // LXActionSheet.m
  3. // LXActionSheetDemo
  4. //
  5. // Created by lixiang on 14-3-10.
  6. // Copyright (c) 2014年 lcolco. All rights reserved.
  7. //
  8. #import "LXActionSheet.h"
  9. #define CANCEL_BUTTON_COLOR [UIColor colorWithRed:53/255.00f green:53/255.00f blue:53/255.00f alpha:1]
  10. #define DESTRUCTIVE_BUTTON_COLOR [UIColor colorWithRed:185/255.00f green:45/255.00f blue:39/255.00f alpha:1]
  11. #define OTHER_BUTTON_COLOR [UIColor whiteColor]
  12. #define ACTIONSHEET_BACKGROUNDCOLOR [UIColor colorWithRed:83/255.00f green:202/255.00f blue:195/255.00f alpha:1]
  13. #define WINDOW_COLOR [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]
  14. #define CORNER_RADIUS 5
  15. #define BUTTON_INTERVAL_HEIGHT 20
  16. #define BUTTON_HEIGHT 40
  17. #define BUTTON_INTERVAL_WIDTH 30
  18. #define BUTTON_WIDTH (JX_SCREEN_WIDTH - 60)
  19. #define BUTTONTITLE_FONT [UIFont fontWithName:@"HelveticaNeue-Bold" size:18]
  20. #define BUTTON_BORDER_WIDTH 0.5f
  21. #define BUTTON_BORDER_COLOR [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.8].CGColor
  22. #define TITLE_INTERVAL_HEIGHT 15
  23. #define TITLE_HEIGHT 35
  24. #define TITLE_INTERVAL_WIDTH 30
  25. #define TITLE_WIDTH 260
  26. #define TITLE_FONT [UIFont fontWithName:@"Helvetica-Bold" size:14]
  27. #define SHADOW_OFFSET CGSizeMake(0, 0.8f)
  28. #define TITLE_NUMBER_LINES 2
  29. #define ANIMATE_DURATION 0.25f
  30. @interface LXActionSheet ()
  31. @property (nonatomic,strong) UIView *backGroundView;
  32. @property (nonatomic,strong) NSString *actionTitle;
  33. @property (nonatomic,assign) NSInteger postionIndexNumber;
  34. @property (nonatomic,assign) BOOL isHadTitle;
  35. @property (nonatomic,assign) BOOL isHadDestructionButton;
  36. @property (nonatomic,assign) BOOL isHadOtherButton;
  37. @property (nonatomic,assign) BOOL isHadCancelButton;
  38. @property (nonatomic,assign) CGFloat LXActionSheetHeight;
  39. @property (nonatomic,weak) id<LXActionSheetDelegate>delegate;
  40. @end
  41. @implementation LXActionSheet
  42. #pragma mark - Public method
  43. - (id)initWithTitle:(NSString *)title delegate:(id<LXActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitlesArray;
  44. {
  45. self = [super init];
  46. if (self) {
  47. //初始化背景视图,添加手势
  48. self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
  49. self.backgroundColor = WINDOW_COLOR;
  50. self.userInteractionEnabled = YES;
  51. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedCancel)];
  52. [self addGestureRecognizer:tapGesture];
  53. if (delegate) {
  54. self.delegate = delegate;
  55. }
  56. [self creatButtonsWithTitle:title cancelButtonTitle:cancelButtonTitle destructionButtonTitle:destructiveButtonTitle otherButtonTitles:otherButtonTitlesArray];
  57. }
  58. return self;
  59. }
  60. - (void)showInView:(UIView *)view
  61. {
  62. [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:self];
  63. }
  64. #pragma mark - CreatButtonAndTitle method
  65. - (void)creatButtonsWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructionButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitlesArray
  66. {
  67. //初始化
  68. self.isHadTitle = NO;
  69. self.isHadDestructionButton = NO;
  70. self.isHadOtherButton = NO;
  71. self.isHadCancelButton = NO;
  72. //初始化LXACtionView的高度为0
  73. self.LXActionSheetHeight = 0;
  74. //初始化IndexNumber为0;
  75. self.postionIndexNumber = 0;
  76. //生成LXActionSheetView
  77. self.backGroundView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, 0)];
  78. self.backGroundView.layer.cornerRadius = 20;
  79. self.backGroundView.clipsToBounds = YES;
  80. self.backGroundView.backgroundColor = ACTIONSHEET_BACKGROUNDCOLOR;
  81. //给LXActionSheetView添加响应事件
  82. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedBackGroundView)];
  83. [self.backGroundView addGestureRecognizer:tapGesture];
  84. [self addSubview:self.backGroundView];
  85. if (title) {
  86. self.isHadTitle = YES;
  87. UILabel *titleLabel = [self creatTitleLabelWith:title];
  88. self.LXActionSheetHeight = self.LXActionSheetHeight + 2*TITLE_INTERVAL_HEIGHT+TITLE_HEIGHT;
  89. [self.backGroundView addSubview:titleLabel];
  90. }
  91. if (destructiveButtonTitle) {
  92. self.isHadDestructionButton = YES;
  93. UIButton *destructiveButton = [self creatDestructiveButtonWith:destructiveButtonTitle];
  94. destructiveButton.tag = self.postionIndexNumber;
  95. [destructiveButton addTarget:self action:@selector(clickOnButtonWith:) forControlEvents:UIControlEventTouchUpInside];
  96. if (self.isHadTitle == YES) {
  97. //当有title时
  98. [destructiveButton setFrame:CGRectMake(destructiveButton.frame.origin.x, self.LXActionSheetHeight, destructiveButton.frame.size.width, destructiveButton.frame.size.height)];
  99. if (otherButtonTitlesArray && otherButtonTitlesArray.count > 0) {
  100. self.LXActionSheetHeight = self.LXActionSheetHeight + destructiveButton.frame.size.height+BUTTON_INTERVAL_HEIGHT/2;
  101. }
  102. else{
  103. self.LXActionSheetHeight = self.LXActionSheetHeight + destructiveButton.frame.size.height+BUTTON_INTERVAL_HEIGHT;
  104. }
  105. }
  106. else{
  107. //当无title时
  108. if (otherButtonTitlesArray && otherButtonTitlesArray.count > 0) {
  109. self.LXActionSheetHeight = self.LXActionSheetHeight + destructiveButton.frame.size.height+(BUTTON_INTERVAL_HEIGHT+(BUTTON_INTERVAL_HEIGHT/2));
  110. }
  111. else{
  112. self.LXActionSheetHeight = self.LXActionSheetHeight + destructiveButton.frame.size.height+(2*BUTTON_INTERVAL_HEIGHT);
  113. }
  114. }
  115. [self.backGroundView addSubview:destructiveButton];
  116. self.postionIndexNumber++;
  117. }
  118. if (otherButtonTitlesArray) {
  119. if (otherButtonTitlesArray.count > 0) {
  120. self.isHadOtherButton = YES;
  121. //当无title与destructionButton时
  122. if (self.isHadTitle == NO && self.isHadDestructionButton == NO) {
  123. for (int i = 0; i<otherButtonTitlesArray.count; i++) {
  124. UIButton *otherButton = [self creatOtherButtonWith:[otherButtonTitlesArray objectAtIndex:i] withPostion:i];
  125. otherButton.tag = self.postionIndexNumber;
  126. [otherButton addTarget:self action:@selector(clickOnButtonWith:) forControlEvents:UIControlEventTouchUpInside];
  127. if (i != otherButtonTitlesArray.count - 1) {
  128. self.LXActionSheetHeight = self.LXActionSheetHeight + otherButton.frame.size.height+(BUTTON_INTERVAL_HEIGHT/2);
  129. }
  130. else{
  131. self.LXActionSheetHeight = self.LXActionSheetHeight + otherButton.frame.size.height+(2*BUTTON_INTERVAL_HEIGHT);
  132. }
  133. [self.backGroundView addSubview:otherButton];
  134. self.postionIndexNumber++;
  135. }
  136. }
  137. //当有title或destructionButton时
  138. if (self.isHadTitle == YES || self.isHadDestructionButton == YES) {
  139. for (int i = 0; i<otherButtonTitlesArray.count; i++) {
  140. UIButton *otherButton = [self creatOtherButtonWith:[otherButtonTitlesArray objectAtIndex:i] withPostion:i];
  141. otherButton.tag = self.postionIndexNumber;
  142. [otherButton addTarget:self action:@selector(clickOnButtonWith:) forControlEvents:UIControlEventTouchUpInside];
  143. [otherButton setFrame:CGRectMake(otherButton.frame.origin.x, self.LXActionSheetHeight, otherButton.frame.size.width, otherButton.frame.size.height)];
  144. if (i != otherButtonTitlesArray.count - 1) {
  145. self.LXActionSheetHeight = self.LXActionSheetHeight + otherButton.frame.size.height+(BUTTON_INTERVAL_HEIGHT/2);
  146. }
  147. else{
  148. self.LXActionSheetHeight = self.LXActionSheetHeight + otherButton.frame.size.height+(BUTTON_INTERVAL_HEIGHT);
  149. }
  150. [self.backGroundView addSubview:otherButton];
  151. self.postionIndexNumber++;
  152. }
  153. }
  154. }
  155. }
  156. if (cancelButtonTitle) {
  157. self.isHadCancelButton = YES;
  158. UIButton *cancelButton = [self creatCancelButtonWith:cancelButtonTitle];
  159. cancelButton.tag = self.postionIndexNumber;
  160. cancelButton.tag = -1;
  161. [cancelButton addTarget:self action:@selector(clickOnButtonWith:) forControlEvents:UIControlEventTouchUpInside];
  162. //当没title destructionButton otherbuttons时
  163. if (self.isHadTitle == NO && self.isHadDestructionButton == NO && self.isHadOtherButton == NO) {
  164. self.LXActionSheetHeight = self.LXActionSheetHeight + cancelButton.frame.size.height+(2*BUTTON_INTERVAL_HEIGHT);
  165. }
  166. //当有title或destructionButton或otherbuttons时
  167. if (self.isHadTitle == YES || self.isHadDestructionButton == YES || self.isHadOtherButton == YES) {
  168. [cancelButton setFrame:CGRectMake(cancelButton.frame.origin.x, self.LXActionSheetHeight, cancelButton.frame.size.width, cancelButton.frame.size.height)];
  169. self.LXActionSheetHeight = self.LXActionSheetHeight + cancelButton.frame.size.height+BUTTON_INTERVAL_HEIGHT;
  170. }
  171. [self.backGroundView addSubview:cancelButton];
  172. self.postionIndexNumber++;
  173. }
  174. [UIView animateWithDuration:ANIMATE_DURATION animations:^{
  175. [self.backGroundView setFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height-self.LXActionSheetHeight, [UIScreen mainScreen].bounds.size.width, self.LXActionSheetHeight)];
  176. } completion:^(BOOL finished) {
  177. }];
  178. }
  179. - (UILabel *)creatTitleLabelWith:(NSString *)title
  180. {
  181. UILabel *titlelabel = [[UILabel alloc] initWithFrame:CGRectMake(TITLE_INTERVAL_WIDTH, TITLE_INTERVAL_HEIGHT, TITLE_WIDTH, TITLE_HEIGHT)];
  182. titlelabel.backgroundColor = [UIColor clearColor];
  183. titlelabel.textAlignment = NSTextAlignmentCenter;
  184. titlelabel.shadowColor = [UIColor blackColor];
  185. titlelabel.shadowOffset = SHADOW_OFFSET;
  186. titlelabel.font = TITLE_FONT;
  187. titlelabel.text = title;
  188. titlelabel.textColor = [UIColor whiteColor];
  189. titlelabel.numberOfLines = TITLE_NUMBER_LINES;
  190. return titlelabel;
  191. }
  192. - (UIButton *)creatDestructiveButtonWith:(NSString *)destructiveButtonTitle
  193. {
  194. UIButton *destructiveButton = [[UIButton alloc] initWithFrame:CGRectMake(BUTTON_INTERVAL_WIDTH, BUTTON_INTERVAL_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT)];
  195. destructiveButton.layer.masksToBounds = YES;
  196. destructiveButton.layer.cornerRadius = CORNER_RADIUS;
  197. destructiveButton.layer.borderWidth = BUTTON_BORDER_WIDTH;
  198. destructiveButton.layer.borderColor = BUTTON_BORDER_COLOR;
  199. //取消按钮,红色改为白色
  200. destructiveButton.backgroundColor = [UIColor whiteColor];
  201. [destructiveButton setTitle:destructiveButtonTitle forState:UIControlStateNormal];
  202. destructiveButton.titleLabel.font = BUTTONTITLE_FONT;
  203. [destructiveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  204. [destructiveButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
  205. return destructiveButton;
  206. }
  207. - (UIButton *)creatOtherButtonWith:(NSString *)otherButtonTitle withPostion:(NSInteger )postionIndex
  208. {
  209. UIButton *otherButton = [[UIButton alloc] initWithFrame:CGRectMake(BUTTON_INTERVAL_WIDTH, BUTTON_INTERVAL_HEIGHT + (postionIndex*(BUTTON_HEIGHT+(BUTTON_INTERVAL_HEIGHT/2))), BUTTON_WIDTH, BUTTON_HEIGHT)];
  210. otherButton.layer.masksToBounds = YES;
  211. otherButton.layer.cornerRadius = CORNER_RADIUS;
  212. otherButton.layer.borderWidth = BUTTON_BORDER_WIDTH;
  213. otherButton.layer.borderColor = BUTTON_BORDER_COLOR;
  214. otherButton.backgroundColor = OTHER_BUTTON_COLOR;
  215. [otherButton setTitle:otherButtonTitle forState:UIControlStateNormal];
  216. otherButton.titleLabel.font = BUTTONTITLE_FONT;
  217. [otherButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  218. [otherButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
  219. return otherButton;
  220. }
  221. - (UIButton *)creatCancelButtonWith:(NSString *)cancelButtonTitle
  222. {
  223. UIButton *cancelButton = [[UIButton alloc] initWithFrame:CGRectMake(BUTTON_INTERVAL_WIDTH, BUTTON_INTERVAL_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT)];
  224. cancelButton.layer.masksToBounds = YES;
  225. cancelButton.layer.cornerRadius = CORNER_RADIUS;
  226. cancelButton.layer.borderWidth = BUTTON_BORDER_WIDTH;
  227. cancelButton.layer.borderColor = BUTTON_BORDER_COLOR;
  228. cancelButton.backgroundColor = CANCEL_BUTTON_COLOR;
  229. [cancelButton setTitle:cancelButtonTitle forState:UIControlStateNormal];
  230. cancelButton.titleLabel.font = BUTTONTITLE_FONT;
  231. [cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  232. [cancelButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
  233. return cancelButton;
  234. }
  235. - (void)clickOnButtonWith:(UIButton *)button
  236. {
  237. if (self.isHadDestructionButton == YES) {
  238. if (self.delegate) {
  239. if (button.tag == 0) {
  240. if ([self.delegate respondsToSelector:@selector(didClickOnDestructiveButton)] == YES){
  241. [self.delegate didClickOnDestructiveButton];
  242. }
  243. }
  244. }
  245. }
  246. if (self.isHadCancelButton == YES) {
  247. if (self.delegate) {
  248. // if (button.tag == self.postionIndexNumber-1) {
  249. if (button.tag == -1) {
  250. if ([self.delegate respondsToSelector:@selector(didClickOnCancelButton)] == YES) {
  251. [self.delegate didClickOnCancelButton];
  252. }
  253. }
  254. }
  255. }
  256. if (self.delegate) {
  257. if ([self.delegate respondsToSelector:@selector(didClickOnButtonIndex:buttonIndex:)] == YES) {
  258. [self.delegate didClickOnButtonIndex:self buttonIndex:(int)button.tag];
  259. }
  260. }
  261. [self tappedCancel];
  262. }
  263. - (void)tappedCancel
  264. {
  265. [UIView animateWithDuration:ANIMATE_DURATION animations:^{
  266. [self.backGroundView setFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, 0)];
  267. self.alpha = 0;
  268. } completion:^(BOOL finished) {
  269. if (finished) {
  270. [self removeFromSuperview];
  271. }
  272. }];
  273. }
  274. - (void)tappedBackGroundView
  275. {
  276. //
  277. }
  278. @end