Problem with UIScrollView and CATiledLayer - iphone

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

Related

Can someone explain if multi-touch zoom is supposed to work for UITextView or UIScrollView

Has anyone gotten multi-touch zoom to work on a textView?
I have searched SO and found no simple way to zoom in on a UITextView or UIScrollView. I was led to this link which says I need to write custom views to overwrite the existing ones in order to be able to zoom in to a textView. I can not believe this and would like someone to please let me know if there is a simple way to zoom in and zoom out using multi-touch on a UITextView or a UIScrollView.
I tried setting the options in the IB to enable multi-touch as well as the max zoom. But this does not work.
Please advise. Thank you.
1 Create a new project with single view (using storyboard & arc)
2 Open Storyboard and add a UIScrollView to your main view controller
3 Set the UIScrollView's delegate to the view controller and create an IBOutlet for the UIScrollView called scrollview
4 Add a UITextView to the scrollview and set an IBOutlet called textview
5 At the end of the ViewDidLoad add the following code:
self.scrollview.minimumZoomScale = 0.5;
self.scrollview.maximumZoomScale = 5.0;
self.textview.text = #"Hellow World!";
6 Add the following method
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.textview;
}
7 Run the project and zoom away!
If you want the text to look not render blurry when use the answer at this Blurry UITextField Question
The UIScrollView class provides support for displaying content that is larger than the size of the application’s window. It enables users to scroll within that content by making swiping gestures, and to zoom in and back from portions of the content by making pinching gestures.
By adding your UITextView to a UIScrollView, you can implement muti-touch zoom.
I am resolving to answer this question myself with the assumption that this is not possible at this time. With a textArea I have found no way to zoom in on the text. I have not found any tutorial or example that shows this is possible.

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;

iPhone ScrollView zoom problems

I'm new to iPhone dev and Obj-C and I have several problems with ScrollView/ImageView while getting close to deadline. I used IB to create interface so I access most parameters via builder.
1) I was using touch events (begin/moved/ended) on imageView to switch images. When I put ImageView to ScrollView the old gestures stopped working and I can only zoom. If scrollView of both have focus I can't use my gestures even when zoomed out. How can I use both?
2) How do I zoom only image part of view? Unfortunately I also see background area around :/ What's worse - after rotating the view keeps it's old dimensions and I have even more black areas around image. For some reason image is in top-left corner.
Code snippets I found doesn't really help me much in this case. I have various images of different sizes in imageView to switch and zoom in/out.
EDIT: Ok, a little different. How do I override scrollview touch mode so that when image is zoomed out (to screen size) "normal" gestures would work. Currenly I have either scroll view scrolling or gestures, can't use both. Anyone?
Solved by dynamically changing imageview to imagesize and switching like:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
if (scrollView.zoomScale==1.0) {
scrollView.userInteractionEnabled = NO;
imageView.userInteractionEnabled = YES;
}
Not the best solution but works good enough.

UIScrollView doesn't bounce

I have a UIScrollView contained within a custom UIView with a content size larger than the ScrollView's frame.
I am able to drag scroll as I expect, but the thing doesn't give me the rubber banding effect that you get with the UITableView or UIWebView. It just stops when you get to one of the extremes.
I have set bounce = YES, is there something else I'm supposed to do?
I read the docs, and they say I have to implement the delegate. I did that.
They also say I should change the zoom levels, but I don't want the user to actually be able to zoom so I haven't set these.
For anyone that finds this thread later, if you are subclassing UIView and re-setting the UIScrollView's frame on every layoutSubviews, that is the problem - it cancels the bounce:
http://openradar.appspot.com/8045239
You should do something similar to this:
- (void)layoutSubviews;
{
[super layoutSubviews];
CGRect frame = [self calculateScrollViewFrame];
if (!CGRectEqualToRect(frame, self.scrollView.frame))
self.scrollView.frame = frame;
}
I had the same problem, on a UIScrollView that wasn't all filled up (but I still wanted it to bounce). Just setted:
scroll.alwaysBounceVertical/Horizontal = YES;
And it worked as expected
It turns out that keeping the UIScrollView within my custom UIView was causing the trouble.
Once I switched my custom UIView to instead inherit from UIScrollView, then the bouncing started working.
That is interesting... Is there a lot going on while the user scrolls the scroll view? Maybe that could cause the problem. The iPhone can multitask, but not too much. Can I see your entire code having to do with the scroll view?

How to get active subview (UIImageView) from UIScrollView

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.