I am trying to accomplish what the Imgur app has done in one of their UICollectionViewCells in their about view. See below:
I want 1 UICollectionViewCell but instead of 3 sections of views inside the cell, I just want two (comments and posts).
For my UICollectionView I am resizing the cell at runtime to make it fit almost the whole screen minus a bit for margin's sake because I want to make a card view like Imgur.
I followed this stackoverflow post to get 2 views side by side: iOS Autolayout: two buttons of equal width, side by side
and I am able to get 2 views side by side of equal width. Here's what they look like in the storyboard:
but when I run the app, my views get stretched because of the autoresizing. See below:
How can I get the views to both be of equal width and have equal spacing between, before and after the views?
You can use UIStackView. It provides an easy way to lay out a series of views horizontally or vertically.
Select the two views and click on the new Stack button in the Auto Layout toolbar at the bottom right of the storyboard canvas:
Give constraints to your stack view from top, left, right and bottom. Then make your Attributes Inspector of the stack view like this:
NB. If you want to learn more about Stack View, follow this fantastic tutorial in Ray Wenderlich: https://www.raywenderlich.com/114552/uistackview-tutorial-introducing-stack-views
Believe me most of the complexities associated with Autolayout will become trivial once you learned Stack View
Related
I have been struggling with getting buttons (circular) to keep their size in a stack view to no avail.I have two rows of buttons where I place each row in its own horizontal stack view and then embed both stack views in an outer stack view to make it easier to set constraints.
The issue is that the buttons do not keep their original size in portrait or landscape. What settings am I missing to achieve this? I set the size of each button to w=50 and h=50 by resizing each button (no constraints)
Before embedding stack view:
Top row in a stack view:
Each button is of Type CircularButton
I set the size of each button to w=50 and h=50 by resizing each button (no constraints)
That is certainly one thing you are doing wrong: "no constraints". The stack view is a constraint maker. That is all it is. But it is not a mind-reader. It needs its arranged views to have certain constraints, under certain configurations, in order to know what you want. You have to tell it. Constraints are how you do that.
Let's stipulate that a lot of your question is a red herring — the roundedness of the buttons, the double set of stack views. All you want to know is how to make three buttons be spaced horizontally at equal distribution by a stack view without losing their size. Here's how.
First, configure your stack view like this:
Second, give your buttons height and width constraints, and wrap them in the stack view. Now use more constraints to position and size the stack view where you want the buttons distributed:
As you can see, that works as desired in the running app:
The rest of your interface merely builds upon that.
In the Attributes Inspector, you can set the alignment and distribution to center. This should work:
Also provide the same height and width for the buttons or put aspect ratio of 1:1 for the buttons.
In highschool we're learning how to build User Interfaces with Xcode.
As homework we have to pick an existing App and rebuild it only using default controls and the Main.storyboard (no code and custom classes allowed).
I picked Twitter's UI:
As you can see there is a TabBarController on top with three TabBar Items (TOP, MENTIONS, VERIFIED).
According to other threads you can't change the position of a UITabBarController without using Custom Classes or some other code.
What would be an easy work around? I was thinking of using normal buttons instead of UITabBarItems but then I would have to implement code for buttons to react on user interaction.
Twitter is a tricky UI because they do a lot of custom things in it. However, a couple of comments here:
1) The buttons you reference (TOP, MENTIONS, VERIFIED) is not a TabBarController. The bottom bar with the 3 icons (ENGAGE, UNDERSTAND, POSTS) is a TabBarController and that wouldn't be too hard to create.
2) The buttons (TOP, MENTIONS, VERIFIED) could be created using a UISegmentControl. However, they have customized the look of it. By default, it will look something like this:
Apple Docs for SegmentControl
Here is a stackoverflow discussion on changing the look of it:
How to display only bottom border for selected item in UISegmentedControl?
3) The other items on that view could be created using a UITableView but those are custom cells that you'd have to build which sounds like would violate the rules of your assignment.
There are lots of examples out there on how to create and use custom uitableview cells such as this one:
Making Apple Pie
Hope this helps you!!!
Update#2:
As you can't use code, creating a tableview is out. You could just drop some controls in the storyboard to minic those tableview cells. For excample, drop UIImageViews (with pictures), UILabels (with text), the icons for reply, retweet, favorite would be UIImageViews as well. The gray lines can be created by dropping a UIView with a height of 1 and background color of grey.
The 3 UITabBarItem (Engage, Understand, Posts) are on the very bottom.
On the top are just 3 regular buttons in a view.
So what you thought will definitely work, use just normal buttons inside a SuperView, you do not need code for this, just use following constraints:
SuperView (Top, Leading, Trailing, Height(40-50) constraints)
Button-1 (Leading to superview, Width to superview (multiplier 0.33))
Button-3 (Trailing to superview, Width to superview (multiplier 0.33))
Button-2 (Leading to button-1, trailing to button-3)
2 constraints for all 3 buttons:
Top to superview
Bottom to superview
I just started iOS programming and I want to make a login screen. I want to align center horizontally the everything on all devices like the iPhone 5 and iPhone 6 and iPhone 6 Plus but it's not working. I just put the elements on the screen. Anything else i need to do?
There are a few ways you can do this...auto layout as #ozgur said is your friend.
what I would do is throw them into a Stack View
To do that tap each horizontal group so for example "username" label AND the text field to the right and while they are both selected tap the icon at the bottom right that is on the left of the 4 icons (it has a downward arrow)...now do the same for the password...now do the same for the login button...now select all 3 stackviews and tap stackview again...
NOW....on the left navigation select the topmost stackview and then again on the bottom this time tap the small icon to the right of the stackview button...to make it simple and in the center tap horizontally in container and vertically in container then add the 2 constraints....
you will also need a height and width so now once more with the whole thing selected tap the |o| looking icon to the right...now give it the height and width you like but before you tap add 2 contraints at the bottom of that menu is a drop down menu..tap it and select "update all frames in container"
that should do it
Use AutoLayOut Constraints to fix your issue.
Contraints will set the spacing with the view.You have to apply it on every single element of your view.
if you only want every thing in center no different spacing for different iPhone use stack View. it will provide the best solution for you.
stackView means collection of your objects. it act as group of your elements so only apply constraints to your stackview.
Rule of thumb is to use Stack views and then use auto layout. Just put the Username and the text field in a stack view (horizontal stack view), same for the other) and then apply necessary spacing and/or autolayout constraints.
You need to learn how to work with Autolayout (I read you just started) and it could be hard concept to grasp at first (it was for me at least) but with practice, you'll master it.
If you do not use the stack view, you need to learn auto layout and size class for adapting the screen.
auto layout began in iOS 6, sizeclass began in iOS 8.
Here is the official apple documentation, to study it. https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/
I understand the old Struts and Springs method of aligning, sizing and distributing views in Interface Builder. However, I cannot seem to figure out how to evenly distribute views using auto layout with Xcode 5. There was a way to do it using Xcode 4, but that option is gone.
I have 7 buttons arranged in a vertical stack. On a 3.5" layout, it looks great. When I preview the screen in the 4" layout, all of the buttons remain tightly packed and there is a large amount of space below the last button.
I want them to stay the same height, but I want the space between them to be able flex so they can spread out across the screen.
I've been able to get the height of the buttons to flex and fill the space, but that is not my desired behavior. I would like to learn how to use Auto Layout to replace my old Springs behavior, but I can't seem to find any way to do it through Interface Builder.
I'm ok with the top button either being a fixed space from the top edge or a proportional space from the top edge, likewise for the bottom button and the bottom edge. Those are less important to me, I'm good with either.
But I really need to figure out how to evenly distribute the extra space between each of the items in the view.
EDIT Note that in iOS 9 this technique will become unnecessary, because a UIStackView will perform distribution automatically. I'll add another answer explaining how that works.
How to Perform Even Distribution Using Autolayout
The simplest way to do this in Interface Builder alone (rather than constructing constraints in code) is to use "spacer" views:
Position the top and bottom buttons absolutely.
Place spacer views between all the buttons. Use constraints to position them horizontally (centering them horizontally is simplest) and to set their widths.
Make constraints between each button and the spacer view above and below it, with a Constant of 0.
Now select all the spacer views and set their heights to be equal.
The first screen shot shows me setting this up in IB:
I have deliberately not corrected for the "misplaced views" because I want you to see what it looks like while I'm designing the constraints. Here's the result on both a 4 inch and a 3.5 inch screen:
I have left the spacer views black, just to show you how this technique works, but of course in real life you would make them transparent and hence invisible! So the user sees just your buttons, evenly distributed on either height of screen.
The reason for the use of this technique is that although the notion of equality performs the distribution of values you are asking for, constraints can apply equality only between aspects of views; thus we need the extra views (the spacer views) so that we have things we can make equal to other things (here, the heights of the spacer views).
Other Approaches
Obviously, a more flexible approach is to assign the constraints in code. This may sound daunting, but there's a lot of third-party code out there to help you, such as this sort of thing.
For example, if we have a (possibly invisible) superview whose height acts as a boundary to dictate maximum vertical distribution of our four buttons, we can pin their tops to the vertical center of that superview with a constant of 0 but a multiplier of 0.000001, 0.666667, 1.33333, and 2.0 respectively (if we have four buttons); now the buttons will stay vertically distributed even as the superview changes size in response to screen height or whatever. [In Xcode 5.1, it will be possible to set that up in Interface Builder, but in earlier versions of Xcode it is not possible.]
In iOS 9 / Xcode 7 this problem will be trivially solved in IB. Simply select the buttons (or whatever it is you want to distribute vertically) and choose Editor > Embed In > Stack View. Then you simply configure the stack view:
Provide constraints that position and size the stack view itself. For example, pin the four edges of the stack view to the four edges of its superview.
Set the stack view's attributes. In this case we want Vertical axis, Fill alignment, Equal Spacing distribution.
That's all! However, you may be curious about how this works, because it is still possible to do the same thing manually in code. A stack view performs distribution, not by inserting spacer views, but by inserting spacer guides. A guide (a UILayoutGuide) is a lightweight object that behaves like a view for purposes of layout constraints, but is not a view and therefore doesn't have to be made invisible and doesn't carry any of the overhead of a view.
To illustrate, I'll do in code what the stack view is doing. Presume we have four views to distribute vertically. We assign them constraints for everything but their distribution:
They all have absolute height constraints
Their left is pinned to the superview's left, and their right is pinned to the superview's right
The top view's top is pinned to the superview's top, and the bottom view's bottom is pinned to the superview's bottom
Now, presume we have references to the four views as views, an array. Then:
let guides = [UILayoutGuide(), UILayoutGuide(), UILayoutGuide()]
for guide in guides {
self.view.addLayoutGuide(guide)
}
NSLayoutConstraint.activateConstraints([
// guide heights are equal
guides[1].heightAnchor.constraintEqualToAnchor(guides[0].heightAnchor),
guides[2].heightAnchor.constraintEqualToAnchor(guides[0].heightAnchor),
// guide widths are arbitrary, let's say 10
guides[0].widthAnchor.constraintEqualToConstant(10),
guides[1].widthAnchor.constraintEqualToConstant(10),
guides[2].widthAnchor.constraintEqualToConstant(10),
// guide left is arbitrary, let's say superview margin
guides[0].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
guides[1].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
guides[2].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
// bottom of each view is top of following guide
views[0].bottomAnchor.constraintEqualToAnchor(guides[0].topAnchor),
views[1].bottomAnchor.constraintEqualToAnchor(guides[1].topAnchor),
views[2].bottomAnchor.constraintEqualToAnchor(guides[2].topAnchor),
// top of each view is bottom of preceding guide
views[1].topAnchor.constraintEqualToAnchor(guides[0].bottomAnchor),
views[2].topAnchor.constraintEqualToAnchor(guides[1].bottomAnchor),
views[3].topAnchor.constraintEqualToAnchor(guides[2].bottomAnchor)
])
(Obviously I could make that code cuter and shorter using loops, but I have deliberately unrolled the loops for clarity, so that you can see the pattern and the technique.)
I'm completely stuck with getting along storyboards.
What I'm trying to do is the view that basically groups two label to look like this:
So I want the quote and the author right under the quote which is anchored to right edge.
This view will be reused multiple times so I created a xib for that which looks like this.
As you can see the view is free form and the quote label centered with the author label anchored to the right edge of it.
What I expect from it that I can place it in the storyboard view controller with the following conditions:
This view has as much width as it needs but it shrinks if too width to make at least 10 points from each side
This view has as much height as it needs but aligns at center of the parent view horizontally.
So I've added it to the view and set the following constaints.
But when I compile I see the following:
What am I doing wrong?