Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Refactor + README
Browse files Browse the repository at this point in the history
  • Loading branch information
marciomeschini committed Dec 13, 2012
1 parent d288d5f commit da69997
Show file tree
Hide file tree
Showing 14 changed files with 336 additions and 143 deletions.
2 changes: 2 additions & 0 deletions FWTOverlayView/FWTOverlayView.xcodeproj/project.pbxproj
Expand Up @@ -29,6 +29,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
A923ED621678A39300709A25 /* FWTOverlayBlockDefinitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FWTOverlayBlockDefinitions.h; sourceTree = "<group>"; };
A997599D1611C35A00BFB780 /* libFWTOverlayView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFWTOverlayView.a; sourceTree = BUILT_PRODUCTS_DIR; };
A99759A01611C35A00BFB780 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
A99759A41611C35A00BFB780 /* FWTOverlayView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FWTOverlayView-Prefix.pch"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -118,6 +119,7 @@
A99759B81611C3B300BFB780 /* Private */ = {
isa = PBXGroup;
children = (
A923ED621678A39300709A25 /* FWTOverlayBlockDefinitions.h */,
A99759AE1611C39800BFB780 /* FWTOverlayScrollViewHelper.h */,
A99759AF1611C39800BFB780 /* FWTOverlayScrollViewHelper.m */,
);
Expand Down
10 changes: 10 additions & 0 deletions FWTOverlayView/FWTOverlayView/FWTOverlayBlockDefinitions.h
@@ -0,0 +1,10 @@
//
// FWTOverlayBlockDefinitions.h
// FWTOverlayView
//
// Created by Marco Meschini on 12/12/2012.
// Copyright (c) 2012 Marco Meschini. All rights reserved.
//

typedef void (^FWTOverlayLayoutBlock)(BOOL);
typedef void (^FWTOverlayDismissBlock)();
4 changes: 4 additions & 0 deletions FWTOverlayView/FWTOverlayView/FWTOverlayScrollViewHelper.h
Expand Up @@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "FWTOverlayBlockDefinitions.h"

// This is a private class. You can access its properties through the UIScrollView (FWTOverlay) category.
//
Expand All @@ -17,6 +18,9 @@
@property (nonatomic, retain) UIView *overlayView;
@property (nonatomic, assign) UIEdgeInsets edgeInsets;
@property (nonatomic, assign) CGFloat hideAfterDelay;
@property (nonatomic, assign) UIViewAutoresizing flexibleMargin;
@property (nonatomic, copy) FWTOverlayLayoutBlock layoutBlock;
@property (nonatomic, copy) FWTOverlayDismissBlock dismissBlock;

- (id)initWithScrollView:(UIScrollView *)scrollView;

Expand Down
156 changes: 86 additions & 70 deletions FWTOverlayView/FWTOverlayView/FWTOverlayScrollViewHelper.m
Expand Up @@ -11,7 +11,7 @@
#import <QuartzCore/QuartzCore.h>
#import "UIScrollView+FWTOverlayView.h"

#define DEBUG_ENABLED YES
#define DEBUG_ENABLED NO

static BOOL isMethodPartOfProtocol(SEL aSelector, Protocol *aProtocol)
{
Expand Down Expand Up @@ -44,9 +44,9 @@ @interface FWTOverlayScrollViewHelper () <UIScrollViewDelegate>
@property (nonatomic, assign) UIScrollView *scrollView;
@property (nonatomic, assign) id<UIScrollViewDelegate> realDelegate;
@property (nonatomic, retain) UIView *debugView;
@property (nonatomic, assign) CGFloat presentAnimationDuration, dismissAnimationDuration;
@property (nonatomic, assign) CGFloat slideOffset;
@property (nonatomic, assign, getter = isOverlayViewVisible) BOOL overlayViewVisible;
@property (nonatomic, assign, getter = isDismissAnimationRunning) BOOL dismissAnimationRunning;
@property (nonatomic, assign) BOOL overlayViewWillDisappear;
@end


Expand All @@ -55,6 +55,8 @@ @implementation FWTOverlayScrollViewHelper

- (void)dealloc
{
self.dismissBlock = NULL;
self.layoutBlock = NULL;
self.debugView = nil;
self.overlayView = nil;
self.realDelegate = nil;
Expand All @@ -68,9 +70,6 @@ - (id)initWithScrollView:(UIScrollView *)scrollView
{
self.scrollView = scrollView;
self.hideAfterDelay = 2.0f;
self.presentAnimationDuration = .2f;
self.dismissAnimationDuration = .2f;
self.slideOffset = 20.0f;
}

return self;
Expand All @@ -96,6 +95,7 @@ - (void)setScrollView:(UIScrollView *)scrollView
//
[self->_scrollView addObserver:self forKeyPath:keyPathDelegate options:NSKeyValueObservingOptionNew context:NULL];
[self->_scrollView addObserver:self forKeyPath:keyPathFrame options:NSKeyValueObservingOptionNew context:NULL];
//TODO: add observer for contentSize
}
}
}
Expand Down Expand Up @@ -168,6 +168,49 @@ - (UIView *)debugView
return self->_debugView;
}

