How to get active subview (UIImageView) from UIScrollView - iphone

I have several UIImage subviews in one UIScrollView. I'm trying to emulate iPhones's Photos app. To enable pinch zooming, I have implemented UIScrollViewDelegate and the one thing I'm unable to figure out is this delegate function:
(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
How do I find out which UIImage subview is currently active?
Something like:
(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return activeUIImageViewSubView;
}

You probably want to keep track yourself of the current UIImage subview.
Or if you have only one visible at a time, look for the one with the coordinate values that make it visible.
If you want to zoom them all at the same time, you may want to group all your UIImage in an intermediate UIView that could be scrolled and panned.

Related

Reposition UIButtons after zoom

I have a scrollview with an imageview on it. I am able to zoom the image view placed inside the scrollview. On top of it I have some uibuttons, which do not reposition after zoom.
How do I reposition UIButtons after zoom?
Please help
Thanks
One way would be to implement the scrollViewDidZoom: delegate method of your scroll view delegate, determine the currently visible rectangle using contentOffset and contentSize properties of your UIScrollView, compute the new location of your buttons relative to the visible rectangle of the scroll view, and reposition your buttons into that rectangle by setting their frame property as desired.
As Fisk mentioned, the UIScrollViewDelegate should help. One of the delegate methods is:
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
If you implement the UIScrollview delegate this method should get called when your scrollview is done zooming. So in this method you can reposition your button after the zoom:
[yourButton1 setCenter:CGPointMake(newX,newY)];
Good luck.
Your question is a bit vague. However, whatever it is that you are doing, I believe UIScrollViewDelegate can help you.
This is a delegate for the scroll view that lets you know when it is scrolling. I never got where the buttons are supposed to be, but with this delegate I guess you can simply place them wherever they need to be.

Create a scrollable menu with UIImages representing each possible selection. These UIImages must be able to snap to the grid one by one

I'm trying to create a menu (using UIScrollView) where the user can select images (using UIImageViews).
I intend to have at least 3 images visible at anytime. When I scroll, the images will be able to snap into position.
However, if I am to use a UIScrollView which is large enough to display 3 images at anyone time, and I enable paging, the paging will move all 3 images together and snap only at the next 3 images.
And if I am to use UIScrollView that fits just 1 image, and I enable clipsToBounds (which helps me draw the images beyond the boundary of the UIScrollView). My figure gestures can only be detected within UIScrollView itself, I want my figure gestures to be detected as long as any of the images are touched.
Thanks.
You can use following method of UIScrollView to scroll it from code as much as you want.
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
you can call this from following method of UIScrowViewDelegate.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
Thus, you can manage how much you scroll view will call.
And for getting touches, implement a separate class that display images(inherit it from UIImageView or UIView) and implement touchesBegin or touchesEnded in that. Here when you get the touch in your custom view call some method of parent view and notify it with proper arguments(you can assign tag property and pass it to scroll view to find exactly which image was tapped).
.....I am not sure weather I am solving your problem or not.....so post here if you need any further assistance.
I wrote a custom UIView class which overrides the hitTest method of UIView.
In the header of the custom UIView class, declare a UIScrollView, later you will need to assign the UIScrollView which is displaying the menu to this variable.
UIScrollView *thatScrollView;
In the implementation, remember to synthesize the variable and overwrite hitTest
#synthesize thatScrollView;
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if ([self pointInside:point withEvent:event]) {
return thatScrollView;
}
return nil;
}
Then in the UIViewController class, create an instance of the class and assign the scrollview you want to scroll:
hiddenView.underneathButton = scrollView1;

How to zoom for an iOS drawing app?

I'm making a drawing application for the iPad where users use one finger to draw lines and rectangles. However, i'm struggling with adding the zoom features.
Some background info of my current code:
There is an appdelegate which sets the view controller
Most of the action takes place inside the view controller including IBActions, popovers, etc.
The xib file uses a custom view i made and this is where all the drawing actions take place
This is what i've done so far:
Inside viewDidLoad, i have
[scrollView setContentSize:CGSizeMake(768, 1024)];
[scrollView setMinimumZoomScale:0.5];
[scrollView setMaximumZoomScale:5];
[scrollView setDelegate:self];
In my xib file, i tried tossing a UIScrollView ontop of my customview (and making the IB connections), but of course, it covers my custom view and you can't draw. I tried the reverse by placing a UIScrollView followed by my own custom view, but i still can't draw either.
Any pointers on what to do?
Add this to your viewController in the .h file:
<UIScrollViewDelegate>
An then this on your .m file:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return backgroundImage;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
NSLog(#"scrollViewDidEndZooming");
}
Also, make sure that in your xib, the scrollview's delegate is linked to File's Owner.
Edit 1:

Problem with UIScrollView and CATiledLayer

I'm working on the example code named PhotoScroller (an Apple's example of WWDC 2010).
There is an UIScrollView which return a custom UIView when zooming
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return imageView;
}
The layer of this imageView is a CATiledLayer.
My problem is for each zoom the drawRect of the imageView is called (so 10 or 30 times for a basic zoom). And then it refresh ALL the screen (so the size given to drawrect in fact).
I would like to refresh some parts of the UIImageView when a zoom occured and not all the screen (so by using setNeedDisplayInRect: instead of setNeedDisplay).
But I don't know how to proceed to avoid the call of this refresh method to do some if else and so refresh some parts of the imageView.
I tried to add an other UIView between the UIScrollView and the subclassed uiview (with catiledlayer). But I don't know how to prevent the subviews to be refreshed :-/
If anyone has an idea, It would be very helpful !
Thanks :-)
Vincent

Can a UIScrollView be adapted to zoom horizontally but not vertically? (how)

I'm trying to make a timeline view that shows events as UIButtons that can be pressed for more info.
Ideally I want to lay out the buttons on a UIScrollView, and allow them to stretch/shrink horizontally, but not vertically.
What I'm trying to accomplish would basically be equivalent to using pinch gestures to resize the content view, and using a scroll view to move side to side - could you point me in the right direction, or suggest how you might accomplish something like this?
My first thought is a UIScrollView to scale a UIView subview, and have the UIView subview contain another subview that does not resize vertically, but only does horizontally when bounds change, and disable vertical scrolling. Maybe I could skip one of these UIView subviews and have only one do everything. It just feels like I'm trying to hack this together like an HTML page or something with all these containers.
Not sure if I've explained any of this well enough to hope for an answer, any help is appreciated though.
I've implemented horizontal-only scaling by creating a subclass of UIView that simply overrides setTransform and sets the Y scale to 1 whenever the UIScrollView changes the scale:
#interface DiagramStripView : UIView { }
#end
#implementation DiagramStripView
- (void)setTransform:(CGAffineTransform)newValue;
{
newValue.d = 1.0;
[super setTransform:newValue];
}
#end
As the class name suggests, my view holds a series of diagrams that are each one screen wide. When the user lets go, the view controller resets the view's scale to 1 and redraws everything to the new scale:
- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView
withView:(UIView *)view atScale:(float)scale
{
diagramStripView.transform = CGAffineTransformIdentity;
[self redrawDiagrams:scale];
}
Haven't tried this, but you could try placing everything in a UIScrollView, and whenever you detect a zoom level change, adjust all of the child view transforms to CGAffineTransformMakeScale(1.0, 1.0/zoomLevel). This way, the scrollview is zooming everything up, but each subview is scaling themselves vertically downward, canceling out the zoom.
Assuming you don't actually want to stretch/shrink the button text, the easiest way is to resize all the buttons. I know, it's a pain.