├── .gitignore ├── ABMenuTableViewCell.podspec ├── ABMenuTableViewCell ├── ABMenuTableViewCell.h ├── ABMenuTableViewCell.m ├── UITableView+VisibleMenuCell.h └── UITableView+VisibleMenuCell.m ├── LICENSE ├── README.md ├── SampleProject ├── MainViewController.xib ├── Podfile ├── Podfile.lock ├── Pods │ ├── ABDataSourceController │ │ ├── ABDataSourceController │ │ │ ├── ABDataSourceController.h │ │ │ ├── UITableView+DataSourceController.h │ │ │ └── UITableView+DataSourceController.m │ │ ├── LICENSE │ │ └── README.md │ ├── Headers │ │ ├── Private │ │ │ ├── ABDataSourceController │ │ │ │ ├── ABDataSourceController.h │ │ │ │ └── UITableView+DataSourceController.h │ │ │ └── SmudgeKit │ │ │ │ └── SmudgyWindow.h │ │ └── Public │ │ │ ├── ABDataSourceController │ │ │ ├── ABDataSourceController.h │ │ │ └── UITableView+DataSourceController.h │ │ │ └── SmudgeKit │ │ │ └── SmudgyWindow.h │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ ├── SmudgeKit │ │ ├── LICENSE │ │ ├── README.md │ │ └── Source-ObjectiveC │ │ │ ├── SmudgyWindow.h │ │ │ └── SmudgyWindow.m │ └── Target Support Files │ │ ├── Pods-ABDataSourceController │ │ ├── Pods-ABDataSourceController-Private.xcconfig │ │ ├── Pods-ABDataSourceController-dummy.m │ │ ├── Pods-ABDataSourceController-prefix.pch │ │ └── Pods-ABDataSourceController.xcconfig │ │ ├── Pods-SmudgeKit │ │ ├── Pods-SmudgeKit-Private.xcconfig │ │ ├── Pods-SmudgeKit-dummy.m │ │ ├── Pods-SmudgeKit-prefix.pch │ │ └── Pods-SmudgeKit.xcconfig │ │ └── Pods │ │ ├── Pods-acknowledgements.markdown │ │ ├── Pods-acknowledgements.plist │ │ ├── Pods-dummy.m │ │ ├── Pods-environment.h │ │ ├── Pods-resources.sh │ │ ├── Pods.debug.xcconfig │ │ └── Pods.release.xcconfig ├── SampleProject.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── SampleProject.xccheckout │ │ └── xcuserdata │ │ │ └── alexbumbu.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── alexbumbu.xcuserdatad │ │ └── xcschemes │ │ ├── SampleProject.xcscheme │ │ └── xcschememanagement.plist ├── SampleProject.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── SampleProject.xccheckout ├── SampleProject │ ├── ABCellCustomStyleMenuView.xib │ ├── ABCellMailStyleMenuView.xib │ ├── ABCellMenuView.h │ ├── ABCellMenuView.m │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── CustomMenuTableViewCell.h │ ├── CustomMenuTableViewCell.m │ ├── DataSource.plist │ ├── DetailsViewController.h │ ├── DetailsViewController.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── cats.imageset │ │ │ ├── Contents.json │ │ │ ├── cats.jpg │ │ │ ├── cats@2x.jpg │ │ │ └── cats@3x.jpg │ ├── Info.plist │ ├── MainDataSourceController.h │ ├── MainDataSourceController.m │ ├── MainViewController.h │ ├── MainViewController.m │ ├── Options.h │ ├── UIView+XIB.h │ ├── UIView+XIB.m │ └── main.m └── SampleProjectTests │ ├── Info.plist │ └── SampleProjectTests.m ├── sample_custom_delete.gif ├── sample_mail_delete.gif └── sample_mail_hide.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # MAC OS 2 | *.DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | *.moved-aside 17 | DerivedData 18 | *.hmap 19 | *.ipa 20 | *.xcuserstate 21 | 22 | # CocoaPods 23 | #Pods/ 24 | -------------------------------------------------------------------------------- /ABMenuTableViewCell.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "ABMenuTableViewCell" 3 | s.version = "2.0.1" 4 | s.summary = "Highly customizable, yet simple to use, solution for UITableViewCell right menu, shown by 'swipe to delete' gesture." 5 | s.homepage = "https://github.com/alexbumbu/ABMenuTableViewCell" 6 | s.license = "MIT" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | s.author = {"Alex Bumbu" => "https://github.com/alexbumbu"} 9 | s.platform = :ios, "7.0" 10 | s.source = { :git => "https://github.com/alexbumbu/ABMenuTableViewCell.git", :tag => "2.0.1" } 11 | s.source_files = "ABMenuTableViewCell" 12 | s.requires_arc = true 13 | end 14 | -------------------------------------------------------------------------------- /ABMenuTableViewCell/ABMenuTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABTableViewCell.h 3 | // 4 | // Created by Alex Bumbu on 06/12/14. 5 | // Copyright (c) 2014 Alex Bumbu. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | 26 | #import 27 | 28 | /** 29 | The 'ABMenuTableViewCell' is a 'UITableViewCell' subclass that includes properties and methods for setting and presenting a custom 'UIView' object on the right side of the cell. It can be used with predefined cell styles or with custom cells. Also works with InterfaceBuilder instantiated cells. 30 | 31 | You are responsible for setting and positioning the 'rightMenuView' content and will be added as subview to the 'contentView' property of the cell when property is set. Presentation will be done using well known iOS horizontal swipe gestures. 32 | 33 | @warning Setting the 'accessoryView' property may produce unexpected behaviour due to 'rightMenuView' being a subview of contentView. This behaviour can be avoided by adding the accessory view object as subview to the 'rightMenuView' object. 34 | @warning Using 'UITableViewDataSource -tableView:canEditRowAtIndexPath:' interferes with the swipe gesture causing unexpected behaviour. If a Delete option is required it can be added as subview to the 'rightMenuView' property of the cell. 35 | */ 36 | 37 | @interface ABMenuTableViewCell : UITableViewCell 38 | 39 | /** 40 | Specifies the view to use for the right menu. Default is nil. 41 | 42 | @since v1.0.0 43 | */ 44 | @property (nonatomic, assign) UIView * _Nullable rightMenuView; 45 | 46 | /** 47 | Returns whether the cell is currently showing the right menu view. 48 | 49 | @since v2.0.2 50 | */ 51 | @property (nonatomic, readonly) BOOL showingRightMenu; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /ABMenuTableViewCell/ABMenuTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABTableViewCell.m 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 06/12/14. 6 | // Copyright (c) 2014 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "ABMenuTableViewCell.h" 10 | #import "UITableView+VisibleMenuCell.h" 11 | 12 | 13 | typedef NS_ENUM(NSInteger, ABMenuUpdateAction) { 14 | ABMenuUpdateShowAction = 1, 15 | ABMenuUpdateHideAction = -1 16 | }; 17 | 18 | typedef NS_ENUM(NSInteger, ABMenuState) { 19 | ABMenuStateHidden = 0, 20 | ABMenuStateShowing, 21 | ABMenuStateShown, 22 | ABMenuStateHiding 23 | }; 24 | 25 | static CGFloat const kSpringAnimationDuration = .6; 26 | static CGFloat const kAnimationDuration = .26; 27 | static CGFloat const kHighlightAnimationDuration = 0.45; // value obtained through trial & error 28 | 29 | 30 | @interface ABMenuTableViewCell () 31 | 32 | @property (nonatomic, assign) UITableView *parentTableView; 33 | 34 | @property (nonatomic, assign) ABMenuState rightMenuState; 35 | @property (nonatomic, assign) CGPoint lastGestureLocation; 36 | @property (nonatomic, assign) CGPoint startGestureLocation; 37 | @property (nonatomic, assign) CGFloat prevDistance; 38 | @property (nonatomic, assign) BOOL ongoingSelection; 39 | 40 | @end 41 | 42 | 43 | @implementation ABMenuTableViewCell { 44 | CGRect _rightMenuViewInitialFrame; 45 | UIPanGestureRecognizer *_swipeGesture; 46 | } 47 | 48 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 49 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 50 | if (self) { 51 | [self commonInit]; 52 | } 53 | 54 | return self; 55 | } 56 | 57 | - (void)awakeFromNib { 58 | [super awakeFromNib]; 59 | [self commonInit]; 60 | } 61 | 62 | - (void)didMoveToSuperview { 63 | [super didMoveToSuperview]; 64 | 65 | // find out the table view 66 | UIView *view = self.superview; 67 | 68 | while (view && [view isKindOfClass:[UITableView class]] == NO) { 69 | view = view.superview; 70 | } 71 | 72 | self.parentTableView = (UITableView *)view; 73 | } 74 | 75 | - (void)willTransitionToState:(UITableViewCellStateMask)state { 76 | if (state == UITableViewCellStateShowingEditControlMask) { 77 | if (self.rightMenuState == ABMenuStateShown || self.rightMenuState == ABMenuStateShowing) { 78 | [self updateMenuView:ABMenuUpdateHideAction animated:YES]; 79 | } 80 | } 81 | 82 | [super willTransitionToState:state]; 83 | } 84 | 85 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 86 | // hide menu if presented 87 | ABMenuTableViewCell *cell = nil; 88 | if (self.parentTableView.visibleMenuCell) { 89 | if (selected && (self.rightMenuState == ABMenuStateShowing || self.rightMenuState == ABMenuStateShown)) { 90 | cell = self; 91 | } 92 | else { 93 | cell = self.parentTableView.visibleMenuCell; 94 | } 95 | 96 | [cell updateMenuView:ABMenuUpdateHideAction animated:YES]; 97 | self.parentTableView.visibleMenuCell = nil; 98 | 99 | return; 100 | } 101 | 102 | [super setSelected:selected animated:animated]; 103 | 104 | // prevent swipeGesture before highlight animation completes 105 | if (!selected) { 106 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kHighlightAnimationDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 107 | self.ongoingSelection = NO; 108 | }); 109 | } 110 | } 111 | 112 | - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { 113 | // iPad special case - highlighting the cell is not prevented when starting swipeGesture 114 | // fix by checking if swipeGesture is started 115 | CGFloat gestureVelocity = [_swipeGesture velocityInView:self].x; 116 | if (gestureVelocity) 117 | return; 118 | 119 | // prevent highlighting when menu is on screen 120 | if (self.parentTableView.visibleMenuCell) 121 | return; 122 | 123 | if (self.rightMenuState == ABMenuStateShowing || self.rightMenuState == ABMenuStateShown) 124 | return; 125 | 126 | if (highlighted) 127 | self.ongoingSelection = YES; 128 | 129 | [super setHighlighted:highlighted animated:animated]; 130 | } 131 | 132 | - (void)prepareForReuse { 133 | [super prepareForReuse]; 134 | 135 | [self hideMenu]; 136 | 137 | // reset states 138 | self.ongoingSelection = NO; 139 | self.rightMenuState = ABMenuStateHidden; 140 | self.prevDistance = .0; 141 | self.startGestureLocation = CGPointZero; 142 | 143 | [self resetLastGestureLocation]; 144 | } 145 | 146 | - (void)layoutSubviews { 147 | if (self.rightMenuState == ABMenuStateHidden && _rightMenuView) { 148 | [self hideMenu]; 149 | } 150 | 151 | [super layoutSubviews]; 152 | } 153 | 154 | - (void)setRightMenuView:(UIView *)rightMenuView { 155 | if (_rightMenuView != rightMenuView) { 156 | // clean 157 | [_rightMenuView removeFromSuperview]; 158 | 159 | // add new 160 | _rightMenuView = rightMenuView; 161 | _rightMenuViewInitialFrame = _rightMenuView.frame; 162 | 163 | [self hideMenu]; 164 | [self.contentView addSubview:_rightMenuView]; 165 | } 166 | } 167 | 168 | - (BOOL)showingRightMenu { 169 | return self.rightMenuState != ABMenuStateHidden; 170 | } 171 | 172 | 173 | #pragma mark UIGestureRecognizerDelegate Methods 174 | 175 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 176 | return NO; 177 | } 178 | 179 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 180 | if (gestureRecognizer == _swipeGesture) { 181 | CGPoint velocity = [(UIPanGestureRecognizer*)gestureRecognizer velocityInView:self]; 182 | 183 | // prevent swipeGesture before highlight animation completes 184 | if (self.ongoingSelection) 185 | return NO; 186 | 187 | // prevent swipeGesture when editing control is shown 188 | if (self.editing) 189 | return NO; 190 | 191 | // make sure to update cells and hide any visible menu 192 | if (self.parentTableView.visibleMenuCell) { 193 | [self.parentTableView.visibleMenuCell updateMenuView:ABMenuUpdateHideAction animated:YES]; 194 | self.parentTableView.visibleMenuCell = nil; 195 | 196 | // check sipe direction & allow only swipe to close gesture 197 | if (velocity.x < 0) 198 | return NO; 199 | } 200 | 201 | // enable only horizontal gesture 202 | BOOL shouldBegin = fabs(velocity.x) > fabs(velocity.y); 203 | 204 | return shouldBegin; 205 | } 206 | 207 | return YES; 208 | } 209 | 210 | 211 | #pragma mark Actions 212 | 213 | - (void)handleSwipeGesture:(UIPanGestureRecognizer *)gesture { 214 | CGFloat initialWidth = CGRectGetWidth(_rightMenuViewInitialFrame); 215 | ABMenuUpdateAction direction = [self actionForGesture:gesture]; 216 | CGPoint gestureLocation = [gesture locationInView:self]; 217 | 218 | switch (gesture.state) { 219 | case UIGestureRecognizerStateBegan: { 220 | // reset values 221 | self.prevDistance = .0; 222 | self.startGestureLocation = [gesture locationInView:self]; 223 | [self resetLastGestureLocation]; 224 | 225 | // get new direction value after reseting gesture location values 226 | direction = [self actionForGesture:gesture]; 227 | 228 | // update menu state 229 | if (direction == ABMenuUpdateShowAction) { 230 | self.rightMenuState = ABMenuStateShowing; 231 | } 232 | else { 233 | self.rightMenuState = ABMenuStateHiding; 234 | } 235 | 236 | break; 237 | } 238 | case UIGestureRecognizerStateChanged: { 239 | // get distance since gesture beginning 240 | CGFloat totalDistance = self.startGestureLocation.x - gestureLocation.x; 241 | 242 | // handle out of bounds case considering menuState and direction 243 | if (totalDistance <= .0) { 244 | if (direction == ABMenuUpdateHideAction && self.rightMenuState == ABMenuStateHidden) 245 | totalDistance = .0; 246 | 247 | self.startGestureLocation = [gesture locationInView:self]; 248 | } 249 | 250 | // update UI with distance since previous gesture state 251 | [self updateMenuView:direction delta:fabs(totalDistance - self.prevDistance) animated:NO completion:nil]; 252 | 253 | self.prevDistance = totalDistance; 254 | 255 | break; 256 | } 257 | case UIGestureRecognizerStateCancelled: { 258 | break; 259 | } 260 | case UIGestureRecognizerStateEnded: { 261 | // calculate deltaX considering menuState and direction 262 | CGFloat deltaX = .0; 263 | switch (self.rightMenuState) { 264 | case ABMenuStateShowing: { 265 | deltaX = (direction == ABMenuUpdateShowAction? initialWidth : 0) - self.prevDistance; 266 | break; 267 | } 268 | case ABMenuStateHiding: { 269 | deltaX = (direction == ABMenuUpdateShowAction? 0 : initialWidth) - self.prevDistance; 270 | break; 271 | } 272 | case ABMenuStateShown: 273 | case ABMenuStateHidden: 274 | break; 275 | 276 | default: 277 | break; 278 | } 279 | 280 | // update UI 281 | [self updateMenuView:direction delta:fabs(deltaX) animated:YES completion:nil]; 282 | 283 | // update menu state 284 | if (direction == ABMenuUpdateShowAction) { 285 | self.rightMenuState = ABMenuStateShown; 286 | self.parentTableView.visibleMenuCell = self; 287 | } 288 | else { 289 | self.rightMenuState = ABMenuStateHidden; 290 | } 291 | 292 | break; 293 | } 294 | 295 | default: 296 | break; 297 | } 298 | 299 | self.lastGestureLocation = gestureLocation; 300 | } 301 | 302 | 303 | #pragma mark Private Methods 304 | 305 | - (void)commonInit { 306 | self.ongoingSelection = NO; 307 | self.rightMenuState = ABMenuStateHidden; 308 | self.prevDistance = .0; 309 | self.startGestureLocation = CGPointZero; 310 | 311 | [self resetLastGestureLocation]; 312 | 313 | _swipeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; 314 | _swipeGesture.delegate = self; 315 | [self addGestureRecognizer:_swipeGesture]; 316 | } 317 | 318 | - (void)resetLastGestureLocation { 319 | if (self.rightMenuState == ABMenuStateShown) { 320 | self.lastGestureLocation = CGPointZero; 321 | } 322 | else if (self.rightMenuState == ABMenuStateHidden){ 323 | self.lastGestureLocation = CGPointMake(CGRectGetWidth(self.frame), .0); 324 | } 325 | } 326 | 327 | - (void)updateMenuView:(ABMenuUpdateAction)action animated:(BOOL)animated { 328 | CGFloat initialWidth = CGRectGetWidth(_rightMenuViewInitialFrame); 329 | 330 | // update menu starting state 331 | if (action == ABMenuUpdateShowAction) { 332 | self.rightMenuState = ABMenuStateShowing; 333 | } 334 | else { 335 | self.rightMenuState = ABMenuStateHiding; 336 | } 337 | 338 | [self updateMenuView:action delta:initialWidth animated:animated completion:^{ 339 | // update menu final state 340 | if (action == ABMenuUpdateShowAction) { 341 | self.rightMenuState = ABMenuStateShown; 342 | } 343 | else { 344 | self.rightMenuState = ABMenuStateHidden; 345 | } 346 | }]; 347 | } 348 | 349 | - (ABMenuUpdateAction)actionForGesture:(UIPanGestureRecognizer *)gesture { 350 | static ABMenuUpdateAction direction = 0; 351 | CGPoint gestureLocation = [gesture locationInView:self]; 352 | 353 | // find swipe direction - not using velocityInView due to incorrect reporting when changing swipe direction 354 | if (gestureLocation.x == self.lastGestureLocation.x) { 355 | // do nothing 356 | } 357 | else if (gestureLocation.x < self.lastGestureLocation.x) { 358 | // towards left - show menu view 359 | direction = ABMenuUpdateShowAction; 360 | } 361 | else { 362 | // towards right - hide menu view 363 | direction = ABMenuUpdateHideAction; 364 | } 365 | 366 | return direction; 367 | } 368 | 369 | - (void)updateMenuView:(ABMenuUpdateAction)action delta:(CGFloat)deltaX animated:(BOOL)animated completion: (void (^)())completionHandler { 370 | CGFloat initialWidth = CGRectGetWidth(_rightMenuViewInitialFrame); 371 | 372 | // adjust deltaX so it doesn't get out of bounds 373 | CGFloat newWidth = CGRectGetWidth(_rightMenuView.frame) + action*deltaX; 374 | CGFloat deltaOffset = initialWidth - newWidth; 375 | 376 | if (newWidth < 0) { 377 | deltaX += newWidth; 378 | } 379 | else if (deltaOffset < 0) { 380 | deltaX += deltaOffset; 381 | } 382 | 383 | // calculate new menu frame 384 | CGRect menuNewFrame = CGRectMake(CGRectGetMinX(_rightMenuView.frame) - action*deltaX, .0, 385 | CGRectGetWidth(_rightMenuView.frame) + action*deltaX, CGRectGetHeight(self.contentView.frame)); 386 | 387 | // get list of subviews to update 388 | NSMutableArray *subviews = [NSMutableArray array]; 389 | for (UIView *subview in self.contentView.subviews) { 390 | if (subview == _rightMenuView) 391 | continue; 392 | 393 | [subviews addObject:subview]; 394 | } 395 | 396 | // animate updates 397 | [self layoutIfNeeded]; 398 | 399 | [UIView animateWithDuration:(animated? kAnimationDuration : .0) 400 | animations:^{ 401 | _rightMenuView.frame = menuNewFrame; 402 | 403 | [self layoutIfNeeded]; 404 | } 405 | completion:^(BOOL finished) { 406 | if (completionHandler) { 407 | completionHandler(); 408 | } 409 | }]; 410 | 411 | [UIView animateWithDuration:(animated? kSpringAnimationDuration : .0) 412 | delay:.0 413 | usingSpringWithDamping:(action > 0) ? kSpringAnimationDuration : 1.0 414 | initialSpringVelocity:(action > 0) ? 1.0 : .0 415 | options:0 416 | animations:^{ 417 | for (UIView *subview in subviews) { 418 | subview.frame = CGRectMake(CGRectGetMinX(subview.frame) - action*deltaX, CGRectGetMinY(subview.frame), 419 | CGRectGetWidth(subview.frame), CGRectGetHeight(subview.frame)); 420 | } 421 | } 422 | completion:^(BOOL finished) { 423 | if (completionHandler) { 424 | completionHandler(); 425 | } 426 | }]; 427 | } 428 | 429 | - (void)hideMenu { 430 | _rightMenuView.frame = CGRectMake(CGRectGetWidth(self.contentView.frame), .0, .0, CGRectGetHeight(self.contentView.frame)); 431 | } 432 | 433 | @end 434 | -------------------------------------------------------------------------------- /ABMenuTableViewCell/UITableView+VisibleMenuCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+VisibleMenuCell.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 19/11/15. 6 | // Copyright © 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ABMenuTableViewCell; 12 | 13 | @interface UITableView (VisibleMenuCell) 14 | 15 | @property (nonatomic, assign) ABMenuTableViewCell *visibleMenuCell; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ABMenuTableViewCell/UITableView+VisibleMenuCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+VisibleMenuCell.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 19/11/15. 6 | // Copyright © 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "UITableView+VisibleMenuCell.h" 10 | #import 11 | 12 | @implementation UITableView (VisibleMenuCell) 13 | 14 | @dynamic visibleMenuCell; 15 | 16 | - (void)setVisibleMenuCell:(ABMenuTableViewCell *)visibleMenuCell { 17 | objc_setAssociatedObject(self, @selector(visibleMenuCell), visibleMenuCell, OBJC_ASSOCIATION_ASSIGN); 18 | } 19 | 20 | - (ABMenuTableViewCell *)visibleMenuCell { 21 | return objc_getAssociatedObject(self, @selector(visibleMenuCell)); 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alex Bumbu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ABMenuTableViewCell 2 | 3 | **Fully compatible with iOS 9** 4 | 5 | Highly customizable, yet simple to use, solution for UITableViewCell right menu, shown by 'swipe to delete' gesture. 6 | 7 | **Mail App Styled Menu - show & hide example:** 8 | 9 | Without any extra work needed, showing the right menu view works with default swipe-to-delete gesture. Also, hiding the menu is done using known gestures like tapping or swiping back. 10 | 11 | ![Screenshot](https://github.com/alexbumbu/ABMenuTableViewCell/blob/master/sample_mail_hide.gif) 12 | 13 | **Mail App Styled Menu - delete item example:** 14 | 15 | Deleting rows is as simple as the default implementation. 16 | 17 | ![Screenshot](https://github.com/alexbumbu/ABMenuTableViewCell/blob/master/sample_mail_delete.gif) 18 | 19 | **Custom Styled Menu - show, hide & delete example** 20 | 21 | The advantage of using custom menus is that you're not stuck with Apple style buttons and you can easily integrate your own design. 22 | 23 | ![Screenshot](https://github.com/alexbumbu/ABMenuTableViewCell/blob/master/sample_custom_delete.gif) 24 | 25 | ## Integration 26 | 27 | * Install via cocoapods (just add ```pod 'ABMenuTableViewCell', '~> 2.0'``` to your Podfile), or clone this repository and drag the content of ABMenuTableViewCell folder to your project. 28 | * To use you just need to replace UITableViewCell with ABMenuTableViewCell and assign your custom menu view to rightMenuView property and you're ready to go! You can take a look at the following snippet for details. 29 | 30 | ```objective-c 31 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 32 | static NSString *identifier = @"ABMenuTableViewCell"; 33 | ABMenuTableViewCell *cell = (ABMenuTableViewCell*)[tableView cellForRowAtIndexPath:indexPath]; 34 | 35 | if (!cell) { 36 | cell = [[ABMenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; 37 | } 38 | 39 | // use your own custom menu view 40 | UIView *menuView = [[UIView alloc] initWithFrame:CGRectMake(.0, .0, 160.0, 44.0)]; 41 | menuView.backgroundColor = [UIColor redColor]; 42 | 43 | cell.rightMenuView = menuView; 44 | cell.textLabel.text = @"Lorem ipsum dolor sit amet"; 45 | 46 | return cell; 47 | } 48 | ``` 49 | 50 | ## Requirements 51 | 52 | * iOS 7.x or newer 53 | * ARC 54 | * Xcode 6.x 55 | 56 | ## Credits 57 | 58 | ABMenuTableViewCell was created by [Alex Bumbu](https://github.com/alexbumbu). 59 | 60 | ## License 61 | 62 | ABMenuTableViewCell is available under the MIT license. See the LICENSE file for more info. 63 | For usage without attribution contact [Alex Bumbu](mailto:alex.bumbu@gmail.com). 64 | -------------------------------------------------------------------------------- /SampleProject/MainViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /SampleProject/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | inhibit_all_warnings! 3 | 4 | pod 'ABDataSourceController', '~> 1.0' 5 | pod 'SmudgeKit' -------------------------------------------------------------------------------- /SampleProject/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ABDataSourceController (1.0.1) 3 | - SmudgeKit (0.1.2) 4 | 5 | DEPENDENCIES: 6 | - ABDataSourceController (~> 1.0) 7 | - SmudgeKit 8 | 9 | SPEC CHECKSUMS: 10 | ABDataSourceController: eeea6521b0591c63715bd93db1586c7eecfaf790 11 | SmudgeKit: d605782fc87271803b32c3fac6e9d6a2963f6ee8 12 | 13 | COCOAPODS: 0.36.3 14 | -------------------------------------------------------------------------------- /SampleProject/Pods/ABDataSourceController/ABDataSourceController/ABDataSourceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABDataSourceController.h 3 | // ABDataSourceController 4 | // 5 | // Created by Alex Bumbu on 10/07/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @protocol ABDataSourceController 13 | 14 | @property (nonatomic, assign) IBOutlet UITableView *tableView; 15 | @property (nonatomic, assign) IBOutlet UIViewController *viewController; 16 | 17 | - (void)refreshDataSourceWithCompletionHandler:(void (^)())completion; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SampleProject/Pods/ABDataSourceController/ABDataSourceController/UITableView+DataSourceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+DataSourceController.h 3 | // ABDataSourceController 4 | // 5 | // Created by Alex Bumbu on 10/07/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ABDataSourceController.h" 11 | 12 | @interface UITableView (DataSourceController) 13 | 14 | @property (nonatomic, strong) IBOutlet id dataSourceController; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /SampleProject/Pods/ABDataSourceController/ABDataSourceController/UITableView+DataSourceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+DataSourceController.m 3 | // ABDataSourceController 4 | // 5 | // Created by Alex Bumbu on 10/07/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "UITableView+DataSourceController.h" 10 | #import 11 | 12 | @implementation UITableView (DataSourceController) 13 | 14 | @dynamic dataSourceController; 15 | 16 | - (void)setDataSourceController:(id)dataSourceController { 17 | objc_setAssociatedObject(self, @selector(dataSourceController), dataSourceController, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 18 | 19 | self.delegate = dataSourceController; 20 | self.dataSource = dataSourceController; 21 | 22 | dataSourceController.tableView = self; 23 | } 24 | 25 | - (id)dataSourceController { 26 | return objc_getAssociatedObject(self, @selector(dataSourceController)); 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SampleProject/Pods/ABDataSourceController/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alex Bumbu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /SampleProject/Pods/ABDataSourceController/README.md: -------------------------------------------------------------------------------- 1 | # ABDataSourceController 2 | 3 | Simple to use approach to get rid of your UITableViewDataSource & UITableViewDelegate code from your UIViewController and share it between UIViewControllers. 4 | 5 | ## Integration 6 | 7 | * Clone this repository and drag the content of ```ABDataSourceController``` folder to your project. 8 | * To use you just need to create your custom data source controller object that implements ```ABDataSourceController``` protocol: 9 | 10 | ```objective-c 11 | #import "ABDataSourceController.h" 12 | 13 | @interface CustomDataSourceController : NSObject 14 | 15 | @property (nonatomic, assign) IBOutlet UITableView *tableView; 16 | @property (nonatomic, assign) IBOutlet UIViewController *viewController; 17 | 18 | @end 19 | 20 | @implementation CustomDataSourceController { 21 | NSArray *_dataSource; 22 | } 23 | 24 | @synthesize tableView = _tableView; 25 | @synthesize viewController = _viewController; 26 | 27 | @end 28 | ``` 29 | 30 | * Now override ```refreshDataSourceWithCompletionHandler``` method to load data source: 31 | 32 | ```objective-c 33 | - (void)refreshDataSourceWithCompletionHandler:(void (^)())completion { 34 | [self loadDataSource]; 35 | 36 | if (completion) 37 | completion(); 38 | } 39 | ``` 40 | 41 | * and write all your ```UITableViewDataSource``` & ```UITableViewDelegate``` code: 42 | 43 | ```objective-c 44 | #pragma mark UITableViewDataSource Methods 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 | return _dataSource.count; 48 | } 49 | 50 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 51 | static NSString *identifier = @"DefaultCell"; 52 | 53 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 54 | if (!cell) { 55 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; 56 | } 57 | 58 | cell.textLabel.text = [_dataSource objectAtIndex:indexPath.row]; 59 | 60 | return cell; 61 | } 62 | 63 | ``` 64 | 65 | * All that's left is to initialize the data source controller in your UIViewController and assign it to your UITableView ```dataSourceController``` property and you're ready to go! 66 | 67 | ```objective-c 68 | #import "UITableView+DataSourceController.h" 69 | 70 | @implementation MainViewController { 71 | IBOutlet UITableView *tableView; 72 | } 73 | 74 | - (void)viewDidLoad { 75 | [super viewDidLoad]; 76 | // Do any additional setup after loading the view from its nib. 77 | 78 | // setup data source controller 79 | CustomDataSourceController *dataSourceCtrl = [[CustomDataSourceController alloc] init]; 80 | dataSourceCtrl.tableView = tableView; 81 | dataSourceCtrl.viewController = self; 82 | tableView.dataSourceController = dataSourceCtrl; 83 | 84 | // load data source 85 | [tableView.dataSourceController refreshDataSourceWithCompletionHandler:nil]; 86 | } 87 | 88 | @end 89 | ``` 90 | 91 | ## Compatibility 92 | 93 | * iOS 7 and iOS 8 94 | 95 | ## Credits 96 | 97 | ABDataSourceController was created by [Alex Bumbu](https://github.com/alexbumbu). 98 | 99 | ## License 100 | 101 | ABDataSourceController is available under the MIT license. See the LICENSE file for more info. 102 | For usage without attribution contact [Alex Bumbu](mailto:alex.bumbu@gmail.com). -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Private/ABDataSourceController/ABDataSourceController.h: -------------------------------------------------------------------------------- 1 | ../../../ABDataSourceController/ABDataSourceController/ABDataSourceController.h -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Private/ABDataSourceController/UITableView+DataSourceController.h: -------------------------------------------------------------------------------- 1 | ../../../ABDataSourceController/ABDataSourceController/UITableView+DataSourceController.h -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Private/SmudgeKit/SmudgyWindow.h: -------------------------------------------------------------------------------- 1 | ../../../SmudgeKit/Source-ObjectiveC/SmudgyWindow.h -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Public/ABDataSourceController/ABDataSourceController.h: -------------------------------------------------------------------------------- 1 | ../../../ABDataSourceController/ABDataSourceController/ABDataSourceController.h -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Public/ABDataSourceController/UITableView+DataSourceController.h: -------------------------------------------------------------------------------- 1 | ../../../ABDataSourceController/ABDataSourceController/UITableView+DataSourceController.h -------------------------------------------------------------------------------- /SampleProject/Pods/Headers/Public/SmudgeKit/SmudgyWindow.h: -------------------------------------------------------------------------------- 1 | ../../../SmudgeKit/Source-ObjectiveC/SmudgyWindow.h -------------------------------------------------------------------------------- /SampleProject/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ABDataSourceController (1.0.1) 3 | - SmudgeKit (0.1.2) 4 | 5 | DEPENDENCIES: 6 | - ABDataSourceController (~> 1.0) 7 | - SmudgeKit 8 | 9 | SPEC CHECKSUMS: 10 | ABDataSourceController: eeea6521b0591c63715bd93db1586c7eecfaf790 11 | SmudgeKit: d605782fc87271803b32c3fac6e9d6a2963f6ee8 12 | 13 | COCOAPODS: 0.36.3 14 | -------------------------------------------------------------------------------- /SampleProject/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 21F0B28DB5B8066294EDC063 /* SmudgyWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 4222C47669356387FA692D8A /* SmudgyWindow.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-checker -Xanalyzer deadcode"; }; }; 11 | 2BA85CF79BE7C7A17A06D9AC /* Pods-SmudgeKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D111EE2A1816CE8F9864C65F /* Pods-SmudgeKit-dummy.m */; }; 12 | 2F73F7F9012737AC96EC7DDC /* ABDataSourceController.h in Headers */ = {isa = PBXBuildFile; fileRef = F59AAE24CC65A446E5948E0B /* ABDataSourceController.h */; }; 13 | 36F14A8434948BAEE3E53D00 /* SmudgyWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DE69761EF3D1BFBCCB71B65 /* SmudgyWindow.h */; }; 14 | 68AB2A7D7214266717C056B2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B40B692479D25962C8F17F9A /* Foundation.framework */; }; 15 | 8730BC3D02C3AE14F434216B /* UITableView+DataSourceController.h in Headers */ = {isa = PBXBuildFile; fileRef = 79D9B8B8C09E074949894556 /* UITableView+DataSourceController.h */; }; 16 | 9892036709C58D38C9E00D4F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B40B692479D25962C8F17F9A /* Foundation.framework */; }; 17 | AA0BEA9C22E5CE5A3ED8664B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B40B692479D25962C8F17F9A /* Foundation.framework */; }; 18 | BB3194BC286801CFA93A0A9D /* UITableView+DataSourceController.m in Sources */ = {isa = PBXBuildFile; fileRef = B26D991A1D5E159F179BA1AA /* UITableView+DataSourceController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-checker -Xanalyzer deadcode"; }; }; 19 | DF7E3955326D149AD4E2319F /* Pods-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AD8623457CF176F01DBDDEA /* Pods-dummy.m */; }; 20 | EA47F261DF3BB45AB30572AD /* Pods-ABDataSourceController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 239F9CD4184E82D9A5AAEE69 /* Pods-ABDataSourceController-dummy.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | B50E1A27F96109F289B60114 /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = C221CFAB2811A41D386B417E /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = FAD1F566D12EC317A9C7CDAE; 29 | remoteInfo = "Pods-SmudgeKit"; 30 | }; 31 | EE09C726FB526620C72BF9A4 /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = C221CFAB2811A41D386B417E /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = E5E3E003D1EE41C9AE477F41; 36 | remoteInfo = "Pods-ABDataSourceController"; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 09F4498FE8043ABF4BC2B2F6 /* Pods-SmudgeKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SmudgeKit-prefix.pch"; sourceTree = ""; }; 42 | 239F9CD4184E82D9A5AAEE69 /* Pods-ABDataSourceController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ABDataSourceController-dummy.m"; sourceTree = ""; }; 43 | 29EAE6B5378AC5D6D96D1418 /* Pods-SmudgeKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SmudgeKit.xcconfig"; sourceTree = ""; }; 44 | 3419174719E9620D7E6D6B32 /* Pods-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-resources.sh"; sourceTree = ""; }; 45 | 4222C47669356387FA692D8A /* SmudgyWindow.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SmudgyWindow.m; path = "Source-ObjectiveC/SmudgyWindow.m"; sourceTree = ""; }; 46 | 4AD8623457CF176F01DBDDEA /* Pods-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-dummy.m"; sourceTree = ""; }; 47 | 4E21D97CD5F579BA2857F4DE /* Pods-ABDataSourceController-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ABDataSourceController-Private.xcconfig"; sourceTree = ""; }; 48 | 59C40F4DDBFE0BAF46BC7D12 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.release.xcconfig; sourceTree = ""; }; 49 | 5DE69761EF3D1BFBCCB71B65 /* SmudgyWindow.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SmudgyWindow.h; path = "Source-ObjectiveC/SmudgyWindow.h"; sourceTree = ""; }; 50 | 5F019E48F17A39700FCA58D9 /* Pods-ABDataSourceController.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ABDataSourceController.xcconfig"; sourceTree = ""; }; 51 | 635AEC136A8AF21E345BCC46 /* libPods-SmudgeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SmudgeKit.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 796A962CDC5C669DE189CD3C /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.debug.xcconfig; sourceTree = ""; }; 53 | 79D9B8B8C09E074949894556 /* UITableView+DataSourceController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UITableView+DataSourceController.h"; path = "ABDataSourceController/UITableView+DataSourceController.h"; sourceTree = ""; }; 54 | AB4B0540C3341B7D369CD58A /* Pods-ABDataSourceController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ABDataSourceController-prefix.pch"; sourceTree = ""; }; 55 | B26D991A1D5E159F179BA1AA /* UITableView+DataSourceController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UITableView+DataSourceController.m"; path = "ABDataSourceController/UITableView+DataSourceController.m"; sourceTree = ""; }; 56 | B40B692479D25962C8F17F9A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 57 | B4AC627ADE7D25FE916A0CAF /* Pods-SmudgeKit-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SmudgeKit-Private.xcconfig"; sourceTree = ""; }; 58 | D111EE2A1816CE8F9864C65F /* Pods-SmudgeKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SmudgeKit-dummy.m"; sourceTree = ""; }; 59 | D6E1057B18A107FF920AA6A4 /* Pods-environment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-environment.h"; sourceTree = ""; }; 60 | D92BCB48987E3FCC04E45C69 /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; }; 61 | F01371A33DF02EB395BB5A62 /* Pods-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-acknowledgements.markdown"; sourceTree = ""; }; 62 | F21E4409A0C9C1604D622995 /* libPods-ABDataSourceController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ABDataSourceController.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | F2E95B97B5815997FDCFB565 /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 64 | F59AAE24CC65A446E5948E0B /* ABDataSourceController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ABDataSourceController.h; path = ABDataSourceController/ABDataSourceController.h; sourceTree = ""; }; 65 | F5B2DCD1DD69E24056710F2D /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | C42E7E3DF164082407ED802D /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 68AB2A7D7214266717C056B2 /* Foundation.framework in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | E4B071F5032718F2392A05B4 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | AA0BEA9C22E5CE5A3ED8664B /* Foundation.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | F615A7F5CBC6E980A26A724E /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | 9892036709C58D38C9E00D4F /* Foundation.framework in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | /* End PBXFrameworksBuildPhase section */ 94 | 95 | /* Begin PBXGroup section */ 96 | 164390F3D8B9175AD6EB13E4 /* iOS */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | B40B692479D25962C8F17F9A /* Foundation.framework */, 100 | ); 101 | name = iOS; 102 | sourceTree = ""; 103 | }; 104 | 175598B6D7E1A314003AA104 /* Support Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 5F019E48F17A39700FCA58D9 /* Pods-ABDataSourceController.xcconfig */, 108 | 4E21D97CD5F579BA2857F4DE /* Pods-ABDataSourceController-Private.xcconfig */, 109 | 239F9CD4184E82D9A5AAEE69 /* Pods-ABDataSourceController-dummy.m */, 110 | AB4B0540C3341B7D369CD58A /* Pods-ABDataSourceController-prefix.pch */, 111 | ); 112 | name = "Support Files"; 113 | path = "../Target Support Files/Pods-ABDataSourceController"; 114 | sourceTree = ""; 115 | }; 116 | 51A64B4C195340E12EDBF351 /* Pods */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | F01371A33DF02EB395BB5A62 /* Pods-acknowledgements.markdown */, 120 | D92BCB48987E3FCC04E45C69 /* Pods-acknowledgements.plist */, 121 | 4AD8623457CF176F01DBDDEA /* Pods-dummy.m */, 122 | D6E1057B18A107FF920AA6A4 /* Pods-environment.h */, 123 | 3419174719E9620D7E6D6B32 /* Pods-resources.sh */, 124 | 796A962CDC5C669DE189CD3C /* Pods.debug.xcconfig */, 125 | 59C40F4DDBFE0BAF46BC7D12 /* Pods.release.xcconfig */, 126 | ); 127 | name = Pods; 128 | path = "Target Support Files/Pods"; 129 | sourceTree = ""; 130 | }; 131 | 62BE575787B7C659D4F8747B /* Support Files */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 29EAE6B5378AC5D6D96D1418 /* Pods-SmudgeKit.xcconfig */, 135 | B4AC627ADE7D25FE916A0CAF /* Pods-SmudgeKit-Private.xcconfig */, 136 | D111EE2A1816CE8F9864C65F /* Pods-SmudgeKit-dummy.m */, 137 | 09F4498FE8043ABF4BC2B2F6 /* Pods-SmudgeKit-prefix.pch */, 138 | ); 139 | name = "Support Files"; 140 | path = "../Target Support Files/Pods-SmudgeKit"; 141 | sourceTree = ""; 142 | }; 143 | 67E2D6EF115F40572CF9B4E7 /* ABDataSourceController */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | F59AAE24CC65A446E5948E0B /* ABDataSourceController.h */, 147 | 79D9B8B8C09E074949894556 /* UITableView+DataSourceController.h */, 148 | B26D991A1D5E159F179BA1AA /* UITableView+DataSourceController.m */, 149 | 175598B6D7E1A314003AA104 /* Support Files */, 150 | ); 151 | path = ABDataSourceController; 152 | sourceTree = ""; 153 | }; 154 | 6F67851E48DEB118A8F86FFA = { 155 | isa = PBXGroup; 156 | children = ( 157 | F2E95B97B5815997FDCFB565 /* Podfile */, 158 | FD676CB4482772A4B60057AE /* Frameworks */, 159 | 88AF08D1181AF8ED99752E1D /* Pods */, 160 | EDE9F4478AF6628705ECAE64 /* Products */, 161 | A4936282146D857E1F3DCB55 /* Targets Support Files */, 162 | ); 163 | sourceTree = ""; 164 | }; 165 | 728E084C8A3F9D0E3561AECD /* SmudgeKit */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 5DE69761EF3D1BFBCCB71B65 /* SmudgyWindow.h */, 169 | 4222C47669356387FA692D8A /* SmudgyWindow.m */, 170 | 62BE575787B7C659D4F8747B /* Support Files */, 171 | ); 172 | path = SmudgeKit; 173 | sourceTree = ""; 174 | }; 175 | 88AF08D1181AF8ED99752E1D /* Pods */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 67E2D6EF115F40572CF9B4E7 /* ABDataSourceController */, 179 | 728E084C8A3F9D0E3561AECD /* SmudgeKit */, 180 | ); 181 | name = Pods; 182 | sourceTree = ""; 183 | }; 184 | A4936282146D857E1F3DCB55 /* Targets Support Files */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 51A64B4C195340E12EDBF351 /* Pods */, 188 | ); 189 | name = "Targets Support Files"; 190 | sourceTree = ""; 191 | }; 192 | EDE9F4478AF6628705ECAE64 /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | F5B2DCD1DD69E24056710F2D /* libPods.a */, 196 | F21E4409A0C9C1604D622995 /* libPods-ABDataSourceController.a */, 197 | 635AEC136A8AF21E345BCC46 /* libPods-SmudgeKit.a */, 198 | ); 199 | name = Products; 200 | sourceTree = ""; 201 | }; 202 | FD676CB4482772A4B60057AE /* Frameworks */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | 164390F3D8B9175AD6EB13E4 /* iOS */, 206 | ); 207 | name = Frameworks; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXGroup section */ 211 | 212 | /* Begin PBXHeadersBuildPhase section */ 213 | 09499B831A8A8E62A5918AB8 /* Headers */ = { 214 | isa = PBXHeadersBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 36F14A8434948BAEE3E53D00 /* SmudgyWindow.h in Headers */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | 9CE58F0DD7E6F11970890D83 /* Headers */ = { 222 | isa = PBXHeadersBuildPhase; 223 | buildActionMask = 2147483647; 224 | files = ( 225 | 2F73F7F9012737AC96EC7DDC /* ABDataSourceController.h in Headers */, 226 | 8730BC3D02C3AE14F434216B /* UITableView+DataSourceController.h in Headers */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXHeadersBuildPhase section */ 231 | 232 | /* Begin PBXNativeTarget section */ 233 | 7AD8345963A897669099EA06 /* Pods */ = { 234 | isa = PBXNativeTarget; 235 | buildConfigurationList = FD55EC6090C388B047D0C9D6 /* Build configuration list for PBXNativeTarget "Pods" */; 236 | buildPhases = ( 237 | 172099CFF8D0C230A961B4CA /* Sources */, 238 | C42E7E3DF164082407ED802D /* Frameworks */, 239 | ); 240 | buildRules = ( 241 | ); 242 | dependencies = ( 243 | 1AB8B543D281A3BADAB856E2 /* PBXTargetDependency */, 244 | C01A18DC3E58772EFA041076 /* PBXTargetDependency */, 245 | ); 246 | name = Pods; 247 | productName = Pods; 248 | productReference = F5B2DCD1DD69E24056710F2D /* libPods.a */; 249 | productType = "com.apple.product-type.library.static"; 250 | }; 251 | E5E3E003D1EE41C9AE477F41 /* Pods-ABDataSourceController */ = { 252 | isa = PBXNativeTarget; 253 | buildConfigurationList = 78D311E3313A55D41167058A /* Build configuration list for PBXNativeTarget "Pods-ABDataSourceController" */; 254 | buildPhases = ( 255 | F8E7EB38CE2D19232491ACCF /* Sources */, 256 | E4B071F5032718F2392A05B4 /* Frameworks */, 257 | 9CE58F0DD7E6F11970890D83 /* Headers */, 258 | ); 259 | buildRules = ( 260 | ); 261 | dependencies = ( 262 | ); 263 | name = "Pods-ABDataSourceController"; 264 | productName = "Pods-ABDataSourceController"; 265 | productReference = F21E4409A0C9C1604D622995 /* libPods-ABDataSourceController.a */; 266 | productType = "com.apple.product-type.library.static"; 267 | }; 268 | FAD1F566D12EC317A9C7CDAE /* Pods-SmudgeKit */ = { 269 | isa = PBXNativeTarget; 270 | buildConfigurationList = 7B0DDCBF3B78CDAE7A426D8B /* Build configuration list for PBXNativeTarget "Pods-SmudgeKit" */; 271 | buildPhases = ( 272 | 5F813425C44F5F40C7C0A6A6 /* Sources */, 273 | F615A7F5CBC6E980A26A724E /* Frameworks */, 274 | 09499B831A8A8E62A5918AB8 /* Headers */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | ); 280 | name = "Pods-SmudgeKit"; 281 | productName = "Pods-SmudgeKit"; 282 | productReference = 635AEC136A8AF21E345BCC46 /* libPods-SmudgeKit.a */; 283 | productType = "com.apple.product-type.library.static"; 284 | }; 285 | /* End PBXNativeTarget section */ 286 | 287 | /* Begin PBXProject section */ 288 | C221CFAB2811A41D386B417E /* Project object */ = { 289 | isa = PBXProject; 290 | attributes = { 291 | LastUpgradeCheck = 0510; 292 | }; 293 | buildConfigurationList = 22A50062C58328D8705D7359 /* Build configuration list for PBXProject "Pods" */; 294 | compatibilityVersion = "Xcode 3.2"; 295 | developmentRegion = English; 296 | hasScannedForEncodings = 0; 297 | knownRegions = ( 298 | en, 299 | ); 300 | mainGroup = 6F67851E48DEB118A8F86FFA; 301 | productRefGroup = EDE9F4478AF6628705ECAE64 /* Products */; 302 | projectDirPath = ""; 303 | projectRoot = ""; 304 | targets = ( 305 | 7AD8345963A897669099EA06 /* Pods */, 306 | E5E3E003D1EE41C9AE477F41 /* Pods-ABDataSourceController */, 307 | FAD1F566D12EC317A9C7CDAE /* Pods-SmudgeKit */, 308 | ); 309 | }; 310 | /* End PBXProject section */ 311 | 312 | /* Begin PBXSourcesBuildPhase section */ 313 | 172099CFF8D0C230A961B4CA /* Sources */ = { 314 | isa = PBXSourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | DF7E3955326D149AD4E2319F /* Pods-dummy.m in Sources */, 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | 5F813425C44F5F40C7C0A6A6 /* Sources */ = { 322 | isa = PBXSourcesBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | 2BA85CF79BE7C7A17A06D9AC /* Pods-SmudgeKit-dummy.m in Sources */, 326 | 21F0B28DB5B8066294EDC063 /* SmudgyWindow.m in Sources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | F8E7EB38CE2D19232491ACCF /* Sources */ = { 331 | isa = PBXSourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | EA47F261DF3BB45AB30572AD /* Pods-ABDataSourceController-dummy.m in Sources */, 335 | BB3194BC286801CFA93A0A9D /* UITableView+DataSourceController.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | /* End PBXSourcesBuildPhase section */ 340 | 341 | /* Begin PBXTargetDependency section */ 342 | 1AB8B543D281A3BADAB856E2 /* PBXTargetDependency */ = { 343 | isa = PBXTargetDependency; 344 | name = "Pods-ABDataSourceController"; 345 | target = E5E3E003D1EE41C9AE477F41 /* Pods-ABDataSourceController */; 346 | targetProxy = EE09C726FB526620C72BF9A4 /* PBXContainerItemProxy */; 347 | }; 348 | C01A18DC3E58772EFA041076 /* PBXTargetDependency */ = { 349 | isa = PBXTargetDependency; 350 | name = "Pods-SmudgeKit"; 351 | target = FAD1F566D12EC317A9C7CDAE /* Pods-SmudgeKit */; 352 | targetProxy = B50E1A27F96109F289B60114 /* PBXContainerItemProxy */; 353 | }; 354 | /* End PBXTargetDependency section */ 355 | 356 | /* Begin XCBuildConfiguration section */ 357 | 24BA38E848DDC545566AC538 /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 362 | CLANG_CXX_LIBRARY = "libc++"; 363 | CLANG_ENABLE_MODULES = YES; 364 | CLANG_ENABLE_OBJC_ARC = YES; 365 | CLANG_WARN_BOOL_CONVERSION = YES; 366 | CLANG_WARN_CONSTANT_CONVERSION = YES; 367 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 368 | CLANG_WARN_EMPTY_BODY = YES; 369 | CLANG_WARN_ENUM_CONVERSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 372 | CLANG_WARN_UNREACHABLE_CODE = YES; 373 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 374 | COPY_PHASE_STRIP = YES; 375 | ENABLE_NS_ASSERTIONS = NO; 376 | GCC_C_LANGUAGE_STANDARD = gnu99; 377 | GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 385 | STRIP_INSTALLED_PRODUCT = NO; 386 | SYMROOT = "${SRCROOT}/../build"; 387 | VALIDATE_PRODUCT = YES; 388 | }; 389 | name = Release; 390 | }; 391 | 27AAA797229A226865AE8AAD /* Release */ = { 392 | isa = XCBuildConfiguration; 393 | baseConfigurationReference = B4AC627ADE7D25FE916A0CAF /* Pods-SmudgeKit-Private.xcconfig */; 394 | buildSettings = { 395 | ENABLE_STRICT_OBJC_MSGSEND = YES; 396 | GCC_PREFIX_HEADER = "Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit-prefix.pch"; 397 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 398 | MTL_ENABLE_DEBUG_INFO = NO; 399 | OTHER_LDFLAGS = ""; 400 | OTHER_LIBTOOLFLAGS = ""; 401 | PRODUCT_NAME = "$(TARGET_NAME)"; 402 | SDKROOT = iphoneos; 403 | SKIP_INSTALL = YES; 404 | }; 405 | name = Release; 406 | }; 407 | 55C7F8E74792297E91AD4E41 /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | baseConfigurationReference = 4E21D97CD5F579BA2857F4DE /* Pods-ABDataSourceController-Private.xcconfig */; 410 | buildSettings = { 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | GCC_PREFIX_HEADER = "Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController-prefix.pch"; 413 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 414 | MTL_ENABLE_DEBUG_INFO = NO; 415 | OTHER_LDFLAGS = ""; 416 | OTHER_LIBTOOLFLAGS = ""; 417 | PRODUCT_NAME = "$(TARGET_NAME)"; 418 | SDKROOT = iphoneos; 419 | SKIP_INSTALL = YES; 420 | }; 421 | name = Release; 422 | }; 423 | 9156451F01905C0D11D29C16 /* Debug */ = { 424 | isa = XCBuildConfiguration; 425 | baseConfigurationReference = 4E21D97CD5F579BA2857F4DE /* Pods-ABDataSourceController-Private.xcconfig */; 426 | buildSettings = { 427 | ENABLE_STRICT_OBJC_MSGSEND = YES; 428 | GCC_PREFIX_HEADER = "Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController-prefix.pch"; 429 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 430 | MTL_ENABLE_DEBUG_INFO = YES; 431 | OTHER_LDFLAGS = ""; 432 | OTHER_LIBTOOLFLAGS = ""; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | SDKROOT = iphoneos; 435 | SKIP_INSTALL = YES; 436 | }; 437 | name = Debug; 438 | }; 439 | AAD6E33722D662002562B14C /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | buildSettings = { 442 | ALWAYS_SEARCH_USER_PATHS = NO; 443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 444 | CLANG_CXX_LIBRARY = "libc++"; 445 | CLANG_ENABLE_MODULES = YES; 446 | CLANG_ENABLE_OBJC_ARC = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_CONSTANT_CONVERSION = YES; 449 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 450 | CLANG_WARN_EMPTY_BODY = YES; 451 | CLANG_WARN_ENUM_CONVERSION = YES; 452 | CLANG_WARN_INT_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | COPY_PHASE_STRIP = NO; 457 | GCC_C_LANGUAGE_STANDARD = gnu99; 458 | GCC_DYNAMIC_NO_PIC = NO; 459 | GCC_OPTIMIZATION_LEVEL = 0; 460 | GCC_PREPROCESSOR_DEFINITIONS = ( 461 | "DEBUG=1", 462 | "$(inherited)", 463 | ); 464 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 465 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 466 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 467 | GCC_WARN_UNDECLARED_SELECTOR = YES; 468 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 469 | GCC_WARN_UNUSED_FUNCTION = YES; 470 | GCC_WARN_UNUSED_VARIABLE = YES; 471 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 472 | ONLY_ACTIVE_ARCH = YES; 473 | STRIP_INSTALLED_PRODUCT = NO; 474 | SYMROOT = "${SRCROOT}/../build"; 475 | }; 476 | name = Debug; 477 | }; 478 | AD3C04278B6D98F5FDC650A4 /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | baseConfigurationReference = 796A962CDC5C669DE189CD3C /* Pods.debug.xcconfig */; 481 | buildSettings = { 482 | ENABLE_STRICT_OBJC_MSGSEND = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 484 | MTL_ENABLE_DEBUG_INFO = YES; 485 | OTHER_LDFLAGS = ""; 486 | OTHER_LIBTOOLFLAGS = ""; 487 | PODS_ROOT = "$(SRCROOT)"; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | SDKROOT = iphoneos; 490 | SKIP_INSTALL = YES; 491 | }; 492 | name = Debug; 493 | }; 494 | C09AF0D938789656E78D3E1C /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | baseConfigurationReference = 59C40F4DDBFE0BAF46BC7D12 /* Pods.release.xcconfig */; 497 | buildSettings = { 498 | ENABLE_STRICT_OBJC_MSGSEND = YES; 499 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 500 | MTL_ENABLE_DEBUG_INFO = NO; 501 | OTHER_LDFLAGS = ""; 502 | OTHER_LIBTOOLFLAGS = ""; 503 | PODS_ROOT = "$(SRCROOT)"; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | SDKROOT = iphoneos; 506 | SKIP_INSTALL = YES; 507 | }; 508 | name = Release; 509 | }; 510 | C1EC91836A9924FB7857E05A /* Debug */ = { 511 | isa = XCBuildConfiguration; 512 | baseConfigurationReference = B4AC627ADE7D25FE916A0CAF /* Pods-SmudgeKit-Private.xcconfig */; 513 | buildSettings = { 514 | ENABLE_STRICT_OBJC_MSGSEND = YES; 515 | GCC_PREFIX_HEADER = "Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit-prefix.pch"; 516 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 517 | MTL_ENABLE_DEBUG_INFO = YES; 518 | OTHER_LDFLAGS = ""; 519 | OTHER_LIBTOOLFLAGS = ""; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | SDKROOT = iphoneos; 522 | SKIP_INSTALL = YES; 523 | }; 524 | name = Debug; 525 | }; 526 | /* End XCBuildConfiguration section */ 527 | 528 | /* Begin XCConfigurationList section */ 529 | 22A50062C58328D8705D7359 /* Build configuration list for PBXProject "Pods" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | AAD6E33722D662002562B14C /* Debug */, 533 | 24BA38E848DDC545566AC538 /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | 78D311E3313A55D41167058A /* Build configuration list for PBXNativeTarget "Pods-ABDataSourceController" */ = { 539 | isa = XCConfigurationList; 540 | buildConfigurations = ( 541 | 9156451F01905C0D11D29C16 /* Debug */, 542 | 55C7F8E74792297E91AD4E41 /* Release */, 543 | ); 544 | defaultConfigurationIsVisible = 0; 545 | defaultConfigurationName = Release; 546 | }; 547 | 7B0DDCBF3B78CDAE7A426D8B /* Build configuration list for PBXNativeTarget "Pods-SmudgeKit" */ = { 548 | isa = XCConfigurationList; 549 | buildConfigurations = ( 550 | C1EC91836A9924FB7857E05A /* Debug */, 551 | 27AAA797229A226865AE8AAD /* Release */, 552 | ); 553 | defaultConfigurationIsVisible = 0; 554 | defaultConfigurationName = Release; 555 | }; 556 | FD55EC6090C388B047D0C9D6 /* Build configuration list for PBXNativeTarget "Pods" */ = { 557 | isa = XCConfigurationList; 558 | buildConfigurations = ( 559 | AD3C04278B6D98F5FDC650A4 /* Debug */, 560 | C09AF0D938789656E78D3E1C /* Release */, 561 | ); 562 | defaultConfigurationIsVisible = 0; 563 | defaultConfigurationName = Release; 564 | }; 565 | /* End XCConfigurationList section */ 566 | }; 567 | rootObject = C221CFAB2811A41D386B417E /* Project object */; 568 | } 569 | -------------------------------------------------------------------------------- /SampleProject/Pods/SmudgeKit/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ideon AS (http://ideon.co/) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /SampleProject/Pods/SmudgeKit/README.md: -------------------------------------------------------------------------------- 1 | # SmudgeKit 2 | 3 | SmudgeKit provides a drop in replacement for UIWindow to draw visual representations of all touch events to the screen. Ideal for for creating App Previews or other screencasts where it is crucial to show touch gestures. Not intended for production use. 4 | 5 | Originally built to preview The Converted, [check the The Converted website for an example](http://ideon.co/theconverted?utm_source=github&utm_medium=readme&utm_campaign=smudgeKit). 6 | 7 | 8 | ## Usage 9 | 10 | ### Objective-C 11 | 12 | Add SmudgeKit to your Podfile. 13 | 14 | `pod 'SmudgeKit'` 15 | 16 | Or add SmudgyWindow.h and SmudgyWindow.m to your project. 17 | 18 | Then implement the getter method of the window property in your Application Delegate: 19 | 20 | ```objectivec 21 | #import "SmudgyWindow.h" 22 | 23 | // … 24 | 25 | - (UIWindow *)window { 26 | if (!_window) { 27 | _window = [[SmudgyWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 28 | } 29 | return _window; 30 | } 31 | 32 | ``` 33 | 34 | You can change the appearance by editing the SmudgeLayer implementation in SmudgyWindow.m 35 | 36 | 37 | ### Swift 38 | 39 | A swift framework with more features is in the works but not ready due to an apparent bug in the swift compiler. 40 | 41 | ## Contact 42 | 43 | [Hans Petter Eikemo](https://github.com/hpeikemo) 44 | [@hpeikemo](https://twitter.com/hpeikemo) 45 | [Ideon](http://ideon.co/theconverted?utm_source=github&utm_medium=readme&utm_campaign=smudgeKit) 46 | 47 | ## License 48 | 49 | SmudgeKit is available under the MIT license. See the LICENSE file for details. -------------------------------------------------------------------------------- /SampleProject/Pods/SmudgeKit/Source-ObjectiveC/SmudgyWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // SmudgyWindow.h 3 | // SmudgeKit 4 | // 5 | // Created by Hans Petter Eikemo on 29.09.14. 6 | // Copyright (c) 2014 Ideon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * The SmudgyWindow class is a drop in replacement for UIWindow which 13 | * draws a visual representation of all touch events onto the screen. 14 | */ 15 | @interface SmudgyWindow : UIWindow 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SampleProject/Pods/SmudgeKit/Source-ObjectiveC/SmudgyWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // SmudgyWindow.m 3 | // SmudgeKit 4 | // 5 | // Created by Hans Petter Eikemo on 29.09.14. 6 | // Copyright (c) 2014 Ideon. All rights reserved. 7 | // 8 | 9 | #import "SmudgyWindow.h" 10 | 11 | #pragma mark - Private SmudgeLayer implementation - 12 | 13 | @interface SmudgeLayer : CAShapeLayer 14 | 15 | ///Called when the related event changes. Override to update internal state. Position is set automatically by the superlayer. 16 | - (void)appear; 17 | 18 | ///Called after smudge creation when a touch begins. Override to customize appear animation. 19 | - (void)disappear; 20 | 21 | ///Called after the related touch event ends or is cancelled. Override to customize disappear animation, the user must call removeFromSuperview on the instance. 22 | - (void)updateWithTouch:(UITouch *)touch; 23 | 24 | @end 25 | 26 | @interface SmudgeLayer () 27 | 28 | @property CGPoint velocity; 29 | @property CGPoint previousPosition; 30 | 31 | @end 32 | 33 | @implementation SmudgeLayer 34 | 35 | - (instancetype)init 36 | { 37 | if (self = [super init]) { 38 | self.velocity = CGPointZero; 39 | self.contentsScale = [UIScreen mainScreen].scale; 40 | 41 | CGFloat radius = 20.0; 42 | self.path = CGPathCreateWithEllipseInRect(CGRectMake(-radius, -radius, radius*2, radius*2), NULL); 43 | self.fillColor = [UIColor colorWithWhite:0.9 alpha:0.9].CGColor; 44 | self.strokeColor = [UIColor colorWithWhite:0.0 alpha:0.35].CGColor; 45 | self.lineWidth = 1; 46 | 47 | self.shadowPath = self.path; 48 | self.shadowColor = [UIColor blackColor].CGColor; 49 | self.shadowOpacity = 0.15; 50 | self.shadowRadius = 3.0; 51 | self.shadowOffset = CGSizeMake(0.0, 1.0); 52 | } 53 | return self; 54 | } 55 | 56 | - (void)updateWithTouch:(UITouch *)touch 57 | { 58 | if (touch.phase != UITouchPhaseBegan) { 59 | self.velocity = CGPointMake( (self.velocity.x + self.position.x - self.previousPosition.x) * 0.5 , (self.velocity.y + self.position.y - self.previousPosition.y) * 0.5 ); 60 | } 61 | self.previousPosition = self.position; 62 | } 63 | 64 | - (void)appear 65 | { 66 | [CATransaction begin]; 67 | [CATransaction setDisableActions:YES]; 68 | 69 | self.opacity = 0.0; 70 | self.transform = CATransform3DMakeScale(1.5, 1.5, 1); 71 | 72 | [CATransaction commit]; 73 | 74 | [CATransaction begin]; 75 | [CATransaction setAnimationDuration:0.1]; 76 | 77 | self.opacity = 1.0; 78 | self.transform = CATransform3DIdentity; 79 | 80 | [CATransaction commit]; 81 | 82 | } 83 | 84 | - (void)disappear 85 | { 86 | [CATransaction begin]; 87 | [CATransaction setAnimationDuration:0.2]; 88 | 89 | __weak typeof(self) weakSelf = self; 90 | [CATransaction setCompletionBlock:^{ 91 | [weakSelf removeFromSuperlayer]; 92 | }]; 93 | 94 | self.opacity = 0.0; 95 | self.transform = CATransform3DMakeScale(1.5, 1.5, 1); 96 | self.position = CGPointMake( self.position.x + self.velocity.x * 4.0 , self.position.y + self.velocity.y * 4.0 ); 97 | 98 | [CATransaction commit]; 99 | 100 | } 101 | 102 | 103 | @end 104 | 105 | 106 | #pragma mark - Private SmudgeContainer implementation - 107 | 108 | @interface SmudgeContainerLayer : CALayer 109 | 110 | - (void)updateWithEvent:(UIEvent *)event; 111 | 112 | @end 113 | 114 | @interface SmudgeContainerLayer () 115 | 116 | @property (readonly,nonatomic) NSMutableDictionary *touchSmudgeTable; 117 | 118 | @end 119 | 120 | @implementation SmudgeContainerLayer 121 | 122 | - (instancetype)init 123 | { 124 | if (self = [super init]) { 125 | _touchSmudgeTable = @{}.mutableCopy; 126 | } 127 | return self; 128 | } 129 | 130 | - (void)updateWithEvent:(UIEvent *)event 131 | { 132 | for (UITouch *touch in event.allTouches) { 133 | NSValue* touchKey = [NSValue valueWithNonretainedObject:touch]; 134 | SmudgeLayer* smudgeLayer = self.touchSmudgeTable[touchKey]; 135 | 136 | [CATransaction begin]; 137 | [CATransaction setDisableActions:YES]; 138 | 139 | if (!smudgeLayer) { 140 | smudgeLayer = [SmudgeLayer layer]; 141 | self.touchSmudgeTable[touchKey] = smudgeLayer; 142 | [self addSublayer:smudgeLayer]; 143 | } 144 | 145 | smudgeLayer.position = [touch locationInView:nil]; 146 | [smudgeLayer updateWithTouch:touch]; 147 | 148 | [CATransaction commit]; 149 | 150 | switch (touch.phase) { 151 | case UITouchPhaseBegan: 152 | [smudgeLayer appear]; 153 | break; 154 | case UITouchPhaseCancelled: 155 | case UITouchPhaseEnded: 156 | [smudgeLayer disappear]; 157 | [self.touchSmudgeTable removeObjectForKey:touchKey]; 158 | break; 159 | default: 160 | break; 161 | } 162 | 163 | } 164 | } 165 | 166 | @end 167 | 168 | 169 | #pragma mark - SmudgyWindow - 170 | 171 | @interface SmudgyWindow () 172 | 173 | @property (readonly,nonatomic) SmudgeContainerLayer *smudgeContainer; 174 | 175 | @end 176 | 177 | @implementation SmudgyWindow 178 | 179 | - (void)sendEvent:(UIEvent *)event 180 | { 181 | [super sendEvent:event]; 182 | [self renderTouchesForEvent:event]; 183 | } 184 | 185 | - (void)renderTouchesForEvent:(UIEvent *)event 186 | { 187 | if (!self.smudgeContainer) { 188 | _smudgeContainer = [SmudgeContainerLayer layer]; 189 | [self.layer addSublayer:self.smudgeContainer]; 190 | } else if ([self.layer.sublayers lastObject] != self.smudgeContainer) { 191 | [self.smudgeContainer removeFromSuperlayer]; 192 | [self.layer addSublayer:self.smudgeContainer]; 193 | } 194 | [self.smudgeContainer updateWithEvent:event]; 195 | } 196 | 197 | @end 198 | 199 | 200 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-ABDataSourceController.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/ABDataSourceController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/ABDataSourceController" "${PODS_ROOT}/Headers/Public/SmudgeKit" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ABDataSourceController : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ABDataSourceController 5 | @end 6 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController.xcconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/Pods/Target Support Files/Pods-ABDataSourceController/Pods-ABDataSourceController.xcconfig -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-SmudgeKit.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SmudgeKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/ABDataSourceController" "${PODS_ROOT}/Headers/Public/SmudgeKit" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SmudgeKit : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SmudgeKit 5 | @end 6 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit.xcconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/Pods/Target Support Files/Pods-SmudgeKit/Pods-SmudgeKit.xcconfig -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## ABDataSourceController 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Alex Bumbu 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | 30 | ## SmudgeKit 31 | 32 | The MIT License (MIT) 33 | 34 | Copyright (c) 2014 Ideon AS (http://ideon.co/) 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | copies of the Software, and to permit persons to whom the Software is 41 | furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 52 | SOFTWARE. 53 | 54 | 55 | Generated by CocoaPods - http://cocoapods.org 56 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 Alex Bumbu 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | 40 | Title 41 | ABDataSourceController 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | The MIT License (MIT) 48 | 49 | Copyright (c) 2014 Ideon AS (http://ideon.co/) 50 | 51 | Permission is hereby granted, free of charge, to any person obtaining a copy 52 | of this software and associated documentation files (the "Software"), to deal 53 | in the Software without restriction, including without limitation the rights 54 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55 | copies of the Software, and to permit persons to whom the Software is 56 | furnished to do so, subject to the following conditions: 57 | 58 | The above copyright notice and this permission notice shall be included in all 59 | copies or substantial portions of the Software. 60 | 61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 67 | SOFTWARE. 68 | 69 | 70 | Title 71 | SmudgeKit 72 | Type 73 | PSGroupSpecifier 74 | 75 | 76 | FooterText 77 | Generated by CocoaPods - http://cocoapods.org 78 | Title 79 | 80 | Type 81 | PSGroupSpecifier 82 | 83 | 84 | StringsTable 85 | Acknowledgements 86 | Title 87 | Acknowledgements 88 | 89 | 90 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods-environment.h: -------------------------------------------------------------------------------- 1 | 2 | // To check if a library is compiled with CocoaPods you 3 | // can use the `COCOAPODS` macro definition which is 4 | // defined in the xcconfigs so it is available in 5 | // headers also when they are imported in the client 6 | // project. 7 | 8 | 9 | // ABDataSourceController 10 | #define COCOAPODS_POD_AVAILABLE_ABDataSourceController 11 | #define COCOAPODS_VERSION_MAJOR_ABDataSourceController 1 12 | #define COCOAPODS_VERSION_MINOR_ABDataSourceController 0 13 | #define COCOAPODS_VERSION_PATCH_ABDataSourceController 1 14 | 15 | // SmudgeKit 16 | #define COCOAPODS_POD_AVAILABLE_SmudgeKit 17 | #define COCOAPODS_VERSION_MAJOR_SmudgeKit 0 18 | #define COCOAPODS_VERSION_MINOR_SmudgeKit 1 19 | #define COCOAPODS_VERSION_PATCH_SmudgeKit 2 20 | 21 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES="" 10 | 11 | install_resource() 12 | { 13 | case $1 in 14 | *.storyboard) 15 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 16 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 17 | ;; 18 | *.xib) 19 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 20 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 21 | ;; 22 | *.framework) 23 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 25 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 26 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 27 | ;; 28 | *.xcdatamodel) 29 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 30 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 31 | ;; 32 | *.xcdatamodeld) 33 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 34 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 35 | ;; 36 | *.xcmappingmodel) 37 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 38 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 39 | ;; 40 | *.xcassets) 41 | XCASSET_FILES="$XCASSET_FILES '${PODS_ROOT}/$1'" 42 | ;; 43 | /*) 44 | echo "$1" 45 | echo "$1" >> "$RESOURCES_TO_COPY" 46 | ;; 47 | *) 48 | echo "${PODS_ROOT}/$1" 49 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 50 | ;; 51 | esac 52 | } 53 | 54 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 55 | if [[ "${ACTION}" == "install" ]]; then 56 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 57 | fi 58 | rm -f "$RESOURCES_TO_COPY" 59 | 60 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 61 | then 62 | case "${TARGETED_DEVICE_FAMILY}" in 63 | 1,2) 64 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 65 | ;; 66 | 1) 67 | TARGET_DEVICE_ARGS="--target-device iphone" 68 | ;; 69 | 2) 70 | TARGET_DEVICE_ARGS="--target-device ipad" 71 | ;; 72 | *) 73 | TARGET_DEVICE_ARGS="--target-device mac" 74 | ;; 75 | esac 76 | while read line; do XCASSET_FILES="$XCASSET_FILES '$line'"; done <<<$(find "$PWD" -name "*.xcassets" | egrep -v "^$PODS_ROOT") 77 | echo $XCASSET_FILES | xargs actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 78 | fi 79 | -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/ABDataSourceController" "${PODS_ROOT}/Headers/Public/SmudgeKit" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/ABDataSourceController" -isystem "${PODS_ROOT}/Headers/Public/SmudgeKit" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-ABDataSourceController" -l"Pods-SmudgeKit" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /SampleProject/Pods/Target Support Files/Pods/Pods.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/ABDataSourceController" "${PODS_ROOT}/Headers/Public/SmudgeKit" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/ABDataSourceController" -isystem "${PODS_ROOT}/Headers/Public/SmudgeKit" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-ABDataSourceController" -l"Pods-SmudgeKit" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B2045D0A39F38B7D9D0C03B1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B93F7BB346B823C4C1E81513 /* libPods.a */; }; 11 | DD8735971BFA58D6006E7367 /* CustomMenuTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8735961BFA58D6006E7367 /* CustomMenuTableViewCell.m */; }; 12 | DD8B09071B9D6FAA007C8187 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8B09061B9D6FAA007C8187 /* main.m */; }; 13 | DD8B090A1B9D6FAA007C8187 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8B09091B9D6FAA007C8187 /* AppDelegate.m */; }; 14 | DD8B090D1B9D6FAA007C8187 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8B090C1B9D6FAA007C8187 /* MainViewController.m */; }; 15 | DD8B09101B9D6FAA007C8187 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DD8B090E1B9D6FAA007C8187 /* Main.storyboard */; }; 16 | DD8B09121B9D6FAA007C8187 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DD8B09111B9D6FAA007C8187 /* Images.xcassets */; }; 17 | DD8B09151B9D6FAA007C8187 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = DD8B09131B9D6FAA007C8187 /* LaunchScreen.xib */; }; 18 | DD8B09211B9D6FAA007C8187 /* SampleProjectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8B09201B9D6FAA007C8187 /* SampleProjectTests.m */; }; 19 | DD8FB7E41FEEB9AC00ACCF99 /* DetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8FB7E31FEEB9AC00ACCF99 /* DetailsViewController.m */; }; 20 | DD9B6EC61BB9A5490091629D /* DataSource.plist in Resources */ = {isa = PBXBuildFile; fileRef = DD9B6EC51BB9A5490091629D /* DataSource.plist */; }; 21 | DDAF09641BBEAC8800C886E1 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = DDAF09631BBEAC8800C886E1 /* LICENSE */; }; 22 | DDD118AD1BFE253D00761743 /* UITableView+VisibleMenuCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DDD118AC1BFE253D00761743 /* UITableView+VisibleMenuCell.m */; }; 23 | DDD78B021B9D732A009D779E /* UIView+XIB.m in Sources */ = {isa = PBXBuildFile; fileRef = DDD78B011B9D732A009D779E /* UIView+XIB.m */; }; 24 | DDD78B091B9D757D009D779E /* ABCellCustomStyleMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDD78B031B9D757D009D779E /* ABCellCustomStyleMenuView.xib */; }; 25 | DDD78B0A1B9D757D009D779E /* ABCellMailStyleMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDD78B041B9D757D009D779E /* ABCellMailStyleMenuView.xib */; }; 26 | DDD78B0B1B9D757D009D779E /* ABCellMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = DDD78B061B9D757D009D779E /* ABCellMenuView.m */; }; 27 | DDD78B0C1B9D757D009D779E /* MainDataSourceController.m in Sources */ = {isa = PBXBuildFile; fileRef = DDD78B081B9D757D009D779E /* MainDataSourceController.m */; }; 28 | DDD78B131B9D7647009D779E /* ABMenuTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DDD78B121B9D7647009D779E /* ABMenuTableViewCell.m */; }; 29 | DDE29C471BBB08D5000EB816 /* ABMenuTableViewCell.podspec in Resources */ = {isa = PBXBuildFile; fileRef = DDE29C461BBB08D5000EB816 /* ABMenuTableViewCell.podspec */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | DD8B091B1B9D6FAA007C8187 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = DD8B08F91B9D6FAA007C8187 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = DD8B09001B9D6FAA007C8187; 38 | remoteInfo = SampleProject; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 338A62F79E49041174C62F7D /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 44 | A165A52D653202A7694A92CD /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 45 | B93F7BB346B823C4C1E81513 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | DD1DCA331BBA64E400403CB7 /* Options.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = ""; }; 47 | DD8735951BFA58D6006E7367 /* CustomMenuTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomMenuTableViewCell.h; sourceTree = ""; }; 48 | DD8735961BFA58D6006E7367 /* CustomMenuTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomMenuTableViewCell.m; sourceTree = ""; }; 49 | DD8B09011B9D6FAA007C8187 /* SampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | DD8B09051B9D6FAA007C8187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | DD8B09061B9D6FAA007C8187 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | DD8B09081B9D6FAA007C8187 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | DD8B09091B9D6FAA007C8187 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | DD8B090B1B9D6FAA007C8187 /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; 55 | DD8B090C1B9D6FAA007C8187 /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; 56 | DD8B090F1B9D6FAA007C8187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | DD8B09111B9D6FAA007C8187 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 58 | DD8B09141B9D6FAA007C8187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 59 | DD8B091A1B9D6FAA007C8187 /* SampleProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | DD8B091F1B9D6FAA007C8187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | DD8B09201B9D6FAA007C8187 /* SampleProjectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleProjectTests.m; sourceTree = ""; }; 62 | DD8FB7E21FEEB9AC00ACCF99 /* DetailsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailsViewController.h; sourceTree = ""; }; 63 | DD8FB7E31FEEB9AC00ACCF99 /* DetailsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailsViewController.m; sourceTree = ""; }; 64 | DD9B6EC51BB9A5490091629D /* DataSource.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = DataSource.plist; sourceTree = ""; }; 65 | DDAF09631BBEAC8800C886E1 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../LICENSE; sourceTree = ""; }; 66 | DDAF09651BBEAC9100C886E1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../README.md; sourceTree = ""; }; 67 | DDD118AB1BFE253D00761743 /* UITableView+VisibleMenuCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+VisibleMenuCell.h"; sourceTree = ""; }; 68 | DDD118AC1BFE253D00761743 /* UITableView+VisibleMenuCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+VisibleMenuCell.m"; sourceTree = ""; }; 69 | DDD78B001B9D732A009D779E /* UIView+XIB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+XIB.h"; sourceTree = ""; }; 70 | DDD78B011B9D732A009D779E /* UIView+XIB.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+XIB.m"; sourceTree = ""; }; 71 | DDD78B031B9D757D009D779E /* ABCellCustomStyleMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ABCellCustomStyleMenuView.xib; sourceTree = ""; }; 72 | DDD78B041B9D757D009D779E /* ABCellMailStyleMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ABCellMailStyleMenuView.xib; sourceTree = ""; }; 73 | DDD78B051B9D757D009D779E /* ABCellMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABCellMenuView.h; sourceTree = ""; }; 74 | DDD78B061B9D757D009D779E /* ABCellMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABCellMenuView.m; sourceTree = ""; }; 75 | DDD78B071B9D757D009D779E /* MainDataSourceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainDataSourceController.h; sourceTree = ""; }; 76 | DDD78B081B9D757D009D779E /* MainDataSourceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainDataSourceController.m; sourceTree = ""; }; 77 | DDD78B111B9D7647009D779E /* ABMenuTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABMenuTableViewCell.h; sourceTree = ""; }; 78 | DDD78B121B9D7647009D779E /* ABMenuTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABMenuTableViewCell.m; sourceTree = ""; }; 79 | DDE29C461BBB08D5000EB816 /* ABMenuTableViewCell.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ABMenuTableViewCell.podspec; path = ../../ABMenuTableViewCell.podspec; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | DD8B08FE1B9D6FAA007C8187 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | B2045D0A39F38B7D9D0C03B1 /* libPods.a in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | DD8B09171B9D6FAA007C8187 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | /* End PBXFrameworksBuildPhase section */ 99 | 100 | /* Begin PBXGroup section */ 101 | 49630F37EC7BC5995E2F3170 /* Pods */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | A165A52D653202A7694A92CD /* Pods.debug.xcconfig */, 105 | 338A62F79E49041174C62F7D /* Pods.release.xcconfig */, 106 | ); 107 | name = Pods; 108 | sourceTree = ""; 109 | }; 110 | A8F45E941315318F871BCDCE /* Frameworks */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | B93F7BB346B823C4C1E81513 /* libPods.a */, 114 | ); 115 | name = Frameworks; 116 | sourceTree = ""; 117 | }; 118 | DD8735941BFA589E006E7367 /* Cells */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | DD8735951BFA58D6006E7367 /* CustomMenuTableViewCell.h */, 122 | DD8735961BFA58D6006E7367 /* CustomMenuTableViewCell.m */, 123 | ); 124 | name = Cells; 125 | sourceTree = ""; 126 | }; 127 | DD8B08F81B9D6FAA007C8187 = { 128 | isa = PBXGroup; 129 | children = ( 130 | DD8B09031B9D6FAA007C8187 /* SampleProject */, 131 | DD8B091D1B9D6FAA007C8187 /* SampleProjectTests */, 132 | DD8B09021B9D6FAA007C8187 /* Products */, 133 | 49630F37EC7BC5995E2F3170 /* Pods */, 134 | A8F45E941315318F871BCDCE /* Frameworks */, 135 | ); 136 | sourceTree = ""; 137 | }; 138 | DD8B09021B9D6FAA007C8187 /* Products */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | DD8B09011B9D6FAA007C8187 /* SampleProject.app */, 142 | DD8B091A1B9D6FAA007C8187 /* SampleProjectTests.xctest */, 143 | ); 144 | name = Products; 145 | sourceTree = ""; 146 | }; 147 | DD8B09031B9D6FAA007C8187 /* SampleProject */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | DD8B09081B9D6FAA007C8187 /* AppDelegate.h */, 151 | DD8B09091B9D6FAA007C8187 /* AppDelegate.m */, 152 | DD1DCA331BBA64E400403CB7 /* Options.h */, 153 | DDD78B101B9D7647009D779E /* ABMenuTableViewCell */, 154 | DDD78AFE1B9D72F6009D779E /* Extensions */, 155 | DDD78AFF1B9D72FE009D779E /* UserInterface */, 156 | DD8B090E1B9D6FAA007C8187 /* Main.storyboard */, 157 | DD8B09111B9D6FAA007C8187 /* Images.xcassets */, 158 | DD8B09131B9D6FAA007C8187 /* LaunchScreen.xib */, 159 | DD8B09041B9D6FAA007C8187 /* Supporting Files */, 160 | ); 161 | path = SampleProject; 162 | sourceTree = ""; 163 | }; 164 | DD8B09041B9D6FAA007C8187 /* Supporting Files */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | DD9B6EC51BB9A5490091629D /* DataSource.plist */, 168 | DD8B09051B9D6FAA007C8187 /* Info.plist */, 169 | DD8B09061B9D6FAA007C8187 /* main.m */, 170 | DDAF09631BBEAC8800C886E1 /* LICENSE */, 171 | DDAF09651BBEAC9100C886E1 /* README.md */, 172 | DDE29C461BBB08D5000EB816 /* ABMenuTableViewCell.podspec */, 173 | ); 174 | name = "Supporting Files"; 175 | sourceTree = ""; 176 | }; 177 | DD8B091D1B9D6FAA007C8187 /* SampleProjectTests */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | DD8B09201B9D6FAA007C8187 /* SampleProjectTests.m */, 181 | DD8B091E1B9D6FAA007C8187 /* Supporting Files */, 182 | ); 183 | path = SampleProjectTests; 184 | sourceTree = ""; 185 | }; 186 | DD8B091E1B9D6FAA007C8187 /* Supporting Files */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | DD8B091F1B9D6FAA007C8187 /* Info.plist */, 190 | ); 191 | name = "Supporting Files"; 192 | sourceTree = ""; 193 | }; 194 | DDD78AFE1B9D72F6009D779E /* Extensions */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | DDD78B001B9D732A009D779E /* UIView+XIB.h */, 198 | DDD78B011B9D732A009D779E /* UIView+XIB.m */, 199 | ); 200 | name = Extensions; 201 | sourceTree = ""; 202 | }; 203 | DDD78AFF1B9D72FE009D779E /* UserInterface */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | DD8735941BFA589E006E7367 /* Cells */, 207 | DDD78B031B9D757D009D779E /* ABCellCustomStyleMenuView.xib */, 208 | DDD78B041B9D757D009D779E /* ABCellMailStyleMenuView.xib */, 209 | DDD78B051B9D757D009D779E /* ABCellMenuView.h */, 210 | DDD78B061B9D757D009D779E /* ABCellMenuView.m */, 211 | DDD78B071B9D757D009D779E /* MainDataSourceController.h */, 212 | DDD78B081B9D757D009D779E /* MainDataSourceController.m */, 213 | DD8B090B1B9D6FAA007C8187 /* MainViewController.h */, 214 | DD8B090C1B9D6FAA007C8187 /* MainViewController.m */, 215 | DD8FB7E21FEEB9AC00ACCF99 /* DetailsViewController.h */, 216 | DD8FB7E31FEEB9AC00ACCF99 /* DetailsViewController.m */, 217 | ); 218 | name = UserInterface; 219 | sourceTree = ""; 220 | }; 221 | DDD78B101B9D7647009D779E /* ABMenuTableViewCell */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | DDD78B111B9D7647009D779E /* ABMenuTableViewCell.h */, 225 | DDD78B121B9D7647009D779E /* ABMenuTableViewCell.m */, 226 | DDD118AB1BFE253D00761743 /* UITableView+VisibleMenuCell.h */, 227 | DDD118AC1BFE253D00761743 /* UITableView+VisibleMenuCell.m */, 228 | ); 229 | name = ABMenuTableViewCell; 230 | path = ../../ABMenuTableViewCell; 231 | sourceTree = ""; 232 | }; 233 | /* End PBXGroup section */ 234 | 235 | /* Begin PBXNativeTarget section */ 236 | DD8B09001B9D6FAA007C8187 /* SampleProject */ = { 237 | isa = PBXNativeTarget; 238 | buildConfigurationList = DD8B09241B9D6FAA007C8187 /* Build configuration list for PBXNativeTarget "SampleProject" */; 239 | buildPhases = ( 240 | 6A65F81B45D2EC2D9BE58132 /* Check Pods Manifest.lock */, 241 | DD8B08FD1B9D6FAA007C8187 /* Sources */, 242 | DD8B08FE1B9D6FAA007C8187 /* Frameworks */, 243 | DD8B08FF1B9D6FAA007C8187 /* Resources */, 244 | DA94A497CF58C6B175025117 /* Copy Pods Resources */, 245 | ); 246 | buildRules = ( 247 | ); 248 | dependencies = ( 249 | ); 250 | name = SampleProject; 251 | productName = SampleProject; 252 | productReference = DD8B09011B9D6FAA007C8187 /* SampleProject.app */; 253 | productType = "com.apple.product-type.application"; 254 | }; 255 | DD8B09191B9D6FAA007C8187 /* SampleProjectTests */ = { 256 | isa = PBXNativeTarget; 257 | buildConfigurationList = DD8B09271B9D6FAA007C8187 /* Build configuration list for PBXNativeTarget "SampleProjectTests" */; 258 | buildPhases = ( 259 | DD8B09161B9D6FAA007C8187 /* Sources */, 260 | DD8B09171B9D6FAA007C8187 /* Frameworks */, 261 | DD8B09181B9D6FAA007C8187 /* Resources */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | DD8B091C1B9D6FAA007C8187 /* PBXTargetDependency */, 267 | ); 268 | name = SampleProjectTests; 269 | productName = SampleProjectTests; 270 | productReference = DD8B091A1B9D6FAA007C8187 /* SampleProjectTests.xctest */; 271 | productType = "com.apple.product-type.bundle.unit-test"; 272 | }; 273 | /* End PBXNativeTarget section */ 274 | 275 | /* Begin PBXProject section */ 276 | DD8B08F91B9D6FAA007C8187 /* Project object */ = { 277 | isa = PBXProject; 278 | attributes = { 279 | LastUpgradeCheck = 0710; 280 | ORGANIZATIONNAME = "Alex Bumbu"; 281 | TargetAttributes = { 282 | DD8B09001B9D6FAA007C8187 = { 283 | CreatedOnToolsVersion = 6.4; 284 | LastSwiftMigration = 0920; 285 | }; 286 | DD8B09191B9D6FAA007C8187 = { 287 | CreatedOnToolsVersion = 6.4; 288 | TestTargetID = DD8B09001B9D6FAA007C8187; 289 | }; 290 | }; 291 | }; 292 | buildConfigurationList = DD8B08FC1B9D6FAA007C8187 /* Build configuration list for PBXProject "SampleProject" */; 293 | compatibilityVersion = "Xcode 3.2"; 294 | developmentRegion = English; 295 | hasScannedForEncodings = 0; 296 | knownRegions = ( 297 | en, 298 | Base, 299 | ); 300 | mainGroup = DD8B08F81B9D6FAA007C8187; 301 | productRefGroup = DD8B09021B9D6FAA007C8187 /* Products */; 302 | projectDirPath = ""; 303 | projectRoot = ""; 304 | targets = ( 305 | DD8B09001B9D6FAA007C8187 /* SampleProject */, 306 | DD8B09191B9D6FAA007C8187 /* SampleProjectTests */, 307 | ); 308 | }; 309 | /* End PBXProject section */ 310 | 311 | /* Begin PBXResourcesBuildPhase section */ 312 | DD8B08FF1B9D6FAA007C8187 /* Resources */ = { 313 | isa = PBXResourcesBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | DD8B09101B9D6FAA007C8187 /* Main.storyboard in Resources */, 317 | DDD78B091B9D757D009D779E /* ABCellCustomStyleMenuView.xib in Resources */, 318 | DDAF09641BBEAC8800C886E1 /* LICENSE in Resources */, 319 | DDD78B0A1B9D757D009D779E /* ABCellMailStyleMenuView.xib in Resources */, 320 | DDE29C471BBB08D5000EB816 /* ABMenuTableViewCell.podspec in Resources */, 321 | DD8B09151B9D6FAA007C8187 /* LaunchScreen.xib in Resources */, 322 | DD8B09121B9D6FAA007C8187 /* Images.xcassets in Resources */, 323 | DD9B6EC61BB9A5490091629D /* DataSource.plist in Resources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | DD8B09181B9D6FAA007C8187 /* Resources */ = { 328 | isa = PBXResourcesBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | /* End PBXResourcesBuildPhase section */ 335 | 336 | /* Begin PBXShellScriptBuildPhase section */ 337 | 6A65F81B45D2EC2D9BE58132 /* Check Pods Manifest.lock */ = { 338 | isa = PBXShellScriptBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | ); 342 | inputPaths = ( 343 | ); 344 | name = "Check Pods Manifest.lock"; 345 | outputPaths = ( 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | shellPath = /bin/sh; 349 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 350 | showEnvVarsInLog = 0; 351 | }; 352 | DA94A497CF58C6B175025117 /* Copy Pods Resources */ = { 353 | isa = PBXShellScriptBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | inputPaths = ( 358 | ); 359 | name = "Copy Pods Resources"; 360 | outputPaths = ( 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | shellPath = /bin/sh; 364 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 365 | showEnvVarsInLog = 0; 366 | }; 367 | /* End PBXShellScriptBuildPhase section */ 368 | 369 | /* Begin PBXSourcesBuildPhase section */ 370 | DD8B08FD1B9D6FAA007C8187 /* Sources */ = { 371 | isa = PBXSourcesBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | DDD118AD1BFE253D00761743 /* UITableView+VisibleMenuCell.m in Sources */, 375 | DD8FB7E41FEEB9AC00ACCF99 /* DetailsViewController.m in Sources */, 376 | DD8B090D1B9D6FAA007C8187 /* MainViewController.m in Sources */, 377 | DDD78B131B9D7647009D779E /* ABMenuTableViewCell.m in Sources */, 378 | DD8B090A1B9D6FAA007C8187 /* AppDelegate.m in Sources */, 379 | DDD78B0B1B9D757D009D779E /* ABCellMenuView.m in Sources */, 380 | DD8735971BFA58D6006E7367 /* CustomMenuTableViewCell.m in Sources */, 381 | DDD78B0C1B9D757D009D779E /* MainDataSourceController.m in Sources */, 382 | DDD78B021B9D732A009D779E /* UIView+XIB.m in Sources */, 383 | DD8B09071B9D6FAA007C8187 /* main.m in Sources */, 384 | ); 385 | runOnlyForDeploymentPostprocessing = 0; 386 | }; 387 | DD8B09161B9D6FAA007C8187 /* Sources */ = { 388 | isa = PBXSourcesBuildPhase; 389 | buildActionMask = 2147483647; 390 | files = ( 391 | DD8B09211B9D6FAA007C8187 /* SampleProjectTests.m in Sources */, 392 | ); 393 | runOnlyForDeploymentPostprocessing = 0; 394 | }; 395 | /* End PBXSourcesBuildPhase section */ 396 | 397 | /* Begin PBXTargetDependency section */ 398 | DD8B091C1B9D6FAA007C8187 /* PBXTargetDependency */ = { 399 | isa = PBXTargetDependency; 400 | target = DD8B09001B9D6FAA007C8187 /* SampleProject */; 401 | targetProxy = DD8B091B1B9D6FAA007C8187 /* PBXContainerItemProxy */; 402 | }; 403 | /* End PBXTargetDependency section */ 404 | 405 | /* Begin PBXVariantGroup section */ 406 | DD8B090E1B9D6FAA007C8187 /* Main.storyboard */ = { 407 | isa = PBXVariantGroup; 408 | children = ( 409 | DD8B090F1B9D6FAA007C8187 /* Base */, 410 | ); 411 | name = Main.storyboard; 412 | sourceTree = ""; 413 | }; 414 | DD8B09131B9D6FAA007C8187 /* LaunchScreen.xib */ = { 415 | isa = PBXVariantGroup; 416 | children = ( 417 | DD8B09141B9D6FAA007C8187 /* Base */, 418 | ); 419 | name = LaunchScreen.xib; 420 | sourceTree = ""; 421 | }; 422 | /* End PBXVariantGroup section */ 423 | 424 | /* Begin XCBuildConfiguration section */ 425 | DD8B09221B9D6FAA007C8187 /* Debug */ = { 426 | isa = XCBuildConfiguration; 427 | buildSettings = { 428 | ALWAYS_SEARCH_USER_PATHS = NO; 429 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 430 | CLANG_CXX_LIBRARY = "libc++"; 431 | CLANG_ENABLE_MODULES = YES; 432 | CLANG_ENABLE_OBJC_ARC = YES; 433 | CLANG_WARN_BOOL_CONVERSION = YES; 434 | CLANG_WARN_CONSTANT_CONVERSION = YES; 435 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 436 | CLANG_WARN_EMPTY_BODY = YES; 437 | CLANG_WARN_ENUM_CONVERSION = YES; 438 | CLANG_WARN_INT_CONVERSION = YES; 439 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 440 | CLANG_WARN_UNREACHABLE_CODE = YES; 441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 443 | COPY_PHASE_STRIP = NO; 444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | ENABLE_TESTABILITY = YES; 447 | GCC_C_LANGUAGE_STANDARD = gnu99; 448 | GCC_DYNAMIC_NO_PIC = NO; 449 | GCC_NO_COMMON_BLOCKS = YES; 450 | GCC_OPTIMIZATION_LEVEL = 0; 451 | GCC_PREPROCESSOR_DEFINITIONS = ( 452 | "DEBUG=1", 453 | "$(inherited)", 454 | ); 455 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 456 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 457 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 458 | GCC_WARN_UNDECLARED_SELECTOR = YES; 459 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 460 | GCC_WARN_UNUSED_FUNCTION = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 463 | MTL_ENABLE_DEBUG_INFO = YES; 464 | ONLY_ACTIVE_ARCH = YES; 465 | SDKROOT = iphoneos; 466 | TARGETED_DEVICE_FAMILY = "1,2"; 467 | }; 468 | name = Debug; 469 | }; 470 | DD8B09231B9D6FAA007C8187 /* Release */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ALWAYS_SEARCH_USER_PATHS = NO; 474 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 475 | CLANG_CXX_LIBRARY = "libc++"; 476 | CLANG_ENABLE_MODULES = YES; 477 | CLANG_ENABLE_OBJC_ARC = YES; 478 | CLANG_WARN_BOOL_CONVERSION = YES; 479 | CLANG_WARN_CONSTANT_CONVERSION = YES; 480 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 481 | CLANG_WARN_EMPTY_BODY = YES; 482 | CLANG_WARN_ENUM_CONVERSION = YES; 483 | CLANG_WARN_INT_CONVERSION = YES; 484 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 485 | CLANG_WARN_UNREACHABLE_CODE = YES; 486 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 487 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 488 | COPY_PHASE_STRIP = NO; 489 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 490 | ENABLE_NS_ASSERTIONS = NO; 491 | ENABLE_STRICT_OBJC_MSGSEND = YES; 492 | GCC_C_LANGUAGE_STANDARD = gnu99; 493 | GCC_NO_COMMON_BLOCKS = YES; 494 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 495 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 496 | GCC_WARN_UNDECLARED_SELECTOR = YES; 497 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 498 | GCC_WARN_UNUSED_FUNCTION = YES; 499 | GCC_WARN_UNUSED_VARIABLE = YES; 500 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 501 | MTL_ENABLE_DEBUG_INFO = NO; 502 | SDKROOT = iphoneos; 503 | TARGETED_DEVICE_FAMILY = "1,2"; 504 | VALIDATE_PRODUCT = YES; 505 | }; 506 | name = Release; 507 | }; 508 | DD8B09251B9D6FAA007C8187 /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | baseConfigurationReference = A165A52D653202A7694A92CD /* Pods.debug.xcconfig */; 511 | buildSettings = { 512 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 513 | CLANG_ENABLE_MODULES = YES; 514 | INFOPLIST_FILE = SampleProject/Info.plist; 515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 516 | PRODUCT_BUNDLE_IDENTIFIER = "com.alexbumbu.$(PRODUCT_NAME:rfc1034identifier)"; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 519 | SWIFT_VERSION = 3.0; 520 | }; 521 | name = Debug; 522 | }; 523 | DD8B09261B9D6FAA007C8187 /* Release */ = { 524 | isa = XCBuildConfiguration; 525 | baseConfigurationReference = 338A62F79E49041174C62F7D /* Pods.release.xcconfig */; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | CLANG_ENABLE_MODULES = YES; 529 | INFOPLIST_FILE = SampleProject/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = "com.alexbumbu.$(PRODUCT_NAME:rfc1034identifier)"; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | SWIFT_VERSION = 3.0; 534 | }; 535 | name = Release; 536 | }; 537 | DD8B09281B9D6FAA007C8187 /* Debug */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | BUNDLE_LOADER = "$(TEST_HOST)"; 541 | FRAMEWORK_SEARCH_PATHS = ( 542 | "$(SDKROOT)/Developer/Library/Frameworks", 543 | "$(inherited)", 544 | ); 545 | GCC_PREPROCESSOR_DEFINITIONS = ( 546 | "DEBUG=1", 547 | "$(inherited)", 548 | ); 549 | INFOPLIST_FILE = SampleProjectTests/Info.plist; 550 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 551 | PRODUCT_BUNDLE_IDENTIFIER = "com.alexbumbu.$(PRODUCT_NAME:rfc1034identifier)"; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleProject.app/SampleProject"; 554 | }; 555 | name = Debug; 556 | }; 557 | DD8B09291B9D6FAA007C8187 /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | BUNDLE_LOADER = "$(TEST_HOST)"; 561 | FRAMEWORK_SEARCH_PATHS = ( 562 | "$(SDKROOT)/Developer/Library/Frameworks", 563 | "$(inherited)", 564 | ); 565 | INFOPLIST_FILE = SampleProjectTests/Info.plist; 566 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 567 | PRODUCT_BUNDLE_IDENTIFIER = "com.alexbumbu.$(PRODUCT_NAME:rfc1034identifier)"; 568 | PRODUCT_NAME = "$(TARGET_NAME)"; 569 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleProject.app/SampleProject"; 570 | }; 571 | name = Release; 572 | }; 573 | /* End XCBuildConfiguration section */ 574 | 575 | /* Begin XCConfigurationList section */ 576 | DD8B08FC1B9D6FAA007C8187 /* Build configuration list for PBXProject "SampleProject" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | DD8B09221B9D6FAA007C8187 /* Debug */, 580 | DD8B09231B9D6FAA007C8187 /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | DD8B09241B9D6FAA007C8187 /* Build configuration list for PBXNativeTarget "SampleProject" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | DD8B09251B9D6FAA007C8187 /* Debug */, 589 | DD8B09261B9D6FAA007C8187 /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | DD8B09271B9D6FAA007C8187 /* Build configuration list for PBXNativeTarget "SampleProjectTests" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | DD8B09281B9D6FAA007C8187 /* Debug */, 598 | DD8B09291B9D6FAA007C8187 /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | /* End XCConfigurationList section */ 604 | }; 605 | rootObject = DD8B08F91B9D6FAA007C8187 /* Project object */; 606 | } 607 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/project.xcworkspace/xcshareddata/SampleProject.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 44A9AECD-384C-475E-9B24-23947046D915 9 | IDESourceControlProjectName 10 | SampleProject 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 14 | https://github.com/alexbumbu/ABMenuTableViewCell.git 15 | 16 | IDESourceControlProjectPath 17 | SampleProject/SampleProject.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/alexbumbu/ABMenuTableViewCell.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 36 | IDESourceControlWCCName 37 | ABMenuTableViewCell 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/project.xcworkspace/xcuserdata/alexbumbu.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/SampleProject.xcodeproj/project.xcworkspace/xcuserdata/alexbumbu.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/project.xcworkspace/xcuserdata/alexbumbu.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/xcuserdata/alexbumbu.xcuserdatad/xcschemes/SampleProject.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcodeproj/xcuserdata/alexbumbu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SampleProject.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | DD8B09001B9D6FAA007C8187 16 | 17 | primary 18 | 19 | 20 | DD8B09191B9D6FAA007C8187 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SampleProject/SampleProject.xcworkspace/xcshareddata/SampleProject.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 93FEF39C-544B-4D67-8A29-A1D38174B8E6 9 | IDESourceControlProjectName 10 | SampleProject 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 14 | https://github.com/alexbumbu/ABMenuTableViewCell.git 15 | 16 | IDESourceControlProjectPath 17 | SampleProject/SampleProject.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/alexbumbu/ABMenuTableViewCell.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 0202F087AC62BD914A6B3989C52A7A17C95601DA 36 | IDESourceControlWCCName 37 | ABMenuTableViewCell 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/ABCellCustomStyleMenuView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 24 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/ABCellMailStyleMenuView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 45 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/ABCellMenuView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ABCellMenuView.h 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 17/02/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIView+XIB.h" 11 | 12 | @protocol ABCellMenuViewDelegate; 13 | 14 | @interface ABCellMenuView : UIView 15 | 16 | @property (nonatomic, assign) id delegate; 17 | @property (nonatomic, strong) NSIndexPath *indexPath; 18 | 19 | @end 20 | 21 | 22 | @protocol ABCellMenuViewDelegate 23 | 24 | @optional 25 | - (void)cellMenuViewMoreBtnTapped:(ABCellMenuView *)menuView; 26 | - (void)cellMenuViewFlagBtnTapped:(ABCellMenuView *)menuView; 27 | - (void)cellMenuViewDeleteBtnTapped:(ABCellMenuView *)menuView; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/ABCellMenuView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ABCellMenuView.m 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 17/02/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "ABCellMenuView.h" 10 | 11 | @implementation ABCellMenuView { 12 | IBOutlet UIButton *deleteButton; 13 | IBOutlet UIButton *flagButton; 14 | IBOutlet UIButton *moreButton; 15 | } 16 | 17 | - (void)awakeFromNib { 18 | [super awakeFromNib]; 19 | } 20 | 21 | 22 | #pragma mark Actions 23 | 24 | - (IBAction)deleteBtnPressed:(id)sender { 25 | if (_delegate && [_delegate respondsToSelector:@selector(cellMenuViewDeleteBtnTapped:)]) 26 | [_delegate cellMenuViewDeleteBtnTapped:self]; 27 | } 28 | 29 | - (IBAction)moreBtnPressed:(id)sender { 30 | if (_delegate && [_delegate respondsToSelector:@selector(cellMenuViewMoreBtnTapped:)]) 31 | [_delegate cellMenuViewMoreBtnTapped:self]; 32 | } 33 | 34 | - (IBAction)flagBtnPressed:(id)sender { 35 | if (_delegate && [_delegate respondsToSelector:@selector(cellMenuViewFlagBtnTapped:)]) 36 | [_delegate cellMenuViewFlagBtnTapped:self]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 07/09/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 07/09/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "Options.h" 11 | 12 | #ifdef PRESENTATION 13 | #import 14 | #endif 15 | 16 | @interface AppDelegate () 17 | 18 | @end 19 | 20 | @implementation AppDelegate 21 | 22 | #ifdef PRESENTATION 23 | - (UIWindow *)window { 24 | if (!_window) { 25 | _window = [[SmudgyWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | } 27 | return _window; 28 | } 29 | #endif 30 | 31 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 32 | // Override point for customization after application launch. 33 | return YES; 34 | } 35 | 36 | - (void)applicationWillResignActive:(UIApplication *)application { 37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 39 | } 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application { 42 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | - (void)applicationWillEnterForeground:(UIApplication *)application { 47 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | - (void)applicationDidBecomeActive:(UIApplication *)application { 51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 52 | } 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/CustomMenuTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomMenuTableViewCell.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 16/11/15. 6 | // Copyright © 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "ABMenuTableViewCell.h" 10 | 11 | @interface CustomMenuTableViewCell : ABMenuTableViewCell 12 | 13 | @property (nonatomic, assign, readonly) IBOutlet UILabel *mainLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/CustomMenuTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomMenuTableViewCell.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 16/11/15. 6 | // Copyright © 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "CustomMenuTableViewCell.h" 10 | 11 | @interface CustomMenuTableViewCell () 12 | 13 | @property (nonatomic, assign) IBOutlet UILabel *mainLabel; 14 | 15 | @end 16 | 17 | @implementation CustomMenuTableViewCell 18 | 19 | @synthesize mainLabel; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/DataSource.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | The Godfather 6 | Lord Of The Rigs: The Two Towers 7 | The Matrix 8 | Jupiter Ascending 9 | Guardians Of The Galaxy 10 | 47 Ronin 11 | The Longest Yard 12 | Interstellar 13 | Predator 2 14 | Alien IV 15 | X-Men: Days Of Future Past 16 | Grim Fandango 17 | Pulp Fiction 18 | The Dark Knight 19 | No Country For Old Men 20 | Inception 21 | Goodfellas 22 | Spirited Away 23 | Star Wars 24 | Howl's Moving Castle 25 | Dune 26 | 27 | 28 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/DetailsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailsViewController.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 23/12/2017. 6 | // Copyright © 2017 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString * const showDetailsSegueIdentifier; 12 | 13 | @interface DetailsViewController : UIViewController 14 | 15 | @property (nonatomic, copy) NSString *itemName; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/DetailsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailsViewController.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 23/12/2017. 6 | // Copyright © 2017 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "DetailsViewController.h" 10 | 11 | NSString * const showDetailsSegueIdentifier = @"showDetails"; 12 | 13 | @implementation DetailsViewController { 14 | IBOutlet UILabel *messageLabel; 15 | } 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // Do any additional setup after loading the view. 21 | if ([self.itemName isEqualToString:@"Grim Fandango"]) { 22 | [self showSuccessMessage]; 23 | } 24 | } 25 | 26 | - (void)didReceiveMemoryWarning { 27 | [super didReceiveMemoryWarning]; 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | 32 | #pragma mark Private Methods 33 | 34 | - (void)showSuccessMessage { 35 | messageLabel.text = @"This is the one! Congrats, you've found it!"; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/cats.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cats.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cats@2x.jpg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cats@3x.jpg", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/cats.imageset/cats.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/SampleProject/Images.xcassets/cats.imageset/cats.jpg -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/cats.imageset/cats@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/SampleProject/Images.xcassets/cats.imageset/cats@2x.jpg -------------------------------------------------------------------------------- /SampleProject/SampleProject/Images.xcassets/cats.imageset/cats@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/SampleProject/SampleProject/Images.xcassets/cats.imageset/cats@3x.jpg -------------------------------------------------------------------------------- /SampleProject/SampleProject/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/MainDataSourceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainDataSourceController.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 13/07/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface MainDataSourceController : NSObject 14 | 15 | @property (nonatomic, assign) IBOutlet UITableView *tableView; 16 | @property (nonatomic, assign) IBOutlet UIViewController *viewController; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/MainDataSourceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainDataSourceController.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 13/07/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "MainDataSourceController.h" 10 | #import "ABMenuTableViewCell.h" 11 | 12 | #import "MainViewController.h" 13 | #import "DetailsViewController.h" 14 | #import "ABCellMenuView.h" 15 | #import "CustomMenuTableViewCell.h" 16 | 17 | 18 | static NSString *menuCellIdentifier = @"Default Cell"; 19 | static NSString *customCellIdentifier = @"Custom Cell"; 20 | 21 | @interface MainDataSourceController () 22 | 23 | @end 24 | 25 | @implementation MainDataSourceController { 26 | NSMutableArray *_dataSource; 27 | } 28 | 29 | @synthesize tableView = _tableView; 30 | @synthesize viewController = _viewController; 31 | 32 | - (void)refreshDataSourceWithCompletionHandler:(void (^)())completion { 33 | [self loadDataSource]; 34 | 35 | if (completion) 36 | completion(); 37 | } 38 | 39 | #pragma mark UITableViewDataSource Methods 40 | 41 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 42 | return 44.0 * (self.menuPosition + 1); 43 | } 44 | 45 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 46 | return _dataSource.count; 47 | } 48 | 49 | - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 50 | ABMenuTableViewCell *cell = nil; 51 | 52 | switch (self.menuPosition) { 53 | case 0: { 54 | cell = [self menuCellAtIndexPath:indexPath]; 55 | break; 56 | } 57 | case 1: { 58 | cell = [self customCellAtIndexPath:indexPath]; 59 | break; 60 | } 61 | 62 | default: 63 | break; 64 | } 65 | 66 | // custom menu view 67 | NSString *nibName = (self.menuPosition == 0)? @"ABCellMailStyleMenuView" : @"ABCellCustomStyleMenuView"; 68 | ABCellMenuView *menuView = [ABCellMenuView initWithNib:nibName bundle:nil]; 69 | menuView.delegate = self; 70 | menuView.indexPath = indexPath; 71 | cell.rightMenuView = menuView; 72 | 73 | return cell; 74 | } 75 | 76 | - (ABMenuTableViewCell*)menuCellAtIndexPath:(NSIndexPath*)indexPath { 77 | ABMenuTableViewCell *cell = (ABMenuTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:menuCellIdentifier]; 78 | cell.textLabel.text = [_dataSource objectAtIndex:indexPath.row]; 79 | cell.detailTextLabel.textColor = [UIColor darkGrayColor]; 80 | cell.detailTextLabel.text = @"swipe to show custom menu"; 81 | 82 | return cell; 83 | } 84 | 85 | // 86 | //- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 87 | // return YES; 88 | //} 89 | 90 | 91 | #pragma mark UITableViewDelegate Methods 92 | 93 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 94 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 95 | 96 | ABMenuTableViewCell *cell = (ABMenuTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]; 97 | if (cell.showingRightMenu) { 98 | return; 99 | } 100 | 101 | [self showDetailsForCell:cell]; 102 | } 103 | 104 | #pragma mark ABCellMenuViewDelegate Methods 105 | 106 | - (void)cellMenuViewFlagBtnTapped:(ABCellMenuView *)menuView { 107 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" 108 | message:[NSString stringWithFormat:@"Flag button pressed at position %@", @(menuView.indexPath.row)] 109 | delegate:nil 110 | cancelButtonTitle:@"Ok" 111 | otherButtonTitles:nil]; 112 | [alert show]; 113 | } 114 | 115 | - (void)cellMenuViewMoreBtnTapped:(ABCellMenuView *)menuView { 116 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" 117 | message:[NSString stringWithFormat:@"More button pressed at position %@", @(menuView.indexPath.row)] 118 | delegate:nil 119 | cancelButtonTitle:@"Ok" 120 | otherButtonTitles:nil]; 121 | [alert show]; 122 | } 123 | 124 | - (void)cellMenuViewDeleteBtnTapped:(ABCellMenuView *)menuView { 125 | // update data source 126 | [_dataSource removeObjectAtIndex:menuView.indexPath.row]; 127 | 128 | // update UI 129 | [self.tableView deleteRowsAtIndexPaths: @[menuView.indexPath] withRowAnimation:UITableViewRowAnimationLeft]; 130 | 131 | // make sure to reload in order to update the custom menu index path for each row 132 | NSMutableArray *rowsToReload = [NSMutableArray array]; 133 | for (int i = 0; i < _dataSource.count - menuView.indexPath.row; i++) { 134 | [rowsToReload addObject:[NSIndexPath indexPathForRow:menuView.indexPath.row + i inSection:0]]; 135 | } 136 | 137 | [self.tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationAutomatic]; 138 | } 139 | 140 | 141 | #pragma mark Private Methods 142 | 143 | - (void)loadDataSource { 144 | NSString *dataSourcePath = [[NSBundle mainBundle] pathForResource:@"DataSource" ofType:@"plist"]; 145 | _dataSource = [[NSMutableArray alloc] initWithContentsOfFile:dataSourcePath]; 146 | } 147 | 148 | - (NSInteger)menuPosition { 149 | return ((MainViewController *)self.viewController).segmentedControl.selectedSegmentIndex; 150 | } 151 | 152 | - (CustomMenuTableViewCell*)customCellAtIndexPath:(NSIndexPath*)indexPath { 153 | // prepare the attributed string 154 | NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:[_dataSource objectAtIndex:indexPath.row] 155 | attributes:@{NSForegroundColorAttributeName : [UIColor blackColor]}]; 156 | NSAttributedString *detailsAttrStr = [[NSMutableAttributedString alloc] initWithString:@"\nswipe to show custom menu" 157 | attributes:@{NSForegroundColorAttributeName : [UIColor darkGrayColor], NSFontAttributeName : [UIFont systemFontOfSize:11.0]}]; 158 | [attrStr appendAttributedString:detailsAttrStr]; 159 | 160 | // setup the cell 161 | CustomMenuTableViewCell *cell = (CustomMenuTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:customCellIdentifier]; 162 | cell.mainLabel.attributedText = attrStr; 163 | 164 | return cell; 165 | } 166 | 167 | - (void)showDetailsForCell:(ABMenuTableViewCell *)cell { 168 | [_viewController performSegueWithIdentifier:showDetailsSegueIdentifier sender:cell.textLabel.text]; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/MainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 06/12/14. 6 | // Copyright (c) 2014 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MainViewController : UIViewController 12 | 13 | @property (nonatomic, weak) IBOutlet UISegmentedControl *segmentedControl; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/MainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.m 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 06/12/14. 6 | // Copyright (c) 2014 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "MainViewController.h" 10 | #import "UITableView+DataSourceController.h" 11 | 12 | #import "MainDataSourceController.h" 13 | #import "DetailsViewController.h" 14 | 15 | 16 | @interface MainViewController () 17 | 18 | @end 19 | 20 | @implementation MainViewController { 21 | IBOutlet UITableView *listTableView; 22 | } 23 | 24 | @synthesize segmentedControl; 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | // Do any additional setup after loading the view from its nib. 29 | 30 | // setup data source controller - can also be setup from IB 31 | MainDataSourceController *dataSourceCtrl = [[MainDataSourceController alloc] init]; 32 | dataSourceCtrl.tableView = listTableView; 33 | dataSourceCtrl.viewController = self; 34 | listTableView.dataSourceController = dataSourceCtrl; 35 | 36 | // load data source 37 | [listTableView.dataSourceController refreshDataSourceWithCompletionHandler:nil]; 38 | 39 | self.navigationItem.titleView = segmentedControl; 40 | } 41 | 42 | - (void)didReceiveMemoryWarning { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 48 | if ([segue.identifier isEqualToString:showDetailsSegueIdentifier]) { 49 | 50 | DetailsViewController *detailsController = segue.destinationViewController; 51 | detailsController.itemName = (NSString *)sender; 52 | } 53 | } 54 | 55 | 56 | #pragma mark Actions 57 | 58 | - (IBAction)segmentedControlValueChanged:(UISegmentedControl *)sender { 59 | [listTableView reloadData]; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/Options.h: -------------------------------------------------------------------------------- 1 | // 2 | // Options.h 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 29/09/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | //#define PRESENTATION 10 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/UIView+XIB.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+XIB.h 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 17/02/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (XIB) 12 | 13 | + (instancetype)initFromNib; 14 | + (instancetype)initWithNib:(NSString *)nibName bundle:(NSBundle *)bundle; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/UIView+XIB.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+XIB.m 3 | // Test 4 | // 5 | // Created by Alex Bumbu on 17/02/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import "UIView+XIB.h" 10 | 11 | @implementation UIView (XIB) 12 | 13 | + (instancetype)initFromNib { 14 | return [self initWithNib:NSStringFromClass([self class]) bundle:nil]; 15 | } 16 | 17 | + (instancetype)initWithNib:(NSString *)nibName bundle:(NSBundle *)bundle { 18 | if (!bundle) 19 | bundle = [NSBundle mainBundle]; 20 | 21 | NSArray *viewsArray = [bundle loadNibNamed:nibName owner:nil options:nil]; 22 | if (!viewsArray.count) { 23 | NSLog(@"%@ - no nib found for name %@", NSStringFromClass([self class]), nibName); 24 | 25 | return nil; 26 | } 27 | 28 | for (id aView in viewsArray) { 29 | if ([aView isKindOfClass:[self class]]) 30 | return aView; 31 | } 32 | 33 | return nil; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /SampleProject/SampleProject/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SampleProject 4 | // 5 | // Created by Alex Bumbu on 07/09/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SampleProject/SampleProjectTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SampleProject/SampleProjectTests/SampleProjectTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SampleProjectTests.m 3 | // SampleProjectTests 4 | // 5 | // Created by Alex Bumbu on 07/09/15. 6 | // Copyright (c) 2015 Alex Bumbu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SampleProjectTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation SampleProjectTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /sample_custom_delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/sample_custom_delete.gif -------------------------------------------------------------------------------- /sample_mail_delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/sample_mail_delete.gif -------------------------------------------------------------------------------- /sample_mail_hide.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexbumbu/ABMenuTableViewCell/44a6eb19b0686ad08b39a13bcd90ddfdf0c635ad/sample_mail_hide.gif --------------------------------------------------------------------------------