UIView positioning related questions (iOS) - iphone

I have a bunch of questions:
How do I position a UIView so that it is on the bottom of the view I am adding it to?
How can I add a subview to a view so that it is positioned in the corner of the superview with a small gap (Like if I want a 'x' cross sign for closing something)
Is their a utility class for easy UIView positioning (and rotation)?
Any references, open source tutorials etc. will be more then welcome!

(a) How do I position a UIView so that it is on the bottom of the view I am adding it to?
OK, let's say you want to position button as a subview at the bottom of view form, you calculate the origin.y of the subview button by subtracting button's height from the height of the form
CGRect buttonFrame = button.frame;
buttonFrame.origin.y = form.bounds.size.height - buttonFrame.size.height;
button.frame = buttonFrame;
[form addSubview:button];
You can change origin horizontal position as well. You want it on the bottom left of form?
buttonFrame.origin.x = 0;
Or on the right edge of form?
buttonFrame.origin.x = form.bounds.size.width - buttonFrame.size.width;
Or in the middle (horizontally) of form?
buttonFrame.origin.x = (form.bounds.size.width - buttonFrame.size.width) / 2;
or another way using CGRectGetMidX (found in CGGeometry utility methods):
buttonFrame.origin.x = CGRectGetMidX(form.bounds) - buttonFrame.size.width/2;
Autoresizing handles adjusting the frame when the parent view's size changes. But you still have to position it first.

int xOffset = 20;
int yOffset = 20;
CGRect BottomRight_NewFrame = CGRectMake((superview.frame.size.width - subview.frame.size.width-xOffset), (superview.frame.size.height - subview.frame.size.height-yOffset), subview.frame.size.width, subview.frame.size.height);
subview.frame = BottomFrame;

You can use the new Autolayout feature of iOS 6 or the old Struts & Springs in the Interface Builder to achieve this.
This tutorial explains both:
http://msmvps.com/blogs/kevinmcneish/archive/2012/12/10/tutorial-ios-6-auto-layout-versus-springs-and-struts.aspx
Or you can set the autoresizing mask programatically. It is explained pretty well here:
UIView autoresizingMask - Interface Builder to Code - Programmatically create struts and springs - Swift or Objective-C

It's easy enough to just set the frame, e.g. (untested code )
subview.frame = CGRectMake((superview.frame.origin.x - subview.frame.origin.size.width/2)-20, (superview.view.frame.origin.y - subview.frame.origin.size.height/2)-20, subview.view.frame.size.width, subview.view.frame.size.height);
if you'll be doing a lot of this then create a utility class or method.

