UICollectionView ImageView Problems - ios

I got some serious problems with my collectionview.
So I fetch async. some data from an api and set the data variable, than I reload my collectionview. My collectionview contains basicly some cells with data from the api and one cell extra with a plus icon. The cells shape and layout is the same, so I used the same collectionviewcell class for both.
I calculate my number of items like this:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count + 1
}
And do my cell stuff like this:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! OverviewUserCell
if(indexPath.row == data.count) {
cell.userImageView.image = UIImage(named: "plus")!
//some additional coloring and stuff
} else {
cell.userImageView.image = UIImage(named: "oma")!
//some additional coloring and stuff
}
cell.contentView.frame = cell.bounds
cell.contentView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
cell.layer.cornerRadius = 8
return cell
}
My cell itself contains a round image and a Label:
class OverviewUserCell: UICollectionViewCell {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var userImageView: UIImageView!
override func layoutSubviews() {
super.layoutSubviews()
self.makeItCircle()
}
func makeItCircle() {
self.userImageView.layer.masksToBounds = true
self.userImageView.layer.cornerRadius = CGFloat(roundf(Float(self.userImageView.frame.size.height/2.0)))
}
}
Somehow (maybe because different image sizes) the frame of the imageview changes, or something like this, because the plus image is not round, but I want it to stay the same. I added constraints to every element in the cell. If I don't load the data, the image is perfectly round, but when the data is loaded and the collectionview reloaded, the plus image is not round anymore.
The images should be same sized and same position.

Instead of setting corner radius of cell, try setting corner radius of UIImageView. But before that make sure that your UIImage view should have height equal to width.
And before setting imageview.layer.cornerRadius = 8;
add this line: imageview.layoutIfNeeded();

Related

Have UIimageView width of custom TableViewCell be 1/3 of cell width, and height of cell = image aspect ratio

I'm new to iOS programming, and I'm mainly been using the interface builder to adjust cell layouts.
Currently I have a custom TableView cell with an ImageView and Label.
I would like to:
1) Have the ImageView Width = 1/3 size of cell ( It doesn't seem like I can do this via storyboard)
2) Have the cell height dynamically adjust as the aspect ratio of image is maintained. I've already added constraints for the UIImageView to equal cell height.
I searched StackOverflow but some of the answers got really complicated, so I couldn't really understand how to fit it to my case.
I played around with constraints, but it seems I have to do this programmatically?
Here is what I currently have for cell methods:
extension FirstTableViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataCells.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let folderCell = dataCells[indexPath.row]
print(folderCell)
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! FirstTableViewCell
cell.setCell(cell:folderCell)
return cell
Here is my cell class:
class FirstTableViewCell: UITableViewCell {
#IBOutlet weak var ImageView: ScaledHeightImageView!
#IBOutlet weak var FolderLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
//print(FolderLabel)
}
func setCell (cell : FolderCell){
self.ImageView.image = cell.image
self.FolderLabel.text = cell.label
}
}
You can do it from storyboard by adding equal width with superview, then change it's Multiplier to be 0.3

UIImageView in UICollectionView not drawing correctly

I have an app with a screen that is divided into four equal cells. Each cell has an image, label, and color. I'm trying to add the images in, but for some reason, only the image in the first cell works.
It looks like this now:
Here is my code:
In ViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
colorArray += [UIColor.red, UIColor.blue, UIColor.green, UIColor.yellow]
pictureArray += [UIImage(named: "budget")!, UIImage(named: "journey")!,
UIImage(named: "learn")!, UIImage(named: "settings")!]
titleArray += ["Budget", "Journey", "Learn", "Settings"]
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as UICollectionViewCell
// Set cell properties
cell.backgroundColor = colorArray[indexPath.row]
let imageview:UIImageView=UIImageView(image: pictureArray[indexPath.row])
let size = CGSize(width: 100, height: 100)
imageview.center = cell.center
imageview.bounds = CGRect(origin: cell.bounds.origin, size: size)
cell.contentView.addSubview(imageview)
let label = cell.viewWithTag(1) as! UILabel
label.text = titleArray[indexPath.row]
return cell
}
The labels and colors work fine, but for some reason, the image views seem to be off the screen. I have a feeling that my center/bounds restrictions are forcing the images off the screen, but I've tried many combinations, and none of them seem to work for me.
How should I do this?
I'm posting the correct answer for who ever will google here. (And because it was solved an hour ago without anyone posting the answer)
The best practice is to subclass UICollectionViewCell, connect all the outlets (label, image etc.) and work with this class on the cells
Good luck to all
This is what worked, after Yogesh Suthar's comment:
I subclassed UICollectionViewCell, connected the image and label:
class NavigationCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var navImage: UIImageView!
#IBOutlet weak var navLabel: UILabel!
}
Then, in the ViewController, I did this:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! NavigationCollectionViewCell
// Set cell properties
cell.backgroundColor = colorArray[indexPath.row]
cell.navImage.image = imageArray[indexPath.row]
cell.navLabel.text = titleArray[indexPath.row]
return cell
}
Set the size and position of the image and label in Main.storyboard!
insert the desired view as a subclass and setup all constrains to cell.heightAchor and so on. this will fix the bug for some reason. It works if the subview is added to the cell as a subview but not as an attribute of the cell

