TextView autoheight in a ScrollView - iphone

I'm trying to insert a TextView inside a Scrollview. The scrollview work but the content of TextView not show complete, because appear their scroll. I would show complete content of TextView without scroll.
file.h
#interface DetailViewController : UIViewController{
IBOutlet UITextView *detailTextView;
IBOutlet UIScrollView *scroller;
}
#property(retain, nonatomic) IBOutlet UIScrollView *scroller;
-(void)setTextViewForRecipes: (Recipe *)theRecipe;
#end
file.m
#implementation DetailViewController
#synthesize scroller;
-(void) setTextViewForRecipe:(Recipe *)theRecipe
{
[detailTextView setText:theRecipe.detail];
}
- (void)viewDidLoad {
CGRect frame = detailTextView.frame;
frame.size.height = detailTextView.contentSize.height;
detailTextView.frame = frame;
[scroller setContentSize: CGSizeMake(280, detailTextView.frame.origin.y + detailTextView.frame.size.height + 10)];
}

You've got the right idea in viewDidLoad by setting detailTextView's frame height to its contentSize height. But you need do that after you set the text of the view, and of course you need to adjust the scroller's contentSize again.
-(void) setTextViewForRecipe:(Recipe *)theRecipe
{
detailTextView.text = theRecipe.detail;
CGRect frame = detailTextView.frame;
frame.size.height = detailTextView.contentSize.height;
detailTextView.frame = frame;
scroller.contentSize = CGSizeMake(280, 10 + CGRectGetMaxY(frame));
}

UITextView is a subclass of UIScrollView, so you shouldn't add it to a scroll view.

As bandejapaisa pointed out, it's usually not necessary to wrap a UITextView inside a UIScrollView, because the textView can scroll by itself.
If, however, you really find this necessary, you can find out the size of the text if it were rendered with a certain font:
CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:fontSizeOfYourTextView]
constrainedToSize:CGSizeMake(widthOfYourTextView, MAXFLOAT)
lineBreakMode:UILineBreakModeOfYourTextView];
This will find out the height. Adapt to your needs, but be warned: This gets a little hackery, and you'll probably need to do some trial and error before you achieve the desired outcome.

Related

Autosizing a UIView that contains a UITextView

I have a UITableViewController with a UIView before the table view. The UIView (IBOutlet UIView *templateDescriptionView) has a UITextView (IBOutlet UITextView *templateDescription) in it. It looks like this:
The UITextView can have a variable amount of text. I'm trying to programmatically resize the UITextView and UIView to compensate for this, but it's not working as expected.
-(void) viewDidLoad
{
[templateDescription sizeToFit];
CGRect frame = templateDescription.frame;
frame.size.height = templateDescription.contentSize.height;
templateDescription.frame = frame;
CGRect viewFrame = templateDescriptionView.frame;
viewFrame.size.height = templateDescription.contentSize.height + 40; // 40 for padding
templateDescriptionView.frame = viewFrame;
}
The problem is, when everything renders, the UIView is partially on top of the UITableView. It resizes, but it's not resizing to the proper height. What am I doing wrong? This is Xcode 5, iOS7.
I am afraid I misunderstood your meaning. But UITableViewController is used to control a UITableView. Does it run well that a UITableViewController control a UIView? Maybe you put a UIView into the HeaderInSection of tableView. In iOS7, self.automaticallyAdjustsScrollViewInsets = NO; can be used to remove the space inset in scrollview.

UIScrollView Resizable?

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 .

Resized UILabel snaps back to initial size

On detailview (Scrollview) in my app I have a UILabel that gets text that will have about 1000 words.
I want to resize it so the label fits - works fine so far
-(void) viewDidAppear:(BOOL)animated {
NSString *message = storycontent.text;
CGSize maximumLabelSize = CGSizeMake(280,5000);
CGSize expectedLabelSize = [message sizeWithFont:storycontent.font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
CGRect newFrame = storycontent.frame;
newFrame.size.height = expectedLabelSize.height;
storycontent.frame = newFrame;
}
When navigation to that detailview the label is resized as expected.
Now the weird thing: The moment I want to scroll down the UILabel snaps back to the initial size, so that only the first words are visible.
What can I do to avoid that behavior?
UPDATE:
When i delete the label and put in a new one it works fine. The strange behavior starts the moment i change the font size to something other then 17.
My current solution (or workaround) was now to deactivate "Use Autolayout" (thx to Mark Kryzhanouski), which solves the snapping issue.
With not having the Autolayout the ScrollView does not automatically resize, so i added
#property (retain, nonatomic) IBOutlet UIScrollView *scroller;
and calculated a new FrameSize for it with the content size i already know from above, plus the static content that will be shown always.
NSString *message = storycontent.text;
CGSize maximumLabelSize = CGSizeMake(280,5000);
CGSize expectedLabelSize = [message sizeWithFont:storycontent.font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
[scroller setContentSize:CGSizeMake(280,expectedLabelSize.height + 400)];
Maybe there is a way to do the same with "Use Autolayout" activated?!

Uitext Content SIze in UI Scroll View , the text in bottom is cut off

I have UIScroll that have uitextview inside it.
My apps look like this:
rootviewcontroller -> PhoneContentController (UIScrollView and PageControl) -> DetailController (UITextView, UIWebView, UILabel).
My Flow is like this:
Set UIScrollView default size -> call DetailController (calculate UITextView and other page inside it in viewDidLoad) -> PhoneContentController get the total height size from DetailController-> Change the height of UIScrollView
This is the code in PhoneContentController (loadSCrollViewWithPage):
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, [detailController.getTotalHeight]);
The code in Detail Controller (viewDidLoad):
summaryBlogParsed = [summaryBlogParsed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[self.itemSummaryText setText:summaryBlogParsed];
CGRect frameTextView = self.itemSummaryText.frame;
frameTextView.size.height = self.itemSummaryText.contentSize.height;
self.itemSummaryText.frame = frameTextView;
This code in DetailController getTotalHeight:
CGRect cgRect = [[UIScreen mainScreen] bounds];
CGFloat scrollFrame = (cgRect.size.height/2) + itemSummaryText.frame.size.height;
return scrollFrame;
I can scroll the scrollview but the textview not load all of the string. like only half of it, but i can scroll down but with blank pages :(.
Anyone can help me?
Thank you
set content size of scroll view using this function.
-(void)setContentSizeOfScrollView:(UIScrollView*)scroll
{
CGRect rect = CGRectZero;
for(UIView * vv in [scroll subviews])
{
rect = CGRectUnion(rect, vv.frame);
}
[scroll setContentSize:CGSizeMake(rect.size.width, rect.size.height)];
}
after adding all controls to your scroll view call this function and pass yourScrollView as argument. Hope this will help you.........
According to Apple... When debugging issues with text views, watch for this common pitfall:
Placing a text view inside of a scroll view. Text views handle their own scrolling. You should not embed text view objects in scroll views. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.

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)
}
}