How to change attribute value? #77

soundtravel opened this Issue May 4, 2013 · 9 comments

5 participants


My svg is like this:

And I try to change the "fill" attribute of element "polygon" and render the SVGKLayeredImageView again.
I have already got the element "polygon",here is my code:
[element setAttribute:@"fill" value:@"#000000"];

But sadly it did not work.
Did I use the wrong method? Can anyone give me some suggestions?

Thanks !


Github has stripped out part of your post, sorry :(.


  1. If you change anything in the DOM (i.e. anything using DOM methods such as setAttribute:value: ... or anything acting upon DOM subclasses (Node, Element, SVGElement - and anything that extends them

...then your changes will NOT change your output image unless you regenerate the image by calling "SVGKImage.CALayerTree" or "[SVGKImage newCALayerTree]" and doing something with the output (e.g. assigning it to an SVGKLayeredImageView's layer)

  1. If you want to directly change values to render on screen, it's better to find the CALayer object that matches your SVGElement object (there are methods in SVGKImage to help with this, I think), and change values on the CALayer isntead (it's usually a CAShapeLayer, with properties like ".fillColor"

... these changes will be refleced IMMEDIATELY in an SVGKLayeredImageView. c.f.


Hi Adam,

Having trouble with this right now and found this issue, wondering if you can give me some pointers:

- (void)colorSketch:(UIColor *)newColor
    [self colorElement:self.svgImage.DOMTree color:newColor];
    [self.svgImage newCALayerTree];
    self.svgView.image = nil;
    self.svgView.image = self.svgImage;
    [self.svgView setNeedsDisplay];

- (void)colorElement:(SVGElement *)element color:(UIColor *)color {
    if ([element isKindOfClass:[BaseClassForAllSVGBasicShapes class]]) {
        NSString *colorVal = [color stringValue];
        [element setAttributeNS:@"" qualifiedName:@"fill" value:colorVal];
    for (SVGElement *subelement in element.childNodes) {
        [self colorElement:subelement color:color];

self.svgView is a FastImageView - I can't use LayeredImageView since it doesn't seem to respect transforms (the imageview is being scaled/rotated/moved by user input). Plus I need to persist the edits since the SVGKImage is later used to render to a UIImage (via SVGKImage.UIImage).

The setAttribute call works - and I can verify that the new fill color is in the DOM tree. I can't get the new color to reflect in either the FastImageView, or the rendered UIImage. Is there something I must do to update after making attribute changes?

[EDIT] The following appears to work (but is a bit ugly since it involves reaching into a private member...)

self.svgImage.CALayerTree = nil;
[self.svgImage CALayerTree];

This seems to regenerate correctly. If there is a less invasive/less hacky way to do this, please let me know!


Try this; (The fill attr is working, but width and height is not changing.)

Nodelist *list= [image.DOMDocument getElementsByTagName:@"*"];
for (SVGElement *svgElement in list){
[svgElement setAttributeNS:@"" qualifiedName:@"width" value:@"1100px"];
[svgElement setAttributeNS:@"" qualifiedName:@"fill" value:@"rgb(100, 100, 100)"];
[self.view.layer addSublayer: [image newCALayerTree] or [image CALayerTree];];


I'm trying to update value of "viewbox" attribute.But the change is not reflecting.
I have tried the above methods but still the same.

I think'm doing something wrong.
It'll be great if anyone can help me out with a code snippet.
Sharing my code :

        SVGKImage* svgImage = [SVGKImage imageWithContentsOfURL:url];
        CGContextRef context = UIGraphicsGetCurrentContext();
        [svgImage addObserver:svgImage forKeyPath:@"DOMTree.viewport" options:NSKeyValueObservingOptionOld context:context];

        NSString* tagToFind = @"svg";
        NodeList* result = [svgImage.DOMDocument getElementsByTagName:tagToFind];

        for( Element* domElement in result )
            SVGElement* svgElement = (SVGElement*) domElement;
            [svgElement setAttributeNS:@"" qualifiedName:@"viewBox" value:@"0 0 160 160"];


[cell.imageView.layer addSublayer:[svgImage CALayerTree]];

Thanks in advance,


Thanks Adam for the quick reply.
I'll avoid using do it.

I'm loading svgz images from remote url.
Some svgz are rendering and some are not.

So i was trying hit and trial method by adding few attributes.
If we leave out viewport for now.
If i just want to add width and height attribute.

The image is not getting updated from the code shared earlier.
Any pointers on that?

Thanks in advance


Use "newCALayerTree" if you want it to regeenrate


Thanks Adams.

Still the same. But now my app is not crashing in any case.
Will try some way to render the svgz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment