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

Commit

Permalink
[0.9.9] Updated sample project, fixed bugs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas Gessner committed Nov 4, 2013
1 parent a8168e5 commit 1ea455f
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 31 deletions.
Binary file modified Demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions JGScrollableTableViewCell Examples/JGAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
@property (strong, nonatomic) UIWindow *window;

@property (nonatomic, strong) JGTextViewController *mainViewController;
@property (nonatomic, strong) UINavigationController *mainNavigationController;

@end
4 changes: 3 additions & 1 deletion JGScrollableTableViewCell Examples/JGAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

self.mainViewController = [[JGTextViewController alloc] initWithStyle:UITableViewStylePlain];

self.window.rootViewController = self.mainViewController;
self.mainNavigationController = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];

self.window.rootViewController = self.mainNavigationController;

[self.window makeKeyAndVisible];

Expand Down
49 changes: 43 additions & 6 deletions JGScrollableTableViewCell Examples/JGTextViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

@interface JGTextViewController () <JGScrollableTableViewCellDelegate> {
NSIndexPath *_openedIndexPath;
BOOL _left;
}

@end
Expand All @@ -25,11 +26,25 @@ - (instancetype)initWithStyle:(UITableViewStyle)style {
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

[self.tableView registerClass:[JGScrollableTableViewCell class] forCellReuseIdentifier:@"ScrollCell"];

UISwitch *s = [[UISwitch alloc] init];
[s addTarget:self action:@selector(switched:) forControlEvents:UIControlEventValueChanged];

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:s];

self.title = @"Option view on the left->";

printf("NOTE: Real world implementations should use subclasses of JGScrollableTableViewCell to manage and display more content in the cell\n");
}
return self;
}


- (void)switched:(UISwitch *)sender {
_left = sender.on;
[self.tableView reloadData];
}


#pragma mark - JGScrollableTableViewCellDelegate

Expand Down Expand Up @@ -68,20 +83,42 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *const CellIdentifier = @"ScrollCell";

JGScrollableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

[cell setScrollViewBackgroundColor:[UIColor colorWithWhite:0.975f alpha:1.0f]];
[cell setScrollViewInsets:UIEdgeInsetsMake(0.0f, 1.0f, 1.0f, 1.0f)];
cell.contentView.backgroundColor = [UIColor colorWithWhite:0.7f alpha:1.0f];

JGScrollableTableViewCellAccessoryButton *optionView = [JGScrollableTableViewCellAccessoryButton button];
[optionView setButtonColor:[UIColor colorWithRed:0.975f green:0.0f blue:0.0f alpha:1.0f] forState:UIControlStateNormal];
[optionView setButtonColor:[UIColor colorWithRed:0.8f green:0.1f blue:0.1f alpha:1.0f] forState:UIControlStateHighlighted];
JGScrollableTableViewCellAccessoryButton *actionView = [JGScrollableTableViewCellAccessoryButton button];

[actionView setButtonColor:[UIColor colorWithRed:0.975f green:0.0f blue:0.0f alpha:1.0f] forState:UIControlStateNormal];
[actionView setButtonColor:[UIColor colorWithRed:0.8f green:0.1f blue:0.1f alpha:1.0f] forState:UIControlStateHighlighted];

[actionView setTitle:@"Sample" forState:UIControlStateNormal];

actionView.frame = CGRectMake(80.0f, 0.0f, 80.0f, 0.0f); //width is the only frame parameter that needs to be set on the option view
actionView.autoresizingMask = UIViewAutoresizingFlexibleHeight;


JGScrollableTableViewCellAccessoryButton *moreView = [JGScrollableTableViewCellAccessoryButton button];

[moreView setButtonColor:[UIColor colorWithWhite:0.8f alpha:1.0f] forState:UIControlStateNormal];
[moreView setButtonColor:[UIColor colorWithWhite:0.65f alpha:1.0f] forState:UIControlStateHighlighted];

[moreView setTitle:@"Sample" forState:UIControlStateNormal];

moreView.frame = CGRectMake(0.0f, 0.0f, 80.0f, 0.0f); //width is the only frame parameter that needs to be set on the option view
moreView.autoresizingMask = UIViewAutoresizingFlexibleHeight;


UIView *optionView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 160.0f, 0.0f)];

[optionView setTitle:@"Action" forState:UIControlStateNormal];
[optionView addSubview:moreView];
[optionView addSubview:actionView];

optionView.frame = CGRectMake(0.0f, 0.0f, 80.0f, 0.0f); //width is the only frame parameter that needs to be set on the option view

