master
1//
2// BlockTableAlertView.m
3// BlockAlertsDemo
4//
5// Created by Barrett Jacobsen on 2/14/12.
6// Copyright (c) 2012 CodeCrop Software. All rights reserved.
7//
8
9#define SUPPORTS_MULTIPLE_SELECTION [self.tableView respondsToSelector:@selector(setAllowsMultipleSelectionDuringEditing:)]
10
11#define kVerticalSpacing 5
12#define kHorizontalMargin 12
13
14#define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
15
16#define IS_LANDSCAPE UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])
17
18#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
19
20#define kNumMaximumVisibleRowsInTableView (IS_IPAD ? 15 : (IS_LANDSCAPE ? 4 : (IS_IPHONE_5 ? 6 : 5)))
21
22#import "BlockTableAlertView.h"
23#import <QuartzCore/QuartzCore.h>
24#import <dispatch/dispatch.h>
25
26@implementation BlockTableAlertView
27@synthesize tableView=_tableView;
28@synthesize type=_type;
29@synthesize didSelectRow;
30@synthesize willDismissWithButtonIndex;
31@synthesize maxSelection;
32@synthesize cellForRow;
33@synthesize willPresent;
34@synthesize numberOfRowsInTableAlert;
35
36@dynamic indexPathsForSelectedRows;
37
38+ (BlockTableAlertView *)tableAlertWithTitle:(NSString *)title message:(NSString *)message
39{
40 return [[[BlockTableAlertView alloc] initWithTitle:title message:message] autorelease];
41}
42
43
44- (id)initWithTitle:(NSString *)title message:(NSString *)message {
45 self = [super initWithTitle:title message:message];
46
47 if (self) {
48 if (!SUPPORTS_MULTIPLE_SELECTION)
49 selectedItems = [[NSMutableArray alloc] init];
50 }
51
52 return self;
53}
54
55- (void)addComponents:(CGRect)frame {
56 [super addComponents:frame];
57
58 if (!_tableView) {
59 _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
60 [_tableView setDelegate:self];
61 [_tableView setDataSource:self];
62 [_tableView setBackgroundColor:[UIColor colorWithWhite:0.90 alpha:1.0]];
63 [_tableView setRowHeight:kDefaultRowHeight];
64 [_tableView setSeparatorColor:[UIColor lightGrayColor]];
65 _tableView.layer.cornerRadius = kTableCornerRadius;
66 }
67
68 CGFloat tableHeight = kDefaultRowHeight * MIN(self.numberOfRowsInTableAlert(self), kNumMaximumVisibleRowsInTableView);
69
70 _tableView.frame = CGRectMake(kHorizontalMargin, _height, frame.size.width - kHorizontalMargin * 2, tableHeight);
71
72 [_view addSubview:_tableView];
73 _height += tableHeight + kVerticalSpacing;
74}
75
76
77- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
78 if (self.willDismissWithButtonIndex)
79 self.willDismissWithButtonIndex(self, buttonIndex);
80
81 [super dismissWithClickedButtonIndex:buttonIndex animated:animated];
82}
83
84- (void)updateAlertHeight:(CGFloat)oldTableHeight {
85 CGFloat newTableHeight = kDefaultRowHeight * MIN(self.numberOfRowsInTableAlert(self), kNumMaximumVisibleRowsInTableView);
86
87 if (newTableHeight != oldTableHeight) {
88 CGFloat diff = newTableHeight - oldTableHeight;
89 [UIView animateWithDuration:0.3 animations:^{
90 [self.view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
91 UIView *v = obj;
92 if (v.frame.origin.y >= _tableView.frame.origin.y + _tableView.frame.size.height)
93 v.frame = CGRectMake(v.frame.origin.x, v.frame.origin.y + diff, v.frame.size.width, v.frame.size.height);
94 }];
95
96 _tableView.frame = CGRectMake(_tableView.frame.origin.x, _tableView.frame.origin.y, _tableView.frame.size.width, newTableHeight);
97 self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height + diff);
98 }];
99 }
100}
101
102- (void)reloadData {
103 CGFloat oldTableHeight = _tableView.frame.size.height;
104
105 [self.tableView reloadData];
106
107 [self updateAlertHeight:oldTableHeight];
108}
109
110- (void)insertRowsAtIndexPaths:(NSArray*)rows {
111 CGFloat oldTableHeight = _tableView.frame.size.height;
112
113 [self.tableView insertRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
114
115 [self updateAlertHeight:oldTableHeight];
116}
117
118- (void)deleteRowsAtIndexPaths:(NSArray*)rows {
119 CGFloat oldTableHeight = _tableView.frame.size.height;
120
121 [self.tableView deleteRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
122
123 [self updateAlertHeight:oldTableHeight];
124}
125
126
127- (void)show {
128 if (!_shown)
129 [self setupDisplay];
130
131 if (self.willPresent)
132 self.willPresent(self);
133
134 if (self.type == BlockTableAlertTypeMultipleSelct && SUPPORTS_MULTIPLE_SELECTION) {
135 self.tableView.allowsMultipleSelectionDuringEditing = YES;
136 self.tableView.editing = YES;
137 }
138
139 [super show];
140}
141
142#pragma mark - iOS 4 Compatibility
143
144- (NSArray*)indexPathsForSelectedRows {
145 if (SUPPORTS_MULTIPLE_SELECTION) {
146 return self.tableView.indexPathsForSelectedRows;
147 }
148 else {
149 return selectedItems;
150 }
151}
152
153- (void)selectRowAtIndexPath:(NSIndexPath*)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scroll {
154 if (SUPPORTS_MULTIPLE_SELECTION) {
155 [self.tableView selectRowAtIndexPath:indexPath animated:animated scrollPosition:scroll];
156 }
157 else {
158 UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
159
160 if (cell.accessoryType == UITableViewCellAccessoryNone) {
161 [selectedItems addObject:indexPath];
162 cell.accessoryType = UITableViewCellAccessoryCheckmark;
163 }
164 }
165}
166
167
168#pragma mark - UITableViewDelegate
169
170- (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
171 if (self.type == BlockTableAlertTypeSingleSelect || self.maxSelection == 0)
172 return indexPath;
173
174 NSIndexPath *toSelect = indexPath;
175
176 if ([self.indexPathsForSelectedRows count] + 1 > self.maxSelection)
177 toSelect = nil;
178
179 return toSelect;
180}
181
182- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
183 if (_type == BlockTableAlertTypeSingleSelect)
184 [self dismissWithClickedButtonIndex:-1 animated:YES];
185
186 if (!SUPPORTS_MULTIPLE_SELECTION) {
187 UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
188
189 if (cell.accessoryType == UITableViewCellAccessoryNone) {
190 [selectedItems addObject:indexPath];
191 cell.accessoryType = UITableViewCellAccessoryCheckmark;
192
193 if (self.didSelectRow)
194 self.didSelectRow(self, [indexPath row]);
195 }
196 else {
197 [selectedItems removeObject:indexPath];
198 cell.accessoryType = UITableViewCellAccessoryNone;
199 }
200
201 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
202
203 return;
204 }
205
206 if (self.didSelectRow)
207 self.didSelectRow(self, [indexPath row]);
208}
209
210#pragma mark - UITableViewDataSource
211
212- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
213 return self.cellForRow(self,[indexPath row]);
214}
215
216- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
217 return 1;
218}
219
220- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
221 return self.numberOfRowsInTableAlert(self);
222}
223
224
225@end