UIScrollView with dynamic content - ios

I'm trying to implement a UIScrollView, but every tutorial out there deals with a preset number of items.
What I have are multiple UITextField's, but the number of textfields vary. Basically, as soon as one textField contains text, another empty one appears below it, allowing the user to fill in an unlimited number of textfields.
My code creates a new textfield as soon as the user types something into a previous one. The x-coordinatesof this is the same as the previous one, but the y-coordinatesto the new one equals the height of the previous + 5px.
I'm using storyboards, and I have placed my original textField within a UIScrollView. I have connected this scrollView to my code, and I add a new textfield this way: [self.scrollView addSubview:newTextField];
However, when the amount of textFields exceeds the scrollView, I cannot scroll to reveal the new one that's been added.
How would I go about doing this? I don't think I completely get the setContentSize thing, so it might have something to do with that. Here are some pictures and code to explain my problem:
Code to add new textfield:
UITextField *newTextField = [[UITextField alloc]initWithFrame:CGRectMake(textField.frame.origin.x, textField.frame.origin.y + textField.frame.size.height+5, textField.frame.size.width, textField.frame.size.height)];
newTextField.placeholder = #"Add more text";
newTextField.borderStyle = UITextBorderStyleNone;
newTextField.font = [UIFont systemFontOfSize:14];
newTextField.autocorrectionType = UITextAutocorrectionTypeYes;
newTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
newTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
newTextField.returnKeyType = UIReturnKeyDone;
[newTextField setTag:textFieldTag];
newTextField.delegate = self;
[self.scrollView addSubview:newTextField];
Storyboard:
Here you can see how I have placed the original textfield within my scrollview
How it looks in the simulator:
When you enter text in the textfield, this happens:
An empty textfield appears below the previous one.
However, when you exceed the ScrollView, this happens
You can no longer see the new textField because it is below the scrollView's boundaries. You can not scroll to reveal it either.
Does anyone know how to solve this? And if you have time, how would you make it so the scrollview automatically scrolls down to reveal the new textfield that's been added?
Any help is greatly appreciated! Thanks!

The contentSize needs to be the size of content contained within the scroll view.
If the contentSize is wider than the bounds.size, then you can scroll left and right. If the contentSize is taller than the bounds.size, then you can scroll up and down.
You need to set the contentSize to be the entire area you wish to contain within your scroll view.
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(textField.frame.origin.x, textField.frame.origin.y + textField.frame.size.height+5, textField.frame.size.width, textField.frame.size.height)];
textField.placeholder = #"Add more text";
textField.borderStyle = UITextBorderStyleNone;
textField.font = [UIFont systemFontOfSize:14];
textField.autocorrectionType = UITextAutocorrectionTypeYes;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
textField.returnKeyType = UIReturnKeyDone;
textField.tag = textFieldTag;
textField.delegate = self;
[self.scrollView addSubview:textField];
// Update the contentSize to include the new text field.
CGFloat width = self.scrollView.bounds.size.width;
CGFloat height = CGRectGetMaxY(textField.frame);
self.scrollView.contentSize = CGSizeMake(width, height);
NOTES:
Don't start variables or methods with new. It has special meaning and you will confuse other Objective-C developers and/or the compiler.
textField.tag = … is the same as [textfield setTag:…]; You seem to like the dot syntax in other places, so I switched to that.
I'm assuming you don't want the scroll view to pan left and right, so I pinned the content width to the scroll view's width.

Related

UITextView missing text at the end?

So the white background part is a UITextView and the blue bubble is a UIImageView. How come the UITextView lost some text at the end when given the same text at different row of the tableview?
Here’s how I configured the UITextView:
self.textView.textContainerInset = UIEdgeInsetsZero;
self.textView.textContainer.lineFragmentPadding = 0;
//self.textView.backgroundColor = [UIColor clearColor];
self.textView.editable = NO;
self.textView.scrollEnabled = NO;
I need the selection and copy capabilities of UITextView, so I can’t use UILabel. Basically, I want to make UITextView behaves like UILabel.
Thank you in advance.
Edit 1:
This is how I set the constraints:
[self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.msgContainerView).insets(UIEdgeInsetsMake(kPaddingTB, kPadding, kPaddingTB, kPadding))
}];
Edit 2:
It seems that the text disappears when tableview is scrolled.

UITextView not scroll properly when using TextKit

