In my project I am using AutoLayOut, There is one UIView which is subView main View, I have set its width(using constrains) equal to 2 :3 superView's width and its height equal to its View. I need view to be circular shape so I am setting its cornerRadius to heightOfView/2. There is 1:1 aspect ration of views's height and width. I have created Outlet of that constrain as
#IBOutlet weak var circleHeight: NSLayoutConstraint
Now I want to acces its Height or Width but I m not gwtting actual value,
circleHeight.firstItem.frame.width
I am getting value which I have stored from Storyboard, There Is something I am Missing but could not figured it out
Selected View should be circular. but when i print its constain's values it gives height and width as 214 only
You can create IBOutlet for this UIView, which should be circle shape.
Then in viewDidLayoutSubviews() method you can read its height and make it circle:
override func viewDidLayoutSubviews() {
let viewHeight = CGRectGetHeight(yourView.frame)
yourView.layer.cornerRadius = viewHeight / 2
yourView.layer.masksToBounds = true
}
I think you might be fetching value in viewWillAppear or
ViewDidLoad but views frames don't get updated when these method gets
called
So you need to fetch the width or height in ViewDidAppear method.
If get the height or width in ViewDidLayoutSubViews, performance
gets degraded as it gets called many times.
Here is Code
override func viewDidAppear(animated: Bool){
super.viewDidAppear(animated)
let viewHeight = CGRectGetHeight(yourView.frame)
yourView.layer.cornerRadius = viewHeight / 2
yourView.layer.masksToBounds = true
}
A constraint does not have height or width, only relationships, priorities and constant values, depending in how you set the constraint itself.
To access the height of the subview you are interested in, you need to access as always:
<uiview_outlet>.frame.size.height
Hope it helps.
Related
The Question
how can I keep Buttons, Images, Buttons...Views rounded in big screens when using constraints of ( buttons, images....views ) equal width and height to superview using swift
The Code I've Tried
I tried this block of code and It works fine in small screens like SE..until 8 :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
roundedObject.layer.cornerRadius = roundedObject.frame.width / 2
roundedObject.clipsToBounds = true
}
the shape of the different sizes screens
my object constraints:
screen1 screen2 screen3
the issue is your constraint
you will not get a square by using proportional width and proportional height constraint together like that, because different device will have different height and width
my suggestion is to use only one proportional width or proportional height (which one you want) and use aspect ratio constraint 1:1 on the roundedObject
Probably you're doing that in viewDidLoad method where the frames didn't get the final value yet (initially they get the values from the storyboard from where they were instantiated. So if in the storyboard preview the size is f.e. 300x300, in the viewDidLoad it also will be 300x300).
So either do that in the viewDidLayoutSubviews or create a subclass and do that in the layoutSubviews.
class RoundedButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
layer.corderRadius = bounds.width / 2
layer.masksToBounds = true
}
}
How can I set the scrollview height programmatically in Xcode 9 with Swift 4? I've set a constraint for the scrollview height and added that as an outlet. But when I change the outlet constant value programmatically it doesn't change the height.
Example:
#IBOutlet weak var scrollview_height: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollview_height.constant = 245
}
The height of the ScrollView should be given by it's content and not for you to change manually. At best if you want to do something like that, you have a view inside the scrollView and change the size of that view instead.
Step-by-step:
Add a ScrollView to your view. Set it's constraints (no height or width)
Add a View inside the ScrollView and set it's constraints. Additionally for a vertical scroll you might want to set it's width equal to the SuperView and ensure it has a height.
Create an IBOutlet for the height of the view
update the constant value of the constraint in code
If it does not update as expected, run a layoutIfNeeded on your superview after updates
You have to increase the content Size of your scrollView instead of increasing the frame of scrollView.
self.scrollview.contentSize = CGSize(width: screenWidth, height: yourDesiredHeight)
the scrollable contentSize of scrollView will change According to it.
I'm trying to have a UITableView that lists all the different HomeKit devices a user has available.
Obviously there is no way to know how many devices they have, so I need to have the UITableView's height in the storyboard change.
I've tried this, which I call in the viewDidLoad() function:
func adjustHeightOfTableView() {
//getting the height of the tableview
var tableHeight = self.tableView.contentSize.height
//the height of the content inside the view
var maxHeight = self.tableView.superview?.frame.size.height
//if the height of the content is bigger then the height of the tableview
if (maxHeight! > tableHeight) {
tableHeight = maxHeight!
//set the tableview height to be the content height
}
//trying to reload the tableview height?
self.view.layoutIfNeeded()
self.tableView.reloadData()
}
I am trying to have some UI Elements under the tableview, and I want them to be a set space from the bottom of the tableview, but also have the tableview be the height that it needs to be, for whatever amount of cells there is.
But it's just not working.
If I'm doing anything wrong, or if anyone knows how to make this work, please let me know.
Thanks!
Note: For this approach you need to have static cell height or figure out a way to know before hand whats the total contentsize height
Assuming you are using constraints, create following constraints on your UITableView (apart from leading and trailing!)
Add a height constraint with a priority of 750 and a bottom spacing constraint of 0 to your super view that will be >= 0 and have a priority of 1000. Create outlet for this height constraint that you created in your UIViewController
Now,
func adjustHeightOfTableView() {
//set the height to be equal to the number of elements multiplied by the height of each cell.
//or use some logic that allows you to know what content size or space the cells will occupy!
tableViewHeightConstraint.constant = dataArray.count * rowHeight
view.layoutIfNeeded()
}
Now if your UITableView height is less than super view, no problems! But if it is greater than screen bounds, it will break the height constraint and become full screen and display the content normally as you expect a UITableView to!
Edit:
Even if you are using UIAutomaticRowDimensions what you can do is add constraints programmatically to your UITableView. i.e
Of course all your other views will still have a bottom constraint to your UITableView.
Create a UITableView in your storyboard with normal leading, trailing, top and bottom to the super view. Fetch the data. Get the contentSize for your UITableView and then remove the bottom constraint. Now add a height constraint that will be the minimum value of your UIScreen.main().bounds.size.height and contentSize.
you can use Automatic Dimensions if you are using autolayouts
in view didload:
let nib = UINib(nibName: "YOURCELLNIB", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "REUSEIDENTIFIER")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
Remove the function
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath)
In your code, you have:
tableHeight = maxHeight!
//set the tableview height to be the content height
But this does not change the table height - it only changes some variable that previously was assigned the value of the old table content height. Nowhere in your code do you actually do anything to change the table height.
One way to change the table height directly is to assign it a completely new frame with values from the old frame, except for the frame's height, which you calculate however you like.
Try something like this (adding whatever other logic you need):
oldFrame = self.tableView.frame
newHeight = rowCount * rowHeight
self.tableView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight)
There is a workaround which can make it seems like the height changes according to the number of the cells.
set tableview height to a proper value when init.
UITableView.init(frame: CGRect.init(x: 0, y: 70, width: self.view.frame.width, height: self.view.frame.height - 350))
set the tableview background color white transparent.
pulldownTableView?.backgroundColor = UIColor.white.withAlphaComponent(0)
set tableFooterView.
pulldownTableView?.tableFooterView = UIView(frame: CGRect.zero)
Below is the result, there are two table in the img. I set the transparent for the front tableview, left img set the backgroundColor to white, right white transparent.
----------------------vs----------------
I would like to rescale my image to fit the width of an iOS screen. The following is the code that I used.
#IBOutlet var bgImageView: UIImageView
override func viewDidLoad() {
super.viewDidLoad()
bgImageView.contentMode = UIViewContentMode.ScaleAspectFit;
bgImageView.frame.size.width = UIScreen.mainScreen().bounds.width;
}
This solution however seems to be causing thread problems. What's wrong here?
You can set your image view constrains as follows - its width should be equal to your super view width, centerX and centerY are the same as super's. And height not an equal constraint, but lessThanOrEqual to super's height.
And yes, it is useless to set frame manually while using auto layout constraints
I want to set view1's height to half of the screen's height for all devices (when the device in the portrait mode)
Here is what I want it to look like:
so I make an auto layout of View1's height
#IBOutlet weak var heighConstraint: NSLayoutConstraint!
my viewwillappear function here:
override func viewWillAppear(animated: Bool) {
self. heighConstraint.constant = self.view.frame.size.height / 2
}
But it's not worked when I ran my app. what's wrong in here?
I know the accepted answer is correct but there is simpler method to do so -
Add the view (the one shown in yellow color). Pin it to three edges (top, leading and trailing). I have set it as 0 but change it as per your need.
Create Height Equal to constraint to main View as
Open that Constraint in the Inspector view and edit the multiplier as 0.5.
Setting it as 0.5 takes the height value of half the height of mainView.
Just make sure FirstItem = View1 and SecondItem = SuperView as shown in the image.
Try to change heightConstraint's constant value in viewDidLayoutSubviews method.
override func viewDidLayoutSubviews() {
heightConstraint.constant = self.view.frame.size.height / 2
}
Please try this out. Hope it will help you out. The below line will take the bounds of the device and will set the frame or height according to it.
view1.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height/2);
Hope this helps!!! Good Luck...