- (FWTOverlayLayoutBlock)layoutBlock
{
if (self->_layoutBlock == NULL)
{
__block typeof(self) myself = self;
self->_layoutBlock = [^(BOOL animated){
if (animated)
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
anim.fromValue = @.0f;
anim.toValue = @1.0f;
myself.overlayView.layer.opacity = 1.0f;
[myself.overlayView.layer addAnimation:anim forKey:@"animation"];
}
else
myself.overlayView.layer.opacity = 1.0f;

} copy];
}

return self->_layoutBlock;
}

- (FWTOverlayDismissBlock)dismissBlock
{
if (self->_dismissBlock == NULL)
{
__block typeof(self) myself = self;
self->_dismissBlock = [^(){
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
anim.fromValue = @1.0f;
anim.toValue = @.0f;
myself.overlayView.layer.opacity = .0f;
[myself.overlayView.layer addAnimation:anim forKey:@"animation"];

} copy];
}

return self->_dismissBlock;
}

#pragma mark - Private
- (void)_swapDelegateForScrollView:(UIScrollView *)scrollView
{
Expand Down Expand Up @@ -204,101 +247,76 @@ - (void)_layoutOverlayView
{
if (!self.overlayView.superview)
{
self.overlayView.frame = [self _overlayFrame];
[self.scrollView addSubview:self.overlayView];
self.overlayView.alpha = .0f;
[UIView animateWithDuration:self.presentAnimationDuration
animations:^{
self.overlayView.alpha = 1.0f;
self.overlayView.transform = CGAffineTransformMakeTranslation(-self.slideOffset, 0.0f);
}];
self.layoutBlock(YES);
}
else
{
[self.scrollView bringSubviewToFront:self.overlayView];
self.overlayView.frame = [self _overlayFrame];
self.overlayView.alpha = 1.0f;
self.layoutBlock(NO);
}
}

- (CGRect)_overlayFrame
{
// Work out positions
CGFloat currentTablePositionPercentage = [self.scrollView fwt_contentOffsetPercentageClampEnabled:YES];
CGPoint contentOffsetRelative = [self.scrollView fwt_relativeContentOffsetNormalized:YES];
CGSize overlaySize = self.overlayView.frame.size;
CGRect overlayFrame = [self _overlayBounds];
CGRect overlayAvailableFrame = [self _overlayBounds];
CGRect toReturn = overlayAvailableFrame;
toReturn.origin.x += ((CGRectGetWidth(overlayAvailableFrame)-overlaySize.width)*contentOffsetRelative.x);
toReturn.origin.y += ((CGRectGetHeight(overlayAvailableFrame)-overlaySize.height)*contentOffsetRelative.y);
toReturn.size = overlaySize;

FWTScrollViewDirection direction = [self.scrollView fwt_scrollDirection];
if (direction == FWTScrollViewDirectionVertical)
if (self.flexibleMargin == UIViewAutoresizingFlexibleLeftMargin)
{
overlayFrame.origin.y += ((CGRectGetHeight(overlayFrame)-overlaySize.height)*currentTablePositionPercentage); // adjust y
overlayFrame.size.height = overlaySize.height;
toReturn.origin.x += CGRectGetWidth(overlayAvailableFrame)-overlaySize.width;
}
else if (direction == FWTScrollViewDirectionHorizontal)
else if (self.flexibleMargin == UIViewAutoresizingFlexibleTopMargin)
{
overlayFrame.origin.x += ((CGRectGetWidth(overlayFrame)-overlaySize.width)*currentTablePositionPercentage); // adjust y
overlayFrame.size.width = overlaySize.width;
toReturn.origin.y += CGRectGetHeight(overlayAvailableFrame)-overlaySize.height;
}

return overlayFrame;
return toReturn;
}

- (CGRect)_overlayBounds
{
CGSize overlaySize = self.overlayView.frame.size;
CGRect toReturn = UIEdgeInsetsInsetRect(self.scrollView.bounds, self.edgeInsets);

FWTScrollViewDirection direction = [self.scrollView fwt_scrollDirection];
if (direction == FWTScrollViewDirectionVertical)
{
if (self.edgeInsets.left == .0f)
toReturn.origin.x += CGRectGetWidth(toReturn)-overlaySize.width;

toReturn.size.width = overlaySize.width;
}
else if (direction == FWTScrollViewDirectionHorizontal)
{
if (self.edgeInsets.top == .0f)
toReturn.origin.y += CGRectGetHeight(toReturn)-overlaySize.height;

toReturn.size.height = overlaySize.height;
}

return toReturn;
return UIEdgeInsetsInsetRect(self.scrollView.bounds, self.edgeInsets);
}

- (void)_dismissOverlayView
{
if (!_dismissOverlayViewAnimating)
if (![self isDismissAnimationRunning])
{
_dismissOverlayViewAnimating = YES;

[UIView animateWithDuration:self.dismissAnimationDuration
animations:^{
self.overlayView.alpha = .0f;
self.overlayView.frame = CGRectOffset(self.overlayView.frame, self.slideOffset, .0f);
}
completion:^(BOOL finished) {

_dismissOverlayViewAnimating = NO;

// check if we did have a scroll during the animation run
if (self.overlayView.alpha == .0f)
{
[self.debugView removeFromSuperview];
[self.overlayView removeFromSuperview];
self.overlayView.transform = CGAffineTransformIdentity;

self.overlayViewVisible = NO;
}
}
];
self.dismissAnimationRunning = YES;
self.overlayViewWillDisappear = YES;

__block typeof(self) myself = self;
[CATransaction begin];
[CATransaction setCompletionBlock:^{
if (myself.overlayViewWillDisappear)
{
[myself.debugView removeFromSuperview];
[myself.overlayView removeFromSuperview];
myself.overlayViewVisible = NO;
}

myself.dismissAnimationRunning = NO;
}];

self.dismissBlock();
[CATransaction commit];
}
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.overlayViewVisible = YES;
self.overlayViewWillDisappear = NO;
[self.overlayView.layer removeAllAnimations];

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_dismissOverlayView) object:nil];

