I have this subclass of UIScrollView:
#interface MyScrollView : UIScrollView <UIScrollViewDelegate>
And I have those delegate methods
- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale(float)aScale{
NSLog(#"zoomed");
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)aScrollView{
NSLog(#"willzoom");
}
When I zoom in MyScrollView viewForZoomingInScrollView is called but scrollViewDidEndZooming never gets called.
Any idea why??
Ok, completely revised answer based on your comment below. This may just be another typo, but your method signature is missing the final parameter.
Instead of:
- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale{
NSLog(#"zoomed");
}
You should have:
- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale:(float)aScale{
NSLog(#"zoomed");
}
Sorry to bump the thread, but it is a very important question. You don't say whether you are implementing a separate pinch gesture recogniser or using the built in zooming of UIScrollView. From my own researches I have found that if you just use UIScrollView to zoom it calls viewForZoomingInScrollView to get the view you want to zoom. Then it calls scrollViewWillBeginZooming, then as it zooms it calls scrollViewDidZoom repeatedly and when it finished it calls scrollViewDidEndZooming. All as you would expect.
However, if you implement your own pinch gesture recognizer to make the zoom smoother or for any other reason, it only calls viewForZoomingInScrollView at the start and scrollViewDidZoom repeatedly. I think this is because you have overridden the built in zoom functionality that calls the other methods.
If you need more control put it into an action method connected to the pinch gesture recogniser.
Related
Is there any notification sent when UIScrollView changes its scroll state? I would like to listen to that notification rather than using delegate methods.
If you don't want to use delegate methods you can observe contentOffset value changes using KVO (key-value-observing)
You can subclass UIScrollView, overload touchesMoved:withEvent:, and send this notification every time your scroll view will scroll.
As the scrolls need to be lightweight events I would not recommend using notifications for every scroll as it will impact your performance much greater than using a delegate method.
These are the delegates that handle scrolling for UIScrollView.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
Is there any specific reason you dont prefer delegates & want notifications? So you can use scrollViewDidScroll for any changes in scroll state.
i need to add NSViewBoundsDidChangeNotification to my iphone application to check if user has scrolled the tableview,however to add this i think i need to import the nsview class.from where should i add this class to my project.and i need to confirm is this the best way to check if my tableview is scrolled by user?
NSView does not exist on the iPhone, as it uses Cocoa-Touch and not Cocoa.
If you want to get notifications about a UITableView's scroll events, just implement the UIScrollView delegate. It's documented here.
The delegate method you'll want to use is this one:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
}
There are other handy methods in there though, like:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
}
NSView has nothing to do with IOS development.
UITableView is a subclass of UIScrollView, and UITableViewDelegate conforms to UIScrollViewDelegate. This means that the delegate you set on your UITableView will get all the calls defined for UIScrollViewDelegate, including scrollViewDidScroll:.
So I wanted to make my UIWebview respon to touch events. I have read several topics about this. I created a Subclass of UIWebView, added it so my UIViewController and linked it via IB.
In my Subclass, i overrode touches ended and called [super touchedEnded]. didnt help.
I overrode hittest, but it doesnt call super either!
If I add this code to my subclassed UIWebView:
#implementation UIWebView (CustomView)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(#"hit");
return self;
}
#end
then the touches ar forwarded to the superclass, but hittest is not(!)and additionally the webview stops scrolling.
Well, I want so recognize a touch in my webview and pass it to super - what am I doing wrong?
EDIT:
I'm wondering, why so many suggestions include using 'hittest' - this results in being unable to scroll your webview.....any ideas?
Answering my own question here - this is the version that did what I wanted: The right way. This is about subclassing UIWindow and passing on the events caught.
I would still love some explanations to my previous questions tho :P
In the iPhone 3.0 SDK, how can I be informed when a zoomToRect:animated: animation completes?
Sometimes the scrollview doesn't zoom at all (if it's already at the proper zoom level), and there doesn't seem to be a way to detect that.
On your delegate, you can listen for - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
see UIScrollView and UIScrollViewDelegate
The easiest way would probably to put in a check before starting the animation. If the zoom level is already correct, call [self performSelectorOnMainThread:#selector(myMethod) withObject:id waitUntilDone:NO].
You won't be able to use the same method as scrollViewDidEndZooming, because you can only pass one argument, but it will trigger an asynchronous call on the main thread
I have added several UIScrollViews as subviews of a single UIView and set the frames so that each one is clearly visable. I set scrollEnabled to YES and set the contentSize larger than the bounds/frame. I do this in a for loop, and with each pass of the loop I release the UIScrollView (though the object is still stored because it has been subviewed into the UIView). This works well for being able to scroll around the imageView stored in each particular UIScrollView but I cannot for the life of me figure out how to get the zoom to work. I included the in the interface. Here are the methods I have tried for choosing the correct view for zooming:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[myView subviews] objectAtIndex:pageNum];
}
and
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [myView viewWithTag:pageNum];
}
neither seems to work. The weird part is that scrolling works fine. I can't even get the viewForZooming method to get called at all if I put in an NSLog call. Any ideas? I think I've lost all my hair from getting frustrated with this.
Edit: Thanks a lot cduhn! All I needed was that little bump, I had forgotten to set the scrollView delegate to self... I've been working with various apps that take advantage of UIScrollView for months now and been using the delegate correctly and this most recent one I don't know where my brain went.
However, you do not need to override the scrollViewDidEndZooming:withView:atScale:, the delegate will call that no matter what after a zoom.
Also, after a little tweeking this worked:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[[myView viewWithTag:pageNum] subviews] objectAtIndex:0];
}
This simply calls the scrollView inside View container and then gets the UIImage inside of that... works well.
It sounds like you may not have set the delegate property on your UIScrollViews to point at the object that implements viewForZoomingInScrollView:
Also note this snippet from the UIScrollView Class Reference:
For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:; in addition, the maximum (maximumZoomScale) and minimum ( minimumZoomScale) zoom scale must be different.
Finally, a word of warning: Be careful when accessing the subviews of UIScrollView. Your subviews are not alone in there. UIScrollView adds its own UIImageViews as subviews of itself to implement its scrollbar UI. So code like this...
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [[myView subviews] objectAtIndex:pageNum];
}
... may not do what you expect.