I'm trying to create an image viewer that behaves exactly like the Apples Photo App. But for now I'm only interested in a single image behavior.
I've placed an UIImageView inside UIScrollView and managed to handle pretty much everything beside one thing, and that is if I zoom-in in a portion of image(for example a portrait image) and then rotate the device in landscape the portion appears to be rotated over the upper left corner instead of center.
Let me try to illustrate that. This is what I have now:
This is what I would want to happen:
Basically I believe I know how I could do it but it seems to involve a bit more coding than it probably deserves. Maybe I'm missing some simple property that I could just set to get this desired behavior.
Any hint, anyone?
self.imageView.center = self.scrollView.center;
do set [imgView setContentMode:UIViewContentModeScaleAspectFit];
Related
So I just spent like one hour Googling for some answers.
I added UIImageView with Interface Builder and I set image to some existing image.
I wanted to make the image centered, so I changed mode to centered. Worked.
Now I wanted to change the image from code. So I set image in IB to nothing and I did imageView.image = (UIImage instance)
Now the image changed, but it's not centered anymore.
Also, here's an interesting thing: I tried also not changing image in IB, I just left it set to some image and then I changed image from code. I could see both images! The one set in IB was centered (like I want it) and the new one was overlaying on the left.
Any ideas please?
Also I probably lack some basic knowledge of this View stuff, can anyone please point me at documentation where this is explained?
It sounds like you have two overlapping UIImageView subviews. One of them is referenced by imageView in your view controller and doesn't center. The other isn't referenced by your view controller but does center. The solution would be to get rid of the non-referenced image view.
I got it! Thanks James Huddleston for useful comments.
You were right. There must have been to UIImageViews.
Here's what happened. I actually used viewWithTag: to find that view (it wasn't linked directly - it was in a UITableViewCell). Well, it apparently didn't work with 0, when I changed tag to 1 - it worked.
What exactly I have to do is I have 2 images one is mask and another is Photo.
Mask.png is just the layout of the person and Photo.png is the image of the person in the position as per the mask.png.
Now the main problem is I want the Photo.png to be resized and moved in such a way that it can be adjusted in that Mask.png.
below is the example of mask and Photo
Now I want that red color must come on the below two legs of the star for that I need to move the Flowers image as per my convininece and then save them whole as one Image. Im my case theres a outlay of person instead of star and the Photo of person instead of flowers image.
Kindly help... Any help would realy be appreciated.
Thanks in advance.
I was recently working on something similar. You could override touchesMoved, but I would recommend using UIGestureRecognizers which you would add to the UIImages themselves.
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[someImageView addGestureRecognizer:rotationRecognizer];
then implement some rotate: method
There is a sample project by apple called Touches which should have all you need to get started.
Hope this helps.
At first you have to decide how to let the user move and resize your image in a user-friendly manner. If your image were rectangular, you could decide for resizing when the user drags on one of the edges and for moving when he drags from a point inside the rectangle.
You might do the same with your star shape, but I doubt that it will be intuitive enough for the users.
Then you can implement moving and dragging by overriding touchesMoved, checking whether the first touch is inside your shape (or on the edge), and move (or resize) to the last touch.
You will find that the calculations are not so easy, but that is the only way [I know] to do it.
I got a UIView subclass that draws a UIImage as its background. The image is created using the stretchableImageWithLeftCapWidth:topCapHeight: method, it has round edges.
I also use an animation block inside of which I resize my view. I had hoped that during animation, the drawRect:method would get called sometimes, which would result in the background image getting drawn correctly.
Unfortunately, the animation seems to render the image and then just rescale it during the animation, which obviously makes the formerly round edges getting nastily stretched.
The only workaround I can imagine is put three separate UIImageViews (top cap, middle fill, bottom cap) above my original background image and then reposition the caps images and scaling the fill image. However, this seems quite complicated...
Is there any better way I can prevent this from happening?
EDIT: Found this. Sounds bad...
While digging through some Apple docs, I coincidentally found the solution to my problem. All you have to do is play with UIView's contentStretch parameter. It allows you to manually specify the area of your view that gets stretched during animation.
This is probably either real easy, real dumb, or my google fu has taken a serious turn for the worse. Anyway, I'm implementing custom view for my app, which is using pure CGContext drawing, no subviews (for now at least). The thing is, I want it to autorotate, so I have shouldAutorotateToInterfaceOrientation return YES, and voila, the view rotates. But in doing so it's not actually redrawing the content (which I assume is rendered into a texture somewhere in the framework and splashed onto a rect, but that's not really relevant here), the rect is simply stretched, squishing the content. How can I get it to simply issue a draw of a bigger area while rotating? That is, my content is bigger than the screen, and I'd simply like the viewport to change during the rotation.
I've tried setting the view's contentMode to UIViewContentModeRedraw, but that didn't do anything, I've tried playing around with the autoresizeMask stuff, but didn't seem to help either. I've also tried inserting a setNeedsDisplay in willRotateToInterfaceOrientation, however that only caused it to redraw using the new bounds (i.e. squishing it first, and then stretching it out to the right size during the rotation), which is also not what I'd like to see.
Does anyone have any idea how I might go about getting this to work?
As it turns out, it's a mix of dumb and easy. I'm posting it here if anyone should care to read it someday. They way I managed to solve it was actually sandwiching a view between window and my view (I suppose you might be able to go to work on the window directly, but it felt more intuitive this way). That is, I added my view as a child view to that view, which I'll call the frame.
The frame is a resizing as normal, however, I turn OFF resizing of child views, and make my own view LARGER than the viewing area (square actually, 480x480, so it can cover the entire screen either way). Problem solved, basically.
Now I'm playing around with animating the offset of the view in the frame during willRotateToInterfaceOrientation, to have it appear to be rotating around the center, rather than the upper left corner, but that's a different question.
My application consists of a UIImageView inside a UIScrollView, and I display a big image inside of it. The scroll view allows the user to pinch to zoom in/out in the image, and that all seems to work just fine.
However, when my application is terminated and then re-launched, the UIScrollView displays the image again in the original zoom level (which is currently set to display the whole image, by scaling it in a "aspect fit" mode).
I would really like to be able to re-launch my app and have the UIScrollView reopen with the same parameters as it was set when the app terminated. So if my image is currently zoomed in to the max, and scrolled all the way to the bottom left of it, that should be the view when I open the app again.
How can I do this?
Check the .transform property of the view. If you are zoomed in, this should be modified. Save and restore it on the next launch.
I have found a way to programmatically zoom UIScrollView. This may help you set the desired zoom level upon startup.
The sample code, together with ZoomScrollView class that encapsulates the required zooming magic and a detailed discussion of how (and why) UIScrollView zooming works is available at github.com/andreyvit/ScrollingMadness/.
Someone asked this a while ago, but I don't think you'll like the answer. Hopefully you'll get a better one.
I do it like this:
When you quit save the zoomlevel (myScrollview.zoomScale) and the contentview frame origin.
When you reopen you can set the zoomscale. You also have to set the content size to the new zoomlevel, because otherwise the boundaries are not correct.
[myScrollview setZoomScale:savedZoomScale];
CGSize newsize = CGSizeMake(origsize.width * savedZoomScale,
origsize.height * savedZoomScale);
myScrollview.contentSize = newsize;
To set the offset:
[myScrollView setContentOffset:savedFrameOrigin animated:YES];