Scrollview setcontentsize for dynamic content - iphone

How would I go about setting the content size for a scrollview, when the content size is dynamic. I have added all my content to a UIView named "contentView", then try calling the setcontentsize as below, but this results in no scrolling.
sudo'ish code:
[scrollView setContentSize: contentView.frame.size];
Maybe "contentView" is not stretching its size to fit its children?
Any help would be appreciated.

UIView or UIScrollView will not auto stretch based on content. You have to manually calculate the frames and position it accordingly inside the scrollview and then set the contentSize of the scrollview to the biggest possible size that can hold all its subviews.

This depends on the type of content you are going to add dynamically. So let's say you have a big text data to show, then use the UITextView and as it is a subclass of the UIScrollView, you can get the setContentSize of TextView when you assign the text content. Based on that you can set the total size of the UIScrollView.
float yPoint = 0.0f;
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, yPoint, 320.0f, 400.0f)];
UITextView *calculatorTextView = [[UITextView alloc] init];
calculatorTextView.text = #"My looong content text ..... this has a dynamic content";
[calculatorTextView sizeToFit];
yPoint = yPoint + calculatorTextView.contentSize.height; // Bingo, we have the new yPoiny now to start the next component.
// Now you know the height of your text and where it will end. So you can create a Label or another TextView and display your text there. You can add those components as subview to the scrollview.
UITextView *myDisplayContent = [[UITextView alloc] initWithFrame:CGRectMake(0.0f, yPoint, 300.f, calculatorTextView.contentSize.height)];
myDisplayContent.text = #"My lengthy text ....";
[myScrollView addSubview:myDisplayContent];
// At the end, set the content size of the 'myScrollView' to the total length of the display area.
[myScrollView setContentSize:yPoint + heightOfLastComponent];
This works for me.

When you add stuff to your contentView call [contentView sizeToFit] and then the content view will stretch to fit its subviews, then, the code you post will work.

Related

Adding a UITextView and scrollview

scrollView = [[UIScrollView alloc] initWithFrame:
[[UIScreen mainScreen] applicationFrame]];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(25, 100, 200, 250)];
textView .text =#"long text ";
I will be getting some data of unknown length. to be added to the UITextView . Sometimes the height of the content of the text might exceed the height of the UITextView which is 250 (shown above).
How can i increase the height of the UITextView based on the text i receive ? I would appreciate a sample code? Later i need to add this to a UIScrollView (i know how to add to a scrollview), but again i don't know how to increase the height of the scrollview. Can someone help me code this ?
note: according to my code i am defining the width and height of the UITextView before adding the text to it.
UITextView is a subclass of UIScrollView. When the text content grows larger than the frame of the text view, the content will automatically begin to scroll. There is no need to embed a UITextView in a UIScrollView because it already is one (and more!).
Set the size of textView equal to it's contentSize.
The scrollView you have to set it's contentSize equal to the size you want.

Image scroller problem

hello every buddy
i want to make horizontal image scroller at bottom view and in the back of side big Image View. i don't know how to make image horizontal scroll.
Place the image view inside a scroll view whose horizontal content size is greater than its frame width, i.e.
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = CGRectMake(0, 0, 100, 100);
scrollView.contentSize = CGSizeMake(300, 100);
[scrollView addSubview:imageView];
You should use contentSize property of the UIScrollView to set its content size according to your requirement and then set the property showsHorizontalScrollIndicator to YES and showsVerticalScrollIndicator to NO . But you don't require to set these two if you set frame and content size properly. Like if _myScrollView.frame.height and _myScrollView.contentSize.height is same then you don't need to set horizontal and vertical scroll. Its vertical scroll will automatically be disabled.
you can use scroll view with page control for a horizontal slideshow. follow the tutorial it might help you
http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/

Calculate the contentsize of scrollview

