Skip to content

Commit

Permalink
Merge branch 'release-1.5.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
odrobnik committed Jul 6, 2015
2 parents f8dbef0 + ee1b22c commit 7129fa4
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 139 deletions.
12 changes: 6 additions & 6 deletions Core/Source/DTLoupeLayerDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ - (void)refreshLoupeContent;

@implementation DTLoupeLayerDelegate
{
DTLoupeView *_loupeView;
DTLoupeView *_loupeView;
}

- (instancetype)initWithLoupeView:(DTLoupeView *)loupeView
{
self = [super init];
self = [super init];

if (self)
if (self)
{
_loupeView = loupeView;
}
_loupeView = loupeView;
}

return self;
return self;
}

- (void)displayLayer:(CALayer *)layer
Expand Down
8 changes: 4 additions & 4 deletions Core/Source/DTLoupeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ typedef NS_ENUM(NSUInteger, DTLoupeStyle)
/**
Loupe is a circle
*/
DTLoupeStyleCircle = 0,
DTLoupeStyleCircle = 0,

/**
Loupe is a ranged rectangle without arrow
*/
DTLoupeStyleRectangle,
DTLoupeStyleRectangle,

/**
Loupe is a ranged rectangle with arrow
*/
DTLoupeStyleRectangleWithArrow,
DTLoupeStyleRectangleWithArrow,
};

extern NSString * const DTLoupeDidHide;
Expand Down Expand Up @@ -89,7 +89,7 @@ extern NSString * const DTLoupeDidHide;
@property(nonatomic,assign) BOOL seeThroughMode;

