Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering content after zoomed in for UIScrollView

Tags:

iphone

I've looked around and it seems like people say you can re-render the data after you zoom in now that you know the scale factor for UIScrollView. I've also seen some posts about making your layer to a CATiledLayer and set the levelsOfDetailBias and levelsOfDetail.

What I have is a UIScrollView, and in it, a ResultsView which is a subclass of UIView:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        CATiledLayer *tiledLayer = (CATiledLayer *)self.layer;
        tiledLayer.levelsOfDetailBias = 3;
        tiledLayer.levelsOfDetail = 3;
        self.opaque = YES;
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

+ (Class)layerClass {
    return [CATiledLayer class];
}

In my class where I have the UIScrollView and ResultsView, I do:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.ResultsView;
}

Is this enough to have the text rerendered (sharp)? Or do I need to implement something in

 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
 }

If so, I'm not sure how to do that. In my class with UIScrollView and ResultsView, in ResultsView (in the XIB), I just have a couple of UILabels and UIViews (UIViews used for headings/footers for the view). So I do not know how to redraw those from ResultsView. Although ResultsView has the UILabels and UIViews as children of it in the XIB, I'm not sure how I would redraw those from the ResultsView class, and what I would need to do anyway.

Or is this the wrong approach? Do I just need to resize the UILabel and UIView by the scale factor in the scrollViewDidEndZooming: delegate method? TIA

like image 475
J W Avatar asked Oct 05 '11 18:10

J W


2 Answers

I think you are taking the wrong approach. If your view consists of UILabels and UIViews that do not do any custom drawing, I would not mess with using a CATiledLayer backed view. Instead implement the scrollViewDidEndZooming:withView:atScale: delegate method and do something like this:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    scale *= [[[self.scrollView window] screen] scale];
    [view setContentScaleFactor:scale];
    for (UIView *subview in view.subviews) {
        [subview setContentScaleFactor:scale];
    }
}
like image 192
Aaron Avatar answered Oct 29 '22 00:10

Aaron


I have something small to add to the accepted solution that caused me a few minutes of pain just in case anyone else runs into the same thing.

Looping through all subviews in the view you're zooming and calling setContentScaleFactor doesn't take into account if any of the subviews themselves have subviews. If you have a more complicated setup like that, make sure to also loop through the subviews of those container views and call

[subview setContentScaleFactor:scale];

on each. I made a method that I can invoke to call setContentScaleFactor on all the subviews of a given view and call that for each "container view" on the screen.

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 
{
    scale *= [[[self.scrollView window] screen] scale];
    [view setContentScaleFactor:scale];
    for (UIView *subview in view.subviews) 
    {
        [self setContentSizeForView:subview andScore:scale];

        //Loop through all the subviews inside the subview
        for(UIView *subSubview in subview.subviews)
        {
            [self setContentSizeForView:subSubview andScale:scale];
        }
    }
}

- (void) setContentSizeForView:(UIView*) view andScale:(float)scale
{
    [view setContentScaleFactor:scale];
}
like image 44
DiscDev Avatar answered Oct 29 '22 02:10

DiscDev