mirror of
https://github.com/zhigang1992/RETableViewManager.git
synced 2026-06-17 05:29:59 +08:00
86
README.md
86
README.md
@@ -24,7 +24,7 @@ Get your `UITableView` up and running in several lines of code:
|
||||
|
||||
// Create the manager and assign a UITableView
|
||||
//
|
||||
_manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
@@ -43,7 +43,7 @@ Get your `UITableView` up and running in several lines of code:
|
||||
|
||||
// Custom items / cells
|
||||
//
|
||||
_manager[@"CustomItem"] = @"CustomCell";
|
||||
self.manager[@"CustomItem"] = @"CustomCell";
|
||||
|
||||
[section addItem:[CustomItem item]];
|
||||
}
|
||||
@@ -99,7 +99,7 @@ Edit your Podfile and add RETableViewManager:
|
||||
|
||||
``` bash
|
||||
platform :ios, '6.0'
|
||||
pod 'RETableViewManager', '~> 1.1.2'
|
||||
pod 'RETableViewManager', '~> 1.2.5'
|
||||
```
|
||||
|
||||
Install into your Xcode project:
|
||||
@@ -220,35 +220,35 @@ Section without a title:
|
||||
|
||||
``` objective-c
|
||||
RETableViewSection *section = [RETableViewSection section];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
```
|
||||
|
||||
Section with a title:
|
||||
|
||||
``` objective-c
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Header"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
```
|
||||
|
||||
Section with a title and a footer:
|
||||
|
||||
``` objective-c
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Header" footerTitle:@"Footer"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
```
|
||||
|
||||
Section with a custom header view:
|
||||
|
||||
``` objective-c
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderView:myCustomSectionHeaderView];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
```
|
||||
|
||||
Section with a custom header and footer view:
|
||||
|
||||
``` objective-c
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderView:myCustomSectionHeaderView footerView:myCustomSectionFooterView];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
```
|
||||
|
||||
### Text (UITextField) and Number (REFormattedNumberField) Item Example
|
||||
@@ -256,35 +256,35 @@ RETableViewSection *section = [RETableViewSection sectionWithHeaderView:myCustom
|
||||
``` objective-c
|
||||
// Create the manager
|
||||
//
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
|
||||
// Add items to the section
|
||||
//
|
||||
_textItem = [RETextItem itemWithTitle:@"Enter text" value:@""];
|
||||
[section addItem:_textItem];
|
||||
self.textItem = [RETextItem itemWithTitle:@"Enter text" value:@""];
|
||||
[section addItem:self.textItem];
|
||||
|
||||
_numberItem = [RENumberItem itemWithTitle:@"Enter text" value:@"" placeholder:@"(123) 456-7890" format:@"(XXX) XXX-XXXX"];
|
||||
[section addItem:_numberItem];
|
||||
self.numberItem = [RENumberItem itemWithTitle:@"Enter text" value:@"" placeholder:@"(123) 456-7890" format:@"(XXX) XXX-XXXX"];
|
||||
[section addItem:self.numberItem];
|
||||
```
|
||||
|
||||
You can read `_textItem.value` and `_numberItem.value` later whenever you need them.
|
||||
You can read `self.textItem.value` and `self.numberItem.value` later whenever you need them.
|
||||
|
||||
### Bool Item (UISwitch) Example
|
||||
|
||||
``` objective-c
|
||||
// Create the manager
|
||||
//
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
|
||||
// Add a bool value cell (using UISwitch)
|
||||
//
|
||||
@@ -298,12 +298,12 @@ RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"
|
||||
``` objective-c
|
||||
// Create the manager
|
||||
//
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
|
||||
// Add radio cell (options)
|
||||
//
|
||||
@@ -333,12 +333,12 @@ RERadioItem *optionItem = [RERadioItem itemWithTitle:@"Radio" value:@"Option 4"
|
||||
``` objective-c
|
||||
// Create the manager
|
||||
//
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
|
||||
// Add a float item
|
||||
//
|
||||
@@ -352,25 +352,44 @@ RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"
|
||||
``` objective-c
|
||||
// Create the manager
|
||||
//
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
|
||||
[_tableViewManager addSection:section];
|
||||
[self.manager addSection:section];
|
||||
|
||||
// Add a date item
|
||||
//
|
||||
[section addItem:[REDateTimeItem itemWithTitle:@"Date / Time" value:[NSDate date] placeholder:nil format:@"MM/dd/yyyy hh:mm a" datePickerMode:UIDatePickerModeDateAndTime]];
|
||||
```
|
||||
|
||||
### Validations
|
||||
|
||||
Validations are performed using [REValidation](https://github.com/romaonthego/REValidation) library.
|
||||
|
||||
Example:
|
||||
|
||||
```objective-c
|
||||
self.textItem = [RETextItem itemWithTitle:@"Text" value:@"" placeholder:@"Text item"];
|
||||
self.textItem.validators = @[@"presence", @"length(3, 10)"];
|
||||
|
||||
self.emailItem = [RETextItem itemWithTitle:@"Email" value:@"" placeholder:@"Email item"];
|
||||
self.emailItem.name = @"Your email";
|
||||
self.emailItem.validators = @[@"presence", @"email"];
|
||||
```
|
||||
|
||||
Each item, each section and the manager have property `errors`. This property is always up to date with errors on each level.
|
||||
For example, an `RETableViewItem` would only have its own validation errors, `RETableViewSection` would have all errors that occured in that section (one per item).
|
||||
`RETableViewManager`'s property `errors` would reflect all errors.
|
||||
|
||||
### Custom Cells
|
||||
|
||||
`RETableViewManager` allows to map custom objects to custom cells. In order to map your custom object (an item) to a cell,
|
||||
simply write:
|
||||
|
||||
```objective-c
|
||||
_manager[@"CustomItem"] = @"CustomCell";
|
||||
self.manager[@"CustomItem"] = @"CustomCell";
|
||||
```
|
||||
|
||||
If you take a look at [RETableViewManager Source Code](https://github.com/romaonthego/RETableViewManager/blob/master/RETableViewManager/RETableViewManager.m) you may
|
||||
@@ -445,16 +464,29 @@ Quick example:
|
||||
```objective-c
|
||||
- (void)cellDidLoad
|
||||
{
|
||||
_testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
|
||||
[self.contentView addSubview:_testLabel];
|
||||
[super cellDidLoad];
|
||||
self.testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
|
||||
[self.contentView addSubview:self.testLabel];
|
||||
}
|
||||
|
||||
- (void)cellWillAppear
|
||||
{
|
||||
_testLabel.text = self.item.someVariable;
|
||||
[super cellWillAppear];
|
||||
self.testLabel.text = self.item.someVariable;
|
||||
}
|
||||
```
|
||||
|
||||
### Interface Builder Support
|
||||
|
||||
Interface builder cells are supported out of the box, no special set up needed.
|
||||
Cells and items are being automatically registered like any other custom cell in `RETableViewManager`:
|
||||
|
||||
```objective-c
|
||||
self.manager[@"XIBTestItem"] = @"XIBTestCell";
|
||||
```
|
||||
|
||||
Here `XIBTestItem` would be your cell identifier and you should have the `XIBTestCell.xib` file in your bundle. That's it.
|
||||
|
||||
### Styling
|
||||
|
||||
It's super easy to customize different offsets and cell background images of
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'RETableViewManager'
|
||||
s.version = '1.1.2'
|
||||
s.version = '1.2.5'
|
||||
s.authors = { 'Roman Efimov' => 'romefimov@gmail.com' }
|
||||
s.homepage = 'https://github.com/romaonthego/RETableViewManager'
|
||||
s.summary = 'Powerful data driven content manager for UITableView.'
|
||||
s.source = { :git => 'https://github.com/romaonthego/RETableViewManager.git',
|
||||
:tag => '1.1.2' }
|
||||
:tag => '1.2.5' }
|
||||
s.license = { :type => "MIT", :file => "LICENSE" }
|
||||
|
||||
s.platform = :ios, '6.0'
|
||||
@@ -17,4 +17,5 @@ Pod::Spec.new do |s|
|
||||
s.ios.deployment_target = '6.0'
|
||||
|
||||
s.dependency 'REFormattedNumberField', '~> 1.0.4'
|
||||
s.dependency 'REValidation', '~> 0.1.3'
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
@interface RERadioItem : RETableViewItem
|
||||
|
||||
@property (strong, readwrite, nonatomic, getter = detailLabelText, setter = setDetailLabelText:) NSString *value;
|
||||
@property (copy, readwrite, nonatomic) NSString *value;
|
||||
|
||||
+ (instancetype)itemWithTitle:(NSString *)title value:(NSString *)value selectionHandler:(void(^)(RERadioItem *item))selectionHandler;
|
||||
- (id)initWithTitle:(NSString *)title value:(NSString *)value selectionHandler:(void(^)(RERadioItem *item))selectionHandler;
|
||||
|
||||
@@ -47,4 +47,10 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setValue:(NSString *)value
|
||||
{
|
||||
_value = value;
|
||||
self.detailLabelText = value;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -55,4 +55,12 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Error validation
|
||||
|
||||
- (NSArray *)errors
|
||||
{
|
||||
return [REValidation validateObject:self.value name:self.name ? self.name : self.title validators:self.validators];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -83,8 +83,12 @@
|
||||
[self addSubview:_placeholderLabel];
|
||||
}
|
||||
|
||||
_placeholderLabel.textAlignment = self.textAlignment;
|
||||
_placeholderLabel.text = self.placeholder;
|
||||
[_placeholderLabel sizeToFit];
|
||||
CGRect frame = _placeholderLabel.frame;
|
||||
frame.size.width = self.bounds.size.width - self.frame.origin.x * 2;
|
||||
_placeholderLabel.frame = frame;
|
||||
[self sendSubviewToBack:_placeholderLabel];
|
||||
}
|
||||
|
||||
|
||||
2
RETableViewManager/RETableViewCell.h
Normal file → Executable file
2
RETableViewManager/RETableViewCell.h
Normal file → Executable file
@@ -96,4 +96,6 @@ typedef NS_ENUM(NSInteger, RETableViewCellType) {
|
||||
- (void)cellWillAppear;
|
||||
- (void)cellDidDisappear;
|
||||
|
||||
@property (assign, readonly, nonatomic) BOOL loaded;
|
||||
|
||||
@end
|
||||
|
||||
23
RETableViewManager/RETableViewCell.m
Normal file → Executable file
23
RETableViewManager/RETableViewCell.m
Normal file → Executable file
@@ -26,6 +26,12 @@
|
||||
#import "RETableViewCell.h"
|
||||
#import "RETableViewManager.h"
|
||||
|
||||
@interface RETableViewCell ()
|
||||
|
||||
@property (assign, readwrite, nonatomic) BOOL loaded;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RETableViewCell
|
||||
|
||||
+ (BOOL)canFocusWithItem:(RETableViewItem *)item
|
||||
@@ -46,7 +52,7 @@
|
||||
|
||||
#pragma mark - UI
|
||||
|
||||
-(void)_addBackgroundImage
|
||||
- (void)addBackgroundImage
|
||||
{
|
||||
self.tableViewManager.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
self.backgroundView = [[UIView alloc] initWithFrame:self.contentView.bounds];
|
||||
@@ -56,7 +62,7 @@
|
||||
[self.backgroundView addSubview:_backgroundImageView];
|
||||
}
|
||||
|
||||
-(void)_addSelectedBackgroundImage
|
||||
- (void)addSelectedBackgroundImage
|
||||
{
|
||||
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.contentView.bounds];
|
||||
self.selectedBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
@@ -71,15 +77,16 @@
|
||||
|
||||
- (void)cellDidLoad
|
||||
{
|
||||
self.loaded = YES;
|
||||
self.actionBar = [[REActionBar alloc] initWithDelegate:self];
|
||||
self.selectionStyle = self.tableViewManager.style.defaultCellSelectionStyle;
|
||||
|
||||
if ([self.tableViewManager.style hasCustomBackgroundImage]) {
|
||||
[self _addBackgroundImage];
|
||||
[self addBackgroundImage];
|
||||
}
|
||||
|
||||
if ([self.tableViewManager.style hasCustomSelectedBackgroundImage]) {
|
||||
[self _addSelectedBackgroundImage];
|
||||
[self addSelectedBackgroundImage];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,15 +139,15 @@
|
||||
|
||||
if ([self.section.style hasCustomBackgroundImage]) {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
if (_backgroundImageView==nil) {
|
||||
[self _addBackgroundImage];
|
||||
if (!_backgroundImageView) {
|
||||
[self addBackgroundImage];
|
||||
}
|
||||
_backgroundImageView.image = [self.section.style backgroundImageForCellType:self.type];
|
||||
}
|
||||
|
||||
if ([self.section.style hasCustomSelectedBackgroundImage]) {
|
||||
if (_selectedBackgroundImageView==nil) {
|
||||
[self _addSelectedBackgroundImage];
|
||||
if (!_selectedBackgroundImageView) {
|
||||
[self addSelectedBackgroundImage];
|
||||
}
|
||||
_selectedBackgroundImageView.image = [self.section.style selectedBackgroundImageForCellType:self.type];
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RETableViewCellStyle.h"
|
||||
#import "REValidation.h"
|
||||
|
||||
@class RETableViewSection;
|
||||
|
||||
@@ -54,6 +55,12 @@
|
||||
@property (assign, readwrite, nonatomic) CGFloat cellHeight;
|
||||
@property (copy, readwrite, nonatomic) NSString *cellIdentifier;
|
||||
|
||||
// Error validation
|
||||
//
|
||||
@property (copy, readwrite, nonatomic) NSString *name;
|
||||
@property (strong, readwrite, nonatomic) NSArray *validators;
|
||||
@property (strong, readonly, nonatomic) NSArray *errors;
|
||||
|
||||
+ (instancetype)item;
|
||||
+ (instancetype)itemWithTitle:(NSString *)title;
|
||||
+ (instancetype)itemWithTitle:(NSString *)title accessoryType:(UITableViewCellAccessoryType)accessoryType selectionHandler:(void(^)(RETableViewItem *item))selectionHandler;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#import "REFloatItem.h"
|
||||
#import "REDateTimeItem.h"
|
||||
#import "REMultipleChoiceItem.h"
|
||||
#import "REValidation.h"
|
||||
|
||||
@protocol RETableViewManagerDelegate;
|
||||
|
||||
@@ -69,7 +70,7 @@ BOOL REDeviceIsUIKit7();
|
||||
/**
|
||||
The array of sections. See RETableViewSection reference for details.
|
||||
*/
|
||||
@property (strong, readwrite, nonatomic) NSMutableArray *sections;
|
||||
@property (strong, readonly, nonatomic) NSArray *sections;
|
||||
|
||||
/**
|
||||
The `UITableView` that needs to be managed using this `RETableViewManager`.
|
||||
@@ -334,6 +335,12 @@ BOOL REDeviceIsUIKit7();
|
||||
*/
|
||||
- (void)sortSectionsUsingSelector:(SEL)comparator;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Checking for Validation Errors
|
||||
///-----------------------------
|
||||
|
||||
@property (strong, readonly, nonatomic) NSArray *errors;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
363
RETableViewManager/RETableViewManager.m
Normal file → Executable file
363
RETableViewManager/RETableViewManager.m
Normal file → Executable file
@@ -43,8 +43,24 @@ BOOL REDeviceIsUIKit7() {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@interface RETableViewManager ()
|
||||
|
||||
/**
|
||||
The array of pairs of items / cell classes.
|
||||
*/
|
||||
@property (strong, readwrite, nonatomic) NSMutableDictionary *registeredXIBs;
|
||||
@property (strong, readwrite, nonatomic) NSMutableArray *mutableSections;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RETableViewManager
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
[REValidation registerDefaultValidators];
|
||||
[REValidation registerDefaultErrorMessages];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
@throw [NSException exceptionWithName:NSGenericException reason:@"init not supported, use initWithTableView: instead." userInfo:nil];
|
||||
@@ -73,9 +89,10 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
self.tableView = tableView;
|
||||
|
||||
_sections = [[NSMutableArray alloc] init];
|
||||
_registeredClasses = [[NSMutableDictionary alloc] init];
|
||||
_style = [[RETableViewCellStyle alloc] init];
|
||||
self.mutableSections = [[NSMutableArray alloc] init];
|
||||
self.registeredClasses = [[NSMutableDictionary alloc] init];
|
||||
self.registeredXIBs = [[NSMutableDictionary alloc] init];
|
||||
self.style = [[RETableViewCellStyle alloc] init];
|
||||
|
||||
[self registerDefaultClasses];
|
||||
|
||||
@@ -103,12 +120,19 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
NSAssert(NSClassFromString(objectClass), ([NSString stringWithFormat:@"Item class '%@' does not exist.", identifier]));
|
||||
NSAssert(NSClassFromString(identifier), ([NSString stringWithFormat:@"Cell class '%@' does not exist.", identifier]));
|
||||
[_registeredClasses setObject:identifier forKey:objectClass];
|
||||
self.registeredClasses[objectClass] = identifier;
|
||||
|
||||
// Perform check if a XIB exists with the same name as the cell class
|
||||
//
|
||||
if ([[NSBundle mainBundle] pathForResource:identifier ofType:@"nib"]) {
|
||||
self.registeredXIBs[identifier] = objectClass;
|
||||
[self.tableView registerNib:[UINib nibWithNibName:identifier bundle:nil] forCellReuseIdentifier:objectClass];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)objectAtKeyedSubscript:(id <NSCopying>)key
|
||||
{
|
||||
return [_registeredClasses objectForKey:key];
|
||||
return [self.registeredClasses objectForKey:key];
|
||||
}
|
||||
|
||||
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key
|
||||
@@ -118,61 +142,83 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (Class)classForCellAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
NSObject *item = [section.items objectAtIndex:indexPath.row];
|
||||
Class cellClass;
|
||||
for (NSString *className in _registeredClasses) {
|
||||
for (NSString *className in self.registeredClasses) {
|
||||
NSString *itemClass = NSStringFromClass([item class]);
|
||||
if ([itemClass isEqualToString:className]) {
|
||||
cellClass = NSClassFromString([_registeredClasses objectForKey:className]);
|
||||
cellClass = NSClassFromString([self.registeredClasses objectForKey:className]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cellClass;
|
||||
}
|
||||
|
||||
- (NSArray *)sections
|
||||
{
|
||||
return self.mutableSections;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return _sections.count;
|
||||
return self.mutableSections.count;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
return ((RETableViewSection *)[_sections objectAtIndex:sectionIndex]).items.count;
|
||||
return ((RETableViewSection *)[self.mutableSections objectAtIndex:sectionIndex]).items.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
|
||||
UITableViewCellStyle cellStyle = UITableViewCellStyleDefault;
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
cellStyle = ((RETableViewItem *)item).style;
|
||||
|
||||
NSString *cellIdentifier = [item respondsToSelector:@selector(cellIdentifier)] && item.cellIdentifier ? item.cellIdentifier : [NSString stringWithFormat:@"RETableViewManager_%@_%i", [item class], cellStyle];
|
||||
|
||||
NSString *cellIdentifier = [NSString stringWithFormat:@"RETableViewManager_%@_%i", [item class], cellStyle];
|
||||
|
||||
Class cellClass = [self classForCellAtIndexPath:indexPath];
|
||||
|
||||
if (self.registeredXIBs[NSStringFromClass(cellClass)]) {
|
||||
cellIdentifier = self.registeredXIBs[NSStringFromClass(cellClass)];
|
||||
}
|
||||
|
||||
if ([item respondsToSelector:@selector(cellIdentifier)] && item.cellIdentifier) {
|
||||
cellIdentifier = item.cellIdentifier;
|
||||
}
|
||||
|
||||
RETableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[cellClass alloc] initWithStyle:cellStyle reuseIdentifier:cellIdentifier];
|
||||
|
||||
void (^loadCell)(RETableViewCell *cell) = ^(RETableViewCell *cell) {
|
||||
cell.tableViewManager = self;
|
||||
|
||||
// RETableViewManagerDelegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(RETableViewManagerDelegate)] && [_delegate respondsToSelector:@selector(tableView:willLoadCell:forRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView willLoadCell:cell forRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(RETableViewManagerDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willLoadCell:forRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView willLoadCell:cell forRowAtIndexPath:indexPath];
|
||||
|
||||
[cell cellDidLoad];
|
||||
|
||||
// RETableViewManagerDelegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(RETableViewManagerDelegate)] && [_delegate respondsToSelector:@selector(tableView:didLoadCell:forRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didLoadCell:cell forRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(RETableViewManagerDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didLoadCell:forRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didLoadCell:cell forRowAtIndexPath:indexPath];
|
||||
};
|
||||
|
||||
if (cell == nil) {
|
||||
cell = [[cellClass alloc] initWithStyle:cellStyle reuseIdentifier:cellIdentifier];
|
||||
loadCell(cell);
|
||||
}
|
||||
|
||||
if ([cell isKindOfClass:[RETableViewCell class]] && [cell respondsToSelector:@selector(loaded)] && !cell.loaded) {
|
||||
loadCell(cell);
|
||||
}
|
||||
|
||||
cell.rowIndex = indexPath.row;
|
||||
@@ -193,14 +239,14 @@ BOOL REDeviceIsUIKit7() {
|
||||
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
|
||||
{
|
||||
NSMutableArray *titles;
|
||||
for (RETableViewSection *section in self.sections) {
|
||||
for (RETableViewSection *section in self.mutableSections) {
|
||||
if (section.indexTitle) {
|
||||
titles = [NSMutableArray array];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (titles) {
|
||||
for (RETableViewSection *section in self.sections) {
|
||||
for (RETableViewSection *section in self.mutableSections) {
|
||||
[titles addObject:section.indexTitle ? section.indexTitle : @""];
|
||||
}
|
||||
}
|
||||
@@ -210,23 +256,23 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
return section.headerTitle;
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
return section.footerTitle;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
|
||||
{
|
||||
RETableViewSection *sourceSection = [_sections objectAtIndex:sourceIndexPath.section];
|
||||
RETableViewSection *sourceSection = [self.mutableSections objectAtIndex:sourceIndexPath.section];
|
||||
RETableViewItem *item = [sourceSection.items objectAtIndex:sourceIndexPath.row];
|
||||
[sourceSection removeItemAtIndex:sourceIndexPath.row];
|
||||
|
||||
RETableViewSection *destinationSection = [_sections objectAtIndex:destinationIndexPath.section];
|
||||
RETableViewSection *destinationSection = [self.mutableSections objectAtIndex:destinationIndexPath.section];
|
||||
[destinationSection insertItem:item atIndex:destinationIndexPath.row];
|
||||
|
||||
if (item.moveCompletionHandler)
|
||||
@@ -235,14 +281,14 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
return item.moveHandler != nil;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
if ([item isKindOfClass:[RETableViewItem class]]) {
|
||||
return item.editingStyle != UITableViewCellEditingStyleNone || item.moveHandler;
|
||||
@@ -254,23 +300,23 @@ BOOL REDeviceIsUIKit7() {
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
if (item.deletionHandlerWithCompletion) {
|
||||
item.deletionHandlerWithCompletion(item, ^{
|
||||
[section.items removeObjectAtIndex:indexPath.row];
|
||||
[section removeItemAtIndex:indexPath.row];
|
||||
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
});
|
||||
} else {
|
||||
if (item.deletionHandler)
|
||||
item.deletionHandler(item);
|
||||
[section.items removeObjectAtIndex:indexPath.row];
|
||||
[section removeItemAtIndex:indexPath.row];
|
||||
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
}
|
||||
|
||||
if (editingStyle == UITableViewCellEditingStyleInsert) {
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
if (item.insertionHandler)
|
||||
item.insertionHandler(item);
|
||||
@@ -286,24 +332,24 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willDisplayHeaderView:forSection:)])
|
||||
[_delegate tableView:tableView willDisplayHeaderView:view forSection:section];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willDisplayHeaderView:forSection:)])
|
||||
[self.delegate tableView:tableView willDisplayHeaderView:view forSection:section];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willDisplayFooterView:forSection:)])
|
||||
[_delegate tableView:tableView willDisplayFooterView:view forSection:section];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willDisplayFooterView:forSection:)])
|
||||
[self.delegate tableView:tableView willDisplayFooterView:view forSection:section];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath
|
||||
@@ -313,65 +359,65 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didEndDisplayingCell:forRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didEndDisplayingCell:forRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didEndDisplayingHeaderView:forSection:)])
|
||||
[_delegate tableView:tableView didEndDisplayingHeaderView:view forSection:section];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didEndDisplayingHeaderView:forSection:)])
|
||||
[self.delegate tableView:tableView didEndDisplayingHeaderView:view forSection:section];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didEndDisplayingFooterView:forSection:)])
|
||||
[_delegate tableView:tableView didEndDisplayingFooterView:view forSection:section];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didEndDisplayingFooterView:forSection:)])
|
||||
[self.delegate tableView:tableView didEndDisplayingFooterView:view forSection:section];
|
||||
}
|
||||
|
||||
// Variable height support
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
id item = [section.items objectAtIndex:indexPath.row];
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView heightForRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView heightForRowAtIndexPath:indexPath];
|
||||
|
||||
return [[self classForCellAtIndexPath:indexPath] heightWithItem:item tableViewManager:self];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
if (section.headerView)
|
||||
return section.headerView.frame.size.height;
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:heightForHeaderInSection:)])
|
||||
return [_delegate tableView:tableView heightForHeaderInSection:sectionIndex];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:heightForHeaderInSection:)])
|
||||
return [self.delegate tableView:tableView heightForHeaderInSection:sectionIndex];
|
||||
|
||||
return UITableViewAutomaticDimension;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
if (section.footerView)
|
||||
return section.footerView.frame.size.height;
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:heightForFooterInSection:)])
|
||||
return [_delegate tableView:tableView heightForFooterInSection:sectionIndex];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:heightForFooterInSection:)])
|
||||
return [self.delegate tableView:tableView heightForFooterInSection:sectionIndex];
|
||||
|
||||
return UITableViewAutomaticDimension;
|
||||
}
|
||||
@@ -380,24 +426,24 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)])
|
||||
return [_delegate tableView:tableView viewForHeaderInSection:sectionIndex];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)])
|
||||
return [self.delegate tableView:tableView viewForHeaderInSection:sectionIndex];
|
||||
|
||||
return section.headerView;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)sectionIndex
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:sectionIndex];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:sectionIndex];
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:viewForFooterInSection:)])
|
||||
return [_delegate tableView:tableView viewForFooterInSection:sectionIndex];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:viewForFooterInSection:)])
|
||||
return [self.delegate tableView:tableView viewForFooterInSection:sectionIndex];
|
||||
|
||||
return section.footerView;
|
||||
}
|
||||
@@ -406,7 +452,7 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
id item = [section.items objectAtIndex:indexPath.row];
|
||||
if ([item respondsToSelector:@selector(setAccessoryButtonTapHandler:)]) {
|
||||
RETableViewItem *actionItem = (RETableViewItem *)item;
|
||||
@@ -416,8 +462,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:accessoryButtonTappedForRowWithIndexPath:)])
|
||||
[_delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:accessoryButtonTappedForRowWithIndexPath:)])
|
||||
[self.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
|
||||
}
|
||||
|
||||
// Selection
|
||||
@@ -426,8 +472,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:shouldHighlightRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView shouldHighlightRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:shouldHighlightRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView shouldHighlightRowAtIndexPath:indexPath];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -436,24 +482,24 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didHighlightRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didHighlightRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didHighlightRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didHighlightRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didUnhighlightRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didUnhighlightRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didUnhighlightRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didUnhighlightRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willSelectRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView willSelectRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willSelectRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView willSelectRowAtIndexPath:indexPath];
|
||||
|
||||
return indexPath;
|
||||
}
|
||||
@@ -462,15 +508,15 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView willDeselectRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView willDeselectRowAtIndexPath:indexPath];
|
||||
|
||||
return indexPath;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
id item = [section.items objectAtIndex:indexPath.row];
|
||||
if ([item respondsToSelector:@selector(setSelectionHandler:)]) {
|
||||
RETableViewItem *actionItem = (RETableViewItem *)item;
|
||||
@@ -480,29 +526,32 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didDeselectRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didDeselectRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
// Editing
|
||||
|
||||
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
|
||||
if (![item isKindOfClass:[RETableViewItem class]])
|
||||
return UITableViewCellEditingStyleNone;
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:editingStyleForRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView editingStyleForRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:editingStyleForRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView editingStyleForRowAtIndexPath:indexPath];
|
||||
|
||||
return item.editingStyle;
|
||||
}
|
||||
@@ -511,8 +560,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath];
|
||||
|
||||
return NSLocalizedString(@"Delete", @"Delete");
|
||||
}
|
||||
@@ -521,8 +570,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:shouldIndentWhileEditingRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView shouldIndentWhileEditingRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:shouldIndentWhileEditingRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView shouldIndentWhileEditingRowAtIndexPath:indexPath];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -531,23 +580,23 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:willBeginEditingRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView willBeginEditingRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:willBeginEditingRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView willBeginEditingRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:didEndEditingRowAtIndexPath:)])
|
||||
[_delegate tableView:tableView didEndEditingRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:didEndEditingRowAtIndexPath:)])
|
||||
[self.delegate tableView:tableView didEndEditingRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
// Moving/reordering
|
||||
|
||||
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
|
||||
{
|
||||
RETableViewSection *sourceSection = [_sections objectAtIndex:sourceIndexPath.section];
|
||||
RETableViewSection *sourceSection = [self.mutableSections objectAtIndex:sourceIndexPath.section];
|
||||
RETableViewItem *item = [sourceSection.items objectAtIndex:sourceIndexPath.row];
|
||||
if (item.moveHandler) {
|
||||
BOOL allowed = item.moveHandler(item, sourceIndexPath, proposedDestinationIndexPath);
|
||||
@@ -557,8 +606,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:)])
|
||||
return [_delegate tableView:tableView targetIndexPathForMoveFromRowAtIndexPath:sourceIndexPath toProposedIndexPath:proposedDestinationIndexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:)])
|
||||
return [self.delegate tableView:tableView targetIndexPathForMoveFromRowAtIndexPath:sourceIndexPath toProposedIndexPath:proposedDestinationIndexPath];
|
||||
|
||||
return proposedDestinationIndexPath;
|
||||
}
|
||||
@@ -569,8 +618,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:indentationLevelForRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:indentationLevelForRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView indentationLevelForRowAtIndexPath:indexPath];
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -579,7 +628,7 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
id anItem = [section.items objectAtIndex:indexPath.row];
|
||||
if ([anItem respondsToSelector:@selector(setCopyHandler:)]) {
|
||||
RETableViewItem *item = anItem;
|
||||
@@ -589,15 +638,15 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:shouldShowMenuForRowAtIndexPath:)])
|
||||
return [_delegate tableView:tableView shouldShowMenuForRowAtIndexPath:indexPath];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:shouldShowMenuForRowAtIndexPath:)])
|
||||
return [self.delegate tableView:tableView shouldShowMenuForRowAtIndexPath:indexPath];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
id anItem = [section.items objectAtIndex:indexPath.row];
|
||||
if ([anItem respondsToSelector:@selector(setCopyHandler:)]) {
|
||||
RETableViewItem *item = anItem;
|
||||
@@ -613,15 +662,15 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableViewDelegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:canPerformAction:forRowAtIndexPath:withSender:)])
|
||||
return [_delegate tableView:tableView canPerformAction:action forRowAtIndexPath:indexPath withSender:sender];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:canPerformAction:forRowAtIndexPath:withSender:)])
|
||||
return [self.delegate tableView:tableView canPerformAction:action forRowAtIndexPath:indexPath withSender:sender];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
|
||||
{
|
||||
RETableViewSection *section = [_sections objectAtIndex:indexPath.section];
|
||||
RETableViewSection *section = [self.mutableSections objectAtIndex:indexPath.section];
|
||||
RETableViewItem *item = [section.items objectAtIndex:indexPath.row];
|
||||
|
||||
if (action == @selector(copy:)) {
|
||||
@@ -641,8 +690,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
|
||||
// Forward to UITableView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [_delegate respondsToSelector:@selector(tableView:performAction:forRowAtIndexPath:withSender:)])
|
||||
[_delegate tableView:tableView performAction:action forRowAtIndexPath:indexPath withSender:sender];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UITableViewDelegate)] && [self.delegate respondsToSelector:@selector(tableView:performAction:forRowAtIndexPath:withSender:)])
|
||||
[self.delegate tableView:tableView performAction:action forRowAtIndexPath:indexPath withSender:sender];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -652,72 +701,72 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidScroll:)])
|
||||
[_delegate scrollViewDidScroll:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidScroll:)])
|
||||
[self.delegate scrollViewDidScroll:self.tableView];
|
||||
}
|
||||
|
||||
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidZoom:)])
|
||||
[_delegate scrollViewDidZoom:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidZoom:)])
|
||||
[self.delegate scrollViewDidZoom:self.tableView];
|
||||
}
|
||||
|
||||
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewWillBeginDragging:)])
|
||||
[_delegate scrollViewWillBeginDragging:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewWillBeginDragging:)])
|
||||
[self.delegate scrollViewWillBeginDragging:self.tableView];
|
||||
}
|
||||
|
||||
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)])
|
||||
[_delegate scrollViewWillEndDragging:self.tableView withVelocity:velocity targetContentOffset:targetContentOffset];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)])
|
||||
[self.delegate scrollViewWillEndDragging:self.tableView withVelocity:velocity targetContentOffset:targetContentOffset];
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)])
|
||||
[_delegate scrollViewDidEndDragging:self.tableView willDecelerate:decelerate];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)])
|
||||
[self.delegate scrollViewDidEndDragging:self.tableView willDecelerate:decelerate];
|
||||
}
|
||||
|
||||
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewWillBeginDecelerating:)])
|
||||
[_delegate scrollViewWillBeginDecelerating:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewWillBeginDecelerating:)])
|
||||
[self.delegate scrollViewWillBeginDecelerating:self.tableView];
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)])
|
||||
[_delegate scrollViewDidEndDecelerating:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)])
|
||||
[self.delegate scrollViewDidEndDecelerating:self.tableView];
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)])
|
||||
[_delegate scrollViewDidEndScrollingAnimation:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)])
|
||||
[self.delegate scrollViewDidEndScrollingAnimation:self.tableView];
|
||||
}
|
||||
|
||||
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(viewForZoomingInScrollView:)])
|
||||
return [_delegate viewForZoomingInScrollView:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(viewForZoomingInScrollView:)])
|
||||
return [self.delegate viewForZoomingInScrollView:self.tableView];
|
||||
|
||||
return nil;
|
||||
}
|
||||
@@ -726,24 +775,24 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewWillBeginZooming:withView:)])
|
||||
[_delegate scrollViewWillBeginZooming:self.tableView withView:view];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewWillBeginZooming:withView:)])
|
||||
[self.delegate scrollViewWillBeginZooming:self.tableView withView:view];
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidEndZooming:withView:atScale:)])
|
||||
[_delegate scrollViewDidEndZooming:self.tableView withView:view atScale:scale];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidEndZooming:withView:atScale:)])
|
||||
[self.delegate scrollViewDidEndZooming:self.tableView withView:view atScale:scale];
|
||||
}
|
||||
|
||||
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)])
|
||||
return [_delegate scrollViewShouldScrollToTop:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)])
|
||||
return [self.delegate scrollViewShouldScrollToTop:self.tableView];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -751,8 +800,8 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
// Forward to UIScrollView delegate
|
||||
//
|
||||
if ([_delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [_delegate respondsToSelector:@selector(scrollViewDidScrollToTop:)])
|
||||
[_delegate scrollViewDidScrollToTop:self.tableView];
|
||||
if ([self.delegate conformsToProtocol:@protocol(UIScrollViewDelegate)] && [self.delegate respondsToSelector:@selector(scrollViewDidScrollToTop:)])
|
||||
[self.delegate scrollViewDidScrollToTop:self.tableView];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -761,83 +810,83 @@ BOOL REDeviceIsUIKit7() {
|
||||
- (void)addSection:(RETableViewSection *)section
|
||||
{
|
||||
section.tableViewManager = self;
|
||||
[_sections addObject:section];
|
||||
[self.mutableSections addObject:section];
|
||||
}
|
||||
|
||||
- (void)addSectionsFromArray:(NSArray *)array
|
||||
{
|
||||
for (RETableViewSection *section in array)
|
||||
section.tableViewManager = self;
|
||||
[_sections addObjectsFromArray:array];
|
||||
[self.mutableSections addObjectsFromArray:array];
|
||||
}
|
||||
|
||||
- (void)insertSection:(RETableViewSection *)section atIndex:(NSUInteger)index
|
||||
{
|
||||
section.tableViewManager = self;
|
||||
[_sections insertObject:section atIndex:index];
|
||||
[self.mutableSections insertObject:section atIndex:index];
|
||||
}
|
||||
|
||||
- (void)insertSections:(NSArray *)sections atIndexes:(NSIndexSet *)indexes
|
||||
{
|
||||
for (RETableViewSection *section in sections)
|
||||
section.tableViewManager = self;
|
||||
[_sections insertObjects:sections atIndexes:indexes];
|
||||
[self.mutableSections insertObjects:sections atIndexes:indexes];
|
||||
}
|
||||
|
||||
- (void)removeSection:(RETableViewSection *)section
|
||||
{
|
||||
[_sections removeObject:section];
|
||||
[self.mutableSections removeObject:section];
|
||||
}
|
||||
|
||||
- (void)removeAllSections
|
||||
{
|
||||
[_sections removeAllObjects];
|
||||
[self.mutableSections removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)removeSectionIdenticalTo:(RETableViewSection *)section inRange:(NSRange)range
|
||||
{
|
||||
[_sections removeObjectIdenticalTo:section inRange:range];
|
||||
[self.mutableSections removeObjectIdenticalTo:section inRange:range];
|
||||
}
|
||||
|
||||
- (void)removeSectionIdenticalTo:(RETableViewSection *)section
|
||||
{
|
||||
[_sections removeObjectIdenticalTo:section];
|
||||
[self.mutableSections removeObjectIdenticalTo:section];
|
||||
}
|
||||
|
||||
- (void)removeSectionsInArray:(NSArray *)otherArray
|
||||
{
|
||||
[_sections removeObjectsInArray:otherArray];
|
||||
[self.mutableSections removeObjectsInArray:otherArray];
|
||||
}
|
||||
|
||||
- (void)removeSectionsInRange:(NSRange)range
|
||||
{
|
||||
[_sections removeObjectsInRange:range];
|
||||
[self.mutableSections removeObjectsInRange:range];
|
||||
}
|
||||
|
||||
- (void)removeSection:(RETableViewSection *)section inRange:(NSRange)range
|
||||
{
|
||||
[_sections removeObject:section inRange:range];
|
||||
[self.mutableSections removeObject:section inRange:range];
|
||||
}
|
||||
|
||||
- (void)removeLastSection
|
||||
{
|
||||
[_sections removeLastObject];
|
||||
[self.mutableSections removeLastObject];
|
||||
}
|
||||
|
||||
- (void)removeSectionAtIndex:(NSUInteger)index
|
||||
{
|
||||
[_sections removeObjectAtIndex:index];
|
||||
[self.mutableSections removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
- (void)removeSectionsAtIndexes:(NSIndexSet *)indexes
|
||||
{
|
||||
[_sections removeObjectsAtIndexes:indexes];
|
||||
[self.mutableSections removeObjectsAtIndexes:indexes];
|
||||
}
|
||||
|
||||
- (void)replaceSectionAtIndex:(NSUInteger)index withSection:(RETableViewSection *)section
|
||||
{
|
||||
section.tableViewManager = self;
|
||||
[_sections replaceObjectAtIndex:index withObject:section];
|
||||
[self.mutableSections replaceObjectAtIndex:index withObject:section];
|
||||
}
|
||||
|
||||
- (void)replaceSectionsWithSectionsFromArray:(NSArray *)otherArray
|
||||
@@ -850,34 +899,52 @@ BOOL REDeviceIsUIKit7() {
|
||||
{
|
||||
for (RETableViewSection *section in sections)
|
||||
section.tableViewManager = self;
|
||||
[_sections replaceObjectsAtIndexes:indexes withObjects:sections];
|
||||
[self.mutableSections replaceObjectsAtIndexes:indexes withObjects:sections];
|
||||
}
|
||||
|
||||
- (void)replaceSectionsInRange:(NSRange)range withSectionsFromArray:(NSArray *)otherArray range:(NSRange)otherRange
|
||||
{
|
||||
for (RETableViewSection *section in otherArray)
|
||||
section.tableViewManager = self;
|
||||
[_sections replaceObjectsInRange:range withObjectsFromArray:otherArray range:otherRange];
|
||||
[self.mutableSections replaceObjectsInRange:range withObjectsFromArray:otherArray range:otherRange];
|
||||
}
|
||||
|
||||
- (void)replaceSectionsInRange:(NSRange)range withSectionsFromArray:(NSArray *)otherArray
|
||||
{
|
||||
[_sections replaceObjectsInRange:range withObjectsFromArray:otherArray];
|
||||
[self.mutableSections replaceObjectsInRange:range withObjectsFromArray:otherArray];
|
||||
}
|
||||
|
||||
- (void)exchangeSectionAtIndex:(NSUInteger)idx1 withSectionAtIndex:(NSUInteger)idx2
|
||||
{
|
||||
[_sections exchangeObjectAtIndex:idx1 withObjectAtIndex:idx2];
|
||||
[self.mutableSections exchangeObjectAtIndex:idx1 withObjectAtIndex:idx2];
|
||||
}
|
||||
|
||||
- (void)sortSectionsUsingFunction:(NSInteger (*)(id, id, void *))compare context:(void *)context
|
||||
{
|
||||
[_sections sortUsingFunction:compare context:context];
|
||||
[self.mutableSections sortUsingFunction:compare context:context];
|
||||
}
|
||||
|
||||
- (void)sortSectionsUsingSelector:(SEL)comparator
|
||||
{
|
||||
[_sections sortUsingSelector:comparator];
|
||||
[self.mutableSections sortUsingSelector:comparator];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Checking for errors
|
||||
|
||||
- (NSArray *)errors
|
||||
{
|
||||
NSMutableArray *errors;
|
||||
for (RETableViewSection *section in self.mutableSections) {
|
||||
NSArray *sectionErrors = section.errors;
|
||||
if (sectionErrors) {
|
||||
if (!errors) {
|
||||
errors = [[NSMutableArray alloc] init];
|
||||
}
|
||||
[errors addObjectsFromArray:sectionErrors];
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
@interface RETableViewOptionsController ()
|
||||
|
||||
@property (strong, readwrite, nonatomic) RETableViewManager *tableViewManager;
|
||||
@property (strong, readwrite, nonatomic) RETableViewSection *mainSection;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RETableViewOptionsController
|
||||
@@ -51,12 +54,12 @@
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
_tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView delegate:self.delegate];
|
||||
_mainSection = [[RETableViewSection alloc] init];
|
||||
[_tableViewManager addSection:_mainSection];
|
||||
self.tableViewManager = [[RETableViewManager alloc] initWithTableView:self.tableView delegate:self.delegate];
|
||||
self.mainSection = [[RETableViewSection alloc] init];
|
||||
[self.tableViewManager addSection:self.mainSection];
|
||||
|
||||
if (self.style)
|
||||
_tableViewManager.style = self.style;
|
||||
self.tableViewManager.style = self.style;
|
||||
|
||||
__typeof (&*self) __weak weakSelf = self;
|
||||
void (^refreshItems)(void) = ^{
|
||||
@@ -84,9 +87,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
[_mainSection addItem:[RETableViewItem itemWithTitle:title accessoryType:accessoryType selectionHandler:^(RETableViewItem *selectedItem) {
|
||||
[self.mainSection addItem:[RETableViewItem itemWithTitle:title accessoryType:accessoryType selectionHandler:^(RETableViewItem *selectedItem) {
|
||||
UITableViewCell *cell = [weakSelf.tableView cellForRowAtIndexPath:selectedItem.indexPath];
|
||||
if (!weakSelf.multipleChoice) {
|
||||
for (NSIndexPath *indexPath in [weakSelf.tableView indexPathsForVisibleRows]) {
|
||||
UITableViewCell *cell = [weakSelf.tableView cellForRowAtIndexPath:indexPath];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
for (RETableViewItem *item in weakSelf.mainSection.items) {
|
||||
item.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
selectedItem.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
RERadioItem * __weak item = (RERadioItem *)weakSelf.item;
|
||||
item.value = selectedItem.title;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/**
|
||||
An array of section items (rows).
|
||||
*/
|
||||
@property (strong, readwrite, nonatomic) NSMutableArray *items;
|
||||
@property (strong, readonly, nonatomic) NSArray *items;
|
||||
|
||||
/**
|
||||
The title of the header of the specified section of the table view.
|
||||
@@ -344,4 +344,10 @@
|
||||
*/
|
||||
- (void)reloadSectionWithAnimation:(UITableViewRowAnimation)animation;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Checking for Validation Errors
|
||||
///-----------------------------
|
||||
|
||||
@property (strong, readonly, nonatomic) NSArray *errors;
|
||||
|
||||
@end
|
||||
@@ -26,6 +26,12 @@
|
||||
#import "RETableViewSection.h"
|
||||
#import "RETableViewManager.h"
|
||||
|
||||
@interface RETableViewSection ()
|
||||
|
||||
@property (strong, readwrite, nonatomic) NSMutableArray *mutableItems;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RETableViewSection
|
||||
|
||||
#pragma mark -
|
||||
@@ -62,7 +68,7 @@
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
_items = [[NSMutableArray alloc] init];
|
||||
self.mutableItems = [[NSMutableArray alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -121,7 +127,7 @@
|
||||
- (CGFloat)maximumTitleWidthWithFont:(UIFont *)font
|
||||
{
|
||||
CGFloat width = 0;
|
||||
for (RETableViewItem *item in self.items) {
|
||||
for (RETableViewItem *item in self.mutableItems) {
|
||||
if ([item isMemberOfClass:[RETextItem class]] || [item isMemberOfClass:[REDateTimeItem class]] || [item isMemberOfClass:[RENumberItem class]]) {
|
||||
CGSize size = [item.title sizeWithFont:font];
|
||||
width = MAX(width, size.width);
|
||||
@@ -133,12 +139,17 @@
|
||||
#pragma mark -
|
||||
#pragma mark Managing items
|
||||
|
||||
- (NSArray *)items
|
||||
{
|
||||
return self.mutableItems;
|
||||
}
|
||||
|
||||
- (void)addItem:(id)item
|
||||
{
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items addObject:item];
|
||||
[self.mutableItems addObject:item];
|
||||
}
|
||||
|
||||
- (void)addItemsFromArray:(NSArray *)array
|
||||
@@ -147,7 +158,7 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items addObjectsFromArray:array];
|
||||
[self.mutableItems addObjectsFromArray:array];
|
||||
}
|
||||
|
||||
- (void)insertItem:(id)item atIndex:(NSUInteger)index
|
||||
@@ -155,7 +166,7 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items insertObject:item atIndex:index];
|
||||
[self.mutableItems insertObject:item atIndex:index];
|
||||
}
|
||||
|
||||
- (void)insertItems:(NSArray *)items atIndexes:(NSIndexSet *)indexes
|
||||
@@ -164,57 +175,57 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items insertObjects:items atIndexes:indexes];
|
||||
[self.mutableItems insertObjects:items atIndexes:indexes];
|
||||
}
|
||||
|
||||
- (void)removeItem:(id)item inRange:(NSRange)range
|
||||
{
|
||||
[_items removeObject:item inRange:range];
|
||||
[self.mutableItems removeObject:item inRange:range];
|
||||
}
|
||||
|
||||
- (void)removeLastItem
|
||||
{
|
||||
[_items removeLastObject];
|
||||
[self.mutableItems removeLastObject];
|
||||
}
|
||||
|
||||
- (void)removeItemAtIndex:(NSUInteger)index
|
||||
{
|
||||
[_items removeObjectAtIndex:index];
|
||||
[self.mutableItems removeObjectAtIndex:index];
|
||||
}
|
||||
|
||||
- (void)removeItem:(id)item
|
||||
{
|
||||
[_items removeObject:item];
|
||||
[self.mutableItems removeObject:item];
|
||||
}
|
||||
|
||||
- (void)removeAllItems
|
||||
{
|
||||
[_items removeAllObjects];
|
||||
[self.mutableItems removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)removeItemIdenticalTo:(id)item inRange:(NSRange)range
|
||||
{
|
||||
[_items removeObjectIdenticalTo:item inRange:range];
|
||||
[self.mutableItems removeObjectIdenticalTo:item inRange:range];
|
||||
}
|
||||
|
||||
- (void)removeItemIdenticalTo:(id)item
|
||||
{
|
||||
[_items removeObjectIdenticalTo:item];
|
||||
[self.mutableItems removeObjectIdenticalTo:item];
|
||||
}
|
||||
|
||||
- (void)removeItemsInArray:(NSArray *)otherArray
|
||||
{
|
||||
[_items removeObjectsInArray:otherArray];
|
||||
[self.mutableItems removeObjectsInArray:otherArray];
|
||||
}
|
||||
|
||||
- (void)removeItemsInRange:(NSRange)range
|
||||
{
|
||||
[_items removeObjectsInRange:range];
|
||||
[self.mutableItems removeObjectsInRange:range];
|
||||
}
|
||||
|
||||
- (void)removeItemsAtIndexes:(NSIndexSet *)indexes
|
||||
{
|
||||
[_items removeObjectsAtIndexes:indexes];
|
||||
[self.mutableItems removeObjectsAtIndexes:indexes];
|
||||
}
|
||||
|
||||
- (void)replaceItemAtIndex:(NSUInteger)index withItem:(id)item
|
||||
@@ -222,7 +233,7 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items replaceObjectAtIndex:index withObject:item];
|
||||
[self.mutableItems replaceObjectAtIndex:index withObject:item];
|
||||
}
|
||||
|
||||
- (void)replaceItemsWithItemsFromArray:(NSArray *)otherArray
|
||||
@@ -237,7 +248,7 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items replaceObjectsInRange:range withObjectsFromArray:otherArray range:otherRange];
|
||||
[self.mutableItems replaceObjectsInRange:range withObjectsFromArray:otherArray range:otherRange];
|
||||
}
|
||||
|
||||
- (void)replaceItemsInRange:(NSRange)range withItemsFromArray:(NSArray *)otherArray
|
||||
@@ -246,7 +257,7 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items replaceObjectsInRange:range withObjectsFromArray:otherArray];
|
||||
[self.mutableItems replaceObjectsInRange:range withObjectsFromArray:otherArray];
|
||||
}
|
||||
|
||||
- (void)replaceItemsAtIndexes:(NSIndexSet *)indexes withItems:(NSArray *)items
|
||||
@@ -255,22 +266,22 @@
|
||||
if ([item isKindOfClass:[RETableViewItem class]])
|
||||
((RETableViewItem *)item).section = self;
|
||||
|
||||
[_items replaceObjectsAtIndexes:indexes withObjects:items];
|
||||
[self.mutableItems replaceObjectsAtIndexes:indexes withObjects:items];
|
||||
}
|
||||
|
||||
- (void)exchangeItemAtIndex:(NSUInteger)idx1 withItemAtIndex:(NSUInteger)idx2
|
||||
{
|
||||
[_items exchangeObjectAtIndex:idx1 withObjectAtIndex:idx2];
|
||||
[self.mutableItems exchangeObjectAtIndex:idx1 withObjectAtIndex:idx2];
|
||||
}
|
||||
|
||||
- (void)sortItemsUsingFunction:(NSInteger (*)(id, id, void *))compare context:(void *)context
|
||||
{
|
||||
[_items sortUsingFunction:compare context:context];
|
||||
[self.mutableItems sortUsingFunction:compare context:context];
|
||||
}
|
||||
|
||||
- (void)sortItemsUsingSelector:(SEL)comparator
|
||||
{
|
||||
[_items sortUsingSelector:comparator];
|
||||
[self.mutableItems sortUsingSelector:comparator];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -281,4 +292,25 @@
|
||||
[self.tableViewManager.tableView reloadSections:[NSIndexSet indexSetWithIndex:self.index] withRowAnimation:animation];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Checking for errors
|
||||
|
||||
- (NSArray *)errors
|
||||
{
|
||||
NSMutableArray *errors;
|
||||
for (RETableViewItem *item in self.mutableItems) {
|
||||
if ([item respondsToSelector:@selector(errors)]) {
|
||||
NSArray *itemErrors = item.errors;
|
||||
if (itemErrors) {
|
||||
if (!errors) {
|
||||
errors = [[NSMutableArray alloc] init];
|
||||
}
|
||||
if (itemErrors.count > 0)
|
||||
[errors addObject:itemErrors[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,6 +39,14 @@
|
||||
30939CF317949A10004D95A9 /* userpic5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 30939CE717949A10004D95A9 /* userpic5.jpg */; };
|
||||
30939CF417949A10004D95A9 /* userpic6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 30939CE817949A10004D95A9 /* userpic6.jpg */; };
|
||||
30939CF917949B2D004D95A9 /* REFormattedNumberField.m in Sources */ = {isa = PBXBuildFile; fileRef = 30939CF817949B2D004D95A9 /* REFormattedNumberField.m */; };
|
||||
30B00D5E17C56EEF0010D439 /* NSError+REValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5217C56EEF0010D439 /* NSError+REValidation.m */; };
|
||||
30B00D5F17C56EEF0010D439 /* REValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5417C56EEF0010D439 /* REValidation.m */; };
|
||||
30B00D6017C56EEF0010D439 /* REValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5617C56EEF0010D439 /* REValidator.m */; };
|
||||
30B00D6117C56EEF0010D439 /* REEmailValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5917C56EEF0010D439 /* REEmailValidator.m */; };
|
||||
30B00D6217C56EEF0010D439 /* RELengthValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5B17C56EEF0010D439 /* RELengthValidator.m */; };
|
||||
30B00D6317C56EEF0010D439 /* REPresenceValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D5D17C56EEF0010D439 /* REPresenceValidator.m */; };
|
||||
30B00D7A17C667A90010D439 /* ValidationsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00D7917C667A90010D439 /* ValidationsViewController.m */; };
|
||||
30B00DEE17D8E9CE0010D439 /* REURLValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B00DED17D8E90D0010D439 /* REURLValidator.m */; };
|
||||
30D1C7D617AC08F4001F731C /* First_Alt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30D1C7D217AC08F3001F731C /* First_Alt@2x.png */; };
|
||||
30D1C7D717AC08F4001F731C /* Last_Alt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30D1C7D317AC08F3001F731C /* Last_Alt@2x.png */; };
|
||||
30D1C7D817AC08F4001F731C /* Middle_Alt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30D1C7D417AC08F3001F731C /* Middle_Alt@2x.png */; };
|
||||
@@ -135,6 +143,22 @@
|
||||
30939CE817949A10004D95A9 /* userpic6.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = userpic6.jpg; sourceTree = "<group>"; };
|
||||
30939CF717949B2D004D95A9 /* REFormattedNumberField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = REFormattedNumberField.h; sourceTree = "<group>"; };
|
||||
30939CF817949B2D004D95A9 /* REFormattedNumberField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = REFormattedNumberField.m; sourceTree = "<group>"; };
|
||||
30B00D5117C56EEF0010D439 /* NSError+REValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+REValidation.h"; sourceTree = "<group>"; };
|
||||
30B00D5217C56EEF0010D439 /* NSError+REValidation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+REValidation.m"; sourceTree = "<group>"; };
|
||||
30B00D5317C56EEF0010D439 /* REValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = REValidation.h; sourceTree = "<group>"; };
|
||||
30B00D5417C56EEF0010D439 /* REValidation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = REValidation.m; sourceTree = "<group>"; };
|
||||
30B00D5517C56EEF0010D439 /* REValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = REValidator.h; sourceTree = "<group>"; };
|
||||
30B00D5617C56EEF0010D439 /* REValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = REValidator.m; sourceTree = "<group>"; };
|
||||
30B00D5817C56EEF0010D439 /* REEmailValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = REEmailValidator.h; sourceTree = "<group>"; };
|
||||
30B00D5917C56EEF0010D439 /* REEmailValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = REEmailValidator.m; sourceTree = "<group>"; };
|
||||
30B00D5A17C56EEF0010D439 /* RELengthValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RELengthValidator.h; sourceTree = "<group>"; };
|
||||
30B00D5B17C56EEF0010D439 /* RELengthValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RELengthValidator.m; sourceTree = "<group>"; };
|
||||
30B00D5C17C56EEF0010D439 /* REPresenceValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = REPresenceValidator.h; sourceTree = "<group>"; };
|
||||
30B00D5D17C56EEF0010D439 /* REPresenceValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = REPresenceValidator.m; sourceTree = "<group>"; };
|
||||
30B00D7817C667A90010D439 /* ValidationsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationsViewController.h; sourceTree = "<group>"; };
|
||||
30B00D7917C667A90010D439 /* ValidationsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ValidationsViewController.m; sourceTree = "<group>"; };
|
||||
30B00DEC17D8E90D0010D439 /* REURLValidator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = REURLValidator.h; sourceTree = "<group>"; };
|
||||
30B00DED17D8E90D0010D439 /* REURLValidator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = REURLValidator.m; sourceTree = "<group>"; };
|
||||
30D1C7D217AC08F3001F731C /* First_Alt@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "First_Alt@2x.png"; path = "Resources/First_Alt@2x.png"; sourceTree = "<group>"; };
|
||||
30D1C7D317AC08F3001F731C /* Last_Alt@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Last_Alt@2x.png"; path = "Resources/Last_Alt@2x.png"; sourceTree = "<group>"; };
|
||||
30D1C7D417AC08F3001F731C /* Middle_Alt@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Middle_Alt@2x.png"; path = "Resources/Middle_Alt@2x.png"; sourceTree = "<group>"; };
|
||||
@@ -250,6 +274,8 @@
|
||||
303D967117B7CDE300A418F3 /* XIBTestViewController.m */,
|
||||
30E5F50A17BBD163005CF1FE /* IndexedListViewController.h */,
|
||||
30E5F50B17BBD163005CF1FE /* IndexedListViewController.m */,
|
||||
30B00D7817C667A90010D439 /* ValidationsViewController.h */,
|
||||
30B00D7917C667A90010D439 /* ValidationsViewController.m */,
|
||||
);
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
@@ -301,6 +327,7 @@
|
||||
30939CF517949B2D004D95A9 /* Vendor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
30B00D5017C56EEF0010D439 /* REValidation */,
|
||||
30939CF617949B2D004D95A9 /* REFormattedNumberField */,
|
||||
);
|
||||
path = Vendor;
|
||||
@@ -315,6 +342,35 @@
|
||||
path = REFormattedNumberField;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
30B00D5017C56EEF0010D439 /* REValidation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
30B00D5117C56EEF0010D439 /* NSError+REValidation.h */,
|
||||
30B00D5217C56EEF0010D439 /* NSError+REValidation.m */,
|
||||
30B00D5317C56EEF0010D439 /* REValidation.h */,
|
||||
30B00D5417C56EEF0010D439 /* REValidation.m */,
|
||||
30B00D5517C56EEF0010D439 /* REValidator.h */,
|
||||
30B00D5617C56EEF0010D439 /* REValidator.m */,
|
||||
30B00D5717C56EEF0010D439 /* Validators */,
|
||||
);
|
||||
path = REValidation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
30B00D5717C56EEF0010D439 /* Validators */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
30B00D5817C56EEF0010D439 /* REEmailValidator.h */,
|
||||
30B00D5917C56EEF0010D439 /* REEmailValidator.m */,
|
||||
30B00D5A17C56EEF0010D439 /* RELengthValidator.h */,
|
||||
30B00D5B17C56EEF0010D439 /* RELengthValidator.m */,
|
||||
30B00D5C17C56EEF0010D439 /* REPresenceValidator.h */,
|
||||
30B00D5D17C56EEF0010D439 /* REPresenceValidator.m */,
|
||||
30B00DEC17D8E90D0010D439 /* REURLValidator.h */,
|
||||
30B00DED17D8E90D0010D439 /* REURLValidator.m */,
|
||||
);
|
||||
path = Validators;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
30DB064616E934AD006C9530 /* RETableViewManager */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -593,6 +649,14 @@
|
||||
303D966B17B7CCF800A418F3 /* XIBTestCell.m in Sources */,
|
||||
303D967217B7CDE300A418F3 /* XIBTestViewController.m in Sources */,
|
||||
30E5F50C17BBD163005CF1FE /* IndexedListViewController.m in Sources */,
|
||||
30B00D5E17C56EEF0010D439 /* NSError+REValidation.m in Sources */,
|
||||
30B00D5F17C56EEF0010D439 /* REValidation.m in Sources */,
|
||||
30B00D6017C56EEF0010D439 /* REValidator.m in Sources */,
|
||||
30B00D6117C56EEF0010D439 /* REEmailValidator.m in Sources */,
|
||||
30B00DEE17D8E9CE0010D439 /* REURLValidator.m in Sources */,
|
||||
30B00D6217C56EEF0010D439 /* RELengthValidator.m in Sources */,
|
||||
30B00D6317C56EEF0010D439 /* REPresenceValidator.m in Sources */,
|
||||
30B00D7A17C667A90010D439 /* ValidationsViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:sectionTitle];
|
||||
section.indexTitle = sectionTitle; // assign index title
|
||||
|
||||
// Add 5 items with name `section title + item index`
|
||||
//
|
||||
for (NSInteger i = 1; i <= 5; i++)
|
||||
[section addItem:[NSString stringWithFormat:@"%@%i", sectionTitle, i]];
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#import "StylingViewController.h"
|
||||
#import "XIBTestViewController.h"
|
||||
#import "IndexedListViewController.h"
|
||||
#import "ValidationsViewController.h"
|
||||
|
||||
@interface RootViewController ()
|
||||
|
||||
@@ -71,6 +72,11 @@
|
||||
[item deselectRowAnimated:YES];
|
||||
[weakSelf.navigationController pushViewController:[[IndexedListViewController alloc] initWithStyle:UITableViewStylePlain] animated:YES];
|
||||
}]];
|
||||
|
||||
[section addItem:[RETableViewItem itemWithTitle:@"Validations" accessoryType:UITableViewCellAccessoryDisclosureIndicator selectionHandler:^(RETableViewItem *item) {
|
||||
[item deselectRowAnimated:YES];
|
||||
[weakSelf.navigationController pushViewController:[[ValidationsViewController alloc] initWithStyle:UITableViewStyleGrouped] animated:YES];
|
||||
}]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// ValidationsViewController.h
|
||||
// RETableViewManagerExample
|
||||
//
|
||||
// Created by Roman Efimov on 8/22/13.
|
||||
// Copyright (c) 2013 Roman Efimov. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "RETableViewManager.h"
|
||||
|
||||
@interface ValidationsViewController : UITableViewController
|
||||
|
||||
@property (strong, readonly, nonatomic) RETableViewManager *manager;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// ValidationsViewController.m
|
||||
// RETableViewManagerExample
|
||||
//
|
||||
// Created by Roman Efimov on 8/22/13.
|
||||
// Copyright (c) 2013 Roman Efimov. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ValidationsViewController.h"
|
||||
|
||||
@interface ValidationsViewController ()
|
||||
|
||||
@property (strong, readwrite, nonatomic) RETextItem *textItem;
|
||||
@property (strong, readwrite, nonatomic) RETextItem *emailItem;
|
||||
@property (strong, readwrite, nonatomic) RETextItem *urlItem;
|
||||
@property (strong, readwrite, nonatomic) RETextItem *inlineTestItem;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ValidationsViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
self.title = @"Controls";
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Validate" style:UIBarButtonItemStyleBordered target:self action:@selector(validateButtonPressed:)];
|
||||
|
||||
// Create manager
|
||||
//
|
||||
_manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
|
||||
|
||||
// Add a section
|
||||
//
|
||||
RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Basic controls"];
|
||||
[_manager addSection:section];
|
||||
|
||||
// Add items
|
||||
//
|
||||
self.textItem = [RETextItem itemWithTitle:@"Text" value:@"" placeholder:@"Text item"];
|
||||
self.textItem.validators = @[@"presence", @"length(3, 10)"];
|
||||
|
||||
self.emailItem = [RETextItem itemWithTitle:@"Email" value:@"" placeholder:@"Email item"];
|
||||
self.emailItem.name = @"Your email";
|
||||
self.emailItem.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
self.emailItem.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
self.emailItem.validators = @[@"presence", @"email"];
|
||||
|
||||
self.urlItem = [RETextItem itemWithTitle:@"URL" value:@"http://invalid-url.co%m" placeholder:@"URL item"];
|
||||
self.urlItem.validators = @[@"url"];
|
||||
|
||||
// Inline Validation Example
|
||||
//
|
||||
REValidator *nameValidator = [REValidator validatorWithInlineValidation:^NSError *(NSString *string, NSString *name) {
|
||||
NSString *cleanString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if ([cleanString componentsSeparatedByString:@" "].count < 2) {
|
||||
return [NSError errorWithDomain:@"" code:0 userInfo:@{ NSLocalizedDescriptionKey: @"Please enter first and last name." }];
|
||||
}
|
||||
return nil;
|
||||
}];
|
||||
self.inlineTestItem = [RETextItem itemWithTitle:@"Name" value:@"" placeholder:@"First & Last Name"];
|
||||
self.inlineTestItem.validators = @[@"presence", nameValidator];
|
||||
|
||||
[section addItem:self.textItem];
|
||||
[section addItem:self.emailItem];
|
||||
[section addItem:self.urlItem];
|
||||
[section addItem:self.inlineTestItem];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Button actions
|
||||
|
||||
- (void)validateButtonPressed:(UIButton *)sender
|
||||
{
|
||||
NSArray *managerErrors = self.manager.errors;
|
||||
if (managerErrors.count > 0) {
|
||||
NSMutableArray *errors = [NSMutableArray array];
|
||||
for (NSError *error in managerErrors) {
|
||||
[errors addObject:error.localizedDescription];
|
||||
}
|
||||
NSString *errorString = [errors componentsJoinedByString:@"\n"];
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Errors" message:errorString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
|
||||
[alert show];
|
||||
} else {
|
||||
NSLog(@"All good, no errors!");
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -24,11 +24,7 @@
|
||||
//
|
||||
_manager = [[RETableViewManager alloc] initWithTableView:self.tableView delegate:self];
|
||||
|
||||
// Register XIB file
|
||||
//
|
||||
[self.tableView registerNib:[UINib nibWithNibName:@"XIBTestCell" bundle:nil] forCellReuseIdentifier:@"XIBTestItem"];
|
||||
|
||||
// Map item to a cell
|
||||
// Map item to a cell, this will also register the XIBTestCell.xib for the XIBTestItem identifier
|
||||
//
|
||||
_manager[@"XIBTestItem"] = @"XIBTestCell";
|
||||
|
||||
@@ -44,9 +40,16 @@
|
||||
selectionHandler:^(RETableViewItem *item) {
|
||||
[item deselectRowAnimated:YES];
|
||||
}];
|
||||
item.cellIdentifier = @"XIBTestItem";
|
||||
[section addItem:item];
|
||||
}
|
||||
|
||||
// Cell is being assigned an automatic identifier
|
||||
//
|
||||
// You can manually set it if you want to:
|
||||
// item.cellIdentifier = @"CustomIdentifier";
|
||||
//
|
||||
// You'll need to register a cell class for it as well:
|
||||
// [self.tableView registerNib:[UINib nibWithNibName:@"XIBTestCell" bundle:nil] forCellReuseIdentifier:@"CustomIdentifier"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
- (void)cellDidLoad
|
||||
{
|
||||
[super cellDidLoad];
|
||||
_pictureView = [[UIImageView alloc] initWithFrame:CGRectMake(7, 0, 306, 306)];
|
||||
_pictureView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
[self addSubview:_pictureView];
|
||||
|
||||
32
RETableViewManagerExample/Vendor/REValidation/NSError+REValidation.h
vendored
Normal file
32
RETableViewManagerExample/Vendor/REValidation/NSError+REValidation.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// NSError+REValidation.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSError (REValidation)
|
||||
|
||||
+ (NSError *)re_validationErrorForDomain:(NSString *)domain, ...;
|
||||
|
||||
@end
|
||||
40
RETableViewManagerExample/Vendor/REValidation/NSError+REValidation.m
vendored
Normal file
40
RETableViewManagerExample/Vendor/REValidation/NSError+REValidation.m
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// NSError+REValidation.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "NSError+REValidation.h"
|
||||
#import "REValidation.h"
|
||||
|
||||
@implementation NSError (REValidation)
|
||||
|
||||
+ (NSError *)re_validationErrorForDomain:(NSString *)domain, ...
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, domain);
|
||||
NSError *error = [NSError errorWithDomain:domain code:0 userInfo:@{ NSLocalizedDescriptionKey:[[NSString alloc] initWithFormat:[REValidation errorMessageForDomain:domain] arguments:args] }];
|
||||
va_end(args);
|
||||
return error;
|
||||
}
|
||||
|
||||
@end
|
||||
60
RETableViewManagerExample/Vendor/REValidation/REValidation.h
vendored
Normal file
60
RETableViewManagerExample/Vendor/REValidation/REValidation.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// REValidation.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "REValidator.h"
|
||||
#import "NSError+REValidation.h"
|
||||
#import "REPresenceValidator.h"
|
||||
#import "RELengthValidator.h"
|
||||
#import "REEmailValidator.h"
|
||||
#import "REURLValidator.h"
|
||||
|
||||
@interface REValidation : NSObject
|
||||
|
||||
///-----------------------------
|
||||
/// @name Registering Validators
|
||||
///-----------------------------
|
||||
|
||||
+ (void)registerDefaultValidators;
|
||||
+ (void)registerDefaultErrorMessages;
|
||||
+ (void)registerValidator:(Class)validatorClass;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Validating Objects
|
||||
///-----------------------------
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object name:(NSString *)name validatorString:(NSString *)string;
|
||||
+ (NSError *)validateObject:(NSObject *)object name:(NSString *)name validator:(REValidator *)validator;
|
||||
+ (NSArray *)validateObject:(NSObject *)object name:(NSString *)name validators:(NSArray *)validators;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Handling Error Messages
|
||||
///-----------------------------
|
||||
|
||||
+ (NSString *)errorMessageForDomain:(NSString *)domain;
|
||||
+ (void)setErrorMessage:(NSString *)message forDomain:(NSString *)domain;
|
||||
+ (void)setErrorMessages:(NSDictionary *)messages;
|
||||
|
||||
@end
|
||||
146
RETableViewManagerExample/Vendor/REValidation/REValidation.m
vendored
Normal file
146
RETableViewManagerExample/Vendor/REValidation/REValidation.m
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// REValidation.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidation.h"
|
||||
|
||||
@interface REValidation ()
|
||||
|
||||
@property (strong, readwrite, nonatomic) NSMutableDictionary *registeredValidators;
|
||||
@property (strong, readwrite, nonatomic) NSMutableDictionary *errorMessages;
|
||||
|
||||
@end
|
||||
|
||||
@implementation REValidation
|
||||
|
||||
+ (instancetype)sharedObject
|
||||
{
|
||||
static REValidation *_sharedClient = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedClient = [[REValidation alloc] init];
|
||||
});
|
||||
|
||||
return _sharedClient;
|
||||
}
|
||||
|
||||
+ (void)registerValidator:(Class)validatorClass
|
||||
{
|
||||
[REValidation sharedObject].registeredValidators[[validatorClass name]] = NSStringFromClass(validatorClass);
|
||||
}
|
||||
|
||||
+ (void)registerDefaultValidators
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[REValidation registerValidator:[REPresenceValidator class]];
|
||||
[REValidation registerValidator:[RELengthValidator class]];
|
||||
[REValidation registerValidator:[REEmailValidator class]];
|
||||
[REValidation registerValidator:[REURLValidator class]];
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)registerDefaultErrorMessages
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSDictionary *messages = @{
|
||||
@"com.REValidation.presence": @"%@ can't be blank.",
|
||||
@"com.REValidation.minimumLength": @"%@ is too short (minimum is %i characters).",
|
||||
@"com.REValidation.maximumLength": @"%@ is too long (maximum is %i characters).",
|
||||
@"com.REValidation.email": @"%@ is not a valid email.",
|
||||
@"com.REValidation.url": @"%@ is not a valid url."
|
||||
};
|
||||
[REValidation sharedObject].errorMessages = [NSMutableDictionary dictionaryWithDictionary:messages];
|
||||
});
|
||||
}
|
||||
|
||||
+ (NSString *)errorMessageForDomain:(NSString *)domain
|
||||
{
|
||||
return NSLocalizedString([REValidation sharedObject].errorMessages[domain], [REValidation sharedObject].errorMessages[domain]);
|
||||
}
|
||||
|
||||
+ (void)setErrorMessage:(NSString *)message forDomain:(NSString *)domain
|
||||
{
|
||||
[REValidation sharedObject].errorMessages[domain] = message;
|
||||
}
|
||||
|
||||
+ (void)setErrorMessages:(NSDictionary *)messages
|
||||
{
|
||||
[REValidation sharedObject].errorMessages = [NSMutableDictionary dictionaryWithDictionary:messages];
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object name:(NSString *)name validatorString:(NSString *)string
|
||||
{
|
||||
NSString *validatorStringName = [string componentsSeparatedByString:@"("][0];
|
||||
for (NSString *validatorName in [REValidation sharedObject].registeredValidators) {
|
||||
if ([validatorName isEqualToString:validatorStringName]) {
|
||||
Class validator = NSClassFromString([REValidation sharedObject].registeredValidators[validatorName]);
|
||||
return [[validator class] validateObject:object variableName:name parameters:[validator parseParameterString:string]];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object name:(NSString *)name validator:(REValidator *)validator
|
||||
{
|
||||
return [[validator class] validateObject:object variableName:name parameters:validator.parameters];
|
||||
}
|
||||
|
||||
+ (NSArray *)validateObject:(NSObject *)object name:(NSString *)name validators:(NSArray *)validators
|
||||
{
|
||||
NSMutableArray *errors = [NSMutableArray array];
|
||||
|
||||
for (id validator in validators) {
|
||||
NSError *error;
|
||||
if ([validator isKindOfClass:[NSString class]]) {
|
||||
error = [self validateObject:object name:name validatorString:(NSString *)validator];
|
||||
} else {
|
||||
REValidator *v = (REValidator *)validator;
|
||||
if (v.inlineValidation) {
|
||||
error = [[v class] validateObject:object variableName:name validation:v.inlineValidation];
|
||||
} else {
|
||||
error = [self validateObject:object name:name validator:validator];
|
||||
}
|
||||
}
|
||||
if (error)
|
||||
[errors addObject:error];
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
self.registeredValidators = [[NSMutableDictionary alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
55
RETableViewManagerExample/Vendor/REValidation/REValidator.h
vendored
Normal file
55
RETableViewManagerExample/Vendor/REValidation/REValidator.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// REValidator.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface REValidator : NSObject
|
||||
|
||||
@property (strong, readonly, nonatomic) NSDictionary *parameters;
|
||||
@property (copy, readwrite, nonatomic) NSError *(^inlineValidation)(id object, NSString *name);
|
||||
|
||||
///-----------------------------
|
||||
/// @name Getting Validator Instance
|
||||
///-----------------------------
|
||||
|
||||
+ (instancetype)validator;
|
||||
+ (instancetype)validatorWithParameters:(NSDictionary *)parameters;
|
||||
+ (instancetype)validatorWithInlineValidation:(NSError *(^)(id object, NSString *name))validation;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Configuring Representation
|
||||
///-----------------------------
|
||||
|
||||
+ (NSString *)name;
|
||||
+ (NSDictionary *)parseParameterString:(NSString *)string;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Validating Objects
|
||||
///-----------------------------
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters;
|
||||
+ (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name validation:(NSError *(^)(id object, NSString *name))validation;
|
||||
|
||||
@end
|
||||
77
RETableViewManagerExample/Vendor/REValidation/REValidator.m
vendored
Normal file
77
RETableViewManagerExample/Vendor/REValidation/REValidator.m
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// REValidator.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidator.h"
|
||||
|
||||
@interface REValidator ()
|
||||
|
||||
@property (strong, readwrite, nonatomic) NSDictionary *parameters;
|
||||
|
||||
@end
|
||||
|
||||
@implementation REValidator
|
||||
|
||||
+ (instancetype)validator
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
+ (instancetype)validatorWithParameters:(NSDictionary *)parameters
|
||||
{
|
||||
REValidator *validator = [[self alloc] init];
|
||||
validator.parameters = parameters;
|
||||
return validator;
|
||||
}
|
||||
|
||||
+ (instancetype)validatorWithInlineValidation:(NSError *(^)(id object, NSString *name))validation
|
||||
{
|
||||
REValidator *validator = [[self alloc] init];
|
||||
validator.inlineValidation = validation;
|
||||
return validator;
|
||||
}
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name validation:(NSError *(^)(id object, NSString *name))validation
|
||||
{
|
||||
if (validation)
|
||||
return validation(object, name);
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)parseParameterString:(NSString *)string
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
30
RETableViewManagerExample/Vendor/REValidation/Validators/REEmailValidator.h
vendored
Normal file
30
RETableViewManagerExample/Vendor/REValidation/Validators/REEmailValidator.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// REEmailValidator.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidator.h"
|
||||
|
||||
@interface REEmailValidator : REValidator
|
||||
|
||||
@end
|
||||
52
RETableViewManagerExample/Vendor/REValidation/Validators/REEmailValidator.m
vendored
Normal file
52
RETableViewManagerExample/Vendor/REValidation/Validators/REEmailValidator.m
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// REEmailValidator.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REEmailValidator.h"
|
||||
#import "REValidation.h"
|
||||
|
||||
@implementation REEmailValidator
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"email";
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters
|
||||
{
|
||||
NSString *string = object ? object : @"";
|
||||
if (string.length == 0)
|
||||
return nil;
|
||||
|
||||
NSError *error = NULL;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" options:NSRegularExpressionCaseInsensitive error:&error];
|
||||
NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
|
||||
|
||||
if (!match)
|
||||
return [NSError re_validationErrorForDomain:@"com.REValidation.email", name];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
30
RETableViewManagerExample/Vendor/REValidation/Validators/RELengthValidator.h
vendored
Normal file
30
RETableViewManagerExample/Vendor/REValidation/Validators/RELengthValidator.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// RELengthValidator.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidator.h"
|
||||
|
||||
@interface RELengthValidator : REValidator
|
||||
|
||||
@end
|
||||
67
RETableViewManagerExample/Vendor/REValidation/Validators/RELengthValidator.m
vendored
Normal file
67
RETableViewManagerExample/Vendor/REValidation/Validators/RELengthValidator.m
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// RELengthValidator.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "RELengthValidator.h"
|
||||
#import "NSError+REValidation.h"
|
||||
|
||||
@implementation RELengthValidator
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"length";
|
||||
}
|
||||
|
||||
+ (NSDictionary *)parseParameterString:(NSString *)string
|
||||
{
|
||||
NSError *error = NULL;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d+)" options:0 error:&error];
|
||||
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
|
||||
NSMutableArray *results = [NSMutableArray array];
|
||||
for (NSTextCheckingResult *matchResult in matches) {
|
||||
NSString *match = [string substringWithRange:[matchResult range]];
|
||||
[results addObject:match];
|
||||
}
|
||||
if (results.count == 2) {
|
||||
return @{ @"min": results[0], @"max": results[1]};
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters
|
||||
{
|
||||
NSUInteger minimumValue = [parameters[@"min"] integerValue];
|
||||
NSUInteger maximumValue = [parameters[@"max"] integerValue];
|
||||
|
||||
if (object.length < minimumValue && minimumValue > 0)
|
||||
return [NSError re_validationErrorForDomain:@"com.REValidation.minimumLength", name, minimumValue];
|
||||
|
||||
if (object.length > maximumValue && maximumValue > 0)
|
||||
return [NSError re_validationErrorForDomain:@"com.REValidation.maximumLength", name, maximumValue];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
30
RETableViewManagerExample/Vendor/REValidation/Validators/REPresenceValidator.h
vendored
Normal file
30
RETableViewManagerExample/Vendor/REValidation/Validators/REPresenceValidator.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// REPresenceValidator.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidator.h"
|
||||
|
||||
@interface REPresenceValidator : REValidator
|
||||
|
||||
@end
|
||||
44
RETableViewManagerExample/Vendor/REValidation/Validators/REPresenceValidator.m
vendored
Normal file
44
RETableViewManagerExample/Vendor/REValidation/Validators/REPresenceValidator.m
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// REPresenceValidator.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REPresenceValidator.h"
|
||||
#import "NSError+REValidation.h"
|
||||
|
||||
@implementation REPresenceValidator
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"presence";
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters
|
||||
{
|
||||
if (![object isKindOfClass:[NSString class]] || object.length == 0)
|
||||
return [NSError re_validationErrorForDomain:@"com.REValidation.presence", name];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
30
RETableViewManagerExample/Vendor/REValidation/Validators/REURLValidator.h
vendored
Normal file
30
RETableViewManagerExample/Vendor/REValidation/Validators/REURLValidator.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// REURLValidator.h
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REValidator.h"
|
||||
|
||||
@interface REURLValidator : REValidator
|
||||
|
||||
@end
|
||||
51
RETableViewManagerExample/Vendor/REValidation/Validators/REURLValidator.m
vendored
Normal file
51
RETableViewManagerExample/Vendor/REValidation/Validators/REURLValidator.m
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// REURLValidator.m
|
||||
// REValidation
|
||||
//
|
||||
// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "REURLValidator.h"
|
||||
#import "REValidation.h"
|
||||
|
||||
@implementation REURLValidator
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"url";
|
||||
}
|
||||
|
||||
+ (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters
|
||||
{
|
||||
NSString *string = object ? object : @"";
|
||||
if (string.length == 0)
|
||||
return nil;
|
||||
|
||||
NSError *error = NULL;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(?i)(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$" options:NSRegularExpressionCaseInsensitive error:&error];
|
||||
NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
|
||||
if (!match)
|
||||
return [NSError re_validationErrorForDomain:@"com.REValidation.url", name];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user