Is there a way to change the height of a UIToolbar? - iphone

I've got an UIToolbar in Interface Builder and I've noticed that it's locked to being 44px tall. Of course I'd like to make this larger.
Does Apple allow resizing of this control? If so, how do I go about it?

Sure, just set its frame differently:
[myToolbar setFrame:CGRectMake(0, 50, 320, 35)];
This will make your toolbar 35 pixels tall. Of course this requires an IBOutlet or creating the UIToolbar programmatically, but that's very easy to do.

If that does not work in SDK 6, it is possible to solve as below:
Select the toolbar element and choose Editor > Pin > Height to create a constraint.
Go to your View Controller Scene and select the created Height(44) constraint, then put the value you want.

I found that if I set the frame on the iPad, when hiding/showing the Toolbar would reset itself back to a height of 44 pixels. I ended up having to override UIToolbar and change the method:
// return 'best' size to fit given size. does not actually resize view. Default is return existing view size
- (CGSize)sizeThatFits:(CGSize)size {
CGSize result = [super sizeThatFits:size];
result.height = 55;
return result;
};
This would correct adjust the height even with the hide/show.

In iOS 6, with autolayout, the simplest approach is a UIToolbar subclass in which you override instrinsicContentSize. Here's code from one my apps, where the toolbar is tall. Its sides and bottom are pinned to the sides and bottom of the superview as usual.
-(CGSize)intrinsicContentSize {
return CGSizeMake(UIViewNoIntrinsicMetric, 85);
}

For Xcode 7.1 iOS 9, in auto layout, the size is locked to 44px. The Xcode menu option Editor > Pin > Height is not there, instead do the following action:
In InterfaceBuilder, click the toolbar element to select it.
Control+Drag down anywhere in the toolbar and release, a popup menu will display showing the option "Height" at the top, select it.
You now have a Height constraint to work with and adjust as necessary.

You could also just edit the xib file:
open it as source code and find the entry that defines the frame for the UIToolbar, something along the lines of
<string key="NSFrame">{{0,420}, {320,44}}</string>
and just change the value for 44 to whatever size you need.
This way the toolbar will be taller, and in InterfaceBuilder you'll see the new size grayed out and you'll be unable to change it, but you don't need any outlets or code.

As long as you have a height constraint on the toolbar you can use this little snippet that has helped me adjust heights for classes that inherit from UIView
-(void)setHeightConstraintTo:(CGFloat)height forView:(UIView *)view{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstAttribute = %d", NSLayoutAttributeHeight];
NSArray *filteredArray = [view.constraints filteredArrayUsingPredicate:predicate];
if(filteredArray.count > 0){
NSLayoutConstraint *constraint = filteredArray.firstObject;
constraint.constant = height;
}
}

I'm not sure how this would sit with Apple - and of course it depends how you wish to use the toolbar - but you can add a default UIView and change its class in the property inspector to UIToolbar. This gives you transparency and customisability (in this case height) for free, at the expense of the layout of bar button items.

Swift Solution:
myToolbar.frame = CGRect(x: myToolbar.frame.origin.x, y: myToolbar.frame.origin.y, width: myToolbar.frame.size.width, height: 20)
The CGRectMake is obsolete. This can be replaced with the CGRect. This will set the height of the toolbar to 20. The same works for Segmented control as well.

In interface builder, there is also the possibility to use "User Defined Runtime Attributes".
Simply add an entry with keypath set to "frame" of type "Rect" and set the value you want.

Related

UIView positioning related questions (iOS)

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.

contentSizeForViewInPopover different height in IOS4 and IOS5