/**
The loupe style.
The loupe style.
Available loupe styles are:
Expand Down
185 changes: 110 additions & 75 deletions Core/Source/DTLoupeView.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ @implementation DTLoupeView
UIImage *_loupeFrameBackgroundImage;
UIImage *_loupeFrameMaskImage;

// look-through-mode, used while scrolling
// look-through-mode, used while scrolling
BOOL _seeThroughMode;

// Draws cross hairs for debugging
Expand Down Expand Up @@ -130,29 +130,29 @@ - (id)init

// --- setup up layers ---

CGFloat scale = [UIScreen mainScreen].scale;
CGFloat scale = [UIScreen mainScreen].scale;
// layer with lo image of loupe
_loupeFrameBackgroundImageLayer = [CALayer layer];
_loupeFrameBackgroundImageLayer.contentsScale = scale;
_loupeFrameBackgroundImageLayer.contentsScale = scale;
[self.layer addSublayer:_loupeFrameBackgroundImageLayer];

// maks for the loupe contents layer
_loupeContentsMaskLayer = [CALayer layer];
_loupeContentsMaskLayer.transform = CATransform3DMakeScale(1.0f, -1.0f, 1.0f);
_loupeContentsMaskLayer.contentsScale = scale;
_loupeContentsMaskLayer.contentsScale = scale;

// layer with contents of the loupe
_loupeContentsLayer = [CALayer layer];
_layerDelegate = [[DTLoupeLayerDelegate alloc] initWithLoupeView:self];
_loupeContentsLayer.delegate = _layerDelegate;
_loupeContentsLayer.delegate = _layerDelegate;
_loupeContentsLayer.mask = _loupeContentsMaskLayer;
_loupeContentsLayer.contentsScale = scale;
_loupeContentsLayer.contentsScale = scale;
[self.layer addSublayer:_loupeContentsLayer];

// layer with hi image of loupe
_loupeFrameImageLayer = [CALayer layer];
_loupeFrameImageLayer.contentsScale = scale;
_loupeFrameImageLayer.contentsScale = scale;
[self.layer addSublayer:_loupeFrameImageLayer];
}

Expand Down Expand Up @@ -269,7 +269,7 @@ - (UIInterfaceOrientation)_inferredInterfaceOrientation
return orientation;
}
}

// last resort, get it from device, might fail for face up and face down
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];

Expand Down Expand Up @@ -341,9 +341,9 @@ - (CGAffineTransform)_loupeWindowTransform
- (void)adjustBaseViewIfNecessary
{
UIWindow *loupeWindow = [DTLoupeView loupeWindow];

NSAssert(self.superview, @"Sombody removed DTLoupeView from superview!!");

CGAffineTransform transform = [self _loupeWindowTransform];

BOOL sameFrame = (CGRectEqualToRect(loupeWindow.frame, _targetRootView.frame));
Expand Down Expand Up @@ -408,15 +408,15 @@ - (void)setTouchPoint:(CGPoint)touchPoint
// Set touchPoint as user moves around screen
_touchPoint = touchPoint;

CGPoint pointInWindow = [_targetView.window convertPoint:_touchPoint fromView:_targetView];
CGPoint pointInWindow = [_targetView.window convertPoint:_touchPoint fromView:_targetView];
CGPoint convertedLocation = [[DTLoupeView loupeWindow] convertPoint:pointInWindow fromWindow:_targetView.window];

// additional NAN check for safety
if (isnan(convertedLocation.x) || (isnan(convertedLocation.y)))
{
return;
}
// additional NAN check for safety
if (isnan(convertedLocation.x) || (isnan(convertedLocation.y)))
{
return;
}
CGPoint newCenter = convertedLocation;
CGPoint offsetFromTouchPoint = [DTLoupeView offsetFromCenterForLoupeStyle:_style];

Expand Down Expand Up @@ -464,47 +464,47 @@ - (void)presentLoupeFromLocation:(CGPoint)location
self.transform = CGAffineTransformAndScaleMake(0.25, 0.25, offset.x, offset.y);

[UIView animateWithDuration:DTLoupeAnimationDuration
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1.0;
self.transform = CGAffineTransformIdentity;
}
completion:^(BOOL finished) {
}];
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.alpha = 1.0;
self.transform = CGAffineTransformIdentity;
}
completion:^(BOOL finished) {
}];
}

- (void)dismissLoupeTowardsLocation:(CGPoint)location
{
[UIView animateWithDuration:DTLoupeAnimationDuration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut
animations:^{
// circular loupe does not fade
self.alpha = (_style == DTLoupeStyleCircle)?1.0:0.0;

// calculate transform
CGPoint convertedLocation = [_targetView convertPoint:location toView:self.superview];
CGPoint offset = CGPointMake(convertedLocation.x - self.center.x, convertedLocation.y - self.center.y);
self.transform = CGAffineTransformAndScaleMake(0.05, 0.05, offset.x, offset.y);
}
completion:^(BOOL finished) {
// hide it completely
self.alpha = 0;

// reset transform to get correct offset on next present
self.transform = CGAffineTransformIdentity;

// reset images so that we don't get old contents flashing in next present.
_loupeFrameBackgroundImageLayer.contents = nil;
_loupeContentsMaskLayer.contents = nil;
_loupeContentsLayer.contents = nil;
_loupeFrameImageLayer.contents = nil;

// keep it in view hierarchy

[[NSNotificationCenter defaultCenter] postNotificationName:DTLoupeDidHide object:self];
}];
delay:0
options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut
animations:^{
// circular loupe does not fade
self.alpha = (_style == DTLoupeStyleCircle)?1.0:0.0;
// calculate transform
CGPoint convertedLocation = [_targetView convertPoint:location toView:self.superview];
CGPoint offset = CGPointMake(convertedLocation.x - self.center.x, convertedLocation.y - self.center.y);
self.transform = CGAffineTransformAndScaleMake(0.05, 0.05, offset.x, offset.y);
}
completion:^(BOOL finished) {
// hide it completely
self.alpha = 0;
// reset transform to get correct offset on next present
self.transform = CGAffineTransformIdentity;
// reset images so that we don't get old contents flashing in next present.
_loupeFrameBackgroundImageLayer.contents = nil;
_loupeContentsMaskLayer.contents = nil;
_loupeContentsLayer.contents = nil;
_loupeFrameImageLayer.contents = nil;
// keep it in view hierarchy
[[NSNotificationCenter defaultCenter] postNotificationName:DTLoupeDidHide object:self];
}];
}

- (BOOL)isShowing
Expand All @@ -517,39 +517,74 @@ - (BOOL)isShowing
// only used for the content layer, draws the view hierarchy of the target root view
- (void)refreshLoupeContent
{
if (_seeThroughMode)
{
return;
}
if (_seeThroughMode)
{
return;
}

UIGraphicsBeginImageContextWithOptions(_loupeContentsLayer.bounds.size, YES, 0);

CGContextRef ctx = UIGraphicsGetCurrentContext();

// **** Draw our Target View Magnified and correctly positioned ****

// move touchpoint by offset
CGPoint offsetTouchPoint = _touchPoint;
offsetTouchPoint.x += _touchPointOffset.width;
offsetTouchPoint.y += _touchPointOffset.height;

CGPoint convertedLocation = [_targetView convertPoint:offsetTouchPoint toView:_targetRootView];

// Translate Right & Down, Scale and then shift back to touchPoint
CGContextTranslateCTM(ctx, self.frame.size.width * 0.5 + _magnifiedImageOffset.x,(self.frame.size.height * 0.5) + _magnifiedImageOffset.y);
CGContextScaleCTM(ctx, _magnification, _magnification);

CGContextTranslateCTM(ctx,-convertedLocation.x, -convertedLocation.y);

// the loupe is not part of the rendered tree, so we don't need to hide it
[_targetRootView.layer renderInContext:ctx];
// **** Draw our Target View Magnified and correctly positioned ****

// move touchpoint by offset
CGPoint offsetTouchPoint = _touchPoint;
offsetTouchPoint.x += _touchPointOffset.width;
offsetTouchPoint.y += _touchPointOffset.height;

CGPoint convertedLocation = [_targetView convertPoint:offsetTouchPoint toView:_targetRootView];

// Translate Right & Down, Scale and then shift back to touchPoint
CGContextTranslateCTM(ctx, self.frame.size.width * 0.5 + _magnifiedImageOffset.x,(self.frame.size.height * 0.5) + _magnifiedImageOffset.y);
CGContextScaleCTM(ctx, _magnification, _magnification);

CGContextTranslateCTM(ctx,-convertedLocation.x, -convertedLocation.y);

// On iOS 8, layers with invalid (x/y) or a frame equal to CGRectZero cause renderInContext: to fail.
// Hide those layers here to prevent that.
[self hideInvalidLayersInView:_targetRootView];

// the loupe is not part of the rendered tree, so we don't need to hide it
[_targetRootView.layer renderInContext:ctx];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
_loupeContentsLayer.contents = (__bridge id)(image.CGImage);

UIGraphicsEndImageContext();
}

- (void)hideInvalidLayersInView:(UIView *)rootView
{
if ([self layerHasInvalidFrame:rootView.layer])
{
rootView.layer.hidden = YES;
}

for (UIView *view in rootView.subviews)
{
if ([self layerHasInvalidFrame:view.layer])
{
view.layer.hidden = YES;
}

for (CALayer *layer in view.layer.sublayers)
{
if ([self layerHasInvalidFrame:layer])
{
layer.hidden = YES;
}
}

[self hideInvalidLayersInView:view];
}
}

- (BOOL)layerHasInvalidFrame:(CALayer *)layer
{
return CGRectIsEmpty(layer.bounds) || isnan((CGRectGetMinX(layer.frame))) || isnan((CGRectGetMinY(layer.frame)));
}

- (void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer!=self.layer)
Expand Down
6 changes: 3 additions & 3 deletions DTLoupe.podspec
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Pod::Spec.new do |spec|
spec.name = 'DTLoupe'
spec.version = '1.5.5'
spec.version = '1.5.6'
spec.platform = :ios, '4.3'
spec.license = 'COMMERCIAL'
spec.source = { :git => '[email protected].com:parts/dtloupe.git', :tag => spec.version.to_s }
spec.license = 'BSD'
spec.source = { :git => 'https://github.com/Cocoanetics/DTLoupe.git', :tag => spec.version.to_s }
spec.source_files = 'Core/Source/*.{h,m}'
spec.frameworks = 'QuartzCore'
spec.requires_arc = true
Expand Down
12 changes: 4 additions & 8 deletions DTLoupe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@
0F01D88313B248CA00419BD7 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0600;
ORGANIZATIONNAME = sendmetospace.co.uk;
LastUpgradeCheck = 0640;
ORGANIZATIONNAME = cocoanetics.com;
};
buildConfigurationList = 0F01D88613B248CA00419BD7 /* Build configuration list for PBXProject "DTLoupe" */;
compatibilityVersion = "Xcode 3.2";
Expand Down Expand Up @@ -509,7 +509,7 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
Expand All @@ -523,7 +523,7 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
};
Expand All @@ -539,7 +539,6 @@
GCC_PREFIX_HEADER = "Demo/Demo-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "Demo/Demo-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
Expand All @@ -554,7 +553,6 @@
GCC_PREFIX_HEADER = "Demo/Demo-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "Demo/Demo-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
PRODUCT_NAME = "$(TARGET_NAME)";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
Expand All @@ -581,7 +579,6 @@
);
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = DTLoupe;
Expand All @@ -604,7 +601,6 @@
GCC_PREFIX_HEADER = "Core/DTLoupe-Prefix.pch";
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = DTLoupe;
Expand Down
Loading

0 comments on commit 7129fa4

Please sign in to comment.