[cell setOptionView:optionView side:JGScrollableTableViewCellSideRight];
[cell setOptionView:optionView side:(_left ? JGScrollableTableViewCellSideLeft : JGScrollableTableViewCellSideRight)];

cell.scrollDelegate = self;

Expand Down
31 changes: 23 additions & 8 deletions JGScrollableTableViewCell/JGScrollableTableViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@

@end


typedef NS_ENUM(BOOL, JGScrollableTableViewCellSide) {
JGScrollableTableViewCellSideLeft = NO,
JGScrollableTableViewCellSideRight = YES
};

/**
Cell with scrollable content and an option view that is revealed when scrolling on the cell.
*/
@interface JGScrollableTableViewCell : UITableViewCell

//scroll view peoperties

//Scroll view properties

/**
Insets the scroll view. Useful for displaying a border around the scroll area (when also setting \c contentView.backgroundColor)
*/
Expand All @@ -52,10 +58,11 @@ typedef NS_ENUM(BOOL, JGScrollableTableViewCellSide) {
@property (nonatomic, assign, readonly) BOOL scrolling;


//opened sides

//Opened sides

/**
The current state of the option view.
@return If the option view is visible.
@return The current visible state of the option view.
*/
@property (nonatomic, assign) BOOL optionViewVisible;

Expand All @@ -66,8 +73,11 @@ typedef NS_ENUM(BOOL, JGScrollableTableViewCellSide) {
- (void)setOptionViewVisible:(BOOL)optionViewVisible animated:(BOOL)animated;


//views

//Views

/**
The option view is set with the \c setOptionView:side: method.
@return The option view.
*/
@property (nonatomic, strong, readonly) UIView *optionView;
Expand All @@ -82,20 +92,25 @@ typedef NS_ENUM(BOOL, JGScrollableTableViewCellSide) {


/**
Add a view to the scrolling area of the cell.
Adds a view to the scrolling area of the cell.
@param view The view to add.
*/
- (void)addContentView:(UIView *)view;

@end




/**
Manage the state of all \c JGScrollableTableViewCells in a \c UITableView
*/
@interface JGScrollableTableViewCellManager : NSObject

/**
Closes all optin views in \c Cell's UITableView.
Closes all option views in the \c UITableView containing \c cell.
@param cell The cell that should not be closed.
*/
+ (void)closeAllCellsWithExceptionOf:(JGScrollableTableViewCell *)cell;

@end
@end
63 changes: 49 additions & 14 deletions JGScrollableTableViewCell/JGScrollableTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,13 @@ + (NSSet *)allCellsInTableView:(UITableView *)host {
@end


#define kJGScrollableTableViewCellAnimationDuration 0.3

@interface JGScrollableTableViewCell () <JGTouchForwarder, UIScrollViewDelegate> {
JGScrollableTableViewCellScrollView *_scrollView;
UIView *_scrollViewCoverView;
JGScrollableTableViewCellSide _side;
BOOL _forceRelayout;

__weak UITableView *_hostingTableView;
}
Expand Down Expand Up @@ -165,19 +168,36 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr
#pragma mark - Delegates

- (void)forwardTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
if (!self.scrolling && !self.optionViewVisible) {
[self touchesBegan:touches withEvent:event];
}
}

- (void)forwardTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesCancelled:touches withEvent:event];
if (!self.scrolling && !self.optionViewVisible) {
[self touchesCancelled:touches withEvent:event];
}
}

- (void)forwardTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesEnded:touches withEvent:event];
if (!self.scrolling && !self.optionViewVisible) {
[self touchesEnded:touches withEvent:event];
}
else if (self.optionViewVisible) {
__weak __typeof(self) weakSelf = self;

[self setOptionViewVisible:NO animationDuration:kJGScrollableTableViewCellAnimationDuration completion:^{
if ([weakSelf.scrollDelegate respondsToSelector:@selector(cellDidEndScrolling:)]) {
[weakSelf.scrollDelegate cellDidEndScrolling:weakSelf];
}
}];
}
}

- (void)forwardTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesCancelled:touches withEvent:event];
if (!self.scrolling && !self.optionViewVisible) {
[self touchesCancelled:touches withEvent:event];
}
}


