Adding a label to a scroll view in iOS - ios

I would like to add a label to a scroll view. This is being done in main controller. However, when I do the following the label is on overlaying the contents of scroll view. I want the label to be exactly on top and then the rest of the scroll view contents.
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 80)];
label.backgroundColor = [UIColor greenColor];
label.text = #"Testing";
[self.scrollView addSubview: label];
[self.scrollView setNeedsDisplay];

Unfortunately, there is a little more to doing this programmatically. I'd highly recommend that you add this label to your xib or storyboard and not do this programmatically but if that isn't an option for what ever reason then there is only one thing you can do. You'll need to iterate over your scrollView's children and push each of the down slightly to make room for your new label, then set the label at the top of the scrollView.
Very simple example, this may not be working perfectly so you'll need to tweak it to what you need/want.
// Set the amount of y padding to push each subview down to make room at the top for the new label
CGFloat yPadding = 80.0f;
CGFloat contentWidth = CGRectGetWidth(self.contentView.frame);
UILabel* label = [[UILabel alloc] initWithFrame:(CGRect){CGPointZero, contentWidth, 44.0f}];
label.text = #"Testing";
// Iterate over each subview and push it down by the amount set in yPadding. Also, check for the subview with the lowest y value and set that as your labels y so that it is at the top of the scrollView.
for (UIView* subview in self.scrollView.subviews) {
CGRect subviewFrame = subview.frame;
CGFloat currentLabelY = CGRectGetMinY(label.frame);
// Set the labels y based off the subview with the lowest y value
if (currentLabelY == 0.0f || (currentLabelY > CGRectGetMinY(subviewFrame))) {
CGRect labelFrame = label.frame;
labelFrame.origin.y = subviewFrame.origin.y;
label.frame = labelFrame;
}
// Push the subview down by the amount set in yPadding
subviewFrame.origin.y += yPadding;
subview.frame = subviewFrame;
}
// Finally, add the label as a subView of the scrollView
[self.scrollView addSubview:label];

You should add the label as a subview of the scrollview:
[self.scrollView addSubview:label]

Related

How to add vertical space between UINavigationBar and UISegmentedControl?

I'm working with my UI completely programmatically here. When I add a UISegmentedControl to my UITableViewController's header view, it just fixes itself up there with no vertical space between the UINavigationBar. How can I add some padding between the UISegmentedControl and the UINavigationBar ?
Instantiate a UIView object and add your UISegmentedControl as a subview. Then set the UIView as your table's headerView. You'll be able to add padding by adjusting the frame of the UIView you created.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 150 /* <-- adjust this value for more or less padding */)];
UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:#[#"One", #"Two", #"Three"]];
segControl.frame = CGRectMake(0, 90, 200, 29);
//calculate the middle of the header view
CGFloat middleOfView = headerView.bounds.size.width / 2;
CGFloat middleOfSegControl = segControl.bounds.size.width / 2;
CGFloat middle = middleOfView - middleOfSegControl;
//position the seg control in the middle
CGRect frame = segControl.frame;
frame.origin.x = middle;
segControl.frame = frame;
[headerView addSubview:segControl];
self.theTableView.tableHeaderView = headerView;
}
Of course you can mess with the frames some more to get things positioned like you want them.

Why a UILabel at Y position of 0 does not sit at top of screen

Context
This is a UIViewController which is within a UINavigationController stack
Within this UIViewController I'm adding a UILabel programmatically at (x,y) coordinates of (0,0)
I've experimented adding UILabel to self.view (this is within a UIViewController) or adding UILabel to a UIView, this UIView is self.containerView
self.containerView is created and added to the view through this code:
- (void)addContainerView
{
// Create a UIView with same frame as the screen bounds
CGRect containerViewFrame = [[UIScreen mainScreen] applicationFrame];
self.containerView = [[UIView alloc] initWithFrame:containerViewFrame];
// Give the UIView a red background
self.containerView.backgroundColor = [UIColor redColor];
// Add the view
[self.view addSubview:self.containerView];
}
The UILabel is added through this code:
- (void)addTestLabel
{
self.navigationController.navigationBarHidden = YES;
CGRect frame = CGRectMake(0, 0, 100, 100);
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.text = #"this is a test";
[self.view addSubview:label]; // OR [self.containerView addSubview:label]
}
When UILabel is added to self.view
When UILabel is added to self.containerView
Questions
Why doesn't the UILabel sit right at the top of the screen, even behind the status bar?
Why is there a difference between the yPos, dependent on whether it is added to self.view or self.containerView
Change the background color of the label and I think you'll see what's going on. The height of the label is 100 pixels and it's vertically centering it within that space. Change the height to 20 or 30 and try it again.

