Skip to content

Commit

Permalink
Lock vertical pan gesture in MXPagerView
Browse files Browse the repository at this point in the history
  • Loading branch information
maxep committed Sep 28, 2015
1 parent b6dd72b commit 903edcf
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ - (UIView *)segmentedPager:(MXSegmentedPager *)segmentedPager viewForPageAtIndex
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSInteger index = (indexPath.row % 2) + 1;
[self.segmentedPager scrollToPageAtIndex:index animated:YES];
[self.segmentedPager.pager showPageAtIndex:index animated:YES];
}

#pragma -mark <UITableViewDataSource>
Expand Down
4 changes: 2 additions & 2 deletions Example/MXSegmentedPager/Parallax/MXRefreshHeaderView.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
</dependencies>
<objects>
Expand Down
2 changes: 1 addition & 1 deletion Example/MXSegmentedPager/Simple/MXSimpleViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ - (UIView *)segmentedPager:(MXSegmentedPager *)segmentedPager viewForPageAtIndex
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSInteger index = (indexPath.row % 2) + 1;
[self.segmentedPager scrollToPageAtIndex:index animated:YES];
[self.segmentedPager.pager showPageAtIndex:index animated:YES];
}

#pragma -mark <UITableViewDataSource>
Expand Down
4 changes: 2 additions & 2 deletions Example/MXSegmentedPager/Storyboard/MXNumberViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ @implementation MXNumberViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.numberLabel.text = [NSString stringWithFormat:@"Page %li", self.number];
self.numberLabel.text = [NSString stringWithFormat:@"Page %li", (long)self.number];
}