I config a textView in a UIViewController like following:
textView configuration
but when controller viewDidAppear I found that UITextView's contentSize = {375, 242} and UITextView can not scroll.
But if i tap the textView, let the textView begin editing (but edit nothing), then i touch the controller's view let textView endEditing, log the textView, this time contentSize = {375, 361} and UITextView can scroll.
Is anybody know why? Thanks.
You can add textView something like,
UITextView *standardTextView = [[UITextView alloc]initWithFrame:CGRectMake(20, 50, self.view.frame.size.width - 40, 120)];
standardTextView.layer.borderWidth = 1.0;
standardTextView.layer.borderColor = [[UIColor lightGrayColor]CGColor];
standardTextView.delegate = self;
standardTextView.font = [UIFont fontWithName:#"Helvetica" size:17.0];
[self.view addSubview:standardTextView];
then when your content(i.e text) will be bigger than textview's height it will enable scroll otherwise it remains disable!!
NSTextContainer has a property called heightTracksTextView which may be interfering with your setup here, as the default is false.
I would double check the height of the NSTextContainer after you initialize the UITextView and after you add the UITextView to the view hierarchy.
Check the documentation here: https://developer.apple.com/reference/uikit/nstextcontainer/1444559-heighttrackstextview
If that doesn't help, let me know, I know I've solved this issue before, but I'm not at my computer right now.

How to show Dynamic UITextView Text Height

Hi have some product description, and data coming from the API,i want to show the data as dynamically. Dependents on this height i need to add some other UIElements please help me
Thanks in Advance
UILabel and UITextView has a method: "sizeThatFits", it can return the size fit the text base on a given size, so all you need to do is:
UITextView *textView = [[UITextView alloc] init];
textView.text = yourContent;
CGSize fitSize = [textView sizeThatFits:CGSizeMake(contentWidth, 10000)];
CGFloat contentHeight = fitSize.height;
Try this
UITextView *textView = [[UITextView alloc] initWithFrame:<set frame>];
textView.text = <text>
[textView sizeToFit]; // calls sizeThatFits: with current view bounds and changes bounds size.
If you don't need text editing and aim code purity, you can use UILabel instead of UITextView, just use AutoLayout and set constraints as shown below. Set Lines to 0 for Expanding Label. If you do everything right, resizing and offsetting of controls will occur automatically, you just can change text in Expanding Label

How to add a UILabel inside a UIScrollView programatically?

Ok i have already gone through similar questions, but none of them helped.
I want to add a UILabel inside a UIScrollView so that the Label can be scrolled if the contents are large. Here is my code:
ViewController.h:
#interface ViewController : UIViewController
{
UILabel *myLabel;
UIScrollView *myScroll;
}
ViewController.h:
myLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+30, self.view.frame.size.width, self.view.frame.size.height)];
myScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+30, self.view.frame.size.width, self.view.frame.size.height)];
myLabel.backgroundColor = [UIColor yellowColor];
myLabel.text = #"Large random text";
[myLabel setNumberOfLines:0];
myLabel.lineBreakMode = NSLineBreakByWordWrapping;
[myLabel sizeToFit];
myScroll.contentSize = CGSizeMake(myLabel.frame.size.width,
myLabel.frame.size.height);
[myScroll addSubview:myLabel];
[self.view addSubview:myScroll];
I searched a lot on the internet but could not find a answer, can someone let me know what the issue is ?
Thank You !
I'm not sure how to do that, but I would like to suggest an alternative that may suit your needs. Use a UITextView, but set " [textView userInteractionEnabled:NO] " and it will act as a label, since it cannot be edited. It might end up looking like how you want.
Based on your comments, you need to size the label as needed so it is big enough for the given text. Then add the label to scroll view. Then set the scroll view's contentSize so it fits the whole label. This will ensure the scroll view allows you to scroll to see the whole label.
In addition to this, make sure the label's frame is relative to the scroll view and not to self.view. In other words, setting the label's frame's origin to 0,0 will put the label in the top left corner of the scroll view regardless of the position of the scroll view relative to its parent.
Try by replacing your contentSize like below code,
myScroll.contentSize = CGSizeMake(self.view.frame.size.width,self.view.frame.size.height + 100);
Hope it will work for u.
1.You have to use View(ContentView) to place the labels.
2.Add the ContentView into ScrollVIew.
3.Assign the ContentView Size whatever You Want
Go Through This Link,You Will get a Clear idea.
https://www.youtube.com/watch?v=UnQsFlMGDsI
Remove scrollView = [[UIScrollView alloc] init]; this is not necessary.Please Upvote if it helps.

ios autolayout similar

I'm pretty new to ios. And while writing my first app i'v encountered that autolayout is only for ios 6.0. And i'd wish to make my app for at least 5.0 ios.
Maybe anyone would know how to make this without autolayout.
I have label which has dynamic text, 1row or 2 rows or 3 rows depends on user settings. And below it i have uitextfield. With autolayout i have no headache as it does all the work, the textfield sits nicely below in 1 2 or 3 rows of text above (resizes, moves automatically).
So how should i do this without autolayout?
Without autolayout you have to handle this in code. The recommended way of doing this would be to subclass your container view (the view that contains your label and text filed) and override the layoutSubviews method. In there you set the frames of the view's subviews manually, based on your desired criteria (e.g., the label text metrics).
EDIT: here's a specific example of something that could be in the containverView layoutSubviews method (typed from the top of my head):
// Those could be IBOutlets, or obtained by inspecting self.subviews
UILabel *label = self.label;
UITextField *textField = self.textField;
// Determine the labelSize, we could limit the maxSize (especially the height) manually here
CGSize maxSize = self.bounds.size;
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
// Set the computed label size
CGRect labelFrame = label.frame;
labelFrame.size = labelSize;
label.frame = labelFrame;
// Now move the textField just below the label (we could also add a vertical margin here if we want)
CGRect textFieldFrame = textField.frame;
textFieldFrame.origin.y = labelFrame.origin.y + labelFrame.size.height;
textField.frame = textFieldFrame;
This just makes sure the text field is always below the label. Depending on the constraints you had in place, you might need to add more code to make sure the UI lays out correctly.
You also need to make sure that [containverView setNeedsLayout] gets called when the label text changes.
if you are using nib or storybord you can just remove the mark in the file inspector

Resources