Expand Down Expand Up @@ -220,13 +240,13 @@ - (void)layoutSubviews {

CGRect scrollViewFrame = UIEdgeInsetsInsetRect(self.contentView.bounds, self.scrollViewInsets);

_scrollView.delegate = nil;

_scrollView.frame = scrollViewFrame;

_scrollView.contentSize = (CGSize){scrollViewFrame.size.width+self.optionView.frame.size.width, scrollViewFrame.size.height};
_scrollView.delegate = self;

_scrolling = YES; //enusres that next call is actually executed
[self setOptionViewVisible:self.optionViewVisible]; //sets correct contentOffset
_scrolling = NO;
_scrollView.contentSize = (CGSize){scrollViewFrame.size.width+self.optionView.frame.size.width, scrollViewFrame.size.height};

_scrollViewCoverView.frame = (CGRect){{(_side == JGScrollableTableViewCellSideLeft ? self.optionView.frame.size.width : 0.0f), 0.0f}, scrollViewFrame.size};

Expand All @@ -240,12 +260,20 @@ - (void)layoutSubviews {

self.optionView.frame = (CGRect){{self.scrollViewInsets.left, self.scrollViewInsets.top}, size};
}

_forceRelayout = YES; //enusres that next call is actually executed
[self setOptionViewVisible:self.optionViewVisible]; //sets correct contentOffset
_forceRelayout = NO;
}

#pragma mark - Setters

- (void)setOptionViewVisible:(BOOL)optionViewVisible animated:(BOOL)animated {
if (_optionViewVisible == optionViewVisible && !self.scrolling) {
[self setOptionViewVisible:optionViewVisible animationDuration:(animated ? kJGScrollableTableViewCellAnimationDuration : 0.0) completion:NULL];
}

- (void)setOptionViewVisible:(BOOL)optionViewVisible animationDuration:(NSTimeInterval)duration completion:(void (^)(void))completion {
if (!_forceRelayout && _optionViewVisible == optionViewVisible && !self.scrolling) {
return;
}

Expand All @@ -263,12 +291,15 @@ - (void)setOptionViewVisible:(BOOL)optionViewVisible animated:(BOOL)animated {
scrollDestination = (CGPoint){(_optionViewVisible ? _scrollView.contentSize.width-1.0f : 0.0f), 0.0f};
}

[UIView animateWithDuration:(animated ? 0.3 : 0.0) delay:0.0 options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState animations:^{
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState animations:^{
[_scrollView.panGestureRecognizer setEnabled:NO];
[_scrollView scrollRectToVisible:(CGRect){scrollDestination, {1.0f, 1.0f}} animated:NO];
} completion:^(__unused BOOL finished) {
[_scrollView.panGestureRecognizer setEnabled:YES];
_scrollView.delegate = self;
if (completion) {
completion();
}
}];
}

Expand Down Expand Up @@ -305,23 +336,27 @@ - (void)addContentView:(UIView *)view {
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
_optionView.hidden = highlighted;
_scrollView.scrollEnabled = !highlighted;
[super setHighlighted:highlighted animated:animated];
}

- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
_optionView.hidden = highlighted;
_scrollView.scrollEnabled = !highlighted;
[super setHighlighted:highlighted];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
_optionView.hidden = selected;
_scrollView.scrollEnabled = !selected;
[super setSelected:selected animated:animated];
}

- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
_optionView.hidden = selected;
_scrollView.scrollEnabled = !selected;
[super setSelected:selected];
}

#pragma mark - Dealloc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,26 @@
#import <UIKit/UIKit.h>


/**
An iOS 7 mail app inspired button. This class is \b not required when using \c JGScrollableTableViewCell.
*/
@interface JGScrollableTableViewCellAccessoryButton : UIButton

/**
Convenience method for +alloc -init.
@warning Always initialize \c JGScrollableTableViewCellAccessoryButton using +alloc -init, or this convenience method.
*/
+ (instancetype)button;


/**
Sets the button's background color for a given state. This is different from \c backgroundColor because \c backgroundColor is constant and doesn't change for different selection states.
@discussion Internally this uses the \c -setBackgroundImage:forState: method of \c UIButton so that should not be set manually after calling this method. To display an image use the \c -setImage:forState: method
@param buttonColor The color of the button. This color fills the entire rect of the button.
@param state The state for which to set the button's color.
*/
- (void)setButtonColor:(UIColor *)buttonColor forState:(UIControlState)state;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ - (instancetype)init {
}

- (void)setButtonColor:(UIColor *)buttonColor forState:(UIControlState)state {
UIGraphicsBeginImageContextWithOptions((CGSize){1.0f, 1.0f}, YES, 0.0f);
CGSize size = (CGSize){1.0f, 1.0f};

UIGraphicsBeginImageContextWithOptions(size, YES, 0.0f);

[buttonColor setFill];

[[UIBezierPath bezierPathWithRect:(CGRect){CGPointZero, {1.0f, 1.0f}}] fill];
[[UIBezierPath bezierPathWithRect:(CGRect){CGPointZero, size}] fill];

UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

Expand Down

0 comments on commit 1ea455f

Please sign in to comment.