How to dynamically change the height of a UITableView Cell containing a UICollectionView cell in Swift?

Currently, I have embedded a UICollectionViewCell in a UITableViewCell within one of the sections of my UITableView. I know how to dynamically change the cell's height in another section of my UITableView because I have a UITextView in another UITableViewCell that dynamically changes the height of the cell based on how much text is in the UITextView.
The problem I have is in regards to the UITableViewCell containing the UICollectionViewCell. My UICollectionViewCell has one row of 4 images that the user can add via the camera or photo library using a UIImagePickerController.
Currently as I have it, when the 5th picture is generated, the UITableViewCell's height remains static, but the user can scroll horizontally in the UICollectionViewCell like so:
My end goal is this:
And my storyboard:
Pretty self-explanatory but if there is only 4 images, the UITableViewCell remains the same as in screenshoot 1, but the cell's height will dynamically change if the UICollectionViewCell's height changes.
I have set the UICollectionView's scroll direction to be vertical only. Before explaining further, here's my partial code:
class TestViewController: UITableViewController, UITextFieldDelegate, UITextViewDelegate, UIImagePickerControllerDelegate
{
override func viewDidLoad()
{
super.viewDidLoad()
....
tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell: UITableViewCell = UITableViewCell()
if indexPath.section == 1
{
cell = tableView.dequeueReusableCell(withIdentifier: "TextViewCell", for: indexPath)
let textView: UITextView = UITextView()
textView.isScrollEnabled = false
textView.delegate = self
cell.contentView.addSubview(textView)
}
else if indexPath.section == 4
{
if let imagesCell = tableView.dequeueReusableCell(withIdentifier: "ImagesCell", for: indexPath) as? CustomCollectionViewCell
{
if images_ARRAY.isEmpty == false
{
imagesCell.images_ARRAY = images_ARRAY
imagesCell.awakeFromNib()
}
return imagesCell
}
}
return cell
}
....
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.section == 1
{
return UITableViewAutomaticDimension
}
else if indexPath.section == 4
{
//return 95.0
return UITableViewAutomaticDimension
}
return 43.0
}
....
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
{
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 4) ) as? CustomCollectionViewCell
{
cell.images_ARRAY.append(selectedImage)
cell.imagesCollectionView.reloadData()
}
}
picker.dismiss(animated: true, completion: nil)
}
....
func textViewDidChange(_ textView: UITextView)
{
...
// Change cell height dynamically
tableView.beginUpdates()
tableView.endUpdates()
}
}
class CustomCollectionViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
#IBOutlet var imagesCollectionView: UICollectionView!
var images_ARRAY = [UIImage]()
var images = [INSPhotoViewable]()
override func awakeFromNib()
{
super.awakeFromNib()
for image in images_ARRAY
{
images.append(INSPhoto(image: image, thumbnailImage: image) )
}
imagesCollectionView.dataSource = self
imagesCollectionView.delegate = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return images_ARRAY.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! ExampleCollectionViewCell
cell.populateWithPhoto(images[(indexPath as NSIndexPath).row]
return cell
}
....
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsetsMake(0.0, 25.0, 0.0, 25.0)
}
}
Originally, my indexPath.section == 4, which contains the UICollectionViewCell returned a height of 95, but I commented that out and replaced it with returning UITableViewAutomaticDimension. I would assume that adjusted the height of the cell to fit the 5th image, but the cell remained a static height even though the UICollectionViewCell' height changed, allowing me to scroll vertically within that static UITableViewCell height.
I know these are some questions I found very similar to my situation, but they didnt help me resolve my particular issue:
Swift: Expand UITableViewCell height depending on the size of the
UICollectionView inside it
Auto Height of UICollectionView inside UITableViewCell
UICollectionView inside a UITableViewCell — dynamic height?
With some of the answers and suggestions, I've added the following:
imagesCell.images_ARRAY = images_ARRAY
imagesCell.awakeFromNib()
// Added code
imagesCell.frame = tableView.bounds
tableView.setNeedsLayout()
tableView.layoutIfNeeded()
However, this did not have any effects. Can anyone point me in the right direction on what code I need and placed where?
Thanks!
I am using these type of cells in my code, Not performing excellent performance wise(as affecting scrolling smoothness) but will let you achieve required design.
Use CollectionView inside tableViewCell with Vertical ScrollDirection and fixed width(I mean not dynamic in nature). This will put overflowing cells in vertical direction after filling horizontal direction.
Take out NSLayoutConstraint from xib(if you are using that) of collectionViewHeight. We will use it in later part.
set UITableViewAutomaticDimension in tableView in heightForRowAtIndexPath method.
And finally set cell's collectionViewHeight while returning cell in cellForRowAtIndexPath method using constraint that we took out in step 2.
Here I am attaching some code that may will help:
UITableView Part:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: xyzTableViewCell.self), for: indexPath) as! xyzTableViewCell
cell.collectionViewHeight.constant = (numberOfCells/5) * cell.cellHeight
return cell
}
UITableViewCell Part:
#IBOutlet fileprivate weak var collectionView: UICollectionView!
#IBOutlet weak var collectionViewHeight: NSLayoutConstraint
And you will need to reload that particular tableViewCell and reload collectionView inside this tableViewCell so that height function of tableView will be called and height of that tableViewCell will be refreshed, and to handle focused condition of that tableViewCell(when tableViewCell is in focus), I am saying this because if it's not in focus(or say cache, there is difference between them though) then cellForRowAtIndexPath method will be called on scrolling(when this cell is going to come in focus) then tableViewCell height will already be taken care of.
Hope this will help to achieve required functionality.