Adding UIScrollView to a UIViewController

I have a UIViewController, and I want to add a UIScrollView to it (enable scroll support), is it possible?
I know it is possible, if you have a UIScrollView to add a UIViewController to it, but I'm interested also if reverse was true, if I cann add a UIScrollView to an existing UIViewController, such that I get scrolling feature.
Edit
I think I have found an answer: Adding a UIViewController to UIScrollView
An UIViewController has a view property. So, you can add a UIScrollView to its view. In other words, you can add the scroll view to the view hierarchy.
This is can achieved by code or through XIB. In addition, you can register the view controller as the delegate for your scroll view. In this way, you can implement methods for performing different functionalities. See UIScrollViewDelegate protocol.
// create the scroll view, for example in viewDidLoad method
// and add it as a subview for the controller view
[self.view addSubview:yourScrollView];
You could also override loadView method for UIViewController class and set the scroll view as the main view for the controller you are considering.
Edit
I created a little sample for you. Here, you have a scroll view as a child of the view of a UIViewController. The scroll view has two views as children: view1 (blue color) and view2 (green color).
Here, I suppose you can scroll in only one direction: horizontally or vertically. In the following, if you scroll horizontally, you can see that the scroll view works as expected.
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 2, self.view.bounds.size.height);
[self.view addSubview:scrollView];
float width = 50;
float height = 50;
float xPos = 10;
float yPos = 10;
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(xPos, yPos, width, height)];
view1.backgroundColor = [UIColor blueColor];
[scrollView addSubview:view1];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width + xPos, yPos, width, height)];
view2.backgroundColor = [UIColor greenColor];
[scrollView addSubview:view2];
}
If you need to scroll only vertically you can change as follows:
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height * 2);
Obviously, you need to rearrange the position of view1 and view2.
P.S. Here I'm using ARC. If you don't use ARC, you need to explicitly release alloc-init objects.

Why does this UIScrollView experiment fail?

In my view contoller's viewDidLoad function, I have this guy:
UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:self.view.frame];
scroller.contentSize = self.view.frame.size; // Tried w/ and w/o this
scroller.showsVerticalScrollIndicator = YES; // Tried w/ and w/o this
for (int x = 0; x < 10; x++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, x * 100, 100, 100)];
label.text = [NSString stringWithFormat:#"%i label", x];
[scroller addSubview:label];
}
[self.view addSubview:scroller];
It shows the first 8 labels OK, but the scroll view won't... scroll. It is just cut off. Any idea why?
It won't scroll because your contentSize is only set to the same size as the scrollview itself. The contentSize is the size of the scrollable area that the scrollview acts as a window in to. You need to set it wide enough to actually see your labels.
Based on your current code, your final label is in rect {0, 900, 100, 100}, so your contentSize needs to be at least CGSizeMake(100, 1000).

UIView in UIScrollView does not appear

I'm trying to create a horizontally scrollable menu similar to that in this video.
For some reason the UIView doesn't appear after adding a bunch of UIButtons to it and adding it to the UIScrollView. Here's my code (it's called in -viewDidLoad of a subclass of UIViewController):
//set up scrollview
UIScrollView *designPicker = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 431, 320, 49)];
//set up a view to drop into the scroll view
UIView * buttonsView = [[UIView alloc] initWithFrame:CGRectMake(0, 431, 640, 49)];
//add buttons to scrollview
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
float runningX = designPicker.frame.origin.x;
for (i = 1; i <= 10; i++)
{
UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[tempBtn setBackgroundImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
CGRect rect = CGRectMake(runningX, designPicker.frame.origin.y, 30.0, 30.0);
tempBtn.frame = rect;
[buttonsView addSubview:tempBtn];
runningX = runningX + 35;
[tempBtn release];
}
[designPicker setContentSize:buttonsView.frame.size];
[designPicker addSubview:buttonsView];
[self.view addSubview:designPicker];
You should not add the buttons using the frame of the UIScrollView. The origin of the frame is in the superview's (superview of the UIScrollView) coordinates. You should make the buttons' frame relative to the UIView. So if you want the buttons to appear at the top of the view that you should start at (0,0).
Instead of adding scrollview as subview to your view, add view as subview of scrollview. As-
[self.scrollView addSubview:self.view];
// release scrollView as self.view retains it
self.view=self.scrollView;
[self.scrollView release];
And make sure your view should have large content size than content size of your scrollview.It worked for me.

Resources