I'm having a scrollview as the detailedview of tableview cell. There are multiple views on the detailedview like labels, buttons etc. which I'm creating through interface builder. What I'm creating through interface builder is static. I'm putting everything on a view of height 480.
A label on my detailedview is having dynamic text which can extend to any length. The problem is that I need to set the scrollview's content size for which I need its height.
How shall I set scrollview's height provided the content is dynamic?
You could try to use the scrollview'ers ContentSize. It worked for me and I had the same problem with the control using dynamic content.
// Calculate scroll view size
float sizeOfContent = 0;
int i;
for (i = 0; i < [myScrollView.subviews count]; i++) {
UIView *view =[myScrollView.subviews objectAtIndex:i];
sizeOfContent += view.frame.size.height;
}
// Set content size for scroll view
myScrollView.contentSize = CGSizeMake(myScrollView.frame.size.width, sizeOfContent);
I do this in the method called viewWillAppear in the controller for the view that holds the scrollview. It is the last thing i do before calling the viewDidLoad on the super.
Hope it will solve your problem.
//hannes
Correct shorter example:
float hgt=0; for (UIView *view in scrollView1.subviews) hgt+=view.frame.size.height;
[scrollView1 setContentSize:CGSizeMake(scrollView1.frame.size.width,hgt)];
Note that this only sums heights, e.g. if there are two subviews side by side their heights with both be added, making the sum greater than it should be. Also, if there are vertical gaps between the subviews, the sum will be less than it should be. Wrong height confuses scrollRectToVisible, giving random scroll positions :)
This loop is working and tested:
float thisy,maxy=0;for (UIView *view in scrollView1.subviews) {
thisy=view.frame.origin.y+view.frame.size.height; maxy=(thisy>maxy) ? thisy : maxy;
}
A somewhat easier way to do this is to nest your layout within a view then put that view within the scrollview. Assuming you use tags, this works as follows:
UIScrollView *scrollview = (UIScrollView *)[self.view viewWithTag:1];
UIView *longView = (UIView *)[self.view viewWithTag:2];
scrollview.contentSize = CGSizeMake(scrollView.frame.size.width, longView.frame.size.height);
That way the longView knows how tall it is, and the scrollview's content is just set to match.
This depends on the type of content you are going to add dynamically. So let's say you have a big text data to show, then use the UITextView and as it is a subclass of the UIScrollView, you can get the setContentSize of TextView when you assign the text content. Based on that you can set the total size of the UIScrollView.
float yPoint = 0.0f;
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, yPoint, 320.0f, 400.0f)];
UITextView *calculatorTextView = [[UITextView alloc] init]; calculatorTextView.text = #"My looong content text ..... this has a dynamic content"; `
[calculatorTextView sizeToFit];
yPoint = yPoint + calculatorTextView.contentSize.height; // Bingo, we have the new yPoint now to start the next component.
// Now you know the height of your text and where it will end. So you can create a Label or another TextView and display your text there. You can add those components as subview to the scrollview.
UITextView *myDisplayContent = [[UITextView alloc] initWithFrame:CGRectMake(0.0f, yPoint, 300.f, calculatorTextView.contentSize.height)];
myDisplayContent.text = #"My lengthy text ....";
[myScrollView addSubview:myDisplayContent];
// At the end, set the content size of the 'myScrollView' to the total length of the display area.
[myScrollView setContentSize:yPoint + heightOfLastComponent];
This works for me.
I guess there's no auto in case of scrollview, and the contentsize should be calculated for static views on the screen at least and for dynamic once it should be calculated on the go.
scrollView.contentSize = [scrollView sizeThatFits:scrollView.frame.size]
I believe would also work
I had the same situation, but then I wrote a new version in Swift 4 mirroring the better answer in Objective-C by Hannes Larsson:
import UIKit
extension UIScrollView {
func fitSizeOfContent() {
let sumHeight = self.subviews.map({$0.frame.size.height}).reduce(0, {x, y in x + y})
self.contentSize = CGSize(width: self.frame.width, height: sumHeight)
}
}

