Skip to content
This repository has been archived by the owner on Aug 24, 2020. It is now read-only.

Commit

Permalink
2.0.1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
davdroman committed Jun 28, 2015
1 parent 6c2bc36 commit 7767101
Show file tree
Hide file tree
Showing 23 changed files with 117 additions and 82 deletions.
4 changes: 2 additions & 2 deletions Bohr.podspec
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Pod::Spec.new do |s|
s.name = "Bohr"
s.version = "2.0.0"
s.version = "2.0.1"
s.summary = "Settings screen composing framework"
s.homepage = "https://github.com/DavdRoman/Bohr"
s.author = { "David Roman" => "d@vidroman.me" }
s.author = { "David Román" => "d@vidroman.me" }
s.license = { :type => 'MIT', :file => 'LICENSE' }

s.platform = :ios, '8.0'
Expand Down
4 changes: 4 additions & 0 deletions Bohr/BOButtonTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@

@interface BOButtonTableViewCell : BOTableViewCell

/// The target of the cell action.
@property (nonatomic) id target;

/// The action defined by the cell, triggered when it's tapped.
@property (nonatomic) SEL action;

/// Sets both the target and action for the cell to be performed.
- (void)setTarget:(id)target action:(SEL)action;

@end
2 changes: 0 additions & 2 deletions Bohr/BOButtonTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ - (void)setup {
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

- (void)wasSelectedFromViewController:(BOTableViewController *)viewController {
[super wasSelectedFromViewController:viewController];

if ([self.target respondsToSelector:self.action]) {
[self.target performSelector:self.action];
}
Expand Down
2 changes: 2 additions & 0 deletions Bohr/BOChoiceTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

@interface BOChoiceTableViewCell : BOTableViewCell

/// An array defining (in short) all the options availables on the cell.
@property (nonatomic, strong) NSArray *options;

/// An array defining all the footer titles for each option assigned to the cell.
@property (nonatomic, strong) IBInspectable NSArray *footerTitles;

@end
2 changes: 0 additions & 2 deletions Bohr/BOChoiceTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ - (NSString *)footerTitle {
}

- (void)wasSelectedFromViewController:(BOTableViewController *)viewController {
[super wasSelectedFromViewController:viewController];

if (self.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
NSInteger currentOption = [self.setting.value integerValue];

Expand Down
3 changes: 2 additions & 1 deletion Bohr/BOOptionTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
// Bohr
//
// Created by David Román Aguirre on 21/6/15.
//
// Copyright (c) 2015 David Roman. All rights reserved.
//

#import "BOTableViewCell.h"

@interface BOOptionTableViewCell : BOTableViewCell

/// The string for the footer title when the cell has a checkmark on it.
@property (nonatomic, strong) IBInspectable NSString *footerTitle;

@end
4 changes: 1 addition & 3 deletions Bohr/BOOptionTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Bohr
//
// Created by David Román Aguirre on 21/6/15.
//
// Copyright (c) 2015 David Roman. All rights reserved.
//

#import "BOOptionTableViewCell.h"
Expand All @@ -17,8 +17,6 @@ - (void)setup {
}

- (void)wasSelectedFromViewController:(BOTableViewController *)viewController {
[super wasSelectedFromViewController:viewController];

NSInteger optionIndex = [viewController.tableView indexPathForCell:self].row;
self.setting.value = @(optionIndex);
}
Expand Down
4 changes: 4 additions & 0 deletions Bohr/BOSetting.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@

@interface BOSetting : NSObject

/// The NSUserDefaults key for the cell.
@property (nonatomic, readonly) NSString *key;

/// The NSUserDefaults value assigned for the key defined on the cell.
@property (nonatomic, assign) id value;

/// Instantiates a new BOSetting object with a key.
+ (instancetype)settingWithKey:(NSString *)key;

@end
4 changes: 4 additions & 0 deletions Bohr/BOSwitchTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@

@interface BOSwitchTableViewCell : BOTableViewCell

/// The switch on the cell.
@property (nonatomic, strong) UISwitch *toggleSwitch;

/// The footer title when the toggle switch is on.
@property (nonatomic, strong) IBInspectable NSString *onFooterTitle;

/// The footer title when the toggle switch is off.
@property (nonatomic, strong) IBInspectable NSString *offFooterTitle;

@end
14 changes: 14 additions & 0 deletions Bohr/BOTableViewCell+Subclass.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,28 @@

@interface BOTableViewCell ()

/// The current index path of the cell relative to its table view.
@property (nonatomic, strong) NSIndexPath *indexPath;

/// The setting object which the cell represents.
@property (nonatomic, strong) BOSetting *setting;

/// The setup method for the cell, where you may set up all the views and constraints necessary for the cell to work.
- (void)setup;

/// The method in charge of updating the appearance of the main cell view components, through properties as mainColor, mainFont, secondaryColor, secondaryFont.
- (void)updateAppearance;

/// You may return the height for the cell to be expanded when tapped.
- (CGFloat)expansionHeight;

/// You may return the footer text for the cell to be set on its section.
- (NSString *)footerTitle;

/// This method gets called whenever a cell gets selected, passing its parent view controller as an argument.
- (void)wasSelectedFromViewController:(BOTableViewController *)viewController;

/// This method gets called when the cell setting value gets changed externally, so that such change can be represented on the cell.
- (void)settingValueDidChange;

@end
8 changes: 8 additions & 0 deletions Bohr/BOTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@

@interface BOTableViewCell : UITableViewCell

/// The NSUserDefaults key associated with the cell.
@property (nonatomic, strong) IBInspectable NSString *key;

/// The main text color for the cell.
@property (nonatomic, strong) IBInspectable UIColor *mainColor;

/// The main text font for the cell.
@property (nonatomic, strong) UIFont *mainFont; // Apple pls rdar://19973159

/// The secondary or detail text color for the cell.
@property (nonatomic, strong) IBInspectable UIColor *secondaryColor;

/// The secondary or detail text font for the cell.
@property (nonatomic, strong) UIFont *secondaryFont;

/// The color for the selected state of the cell.
@property (nonatomic, strong) IBInspectable UIColor *selectedColor;

@end
17 changes: 1 addition & 16 deletions Bohr/BOTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,7 @@ - (void)setupConstraints {}
- (void)updateAppearance {}
- (CGFloat)expansionHeight {return 0;}
- (NSString *)footerTitle {return nil;}

- (void)wasSelectedFromViewController:(BOTableViewController *)viewController {
if (self.expansionHeight > 0) {
viewController.expansionIndexPath = ![self.indexPath isEqual:viewController.expansionIndexPath] ? self.indexPath : nil;

[viewController.tableView deselectRowAtIndexPath:self.indexPath animated:NO];
[viewController.tableView beginUpdates];
[viewController.tableView endUpdates];
[viewController.tableView scrollToRowAtIndexPath:self.indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
} else {
if (self.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
[viewController.tableView deselectRowAtIndexPath:self.indexPath animated:YES];
}
}
}

- (void)wasSelectedFromViewController:(BOTableViewController *)viewController {}
- (void)settingValueDidChange {}

@end
4 changes: 2 additions & 2 deletions Bohr/BOTableViewController+Private.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//
// BOTableViewController+Private.h
//
// Bohr
//
// Created by David Roman on 24/6/15.
//
// Copyright (c) 2015 David Roman. All rights reserved.
//

#import "BOTableViewController.h"
Expand Down
7 changes: 7 additions & 0 deletions Bohr/BOTableViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@

@interface BOTableViewController : UITableViewController

/// The text color for all the headers in the table view.
@property (nonatomic, strong) IBInspectable UIColor *headerTitlesColor;

/// The text font for all the headers in the table view.
@property (nonatomic, strong) UIFont *headerTitlesFont;

/// The text color for all the footers in the table view.
@property (nonatomic, strong) IBInspectable UIColor *footerTitlesColor;

/// The text font for all the footers in the table view.
@property (nonatomic, strong) UIFont *footerTitlesFont;

/// The setup method for the controller.
- (void)setup;

@end
87 changes: 44 additions & 43 deletions Bohr/BOTableViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,11 @@ - (void)tableViewReceivedTap {
[self.tableView endEditing:YES];
}

- (NSArray *)footerViews {
if (!_footerViews) {
_footerViews = [NSArray new];

for (NSInteger i = 0; i < [self.tableView numberOfSections]; i++) {
NSString *footerTitle = [self tableView:self.tableView titleForFooterInSection:i];

if (footerTitle) {
UITableViewHeaderFooterView *footerView = [UITableViewHeaderFooterView new];
_footerViews = [_footerViews arrayByAddingObject:footerView];
} else {
_footerViews = [_footerViews arrayByAddingObject:[NSNull null]];
}
}
}

return _footerViews;
}
// Apple pls http://blog.supertop.co/post/80781694515/viewmightappear

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

[self.tableView beginUpdates];
[self.tableView endUpdates];

NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow];

if (selectedRowIndexPath) {
Expand All @@ -72,7 +52,7 @@ - (void)viewWillAppear:(BOOL)animated {
}
}

// Apple pls http://blog.supertop.co/post/80781694515/viewmightappear
#pragma mark Headers & cells

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
Expand Down Expand Up @@ -118,49 +98,65 @@ - (void)tableView:(UITableView *)tableView willDisplayCell:(BOTableViewCell *)ce
}
}

- (void)reloadTableView {
[UIView performWithoutAnimation:^{
[self updateFooters];
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BOTableViewCell *cell = (BOTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];

if (cell.expansionHeight > 0) {
self.expansionIndexPath = ![cell.indexPath isEqual:self.expansionIndexPath] ? cell.indexPath : nil;

[self.tableView deselectRowAtIndexPath:cell.indexPath animated:NO];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}];
[self.tableView scrollToRowAtIndexPath:cell.indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
} else {
if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
[self.tableView deselectRowAtIndexPath:cell.indexPath animated:YES];
}
}

if ([cell respondsToSelector:@selector(wasSelectedFromViewController:)]) [cell wasSelectedFromViewController:self];
}

- (void)updateFooters {
for (NSInteger i = 0; i < [self.tableView numberOfSections]; i++) {
NSString *footerTitle = [self tableView:self.tableView titleForFooterInSection:i];
UITableViewHeaderFooterView *footerView = self.footerViews[i];
if (![footerView isEqual:[NSNull null]]) {
footerView.textLabel.text = footerTitle;
[footerView sizeToFit];
#pragma mark Dynamic footers

- (NSArray *)footerViews {
if (!_footerViews) {
_footerViews = [NSArray new];

for (NSInteger i = 0; i < [self.tableView numberOfSections]; i++) {
UITableViewHeaderFooterView *footerView = [UITableViewHeaderFooterView new];
_footerViews = [_footerViews arrayByAddingObject:footerView];
}
}

return _footerViews;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BOTableViewCell *cell = (BOTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if ([cell respondsToSelector:@selector(wasSelectedFromViewController:)]) [cell wasSelectedFromViewController:self];
- (void)reloadTableView {
[UIView performWithoutAnimation:^{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}];
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
UITableViewHeaderFooterView *footerView = self.footerViews[section];
footerView.textLabel.text = [self tableView:tableView titleForFooterInSection:section];

if (![footerView isEqual:[NSNull null]]) {
footerView.textLabel.text = [self tableView:tableView titleForFooterInSection:section];
return footerView;
}

return nil;
return [super tableView:tableView heightForFooterInSection:section];
}

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
// First, we get the super value, and if it's nil we set it to an empty string (this is the lowest priority for dynamic footers).
NSString *footerTitle = [super tableView:self.tableView titleForFooterInSection:section];
if (!footerTitle) footerTitle = @"";

// Next, we try to find an existing footer in the last cell of the section (this is the medium priority for dynamic footers).
NSInteger numberOfRows = [super tableView:self.tableView numberOfRowsInSection:section];
BOTableViewCell *lastCell = (BOTableViewCell *)[super tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:numberOfRows-1 inSection:section]];
if ([lastCell isKindOfClass:[BOTableViewCell class]] && [lastCell footerTitle]) footerTitle = [lastCell footerTitle];

// Finally, we try to find an existing footer in any cell that has a checkmark accessory on it (this is the top priority for dynamic footers).
for (NSInteger i = 0; i < numberOfRows; i++) {
BOTableViewCell *cell = (BOTableViewCell *)[super tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:section]];

Expand All @@ -172,6 +168,11 @@ - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInte
return footerTitle;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UITableViewHeaderFooterView *footerView = self.footerViews[section];
return footerView;
}

- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section {
UITableViewHeaderFooterView *footer = (UITableViewHeaderFooterView *)view;

Expand Down
11 changes: 11 additions & 0 deletions Bohr/BOTextTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,28 @@

#import "BOTableViewCell.h"

/// Defines an error after trying to input some new value to the cell text field.
typedef NS_ENUM(NSInteger, BOTextFieldInputError) {
BOTextFieldInputTooShortError
};

@interface BOTextTableViewCell : BOTableViewCell <UITextFieldDelegate>

/**
* Block type defining an input error that has ocurred in the cell text field.
*
* @param cell the cell affected by the input error.
* @param error the received input error.
*/
typedef void(^BOTextFieldInputErrorBlock)(BOTextTableViewCell *cell, BOTextFieldInputError error);

/// The text field on the cell.
@property (nonatomic, strong) UITextField *textField;

/// The minimum amount of non-blank characters necessary for the text field.
@property (nonatomic) IBInspectable NSInteger minimumTextLength;

/// A block defining an input error that has ocurred in the cell text field.
@property (nonatomic, copy) BOTextFieldInputErrorBlock inputErrorBlock;

@end
Loading

0 comments on commit 7767101

Please sign in to comment.