Expand Down Expand Up @@ -326,10 +344,8 @@ - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//
[self _layoutSubviews];

//
if (_realDelegateHas.scrollViewDidScroll)
[self.realDelegate scrollViewDidScroll:scrollView];
}
Expand Down
24 changes: 12 additions & 12 deletions FWTOverlayView/FWTOverlayView/UIScrollView+FWTOverlayView.h
Expand Up @@ -7,24 +7,24 @@
//

#import <UIKit/UIKit.h>
#import "FWTOverlayBlockDefinitions.h"

@interface UIScrollView (FWTRelativeContentOffset)

@property (nonatomic) CGPoint fwt_relativeContentOffset;
- (CGPoint)fwt_relativeContentOffsetNormalized:(BOOL)normalized;

@end

typedef enum _FWTScrollViewDirection
{
FWTScrollViewDirectionNone,
FWTScrollViewDirectionVertical,
FWTScrollViewDirectionHorizontal,
} FWTScrollViewDirection;

@interface UIScrollView (FWTOverlayView)

// configure
@property (nonatomic, retain) UIView *fwt_overlayView;
@property (nonatomic, assign) UIEdgeInsets fwt_overlayViewEdgeInsets;
@property (nonatomic, assign) UIViewAutoresizing fwt_overlayViewFlexibleMargin;
@property (nonatomic, assign) CGFloat fwt_overlayViewHideAfterDelay;
@property (nonatomic, readonly, assign) CGPoint fwt_overlayViewCenter;

@property (nonatomic, readonly, assign) CGFloat fwt_contentOffsetPercentage;
- (CGFloat)fwt_contentOffsetPercentageClampEnabled:(BOOL)clampEnabled;

@property (nonatomic, readonly, assign) FWTScrollViewDirection fwt_scrollDirection;
@property (nonatomic, copy) FWTOverlayLayoutBlock fwt_layoutBlock;
@property (nonatomic, copy) FWTOverlayDismissBlock fwt_dismissBlock;

@end

0 comments on commit da69997

Please sign in to comment.