Resizing a UISegmentedControl within a UIToolBar with constraints for different screen sizes - swift

I have a UIToolBar underneath a navbar, and in this toolbar is a Bar Buttom Item which holds a UISegmentedControl. The problem is I can't add constraints to anything inside the toolbar. The UISegmentedControl pins itself to the left margin when I place it inside the toolbar/bar button item, but then I don't get any dashed blue line when I try to set it width to be the same from the margin on the right side. I see no options to center either, but I don't really want to center, I want to make the segmented control grow in width as the screen goes from iPhone4 to iPhone6+ (in portrait) so that its always some X-pts from the left and right margin. How can I go about doing this?
I have the width of the toolbar, which is 375 for a 4.7inch screen. I can also get the width of the segmented control for this size too, but I can't tell the correct width to make the margins on the left and right the same, I can only eyeball it.

You should add the UISegmentedControl as a direct subview to the UIToolbar (either via addSubview or directly in interface builder). While going the detour around UIBarButtonItem seems convenient here, it deprives you of the possibility to lay things out exactly as wanted, because UIToolbar will handle layout for you and you cannot override this.When you add the UISegmentedControl as a subview, you can add constraints as needed to make it fill the entire width.

Related

Set UIToolBar Vertical setup with StoryBoards

I currently have an app with a square UIView where an image will be drawn. In Portrait view a UIToolBar exists at the bottom of the UIViewController.
It looks like this :
However, when changing into landscape mode,I'd like the view to stay a square on the left hand side, and the toolbar to be aligned vertically on the right hand side, and the icons stacked vertically. Is there a way to do this with Storyboards?
There is no way to do this in storyboard as standard UIToolBar does not support vertical layout. You will need to develop your own component or find something third-party.

custom keyboard UITextField inputView xcode

I am adding a custom keyboard to a view using inputView linked to a UITextField. I have set the size at Width 216, Height 320. I have it entering from the bottom on a portrait orientation. I want it to only cover 216 pixels of the screen but now when it comes up with the keyboard hugging the left side and has the correct aspect ratio. However there is a gray background that extends from the right edge of the keyboard to the right side of the view. Is there any way to remove this so it is clear and I can see the right side of the view? I have tried setting the background of the view to clear color and tried everything I can think of. Does anyone know if this is possible?
I guess you can't do it, because with keyboard opening the view moves up, so there are the "empty" rectangle in the 216x320 pts.

AutoLayout: Vertically centering two UIViews in a superview that can resize

I have two UIButtons, one on top of the other, in a superview whose height can be resized. The two buttons should have a constant vertical spacing between them, but the top and bottom spacing should resize so that the two buttons stay centered in the superview as it resizes.
I tried creating two less-than-or-equal constraints (with equal priority) on the spacing to the superview for each button, as well as a constant vertical spacing between the buttons, as shown below:
(The reason why it's less-than-or-equal here is because this view is defined at the given height in IB for 4" screens, but can be shrunk for 3.5" screens.) However, this doesn't do the trick, as you can see from the screenshot while the app is running:
It's almost as if you want to be able to tell AutoLayout that the two constraints themselves should have equal values, even if they are both set to "less-than-or-equal". Is there any way to do what I'm trying to do, or perhaps a better way?
This is so trivial to do in IB.
1) ⌃ drag from button1 to top. select "center horizontally in container".
2) ⌃ drag from button1 to left. select "center vertically in container".
3) do the same with button2.
4) now the only thing left to do is size the buttons because this is what it looks like.
This is also very trivial.
5) ⌃ drag from button1 to the left. select "leading space to container margin".
6) ⌃ drag from button1 to the right. select "trailing space to container margin".
7) do the exact same thing with button2.
The finished product, looks like this (NB I didn't quite center them, but I could have easily enough):
The simplest way to vertically center is to add a NSLayoutAttributeCenterY constraint - preferably to the element that is near the center of the view. And if all views have a vertical spacing constraints, then they will all be centred. No need to muck with the view hierarchy or add spacer views.
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:button2
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0]];
If you need to adjust the positioning, set the constant. For example: constant:-30 will move it up 30 points.
You can also anchor elements based on different logical areas of the view. For example, if you wanted to anchor your first button at 25% of the view height, you can set the multiplier to 0.5.
Agreed with rdelmar. Here's another option if you want to preserve view hierarchy.
You are currently spacing the buttons at the top and bottom using constraints. Instead, create two empty UIViews, they will be used as spacers. They should be positioned one at the top and one at the bottom of your buttons. Using autolayout constraints, make sure that the height of these two spacer views is always equal. Make sure they are pinned to the top and bottom of the buttons and the top and bottom of the superview, respectively.
In VFL: V:|-[spacer1(==spacer2)]-[button1]-(20)-[button2]-[spacer2(==spacer1)]-|.
You may have to do this in code, I'm not sure if IB can do this.
One way to accomplish this is to enclose the two buttons in another UIView, and center that view in the controller's view. Give the buttons a fixed distance to the top and bottom of this view, and either a fixed distance between them, or a fixed height for the view.

Moving UIBarButtonItems vertically in a UIToolBar

I'm trying to duplicate the look and feel of the Mobile Safari toolbar. As you know, the normal toolbar is too short, so I changed it like this:
[topToolbar setFrame:CGRectMake(0.0, 0.0, 320.0, 57.0)];
and this makes it about as wide as I need, however... now my UITextField is right in the middle instead of being at the bottom like it is in Mobile Safari:
VS.
I've tried what feels like a million things (changing the frame, the insets...) and nothing works. Any ideas?
The toolbar will force the items to be centered vertically. However, this is easily overcome by wrapping your UITextFieldin a UIView container aligned to the bottom of the container. Make the UIView the same height as the toolbar. Adding the container to the toolbar will result in the container being centered and the textField aligned along the bottom.
You could create a custom view that has the label and text field and then use the UIBarButtonItem initWithCustomView: method.

How do I set the right margin of a UITextView?

I have a vertically-scrolling UITextView that fills the width of the screen. I need the text view to have margins (contentInset) of 20 pixels on the left and the right. But for some reason, I can't get the right-hand margin to work, either in Interface Builder or in XCode.
The reason I can't just make the text view narrower is because I am adding a subview which needs to run the full width of the screen. Also, I can't turn subview clipping off, because it plays havoc with a load of other elements on the screen.
Anyone know why the contentInset property is not affecting the right margin?
Thanks!
You could add an intermediate view that can be the superview to your text view and what was previously it's subview.
New View with Frame(0,0,width,height)
->TextView with Frame(20,0,width-20,height)
->Subview with Frame(0,0,width,height)