Take a screenshot of UIScrollView, starting at contentOffset point? - ios

I looked at this code here, which lets you take a screenshot of either the top visible portion of a UIScrollView or of the whole UIScrollView:
Getting a screenshot of a UIScrollView, including offscreen parts
What I want is to take a screenshot of just the portion from contentOffset onwards, as the UIScrollView can be quite long and thus it would take a while to take a screenshot of it. Is it possible to do this?

The solution you mentioned basically resize the scroll view to match the size of its content, and therefore the entire content will be rendered without a scroll and then captured.
If you want to apply the same solution, you can resize the scroll view to match the size of the visible content + the size of remaining content til the end.
So try to replace those lines:
_scrollView.contentOffset = CGPointZero;
_scrollView.frame = CGRectMake(0, 0,
_scrollView.contentSize.width,
_scrollView.contentSize.height);
With:
//_scrollView.contentOffset = CGPointZero; // Don't change the offset
_scrollView.frame = CGRectMake(0, 0,
_scrollView.contentSize.width,
_scrollView.contentSize.height - _scrollView.contentOffset);

I had asked similar question before Taking screenshot of Part of Screen
You can take screenshot of what the user is seeing in terms of 320 x 480 but you cannot take screenshot of a portion of the screen. X and Y coordinates have absolutely no effect on where the screenshot starts/stops.

Related

Adjust content scale and offset on resize of UIScrollView

I have UI which hast two states of layouts (besides portrait-landscape). In each state some other part of UI is exposed (is larger).
Problem is that UIScrollView with some UIImageView is resized on those states changes, and in each state different part of image is shown since scale and offset remains unchanged.
Is there some nice way to update this scale and offset values so more or less same part of image is shown for a large and small sized UIScrollView?
How about the UIScrollView method
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
Rect is a rectangle in the coordinate space of the view returned by viewForZoomingInScrollView:.
Determine what rectangle of the zoomed view is being shown.
Change your views so that the UIScrollView bounds are changed.
Do the zoomToRect to show the same content, scaled as necessary.
Without having compiled and run this, it should be approximately...
CGSize rectSize;
rectSize.origin = scrollview.contentOffset;
rectSize.width = scrollview.bounds.size.width * scrollview.zoomScale;
rectSize.height = scrollview.bounds.size.height * scrollview.zoomScale;
// Do whatever makes the views change
[scrollView zoomToRect:rectSize animated:whateverYouLike];

After Animate UI view Size inside UIScrollView

i wonder if u could help out to fix my issue here.
For example i have 2 UIViews inside the UIScrollView, let say the first UIView i've changed the size of its height and at the same time i change the y axis of the second UIView as well through this animation method. here's my code:
[UIView animateWithDuration:0.1f animations:^{
CGRect rect = informationView.frame;
rect.size.height += 100.f;
informationView.frame = rect;
CGRect rectAddView = additionalView.frame;
rectAddView.origin.y += 100.f;
additionalView.frame = rectAddView;
}];
After those have been rendered (the height and Y axis). It works fine. And i changed the content size of that UIscrollview so it can be scroll it down. Here's the problem when i try to scroll down, surprisingly the height of the First UIView and Y axis of the second UIView are back like from the beginning. i don't how & why. So i just need wise explanation if there's somebody could help me here. Thank you

UIView UIScrollview - frames, bounds, center confusions

I am putting a UIImageView inside a UIScrollView, and trying to control the image so that it is centred on the scrollview after a zoom. and I am not sure the best way to do this.
The apple docs tell us NOT to use the frame property: "Warning If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored." So I am attempting using the following in a UIViewController subclass whose xib contains a scrollView and contained imageView:
scrollView.bounds =
CGRectMake
(scrollView.contentSize.width/2 - scrollView.center.x,
scrollView.contentSize.height/2 - scrollView.center.y,
scrollView.bounds.size.width,
scrollView.bounds.size.height);
containedView.center =
CGPointMake
(containedView.bounds.size.width*scrollView.zoomScale/2,
containedView.bounds.size.height*scrollView.zoomScale/2);
This works accurately where the width and height of the containedView is larger than that of the scrollView and sets the views so that subsequent scrolling will take you exactly to the edges of the containedView. However when either dimension of the image is smaller than the scrollView width and height the image is magnetically attracted to the top left corner of the screen. In the iPad Simulator (only) when the images is shrunk to the size of minimumZoom it does lock on to the centre of the screen. The magnetic attraction is very smooth as if something in the UI is overriding my code after the image has been centred. It looks a bit like a CALayer contentsGravity ( kCAGravityTopLeft ) thing, maybe?
Apple contradict their own advice in their code sample, photoScroller (in a subclass of UIScrollView):
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
imageView.frame = frameToCenter;
This method does a better job of centring when the image is smaller, but when I try this on my project it introduces some kind of inconsistencies. For example, with scrollView.bounces = NO, a horizontal image whose height is smaller than the height of the scrollView but whose width is larger (so it can be scrolled from left to right) will scroll further to the left than it should (when scrolling to the right it stops correctly at the edge of the image, although if scrollView.bounces = YES it then bounces in from the edge so the image is always cropped on the left) When the image is larger in both dimensions than its containing scrollview this issue accentuates and the whole result feels broken, which is unsurprising given Apple's documented advice.
I have scoured the forums and can't find much comment on this. Am I missing something really obvious?
You don't appear to be using the transform property, so you can ignore that warning about not using the frame property when using the transform property. Go ahead and use the frame property, just like Apple (and the rest of us) do.

iOS - squish an image vertically

I have a round image that I want to "squish" vertically so that it looks more like a horizontal line, then expand it back to the original shape. I thought this would work by setting the layer's anchor point to the center and then animating the frame via UIViewAnimation with the height of the frame = 1.
[self.imageToSquish.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y, self.imageToSquish.frame.size.width, 1 );
[UIView animateWithDuration:3
animations:^{self.imageToSquish.frame = newFrame;}
completion:nil];
But the image shrinks toward the top instead of around the center.
You’re giving it a frame that has its origin—at the top left—in the same position as it started. You probably want to do something more like this, adding half the image’s height:
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y + self.imageToSquish.frame.size.height / 2, self.imageToSquish.frame.size.width, 1);
Alternatively—and more efficiently—you could set the image view’s transform property to, say, CGAffineTransformMakeScale(1, 0.01) instead of messing with its frame. That’ll be centered on the middle of the image, and you can easily undo it by setting the transform to CGAffineTransformIdentity.

Detecting rotated width/height of UIView after orientation change

I would like to be able to inspect a UIView instance that may or may not have been rotated from its original orientation (by the user rotating the device for instance) and determine what the "true" width and height are. "true" here meaning, if a view on a portrait-oriented iPad was 768x1024 before rotation, after being turned sideways I would calculate that the new width was 1024 and the new height was 768.
It appears that if I apply the view's transform to its frame property like this:
CGRect rotated = CGRectApplyAffineTransform([myview frame], [myview transform);
I get the desired result. Apple's documentation however states that UIView::frame is undefined if the transform for the view is not the identity transform, so maybe it's not a good idea to rely on this calculation?
view.bounds will return the rect you want
view.frame will return a rect with the transfrom applied to the bounds along with position.
Well due to lack of input, I'm going to go with my solution of using:
CGRect rotated = CGRectApplyAffineTransform([myview frame], [myview transform);
To get the properly oriented bounding. If somebody has another solution or can confirm this is safe I will award the answer to them instead.

Resources