Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[view setNeedsDisplay] seems to be broken for SVGKLayeredImage #70

Open
Aft3rmathpwnz opened this Issue · 9 comments

2 participants

@Aft3rmathpwnz

I'm developing application which provides user interaction with SVG elements, so as you recommended:

#if ALLOW_SVGKFASTIMAGEVIEW_TO_DO_HIT_TESTING // look how much code this requires! It's insane! Use SVGKLayeredImageView instead if you need hit-testing!

I'm using SVGKLayeredImageView. The problem is when I zoomed my SVG out with code you provided to SVGKLayeredImageView, location of touch in my SVG is incorrect because of SVGKLayeredImageView's bounds didn't change after zoom. So I added this method to my code, as you recommended.

#pragma mark - CRITICAL: this method makes Apple render SVGs in sharp focus
-(void)scrollViewDidEndZooming:(UIScrollView )scrollView withView:(UIView *)view atScale:(float)finalScale
{
/
* NB: very important! The "finalScale" paramter to this method is SLIGHTLY DIFFERENT from the scale that Apple reports in the other delegate methods
This is very confusing, clearly it's bit of a hack - the other methods get called
at slightly the wrong time, and so their data is slightly wrong (out-by-one animation step).
ONLY the values passed as params to this method are correct!
*/

/**

 Apple's implementation of zooming is EXTREMELY poorly designed; it's a hack onto a class
 that was only designed to do panning (hence the name: uiSCROLLview)

 So ... "zooming" via a UIScrollView is NOT integrated with UIView
 rendering - in a UIView subclass, you CANNOT KNOW whether you have been "zoomed"
 (i.e.: had your view contents ruined horribly by Apple's class)

 The three lines that follow are - allegedly - Apple's preferred way of handling
 the situation. Note that we DO NOT SET view.frame! According to official docs,
 view.frame is UNDEFINED (this is very worrying, breaks a huge amount of UIKit-related code,
 but that's how Apple has documented / implemented it!)
 */
NSLog(@"Bounds size - %@", NSStringFromCGSize(self.contentView.bounds.size));
view.transform = CGAffineTransformIdentity; // this alters view.frame! But *not* view.bounds
view.bounds = CGRectApplyAffineTransform( view.bounds, CGAffineTransformMakeScale(finalScale, finalScale));
[view setNeedsDisplay];

/**
 Workaround for another bug in Apple's hacks for UIScrollView:

  - when you reset the transform, as advised by Apple, you "break" Apple's memory of the scroll factor.
     ... because they "forgot" to store it anywhere (they read your view.transform as if it were a private
         variable inside UIScrollView! This causes MANY bugs in applications :( )
 */
self.scrollViewForSVG.minimumZoomScale /= finalScale;
self.scrollViewForSVG.maximumZoomScale /= finalScale;
NSLog(@"Bounds size - %@", NSStringFromCGSize(self.contentView.bounds.size));

}

But another problem which I faced is that [view setNeedsDisplay] seems to be broken, because logged bounds after

view.transform = CGAffineTransformIdentity; // this alters view.frame! But not view.bounds
view.bounds = CGRectApplyAffineTransform( view.bounds, CGAffineTransformMakeScale(finalScale, finalScale));

look correctly, but my SVG image returns to *1 scale factor visually, but when I tap on any area, which means to be some object if only svg redraw would happened, it handles touch on correct object. You can see it in your Demo-iOS project by adding "groups-and-layers-test.svg" for example to case of SVGKLayeredImageView initialization. Thank you!

@adamgit
Owner

This code is complicated and hacky, and if you can find a better way of achieving it, we can add it to the project.

But as it stands, this is the best we've been able to do.

@Aft3rmathpwnz

So the only way to correctly interact with zoomed SVG is using SVGKFastImageView? With those tricks to detect svg object touches?

@adamgit
Owner
@Aft3rmathpwnz

Okay, I'll try. But this is weird that svg scene redrawing after zoom occurs only for FastImage. I'll try to find block of code responsible for this. Thank you

@adamgit
Owner

If you're not using the 1.1.0 branch already, I suggest you re-try with that branch.

There's some deep fixes for edge-cases of size (width, height), and scale (resizing, output image sizes, etc).

Those fixes MIGHT improve things for you.

@Aft3rmathpwnz

Thank you! I'll try it.

@Aft3rmathpwnz

I'm afraid this didn't help ;\

@adamgit
Owner

Another thought: the "Demo-iOS" project now has a tap-detection routine that hilights the layer you've tapped on.

It also has zooming ...

So, you could use it as a test-bed for this, perhaps - see if you can find the root bug here?

NB: Demo-iOS uses "fast" view for everything EXCEPT: Monkey, RainbowWing (monkey uses Layered so it can do animations. Rainbow uses Layered to workaround Apple's bugs which only appear in Fast).

So ... you could use Monkey/Rainbow ... and "any other" ... as your test items to compare between.

I think you'll need to tweak the zoom handler in Demoo-iOS - it has hardcoded limits on how far you can zoom in/out, IIRC it's a oneliner to comment those out.

@Aft3rmathpwnz

thank you again, i will try as soon as possible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.