- (void)didReceiveMemoryWarning {
Expand All @@ -27,7 +27,7 @@ - (void)didReceiveMemoryWarning {

- (void)setNumber:(NSInteger)number {
_number = number;
self.numberLabel.text = [NSString stringWithFormat:@"Page %li", self.number];
self.numberLabel.text = [NSString stringWithFormat:@"Page %li", (long)self.number];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@

#import "MXStoryboardViewController.h"
#import "MXNumberViewController.h"
#import "MXRefreshHeaderView.h"

@implementation MXStoryboardViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;

// Parallax Header
[self.segmentedPager setParallaxHeaderView:[MXRefreshHeaderView instantiateFromNib] mode:VGParallaxHeaderModeFill height:150.f];
self.segmentedPager.minimumHeaderHeight = 20.f;

// Segmented Control customization
self.segmentedPager.segmentedControl.selectionIndicatorLocation = HMSegmentedControlSelectionIndicatorLocationDown;
self.segmentedPager.segmentedControl.backgroundColor = [UIColor whiteColor];
Expand Down
33 changes: 33 additions & 0 deletions MXSegmentedPager/MXPagerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,38 @@

#import <UIKit/UIKit.h>

/**
UIPanGestureRecognizer direction enumeration.
*/
typedef NS_ENUM(NSInteger, MXPanGestureDirection){
/** No direction. */
MXPanGestureDirectionNone = 1 << 0,
/** Right direction. */
MXPanGestureDirectionRight = 1 << 1,
/** Left direction. */
MXPanGestureDirectionLeft = 1 << 2,
/** Up direction. */
MXPanGestureDirectionUp = 1 << 3,
/** Down direction. */
MXPanGestureDirectionDown = 1 << 4
};

/**
UIPanGestureRecognizer category with direction getter.
*/
@interface UIPanGestureRecognizer (Direction)

/**
Gets the pan gesture direction of the specified view.
@param view The view
@return The pan gesture direction.
*/
- (MXPanGestureDirection) directionInView:(nullable __kindof UIView *)view;

@end

/**
The pager transition styles.
*/
Expand Down Expand Up @@ -206,4 +238,5 @@ typedef NS_ENUM(NSInteger, MXPagerViewTransitionStyle) {
if the page is reusable (has a reuse identifier), this is called just before the page is returned from the pager view method dequeueReusablePageWithIdentifier:.
*/
- (void) prepareForReuse;

@end
81 changes: 63 additions & 18 deletions MXSegmentedPager/MXPagerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,15 @@
#import <objc/runtime.h>
#import "MXPagerView.h"

@implementation UIView (ReuseIdentifier)

- (NSString *)reuseIdentifier {
return objc_getAssociatedObject(self, @selector(reuseIdentifier));
}

- (void)setReuseIdentifier:(NSString *)reuseIdentifier {
objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_COPY);
}

- (void)prepareForReuse {

}
@interface UIView ()
@property (nonatomic, copy) NSString *reuseIdentifier;
@end

@interface MXContentView : UIScrollView <UIGestureRecognizerDelegate>
@end

@interface MXPagerView () <UIScrollViewDelegate>
@property (nonatomic, strong) UIScrollView *contentView;
@property (nonatomic, strong) MXContentView *contentView;
@property (nonatomic, strong) NSMutableDictionary *pages;

@property (nonatomic, strong) NSMutableDictionary *registration;
Expand Down Expand Up @@ -94,11 +85,12 @@ - (void) reloadData {

//Loads the current selected page
[self loadPageAtIndex:_index];

[self layoutIfNeeded];
}

- (void) showPageAtIndex:(NSInteger)index animated:(BOOL)animated {


//The tab behavior disable animation
animated = (self.transitionStyle == MXPagerViewTransitionStyleTab)? NO : animated;

Expand All @@ -124,7 +116,7 @@ - (void)registerClass:(Class)pageClass forPageReuseIdentifier:(NSString *)identi
[self.registration setValue:NSStringFromClass(pageClass) forKey:identifier];
}

- (__kindof UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier {
- (UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier {

for (UIView *page in self.reuseQueue) {
if (!page.superview && [page.reuseIdentifier isEqualToString:identifier]) {
Expand Down Expand Up @@ -153,9 +145,9 @@ - (__kindof UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier {

#pragma mark Properties

- (UIScrollView *)contentView {
- (MXContentView *)contentView {
if (!_contentView) {
_contentView = [[UIScrollView alloc] init];
_contentView = [[MXContentView alloc] init];
_contentView.delegate = self;
_contentView.scrollsToTop = NO;
_contentView.pagingEnabled = YES;
Expand Down Expand Up @@ -329,3 +321,56 @@ - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
}

@end

@implementation MXContentView

#pragma mark <UIGestureRecognizerDelegate>

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{

if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
MXPanGestureDirection direction = [(UIPanGestureRecognizer*)gestureRecognizer directionInView:self];

//Lock vertical pan gesture.
if (direction == MXPanGestureDirectionUp || direction == MXPanGestureDirectionDown) {
return NO;
}
}
return YES;
}

@end

@implementation UIView (ReuseIdentifier)

- (NSString *)reuseIdentifier {
return objc_getAssociatedObject(self, @selector(reuseIdentifier));
}

- (void)setReuseIdentifier:(NSString *)reuseIdentifier {
objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_COPY);
}

- (void)prepareForReuse {

}

@end

@implementation UIPanGestureRecognizer (Direction)

- (MXPanGestureDirection) directionInView:(UIView *)view {
CGPoint velocity = [self velocityInView:view];
CGFloat absX = fabs(velocity.x);
CGFloat absY = fabs(velocity.y);

if (absX > absY) {
return (velocity.x > 0)? MXPanGestureDirectionRight : MXPanGestureDirectionLeft;
}
else if (absX < absY) {
return (velocity.y > 0)? MXPanGestureDirectionDown : MXPanGestureDirectionUp;
}
return MXPanGestureDirectionNone;
}

@end
8 changes: 0 additions & 8 deletions MXSegmentedPager/MXSegmentedPager.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,6 @@ typedef void (^MXProgressBlock) (CGFloat progress);
*/
- (void) reloadData;

/**
Scrolls through the pager until a page identified by index is at a particular location on the screen.
@param index An index that identifies a page.
@param animated YES if you want to animate the change in position; NO if it should be immediate.
*/
- (void) scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated;

@end

/**
Expand Down
36 changes: 7 additions & 29 deletions MXSegmentedPager/MXSegmentedPager.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,7 @@
#import <objc/runtime.h>
#import "MXSegmentedPager.h"

typedef NS_ENUM(NSInteger, MXPanGestureDirection) {
MXPanGestureDirectionNone = 1 << 0,
MXPanGestureDirectionRight = 1 << 1,
MXPanGestureDirectionLeft = 1 << 2,
MXPanGestureDirectionUp = 1 << 3,
MXPanGestureDirectionDown = 1 << 4
};


@interface MXScrollView : UIScrollView <UIScrollViewDelegate, UIGestureRecognizerDelegate>
@property (nonatomic, assign) CGFloat minimumHeigth;
Expand Down Expand Up @@ -120,11 +114,9 @@ - (void)reloadData {

self.segmentedControl.sectionImages = images;
self.segmentedControl.sectionTitles = titles;
}

- (void) scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated {
[self.segmentedControl setSelectedSegmentIndex:index animated:animated];
[self.pager showPageAtIndex:index animated:animated];

[self.pager reloadData];
[self layoutIfNeeded];
}

#pragma mark Properties
Expand Down Expand Up @@ -336,8 +328,9 @@ - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{

if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
MXPanGestureDirection direction = [self getDirectionOfPanGestureRecognizer:(UIPanGestureRecognizer*)gestureRecognizer];
MXPanGestureDirection direction = [(UIPanGestureRecognizer*)gestureRecognizer directionInView:self];

//Lock horizontal pan gesture.
if (direction == MXPanGestureDirectionLeft || direction == MXPanGestureDirectionRight) {
return NO;
}
Expand All @@ -348,7 +341,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

UIView<MXPageProtocol> *page = (id) self.segmentedPager.pager.selectedPage;
BOOL shouldScroll = self.scrollEnabled;
BOOL shouldScroll = YES;

if ([page respondsToSelector:@selector(segmentedPager:shouldScrollWithView:)]) {
shouldScroll = [page segmentedPager:self.segmentedPager shouldScrollWithView:otherGestureRecognizer.view];
Expand All @@ -360,21 +353,6 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
return shouldScroll;
}

- (MXPanGestureDirection) getDirectionOfPanGestureRecognizer:(UIPanGestureRecognizer*) panGestureRecognizer {

CGPoint velocity = [panGestureRecognizer velocityInView:self];
CGFloat absX = fabs(velocity.x);
CGFloat absY = fabs(velocity.y);

if (absX > absY) {
return (velocity.x > 0)? MXPanGestureDirectionRight : MXPanGestureDirectionLeft;
}
else if (absX < absY) {
return (velocity.y > 0)? MXPanGestureDirectionDown : MXPanGestureDirectionUp;
}
return MXPanGestureDirectionNone;
}

#pragma mark KVO

- (void) addObserverToView:(UIView *)view {
Expand Down

0 comments on commit 903edcf

Please sign in to comment.