Get actual dimensions of iOS view - ios

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

Related

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.

Objective-C - When I add a subview, my subview is going out of the screen at the bottom. Misunderstanding of frames?

Im practicing objective-C, and I try to do everything programmatically.
I'm making a simple view that I add on my view of the ViewController, but this subview is going out of the screen.
When I set my frame, the position for the X and Y are respected, but the rest, no...
Here is the screenshot of my result :
As you can see... The red subview is going out of the screen.
Here is my loadView where I add that subview :
HomeViewController.m - loadView
-(void)loadView
{
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(15, 15, self.view.frame.size.width - 30, self.view.frame.size.height - 30)];
[subview setBackgroundColor:[UIColor redColor]];
[self.view addSubview:subview];
}
For the padding, I did put 15 for the position x and y... And for the frame, I did calculate with the size of the self.view by removing paddings... As you see, it works well for the width, but for the height, it is a big fail. It goes outside the screen.
In my AppDelegate.h, I set the navigationController.navigationBar.translucent = NO;, in order to that when I set position for x, and y, it starts well after the navigationBar .
I don't understand this weird behavior for the height... If someone has a good explanation for this please.
Thanks
First, you shouldn't rely on the value of self.view in viewDidLoad. It is set to a correct value later, in viewWillAppear:. You can keep your code, if you make your subview resize automatically when self.view is displayed. For that, set autoresizingMask on the subview:
subview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
(or add an equivalent set of constraints if you use Auto Layout.)
Also, I recommend to use bounds instead of frame:
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(15, 15, self.view.bounds.size.width - 30, self.view.bounds.size.height - 30)];
It doesn't make a difference here, but it often does, e.g. if you calculate the frame's x and y based on the parent frame.
loadView method just creates the view. At the point when loadView gets called there is no information about final view frame hence its children views cannot be placed properly.
The right place to update your children views' frames is viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// update child view frame here
}
Remarks: you can define auto-layout constraints of your child view in code and they will be automatically applied to child views when view controller's view gets resized.

how to make horizontal scrolling menu in iOS

I would like to make a menu which will have horizontal scrolling.
The menu contains total 16 categories. So I am planning to take 8 on first part and rest 8 on another part.
Can some-one give me insight of what needs to be done?
I believe I need to use below.
UIScrollView
Add buttons in this scrollview
That's it?
What I want is on first screen 8 buttons where first screen will have two rows with 4 buttons set on each row.
Menu sample can be seen at http://www.shoutem.com/
If all you're doing is adding buttons to a horizontal scroll view you would do something like follows...
- (void)createScrollMenu
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
int x = 0;
for (int i = 0; i < 8; i++) {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, 100, 100)];
[button setTitle:[NSString stringWithFormat:#"Button %d", i] forState:UIControlStateNormal];
[scrollView addSubview:button];
x += button.frame.size.width;
}
scrollView.contentSize = CGSizeMake(x, scrollView.frame.size.height);
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:scrollView];
}
This will create a scrollview with a height of 100, width as big as its parent, and add 8 buttons to it.
You can accomplish you're goal using a UIScrollView and your UIButton objects, it would involve setting each button's frame / layout properties depending on what iOS version you're targeting. (As in Eric's answer).
However, if you're targeting iOS 6 and above, using a UICollectionView where your items/cells are the buttons, then you can get the horizontal scrolling "menu bar" for free. There are plenty of SO posts on this, but the main idea is to use a flow layout where the item size has a height such that there will only be one row of items (just make the item height the same as the collection view's height).
EDIT:
I should say, this might seem like overkill (and maybe it is), but you will end up with a much more flexible component in case requirements change in the future. It also doesn't result in much extra code and abstracts away tedious layout details.

UIScrollView in UIView not scrolling through ENTIRE content

Currently I am having a very trivial issue with my UIScrollView that lies within a UIViewController's UIView.
At the moment, I am using a xib file because alot of the info that I am putting inside of the UIScrollView is way too much for me to code.... (ALOT OF INFO, IMAGES, blah blah blah) but their all static.
This is the code I have used to add the UIScrollView to the UIViewController's UIView:
_scrollView = [[UIScrollView alloc] init];
_scrollView.delegate = self;
_scrollView.scrollEnabled = YES;
_scrollView.showsVerticalScrollIndicator = YES;
_scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height * 7 );
[self.view addSubview:_scrollView];
As you can see, the UIScrollView is LARGE!!!
I set it's content size to 7 times the size of the UIView AND set the delegete method to conform to the UIViewController.
Now, I am able to scroll perfectly BUT I am unable to scroll through the entire UIScrollView's content, even though I set it's content size to A LARGE amount!!!
What the heck am I doing wrong? :(
I also commented out this:
//_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.bounds.size.width, 2389)];
But when I use (^) line of code in comparison to the below (/) line of code.... No scrolling can be made....
_scrollView = [[UIScrollView alloc] init];
What am I doing wrong?! /sob....
Thank you!
EDIT:
The UIScrollView is now HALF THE SIZE of the UIView in xib.....Everything was setup in xib as well... this is ALL the CODE there is to be seen...
If you want some snapshots... here....
The UIScrollview in the first picture is scrolled down ALL THE WAY.....
I also NSLOG(#"self.view.bounds.size.height * 7) -> I get 2000+
Well because I cant see all of your code or its results I can only assume that the UIScrollView is larger then the screen.
This means that some of the content is hidden outside the bounds of the screen.
Hope this helps :)
It's a bad idea to place all of the views directly in the scroll view.
try putting them into one view that only it lives directly within the scroll view.

Understanding scaling sizes for UIViews and objects

I am trying to better understand how to control the size of Views in terms of older iphones and the new iphones difference in size.
If I have a design like the below example, how should this be coded programatically in terms of the subviews.
Excuse the badly drawn diagram but it should help to explain.
In this example, the fieldView and buttonView would always need to remain a fixed size as they have objects which would not look great when made smaller. However the logoview has another sub view for the logo itself, so could be shrinked depending on device/screen size.
How would this be accomplished? Setting up the example subviews programatically. The part I do not understand is that in viewDidLoad where the subviews are created would you not have to create in order like this:
-(void)ViewDidLoad {
CGRect screen = [[UIScreen mainScreen] applicationFrame];
wholeView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.size.width, self.view.bounds.size.height)];
logoView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,150);
fieldView = [[UITableView alloc] initWithFrame:CGRectMake(0, logoView.bounds.size.height, 320, 100);
I understand about using
autoresizingMask
but how would it come into use in terms of working out a height depending on the actual view size available?
Not sure I understand your doubts, but adding the following should do the trick:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
logoView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
The remaining view would keep both their margins and height/width fixed (i.e., the default value of UIViewAutoresizingNone for their autoresizingMask is fine.)
how would it come into use in terms of working out a height depending on the actual view size available?
basically, what you see on your iPhone display is a hierarchy of views; the topmost view in this hierarchy is a UIWindow. This has the same size as the device screen (it is initialized that way).
Now, in the code above, our logoView has fixed margins: this means that it will remain at the same distance from the container view frame; if we specify that is size is flexible, then the logoView will simply occupy the whole space to keep the margins fixed.

Resources