Hello,
I have UITableView with static content embedded in UIScrollView
so I have just set size in popover:
- (CGSize)contentSizeForViewInPopover
{
return CGSizeMake(600, 670);
}
but, I got different popover heights (see attachments). In IOS4.3 height is bigger than in IOS5.
I don't want to check IOS version and increase/decrease height.
Please advice.
Thanks
As far as I know, when using the navigation controller as popover contents, you have to
set the contentSizeForViewInPopover on the root controller (or anyone that is being shown as the first). (Don't try to set size on the navigation controller).
whenever you push/pop controllers and you want the popover size changed for the new controller on the stack, call setPopoverContentSize:animated: explicitly. A UINavigationControllerDelegate is good for this.
You can dynamically calculate the height of your popover based on the height of your tableview and overriding contentSizeForViewInPopoverView like this:
- (CGSize)contentSizeForViewInPopoverView {
CGFloat width = 200.0; // Currently no way to obtain the width dynamically, only height.
CGRect rect = [self.tableView rectForSection:[self.tableView numberOfSections] - 1];
CGFloat height = CGRectGetMaxY(rect);
return (CGSize){width, height};
}
This assumes you have 1 section. If you have more, you just need to use rectForSection to determine the height of each section and add them up.

How to set UITextField height?

I am using a UITextField. I want to increase its height but I have not found any property to do this. How can I achieve this?
You can not change the height of the rounded rect border style.
To set the height, just choose any border style other than rounded border in Xcode:
I finally found the fix for this!
As we have found, IB doesn't allow us to change the height of the rounded corner border style. So change it to any of the other styles and set the desired height. In the code change the border style back.
textField.borderStyle = UITextBorderStyleRoundedRect;
CGRect frameRect = textField.frame;
frameRect.size.height = 100; // <-- Specify the height you want here.
textField.frame = frameRect;
If you are using Auto Layout then you can do it on the Story board.
Add a height constraint to the text field, then change the height constraint constant to any desired value. Steps are shown below:
Step 1: Create a height constraint for the text field
Step 2: Select Height Constraint
Step 3: Change Height Constraint's constant value
1.) Change the border Style in the InterfaceBuilder.
2.) After that you're able to change the size.
3.) Create an IBOutlet to your TextField and enter the following code to your viewDidLoad() to change the BorderStyle back.
textField.borderStyle = UITextBorderStyleRoundedRect;
Swift 3:
textField.borderStyle = UITextBorderStyle.roundedRect
Choose the border style as not rounded
Set your height
in your viewWillAppear set the corners as round
yourUITextField.borderStyle = UITextBorderStyleRoundedRect;
Enjoy your round and tall UITextField
Follow these two simple steps and get increase height of your UItextField.
Step 1: right click on XIB file and open it as in "Source Code".
Step 2: Find the same UITextfield source and set the frame as you want.
You can use these steps to change frame of any apple controls.
An update for iOS 6 : using auto-layout, even though you still can't set the UITextField's height from the Size Inspector in the Interface Builder (as of Xcode 4.5 DP4 at least), it is now possible to set a Height constraint on it, which you can edit from the Interface Builder.
Also, if you're setting the frame's height by code, auto-layout may reset it depending on the other constraints your view may have.
I know this an old question but I just wanted to add if you would like to easily change the height of a UITextField from inside IB then simply change that UITextfield's border type to anything other than the default rounded corner type. Then you can stretch or change height attributes easily from inside the editor.
swift3
#IBDesignable
class BigTextField: UITextField {
override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
borderStyle = .roundedRect
}
}
}
Interface Builder
Replace UITextField with BigTextField.
Change the Border Style
to none.
My pathetic contribution to this dumb problem. In IB set the style to none so you can set the height, then in IB set the class to be a subclass of UITextField that forces the style to be rounded rect.
#interface JLTForcedRoundedRectTextField : UITextField
#end
#implementation JLTForcedRoundedRectTextField
- (void)awakeFromNib
{
self.borderStyle = UITextBorderStyleRoundedRect;
}
#end
It kept me from having to hack the XIB file or writing style code into my view controller.
A UITextField's height is not adjustable in Attributes Inspector only
when it has the default rounded corners border style, but adding a
height constraint (plus any other constraints which are required to
satisfy the autolayout system - often by simply using Add Missing
Constraints) to it and adjusting the constraint will adjust the
textfield's height. If you don't want constraints, the constraints can
be removed (Clear Constraints) and the textfield will remain at the
adjusted height.
Works like a charm.
In Swift 3 use:
yourTextField.frame.size.height = 30
try this
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(20, 80, 280, 120)];
UITextField *txt = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[txt setText:#"Ananth"];
[self.view addSubview:txt];
Last two arguments are width and height, You can set as you wish...
You can use frame property of textfield to change frame
Like-Textfield.frame=CGRECTMake(x axis,y axis,width,height)
This is quite simple.
yourtextfield.frame = CGRectMake (yourXAxis, yourYAxis, yourWidth, yourHeight);
Declare your textfield as a gloabal property & change its frame where ever you want to do it in your code.
Happy Coding!
If you're creating a lot of UITextFields it can be quicker to subclass UITextViews and override the setFrame method with
-(void)setFrame:(CGRect)frame{
[self setBorderStyle:UITextBorderStyleRoundedRect];
[super setFrame:frame];
[self setBorderStyle:UITextBorderStyleNone];
}
This way you can just call
[customTextField setFrame:<rect>];
I was having the same issue. tried some of the solutions here but rather than doing all this mumbo-jumbo. I found just setting height constraint is enough.

Getting the width of a UIBarButtonSystemItem

Is there a way to programmatically get the width of a UIBarButtonSystemItem. The width property always returns 0 for system items. In particular, I want to get the exact width of the editButtonItem property of a UIViewController.
On the iPhone the value is 44 but it is a bit bigger on the iPad and I cannot nail it down.
I got my answer from the link that #JoBu1324 left of a comment.
Here is the code I used.
UIBarButtonItem *item = /*...*/;
UIView *view = [item valueForKey:#"view"];
CGFloat width = view? [view frame].size.width : (CGFloat)0.0;
Obviously UIBarButtonItem doesn't have the frame property. As UIBarButtonItem is a direct subclass of NSObject(which in turn don't have the frame), its impossible to get the frame of UIBarButtonItem from code(documented API's).
You have to rely on some other ways to find the width, as you found 44 is the width of editButtonItem in iPhone ;-)
The UIBarButtonItem has a property width, but it generally is 0 for system buttons. So, I usually use my custom button with my localized string inside the button, or use flexibleSpace UIBarbuttonItem to add a flexible space between left and right buttons. You can calculate the width of string by the method -sizeWithFont of NSString. A flexible space can be obtained by the style UIBarButtonSystemItemFlexibleSpace of UIBarButtonItem.

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.