UiScrollView with scrolling content

I have a detail page of type UIScrollView. On it I want an optional UIImageView and a mandatory UITextView. If no image is available then the image view should not take any space. The text for the text view can be of varying sizes.
When the view is loaded with, say, the image and the text I need to be able to scroll through all the contents. So the image slips off the top of the screen.
I just can't get this work and I feel it ought to be easy. Any ideas?
You must call setContentSize with the size of the views.
CGRect frameOfImage;
CGRect frameOfText;
CGRect frameOfContent;
frameOfImage.origin = CGPointZero;
frameOfImage.size = myImage ? [myImage size] : CGSizeZero;
[myImage setFrame:frameOfImage];
frameOfText.origin.x = 0;
frameOfText.origin.y = frameOfImage.origin.y + frameOfImage.size.height;
frameOfText.size = [myText.text sizeWithFont:myText.font forWidth:myScroll.bounds.width lineBreakMode:myText.lineBreakMode];
[myText setFrame:frameOfText];
frameOfContent = CGRectUnion( frameOfImage , frameOfText );
frameOfContent.size.height += frameOfContent.origin.y;
frameOfContent.size.width += frameOfContent.origin.x;
[myScroll setContextSize:frameOfContent.size];
You could do the last bit in the layoutSubviews of a custom UIScrollView or all of it at once in your controller when you know whether there is an image or not.
You should create your own view, which inherits after UIScrollView.
In your custom YourScrollView you should overwrite
- (void) layoutSubviews;
There calculate size of the text, size of the image (and additional spacing between then), and then set the contentSize for the scroll view using:
[self setContentSize:CGSizeMake(CGRectGetWidth(self.bounds), yourCalculatedHeight)];
Hope this helps,
Paul

Autoresize UITextView and UIScrollView

I already did several searches on Stack Overflow and Google, but I couldn't find a solution to my problem.
I have a Detail View for a product that includes a UIScrollView and a few subviews (UIImageView, UILabel, UITextView). You can find an example here.
First I wanna autoresize the UITextView (not the text itself!) to the corresponding height. Then I wanna autoresize the entire UIScrollView so that it fits the height of my UITextView and the elements above it. I've tried the following code:
myUITextView.frame = CGRectMake(2.0, 98.0, 316.0, self.view.bounds.size.height);
[scrollView setContentOffset:CGPointMake(0.0, 0.0) animated:NO];
scrollView.contentSize = CGSizeMake(320.0, 98.0 + [myUITextView frame].size.height);
[self.view addSubview:scrollView];
98.0 + [myUITextView frame].size.height) because my thought was: After getting the height of myUITextView, add the height of the other subviews (98.0) to it.
Unfortunately it doesn't work very well. Depending on the content of the UIScrollView, it is too short or too long. I did some logging with the result that the height of the UITextView is always the same:
2010-01-27 14:15:45.096 myApp[1362:207] [myUITextView frame].size.height: 367.000000
Thanks!
There is actually a very easy way to do resize the UITextView to its correct height using its contentSize.
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
One thing to note is that the correct contentSize is only available after the UITextView has been added to the view with addSubview. Prior to that it is equal to frame.size
A UITextView won't automatically resize itself to it's contents (not as far as I know anyway) so you need to get the size of the text yourself and size the UIView accordingly.
The functions on this page will help - you can use them to get the width and height of a string, something like
// Get the size that the string will render at
NSString *contents = #"This is the content of your UITextView";
CGSize areaSize = [contents sizeWithFont:myView.font forWidth:myView.frame.size.width lineBreakMode:UILineBreakModeWordWrap];
// Then set the frame of your UITextView to be the right size
myView.bounds = CGRectMake(0, 0, areaSize.width, areaSize.height);
Then, you can layout the other components around it.
Hope this helps,
S
PS Warning, the link to the docs is correct but my code example is untested, sorry :)