Swift UICollectionViewCell Animated View Randomly Blank When Scrolling

I am trying to use a UICollectionView to display a square MyCollectionViewCell that has animated GIFs in a UIImageView.
Rows and sections are setup like so:
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 50
}
I'm using SwiftGif to get GIFs assigned to the cell's UIImageView like so:
let gifs = [UIImage.gifWithName("gif1"), UIImage.gifWithName("gif2"), UIImage.gifWithName("gif3")]
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
cell.gifImageView.image = gifs[indexPath.item % gifs.count]
return cell
}
Everything for the most part works great. But my issue is that when scrolling, there are times when cell is blank and no GIF appears. In the debugging process, I've added a label to the cell to display the indexPath.item, as you can see in code above, to make sure that the cell isn't getting passed over and have found that the label will always display indexPath even if the cell does not display a GIF.
I have tested with regular images instead like so:
let testImages = [UIImage(named: "testImage1"), UIImage(named: "testImage2", UIImage(named: "testImage3")]
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
cell.gifImageView.image = testImages[indexPath.item % testImages.count]
return cell
}
and had no occurrences of blank cells.
Even more curious, when I originally actually built the GIF in collectionView(...cellForItemAtIndexPath) I did not get any issues with blank cells either:
let gifNames = ["gif1", "gif2", "gif3"]
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
let gif = UIImage.gifWithName(gifNames[indexPath.item % gifNames.count])
cell.gifImageView.image = gif
return cell
}
This original implementation would have worked if it weren't for the fact the GIF build process drastically affects the scrolling performance of the UICollectionView which is what forced me to change implementation in the first place.
I have confirmed that this is not an issue with SwiftGif as I have replicated this issue in a different application using an animation render library and an AnimatedView in place of the UIImageView in MyCollectionViewCell and displayed animations instead of GIFs and got the same issue with cells randomly showing nothing instead of the animation when scrolling through the CollectionView.
I have tried the StackOverflow solution here and implemented a custom UICollectionViewFlowLayout like so:
class MyFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElementsInRect(rect)
let contentSize = self.collectionViewContentSize()
let newAttrs = attributes?.filter { $0.frame.maxX <= contentSize.width && $0.frame.maxY <= contentSize.height}
return newAttrs
}
}
And assigned it in viewDidLoad() like so:
self.collectionView?.collectionViewLayout = MyFlowLayout()
In MyFlowLayout I have also tried:
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}
I have also messed with various cell sizes (width 1 less than height, height 1 less than width etc) and messed around with some section inset combinations but have not managed to find the source of this issue that is causing the animated view to not to show up.
Any help would be appreciated. Thanks
I solved the issue by setting the gifImageView.image = nil in collectionView(...cellForItemAtIndexPath) before assigning the image.
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
cell.gifImageView.image = nil // Added this line
cell.gifImageView.image = gifs[indexPath.item % gifs.count]
cell.infoLabel.text = String(indexPath.item)
return cell
}
Not sure how/why this fixed it but it works now.

