How to add a UILabel inside a UIScrollView programatically? - ios

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.

Related

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.

Page scrolling not working with Autolayout enabled

I have the following ViewController:
It contains two UILabels at top, an UIImageView, below it a UITextView and below this a UIButton. I have arranged them using the Interface Builder following the blue line. All of this controls are inside a UIScrollView:
[self.scrollView setContentSize:CGSizeMake(320, 660)];
[self.scrollView addSubview:self.descriptionText];
[self.scrollView addSubview:self.descriptionImage];
[self.scrollView addSubview:self.titleLabel];
[self.scrollView addSubview:self.feedNameLabel];
[self.scrollView addSubview:self.load];
So when enabling Autolayout option, I just selected the ViewControler and then "Reset to Suggested Constraints in Description View Controller". But when I run the app, the scroll still appears for the entire page, but the only control scrolling is the UIButton. When scrolling up it will scroll below the UITextView.
I have made the UITextView to resize depending on the text, so I want my UIButton to always have the same distance to the UITextView. For that I have also set Vertical Spacing to the UIButton, but like this I don't have any scroll to my page.
Using the Autolayout for the first time, can I get some suggestions on what am I doing wrong ?
edit:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *contentView = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,660)];
[contentView addSubview:self.descriptionText];
[contentView addSubview:self.descriptionImage];
[contentView addSubview:self.titleLabel];
[contentView addSubview:self.feedNameLabel];
[contentView addSubview:self.load];
contentView.translatesAutoresizingMaskIntoConstraints = YES;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 660)];
//[scrollView setContentSize:CGSizeMake(320, 660)];
[scrollView addSubview:contentView];
[self.view addSubview:scrollView];
// to resize UITextField
[self.descriptionText sizeToFit];
[self.descriptionText layoutIfNeeded];
self.descriptionText.scrollEnabled = NO;
}
Autolayout is a bit tricky when it comes to UIScrollView subviews. I would recommend:
1-Embed all your controls (descriptionText + descriptionImage + titleLabel + feedNameLabel + load) into a UIView first, say contentView:
UIView *contentView = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,660)];
//add all controls as subviews to contenView
2-Add contentView as subview of self.scrollView.
3-Keep the translatesAutoresizingMaskIntoConstraints property of contentView to YES.
I recommend you read this technical note from Apple here.
If you are using AutoLayout you don't have to set the content size of your scroll view. In fact, I believe it has no effect at all. It is set automatically from the constraints you are setting up. The trick is that you have to have at least one constraint related to every side of the scroll view, otherwise the content size will be wrong and it won't scroll. So for example, if you would have a really large image in it you would need 4 constraints connecting the sides of the UIImageView to the sides of the UIScrollView. You can read about this more here.

How to put UIlabel on UIImageView programatically

I'm trying to put a UIlabel on a UIImageView which is in a UIScrollView. How can I accomplish this?
imageView is a UIView, so you can add subviews to it.
also make sure you set the label with an appropriate frame
You can do:
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; //or whatever size you need
[imageView addSubview:myLabel];
You can add it directly by dragging Label from to your storyboard/xib if you want it to e static. But if you want it to dynamically generate at runtime then you should add it by using
UILabel *yourlabel = [[UILabel alloc]initWithFrame:CGRectMake(YOUR COORDINATES)];
then you can add it to any of your view.For your imageview you can add it as
[imageview addSubview:yourlabel];
Often you may require to remove it from that view if not needed. You can similarly call removeFromSuperView also.
Hope this works :)

Multiline UILabel from xib

In my awakeFromNib function, I have:
[_descriptionLabel setLineBreakMode:UILineBreakModeWordWrap];
[_descriptionLabel setNumberOfLines:10];
[_descriptionLabel sizeToFit];
and yet my label looks like this:
I know I'm setting these calls on the right label, because without these lines, the text appears vertically centered rather than aligned at the top. How can I make make my UILabel multiline?
I also tried setNumberOfLines:0.
SOLUTION I had set the width incorrectly in the xib file.
Try to set [_descriptionLabel setNumberOfLines:0]; which set the number of lines to auto.
It might be that sizeToFit is changing your label width, try to set it to explicit width, or remove it.
Just make sure that the initial width is set correctly. Then it should expand/shrink the height. But still the label won't be aligned to the top, it will be centered in its previous size after a call of sizeToFit (in case the new height is smaller than before, otherwise the origin will stay the same).
If you're not using AutoLayout, you need to measure text in code:
CGRect frame = _descriptionLabel.frame;
CGSize size = [_descriptionLabel.text sizeWithFont:_descriptionLabel.font constrainedToSize:CGSizeMake(frame.size.width, FLOAT_MAX) lineBreakMode:_descriptionLabel.lineBreakMode];
frame.size.height = MIN(MAX(size.height, frame.size.height), MAX_ALLOWED_HEIGHT);
_descriptionLabel.frame = frame;
Are you sure your awakeFromNib is in the right place. If it's in the view controller, it won't work. If it's in the implementation of a custom label, it should get called and that code should work:
#interface TestLabel : UILabel
#end
#implementation TestLabel
- (void)awakeFromNib
{
[self setLineBreakMode:UILineBreakModeWordWrap];
[self setNumberOfLines:10];
[self sizeToFit];
NSLog(#"Label: %#", NSStringFromCGRect(self.frame));
}
#end
Also, it's easier to set numberOfLines to 0, which means "any number of lines". And you shouldn't need to set UILineBreakModeWordWrap, since that's the default.
If you want to keep the code in the view controller, you can move it to viewDidLoad, which is the best place to do this kind of setup.

Get actual dimensions of iOS view

How would I get the actual dimensions of a view or subview that I'm controlling? For example:
UIView *firstView = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,100)];
[self addSubview:firstView];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 20, 230, 120)];
[firstView addSubview:button];
As you can see, my button object exceeds the dimensions of the view it is being added to.
With this is mind (assuming there are many objects being added as subviews), how can I determine the actual width and height of firstView?
If you would like to have the button have the same width and height as firstView you should use the bounds property of UIView like this:
UIView *firstView = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,100)];
[self addSubview:firstView];
UIButton *button = [[UIButton alloc] initWithFrame:firstView.bounds];
[firstView addSubview:button];
To just get the width/height of firstView you could do something like this:
CGSize size = firstView.bounds.size;
NSInteger width = size.width;
NSInteger height = size.height;
The first view really is 200 x 100. However, the views inside are not clipped unless you use clipsToBounds.
A preferable solution to your problem is to stop adding views that exceed the dimensions or to stop resizing views so that they overflow the available space, as appropriate.
(To actually calculate the full bounds including all subviews in the hierarchy is not hard, just a lot of work that won't actually get you anywhere. UIView happens to allow views to be larger than their containers, but it doesn't necessarily give any guarantees about what will work correctly and is likely to be a source of bugs if taken advantage of. The reason for clipsToBounds is probably that clipping is expensive but necessary during animation where subviews may be temporarily moved out of bounds for the purposes of an effect before they are removed from the view.)
firstview.frame.size.width
firstview.frame.size.height

Resources