Autolayout will help you position the views and maintain those positions if the size of the superview changes. If the superview isn't going to change, you don't really need to mess with constraints -- you can just set the position of the subview appropra
If you're adding view viewB to view viewA:
a) To position viewB so that it's bottom edge corresponds to the bottom edge of viewA:
viewB.frame.origin.y = viewA.bounds.size.height - viewB.bounds.size.height;
b) You don't say which corner, but it's just a matter of doing the math. For example, the upper right corner of viewA is at {viewA.bounds.size.x, 0} in viewA's coordinate system. If you want to put viewB there, set it's origin to:
{viewA.bounds.size.x-viewB.bounds.size.x, 0}
If you want to add a margin, you can add that to the computation:
int margin = 10;
{viewA.bounds.size.x-viewB.bounds.size.x-margin, margin}
d) Use NSLayoutConstraint to access the autolayout system's constraints programmatically. There's a nice visual format language, so that for your question (a) you could set the constraint for viewA to:
V:|-[viewB]-0-|
The V means that you're working in the vertical direction, |'s represent the edges (top and bottom, thanks to the V) of the superview (that's viewA), and the 0 means that the distance between viewB and the bottom of its superview should be 0.

You can setup constraints in iOS6 but if you want to work on older os's you need to position them manually. Math.

Related

Find the position of subview in a View

Goal : How we can find the position of subView in a View. I wants to find out the upper left (x,y)position of my scrollBar in a View, I am also using navigation Bar in my Application does it effect on the positioning of subViews from the Top?
I know how to find the height and width of subview like
CGSize viewSize = scrollView.frame.size;
height=viewSize.height;
width=viewSize.width;
What you're looking for is probably:
CGPoint viewPosition = scrollView.frame.origin;
x=viewPosition.x;
y=viewPosition.y;
But if you're looking to translate to another view's coordinate system, you could use:
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
And pass it the point and view you wish to translate.
To get the x and y use origin
CGPoint point = scrollView.frame.origin;
float x = point.x;
float y = point.y;
You can use this one too...
CGRect rect = [scrollBar frame];
float origineFromX = rect.origin.x;
float origineFromY = rect.origin.y;
may this will help you ...
If you put navigation bar in the view, the position of the scrollview has to be shifted downwards to align properly in the view. The origin(top left position) of the scrollview will be different with and without the Navigation bar.
If you are using a fullscreen scrollview, you have to reduce the height of the scrollview to accomodate the navigation bar.

UIView positioning in IB of Xcode 4

Consider the screen shot above. The UIView is positioned too much to the top causing the upper test string to be partially off and there is a gap shown at the bottom screen. The screen shot also shows its corresponding positioning values in IB : x = 0 and y = 20. So there is actually an offset (y = 20) default to clear the top status bar. But still the status bar shown covers part of the UIView.
The x, y entry is greyed out, so it seems not possible to change its values. Have spent quite some time but still not able to solve this seemingly easy problem. Hope that somebody who is familiar with this could give some hints on how this should be done.
Update :
Have done it in code as suggested. It seems to work ok. If you find any errors please let me know ...
- (void)viewDidLoad
{
CGRect position_and_size;
CGPoint cg_point;
CGSize cg_size;
[super viewDidLoad];
// setup after loading the view from its nib.
NSLog(#" --- Screen loaded --- ");
cg_size.width = 320;
cg_size.height = 460;
cg_point.x = 0;
cg_point.y = 20;
position_and_size.origin = cg_point;
position_and_size.size = cg_size;
[[self view] setFrame : position_and_size];
}
.
The following is the latest screen shot :
The problem is that you're placing a view that's 460 pixels high at {0,0} in a window that's 480 pixels high. The first 20 pixels of your view therefore ends up under the status bar, and the view fails to cover the bottom 20 pixels of the window. You can fix it in any of the following ways:
Change the autoresize options so that the view's size will be automatically adjusted to fill the window.
Resize the view to match the window's bound, either in code or in IB.
Position the view at {0,20}, either in code or in IB.
You can fix it programmatically:
[yourSubView setFrame:self.view.bounds];
Assuming self.view - parent view, where it should fit.

Is is possible to have a XIB then set the size and have everything scale to fit in a UIView?

I'm new to iOS development and I'm not sure if what I want to do is possible.
Basically I'm retrieving some products via a webservice and I want to display each one across the screen, 4 squares per row. Each one of these squares (with image and name of product) is a UIView which has a .h,.m and xib file. I create each view like this:
CategoryItemView *catItem = [[[NSBundle mainBundle] loadNibNamed:#"CategoryItemView" owner:self options:nil] objectAtIndex:0];
[categoryItems addObject:catItem];
and I position it like:
while (colCount < cols && items < [categoryItems count]) {
CGRect viewRect = CGRectMake( x * colCount + pad , (row * (x-pad)) + pad*row + pad, x - pad, x - pad );
CategoryItemView* myView = [categoryItems objectAtIndex:items];
myView.frame = viewRect;
[self.view addSubview:myView];
colCount++;
items++;
}
I want to use a xib so I can layout all the elements. However I cannot find a way to lay out the xib so that when positioning the UIView like this all the elements are scaled to fit and keep their relative positions in the UIView. Is this possible?
Update: You can view a 2 class example here thats not working http://home.glasscubes.com/share/s/d57sb19
thanks
autoresizingMask is the property you are looking for on those views.
From the docs:
autoresizingMask
An integer bit mask that determines how the receiver resizes itself
when its superview’s bounds change.
#property(nonatomic) UIViewAutoresizing autoresizingMask
Discussion
When a view’s bounds change, that view automatically resizes its
subviews according to each subview’s autoresizing mask. You specify
the value of this mask by combining the constants described in
UIViewAutoresizing using the C bitwise OR operator. Combining these
constants lets you specify which dimensions of the view should grow or
shrink relative to the superview. The default value of this property
is UIViewAutoresizingNone, which indicates that the view should not be
resized at all.
When more than one option along the same axis is set, the default
behavior is to distribute the size difference proportionally among the
flexible portions. The larger the flexible portion, relative to the
other flexible portions, the more it is likely to grow. For example,
suppose this property includes the UIViewAutoresizingFlexibleWidth and
UIViewAutoresizingFlexibleRightMargin constants but does not include
the UIViewAutoresizingFlexibleLeftMargin constant, thus indicating
that the width of the view’s left margin is fixed but that the view’s
width and right margin may change. Thus, the view appears anchored to
the left side of its superview while both the view width and the gap
to the right of the view increase.
If the autoresizing behaviors do not offer the precise layout that you
need for your views, you can use a custom container view and override
its layoutSubviews method to position your subviews more precisely.

iOS Oblique TextView scrolling in Cocos2D or native

How to make UITextView scrolling when text is not vertical?
Like
+--------------+
/ Text /
/ Here /
/ Is /
/ Not /
/ Vertical /
+--------------+
Where starts of lines are in the same angle as border (background) image.
Or we can use another element than UITextView if it can solve the problem.
Scrolling only in vertical direction,
Background image is fixed,
No, visible is only part which fits to shape, other is hidden
Screen is covered by private license, I can't publish it.
You can skew the textfield by using this code:
float angle = -20.0/180*M_PI;
CATransform3D skew = CATransform3DIdentity;
skew.m21 = tanf(angle);
textField.layer.transform = skew;
EDIT: perhaps I've misunderstood your question- you want straight text, but oblique scrolling? If that's the case, you can put your UITextField (or UITextView) into a UIScrollView, but give the scrollView the opposite transform to your textField, like so
float angle = -20.0/180*M_PI;
CATransform3D skew = CATransform3DIdentity;
skew.m21 = tanf(-angle);
scrollView.layer.transform = skew;
skew.m21 = tanf(angle);
textField.layer.transform = skew;
Do you mean that you want the text view to scroll along a diagonal? It's not the most elegant solution but something like this perhaps:
Implement the scrollViewDidScroll: delegate method
Get the existing contentOffset at each delegate callback
Modify the x-value of the offset to an amount that corresponds to the amount of "diagonal-ness" you want to go in
[scrollView setContentOffset:newOffset animated:NO];
Also set the scroll view's directionalLockEnabled to NO.

Set UIView.frame.size.height to zero to hide content?

UIView *stateView = [getSomeUIView thisOne];
CGRect currentFrame = stateView.frame;
if(currentFrame.size.height == 0.0) {
currentFrame.size = CGSizeMake(260, 60);
}
else {
currentFrame.size = CGSizeMake(260, 0);
}
stateView.frame = currentFrame;
I would expect all the subviews would be hidden when the height of the frame is set to zero however this does not happen (in the iPhone 4.0.1 Simulator).
Any suggestions why or alternatives?
I was planing to later animate the frame so it's a sliding effect. I can not use the y position and move it off screen nor can I create a element to hide it behind since I'm working with a background image and everything on top is transparent/alpha layer.
I've got the same problem. Solved it with clipsToBounds property:
stateView.clipsToBounds = YES
Subviews will only change size if you set their springs and struts to do so.
By default, they are set to "stay the SAME width and height, and stay the same distance from top left corner of the parent view".
You can set the springs/struts in Interface Builder, or in code. e.g.:
aSubView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Use UIScrollView instead of UIView. UIScrollView is made to hide "overflow" and works perfectly.