Skip to content

Commit ea6c2b0

Browse files
author
Martin Kluska
committed
- improved detection when resize can be applied for better gesture handling.
1 parent 5673e1b commit ea6c2b0

3 files changed

Lines changed: 58 additions & 38 deletions

File tree

SPUserResizableView/SPUserResizableView.m

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ - (void)drawRect:(CGRect)rect {
5656
CGRect middleRight = CGRectMake(self.bounds.size.width - [self interactiveBorderSize], (self.bounds.size.height - [self interactiveBorderSize])/2, [self interactiveBorderSize], [self interactiveBorderSize]);
5757

5858
// (3) Create the gradient to paint the anchor points.
59-
CGFloat colors [] = {
60-
0.4, 0.8, 1.0, 1.0,
59+
CGFloat colors [] = {
60+
0.4, 0.8, 1.0, 1.0,
6161
0.0, 0.0, 1.0, 1.0
6262
};
6363
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
@@ -110,6 +110,13 @@ -(void)setAnchorPoint:(CGPoint)anchor;
110110
*/
111111
- (BOOL)isDisabledForTouches:(NSSet*)touches;
112112

113+
/**
114+
* Checks if user did change the view
115+
*
116+
* @return BOOL
117+
*/
118+
- (BOOL)willResize:(CGPoint)point;
119+
113120
@end
114121

115122
@implementation SPUserResizableView
@@ -182,9 +189,11 @@ - (void)setContentView:(UIView *)newContentView {
182189
- (void)setFrame:(CGRect)newFrame {
183190
[super setFrame:newFrame];
184191

185-
contentView.frame = CGRectInset(self.bounds, [self resizableInset] + [self interactiveBorderSize]/2, [self resizableInset] + [self interactiveBorderSize]/2);
186-
borderView.frame = CGRectInset(self.bounds, [self resizableInset], [self resizableInset]);
187-
[borderView setNeedsDisplay];
192+
if (contentView) {
193+
contentView.frame = CGRectInset(self.bounds, [self resizableInset] + [self interactiveBorderSize]/2, [self resizableInset] + [self interactiveBorderSize]/2);
194+
borderView.frame = CGRectInset(self.bounds, [self resizableInset], [self resizableInset]);
195+
[borderView setNeedsDisplay];
196+
}
188197
}
189198

190199
static CGFloat SPDistanceBetweenTwoPoints(CGPoint point1, CGPoint point2) {
@@ -217,7 +226,7 @@ - (SPUserResizableViewAnchorPoint)anchorPointForTouchLocation:(CGPoint)touchPoin
217226
CGFloat smallestDistance = MAXFLOAT; CGPointSPUserResizableViewAnchorPointPair closestPoint = centerPoint;
218227
for (NSInteger i = 0; i < 9; i++) {
219228
CGFloat distance = SPDistanceBetweenTwoPoints(touchPoint, allPoints[i].point);
220-
if (distance < smallestDistance) {
229+
if (distance < smallestDistance) {
221230
closestPoint = allPoints[i];
222231
smallestDistance = distance;
223232
}
@@ -242,13 +251,17 @@ - (BOOL)isDisabledForTouches:(NSSet*)touches {
242251
return ([self disable] || ([self disableOnMultiTouch] && [touches count] > 1));
243252
}
244253

254+
- (BOOL)willResize:(CGPoint)point {
255+
// dermine if we will make resize
256+
return [self isResizing] && (point.x != touchStart.x && point.y != touchStart.y);
257+
}
245258

246259
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
247260
if ([self isDisabledForTouches:touches]) {
248261
return;
249262
}
250263

251-
m_originalAnchorPoint = [[self layer] anchorPoint];
264+
//m_originalAnchorPoint = [[self layer] anchorPoint];
252265

253266
// Notify the delegate we've begun our editing session.
254267
if (self.delegate && [self.delegate respondsToSelector:@selector(userResizableViewDidBeginEditing:)]) {
@@ -269,8 +282,10 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
269282
}
270283

271284
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
272-
273-
[self setAnchorPoint:m_originalAnchorPoint];
285+
if ([self isDisabledForTouches:touches]) {
286+
return;
287+
}
288+
//[self setAnchorPoint:m_originalAnchorPoint];
274289

275290
// Notify the delegate we've ended our editing session.
276291
if (self.delegate && [self.delegate respondsToSelector:@selector(userResizableViewDidEndEditing:)]) {
@@ -279,8 +294,11 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
279294
}
280295

281296
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
282-
283-
[self setAnchorPoint:m_originalAnchorPoint];
297+
if ([self isDisabledForTouches:touches]) {
298+
return;
299+
}
300+
301+
//[self setAnchorPoint:m_originalAnchorPoint];
284302

285303
// Notify the delegate we've ended our editing session.
286304
if (self.delegate && [self.delegate respondsToSelector:@selector(userResizableViewDidEndEditing:)]) {
@@ -373,14 +391,14 @@ - (void)resizeUsingTouchLocation:(CGPoint)touchPoint {
373391

374392
end.x = touchStart.y;
375393
end.y = touchPoint.x;
376-
//} else if (-135.0 > rotationDeg) {
377-
394+
//} else if (-135.0 > rotationDeg) {
395+
378396
} else if (rotationDeg > 135.0 || -135.0 > rotationDeg) {
379397
start = touchPoint;
380398
end = touchStart;
381399
}
382400

383-
401+
384402

385403
CGFloat deltaW = anchorPoint.adjustsW * (start.x - end.x) / scaleX;
386404
CGFloat deltaX = anchorPoint.adjustsX * (-1.0 * deltaW);
@@ -395,35 +413,35 @@ - (void)resizeUsingTouchLocation:(CGPoint)touchPoint {
395413

396414
// (4) If the new frame is too small, cancel the changes.
397415
if (newWidth < self.minWidth) {
398-
newWidth = self.bounds.size.width;
416+
newWidth = self.minWidth;
399417
newX = self.frame.origin.x;
400418
}
401419
if (newHeight < self.minHeight) {
402-
newHeight = self.bounds.size.height;
420+
newHeight = self.minHeight;
403421
newY = self.frame.origin.y;
404422
}
405423

406424
// (5) Ensure the resize won't cause the view to move offscreen.
407425
if (self.preventsPositionOutsideSuperview) {
408426
/*
409-
if (newX < self.superview.bounds.origin.x) {
410-
// Calculate how much to grow the width by such that the new X coordintae will align with the superview.
411-
deltaW = self.frame.origin.x - self.superview.bounds.origin.x;
412-
newWidth = self.frame.size.width + deltaW;
413-
newX = self.superview.bounds.origin.x;
414-
}
415-
if (newX + newWidth > self.superview.bounds.origin.x + self.superview.bounds.size.width) {
416-
newWidth = self.superview.bounds.size.width - newX;
417-
}
418-
if (newY < self.superview.bounds.origin.y) {
419-
// Calculate how much to grow the height by such that the new Y coordintae will align with the superview.
420-
deltaH = self.bounds.origin.y - self.superview.bounds.origin.y;
421-
newHeight = self.frame.size.height + deltaH;
422-
newY = self.superview.bounds.origin.y;
423-
}
424-
if (newY + newHeight > self.superview.bounds.origin.y + self.superview.bounds.size.height) {
425-
newHeight = self.superview.bounds.size.height - newY;
426-
}*/
427+
if (newX < self.superview.bounds.origin.x) {
428+
// Calculate how much to grow the width by such that the new X coordintae will align with the superview.
429+
deltaW = self.frame.origin.x - self.superview.bounds.origin.x;
430+
newWidth = self.frame.size.width + deltaW;
431+
newX = self.superview.bounds.origin.x;
432+
}
433+
if (newX + newWidth > self.superview.bounds.origin.x + self.superview.bounds.size.width) {
434+
newWidth = self.superview.bounds.size.width - newX;
435+
}
436+
if (newY < self.superview.bounds.origin.y) {
437+
// Calculate how much to grow the height by such that the new Y coordintae will align with the superview.
438+
deltaH = self.bounds.origin.y - self.superview.bounds.origin.y;
439+
newHeight = self.frame.size.height + deltaH;
440+
newY = self.superview.bounds.origin.y;
441+
}
442+
if (newY + newHeight > self.superview.bounds.origin.y + self.superview.bounds.size.height) {
443+
newHeight = self.superview.bounds.size.height - newY;
444+
}*/
427445
}
428446

429447
// update the frame
@@ -442,7 +460,7 @@ - (void)resizeUsingTouchLocation:(CGPoint)touchPoint {
442460
}
443461

444462
- (void)translateUsingTouchLocation:(CGPoint)touchPoint {
445-
[self setAnchorPoint:CGPointMake(0.5, 0.5)];
463+
//[self setAnchorPoint:CGPointMake(0.5, 0.5)];
446464

447465
CGPoint newCenter = CGPointMake(self.center.x + touchPoint.x - touchStart.x, self.center.y + touchPoint.y - touchStart.y);
448466

@@ -490,8 +508,10 @@ -(void)setAnchorPoint:(CGPoint)anchor {
490508
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
491509
// is disabled or there are more touches
492510
if (![self isDisabledForTouches:touches]) {
493-
if ([self isResizing]) {
494-
[self resizeUsingTouchLocation:[[touches anyObject] locationInView:self.superview]];
511+
CGPoint point = [[touches anyObject] locationInView:self.superview];
512+
513+
if ([self isResizing] && [touches count] == 1 && [self willResize:point]) {
514+
[self resizeUsingTouchLocation:point];
495515
} else if (![self disablePan]){
496516
[self translateUsingTouchLocation:[[touches anyObject] locationInView:self]];
497517
}

SPUserResizableView/ViewController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ - (void)viewDidLoad {
3939

4040
imageResizableView.contentView = imageView;
4141
imageResizableView.delegate = self;
42-
imageResizableView.disablePan = YES;
42+
imageResizableView.disablePan = NO;
4343

4444
[imageResizableView setTransform:CGAffineTransformMakeRotation(0.1)];
4545

0 commit comments

Comments
 (0)