tableview's Row height is not changing , CollectionView is capturing all the unused space instead of resizing itself in the tableViewCell

I put a UICollectionView into the UITableViewCell by following this tutorial and in my UICollectionViewCell, there's a Image View. So when I run my app, the collection view is not resizing itself at the same time in my cell I put a Text View which is resizing itself according to content, see the below images:
In this first image, I have a text view at the top which have some text in it, and below it with (pink background) is my collection view and inside of that with greenBackground is my image view, as you can see that collection view is taking the extra space instead of reducing itself as Text View Did.
in this second image you can see that my textView haves more content then before so its resized itself now overlapping the CollectionView
this is my TableViewCell:
class TableViewCell: UITableViewCell {
#IBOutlet var txtView: UITextView!
#IBOutlet private weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// collectionView.frame = self.bounds;
// collectionView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setCollectionViewDataSourceDelegate
<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
(dataSourceDelegate: D, forRow row: Int) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.tag = row
collectionView.reloadData()
}
var collectionViewOffset: CGFloat {
get {
return collectionView.contentOffset.x
}
set {
collectionView.contentOffset.x = newValue
}
}
}
this is my collectionViewCell
class CollectionViewCell: UICollectionViewCell {
#IBOutlet var imgView: UIImageView!
override func awakeFromNib() {
self.setNeedsLayout()
//
// self.contentView.frame = self.bounds;
// self.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
}
}
and this is my TableviewController
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return imageModel.count
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! TableViewCell
cell.txtView.text = txtArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView,
willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewCell else { return }
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}
override func tableView(tableView: UITableView,
didEndDisplayingCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewCell else { return }
storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
}
}
extension TableViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return imageModel[collectionView.tag].count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
forIndexPath: indexPath) as! CollectionViewCell
cell.imgView.frame = CGRectMake(0, 0, collectionView.frame.width, collectionView.frame.height)
cell.imgView.contentMode = .ScaleAspectFit
//cell.addSubview(imageView)
cell.imgView.image = ResizeImage(UIImage(named: imageModel[collectionView.tag][indexPath.item])!, targetSize: CGSizeMake( cell.imgView.frame.width , cell.imgView.frame.height))
//imageView.image = UIImage(named: imageModel[collectionView.tag][indexPath.item])
return cell
}
}
How can I make this collection view to AutoLayout itself according to the content in it? I also tried this:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 100;
but didn't worked (my collection view got disappear) if anybody knows how to do this, then please guide me..
I faced a similar issue when i used collection view inside a table view cell. No matter what i did i couldn't get the table view to resize automatically but the collection view did. Soo instead of autolayout i did it using code.
I ended up having to calculate the size of the label in the collection view numberOfSections in collection view and passing this height using a delegate to the view controller that has the tableView's delegate and dataSource and reloading the appropriate row of the table view.
As it happens, the numberOfSections in collectionview data source gets called everytime and the delegate resizes the table view height.
Some thing like this-
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
[self.delegate setViewHeight:[self getHeightForCellAtIndexPath:[NSIndexPath indexPathForRow:currentSelected inSection:0]]];
return 1;
}
This ought to give you a general idea.
EDIT: Sorry i misunderstood, your question before. Here is something that should work for you:
As per my understanding, you have a table view cell with a label view and collection view inside of it.
Now, inside your table view cell, you should add top, leading and trailing constraints space to the label. Now inside your collection view position your image vertically in the center and add an appropriate top and bottom to the cell superview. Your collection view itself should have a CONSTANT value in leading, trailing, top to label and bottom to superview. Also add a fixed height constraint to your collection View (assuming you want the image sizes to remain the same).
Now lets says View Controller A is the data source for your table view and the table view cell is the data source for your collection view.
In your viewController A, you should write your height for row at indexPath as-
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGSize stringSize = [yourStringArray[indexPath.row] boundingRectWithSize:CGSizeMake(_yourCollectionView.frame.size.width, FLT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:#{NSFontAttributeName:[UIFont yourFont size:yourFontSize]} context:nil].
return stringSize.height + 35; //magic number 35, play around with it to suit your need. Did this to always have a minimum fixed height.
}
This will allow your tableViewRowForHeight for that particular index to have the height of your label added to it and the constraints ought to do the rest.

Resources