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
Related
I have a UIScrollView and I take a UIImageView and an UITextView that scrolls vertically.
The scrollview is 320*700. I want to do the scroll size depend upon the UITextView size, The image is same size but the text changes depend on the content.
How can I setup the scrollview's size to change only when I've got more or less text in the UITextView?
You can set your UIScrollView's size dynamically according to the size of your UITextViewusing something like
- (void)viewDidLoad
{
float sizeOfContent = 0;
UIView *lLast = [scrollView.subviews lastObject];
NSInteger wd = lLast.frame.origin.y;
NSInteger ht = lLast.frame.size.height;
sizeOfContent = wd+ht;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent);
}
Please also refer to How to set content size of UIScrollView dynamically to be able to understand better .
I've done quite a bit of looking into this but have been unsuccessful in finding a solution.
I have a UIScrollView called scrollView inside of UIView. I'm using this scrollView in pagingEnabled mode. Inside of scrollView, I have 3 different views created programmatically. Inside of these 3 different views, I have a bunch of stuff(UILabel,UITextView etc.). All of the views contents are dynamic and determined at runtime.So, i really don't know scrollView.contentSize. If i give the content size of this scrollView,Sometimes ,I have a screen with white blank at the botton of the screen when user scrolls down. My question is : Can i set the content size dynamically for each single page of this scrollView? For example,for page 1 :
self.scrollViewNews.contentSize = CGSizeMake(constant1,constant2);
And set something else for page 2 as well .
I think you're confused about contentSize vs the paging size. The paging size is always the size of the scrollView bounds, and isn't a property you can otherwise set. That is, when you swipe left/right it will "page" by the width of the scrollview.
contentSize is the size of the virtual bounding box of all the subviews within the scrollview. This only serves to limit how far the scrollview will scroll, and for paging, how many times it will page, i.e. contentSize.width / bounds.size.width.
Assuming the scrollView isn't zoomed in/out (zoomScale = 1.0) then you need to position and size your subviews on the virtual 'page boundaries'. They can take up the full page boundary (be sized to match scrollview.bounds) or be inset. If you have some content that is larger/smaller then you'll have to decide if you want to change the scale of that content or size it up/down within the page bounds.
Yes you can dynamically set the content size of the scrollView. Also You can use this method:
self.scrollViewNews.contentSize = CGSizeMake(constant1,constant2);
Nothing wrong this method. You are seeing the blank space at bottom because you ares setting the height of the scrollView's contentSize to a larger value than it's content. That's the issue. Adjust the height according to the contents, blank space will go.
please, try to get the actual content size from the current content.
the content must be some inherited class from the UIView and it has a frame.size.width and frame.size.height property.
you can use those to set the contentSize of your UIScrollview for the current content at that time when you add the content to the UIScrollView.
Yeah. You can set the scrollView size dynamically through
scroller.contentSize = CGSizeMake(1650, 2000);
You can use the following property to set the dynamic frame for each pages
[urScrollView scrollRectToVisible:frame animated:YES];
if you are using pagingEnabled = YES for your scrollview
The below UIScrollViewDelegate delegate will adjust the page and content
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
int page = urScrollView.contentOffset.x/urScrollView.frame.size.width;
pageControl.currentPage = page;
}
//pager action
- (IBAction)changePage:(id)sender{
int page = pageControl.currentPage;
CGRect frame = urScrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[urScrollView scrollRectToVisible:frame animated:YES];
}
please look at this sample app
Try out this.
- (void)viewDidLoad
{
float sizeOfContent = 0;
UIView *lLast = [scrollView.subviews lastObject];
NSInteger wd = lLast.frame.origin.y;
NSInteger ht = lLast.frame.size.height;
sizeOfContent = wd+ht;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent);
}
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.
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)
}
}
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 :)