Question

I want to be able to pinch zoom on a UIScrollView, so that subviews expand/contract on the the x-axis only.

I create a UIScrollView, and using addSubview to add the UIViews. Each UIView has a UILabel in it. Should I be holding on to these UIViews in an array?

When I zoom I don't want the text size to be affected, just the width of each box. I guess I would need minimum and maximum zoom levels too.

Something like this is used in Apple's garageband app. Any idea how to do this?

1.
-------------------------
|                       |
|  ------   -------  -- |
|  |  1 |   |  2  |  | 3|   < 10 UIView subclass boxes on a UIScollView,
|  |    |   |     |  |  |     with a UILabel in each UIView
|  ------   -------  -- |
|                       |
-------------------------

2.
-------------------------
|                       |
|  ----------   --------|  
|  | 1 more |   | 2     |    < During zoom-in pinch, boxes are stretched
|  |        |   |       |      in x-axis only. Label remains same font size
|  ----------   --------|      and left aligned, showing more text
|                       |
-------------------------
Was it helpful?

Solution

(for the second time in a row, i'm answering my own Q with an answer that is much simpler than the original premise. i guess i should always look from another angle before asking questions..)

For the UIView I want to zoom (x-axis only), I subclass the view and add this method:

- (void)setTransform:(CGAffineTransform)newValue;
{
    newValue.d = 1.0;
    [super setTransform:newValue];
}

Of course I get issues with a UILabel added to this UIView. The label is stretched. So the answer is simply not to add it to the UIView, and instead add it directly to the scroll view. Then, if you have a couple of floats as properties, representing the original x origin and width of the label, you can calculate these, using the scroll view's scale, while the scroll view is zooming:

-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    float scale = self.scrollView.zoomScale;
    self.label.frame = CGRectMake(self.originalXorigin*scale, self.label.frame.origin.y, self.originalWidth*scale, self.label.frame.size.height);
}

OTHER TIPS

Should I be holding on to these UIViews in an array?

This is absolutely personal preference or a design-constraint decision. If you must update these views in a loop, or provide some kind of easy access to modify their content, then yes, they should be stored within some kind of medium (whether that be an array or dictionary is for you to figure out).

I guess I would need minimum and maximum zoom levels too.

You're out of luck then with a regular old UIPinchGestureRecognizer. But honestly, it's not that hard to code in a conditional check for the rect of your view?

Something like this is used in Apple's garageband app. Any idea how to do this?

Sure, make a UIPinchGestureRecognizer object and use the scale property to determine an x factor which you then use to CGAffineTransform() the x scale of your UIView.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top