Why width of view always return zero? - ios

I'm setting up a view programmatically with all the constraints. Then I want to get its width (which vary from a device to another) but it always return zero when I print it.
here is my code:
let myView = UIView()
view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15).isActive = true
myView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15).isActive = true
myView.topAnchor.constraint(equalTo: view.topAnchor, constant: 80).isActive = true
myView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -60).isActive = true
myView.backgroundColor = .blue
let myWidth1 = myView.frame.size.width
let myWidth2 = myView.bounds.width
print(myWidth1)
print(myWidth2)
however, the view actually has a width as shown in this screenshot:

For programmatic development, you should create that view in loadView(). viewDidLoad() is the lifecycle method that is called after the view has been loaded into memory; however, the view hasn't yet been rendered visually. You can get subview dimensions in viewDidLayoutSubviews(), which will be called throughout view mutations (like device orientation changes) or a method like viewDidAppear() that will only be called effectively once.

Related

Revert NSLayoutConstraint of UIView after changing the constraint

Currently, I am expanding a custom view inside a scrollview to
fullscreen after the user taps on it. But I want the View to come back
to the original position once the user taps on it again. Note:- I have
set the original custom view position inside the scrollview on Xib
visually, I haven't added the code programmatically to add views in
scroll view.
Here is my code to expand:-
let frameAnimator = UIViewPropertyAnimator(duration: 0.6, dampingRatio: 1) {
self.playerDescriptionView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
self.playerDescriptionView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
self.playerDescriptionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
self.playerDescriptionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
self.view.layoutIfNeeded()
}
frameAnimator.startAnimation()
So, how can I set the constraint back to the original position while minimizing the view, because I have not set the view constraint programmatically?

TableView not appearing after setting the constraints programmatically

I have a UITableView in my storyboard. I am trying to setup constraints for it in my view controller. After running the application it's not showing up at all. it's only working when i don't run the constraints. here are my constraints.
func tableviewsConstraints(){
homeTableView.translatesAutoresizingMaskIntoConstraints = false
homeTableView.layer.cornerRadius = 10
homeTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
homeTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
homeTableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
homeTableView.heightAnchor.constraint(equalToConstant: homeTableView.rowHeight * 3).isActive = true
self.view.addSubview(homeTableView)
}
override func viewDidLoad() {
super.viewDidLoad()
tableviewsConstraints()
Add the homeTableView as the view's subview before adding the constraints to it. And use a constant value when setting the height of tableView, i.e.
func tableviewsConstraints(){
self.view.addSubview(homeTableView) //here....
homeTableView.layer.cornerRadius = 10
homeTableView.translatesAutoresizingMaskIntoConstraints = false
homeTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
homeTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
homeTableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
let rowHeight: CGFloat = 100.0 //here....
homeTableView.heightAnchor.constraint(equalToConstant: rowHeight * 3).isActive = true
}
Change the rowHeight value as per your requirement.
Don't you have the outlet of the table view if you have it in the storyboard? Then why you need to subview? If you're creating table view programmatically then follow this.

How can I Adjust view height to be below navigation bar in iOS?

I created a WKWebView in code and added it to my view.
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
When the webpage opens I can see that my navigation bar from the previous view is blocking some of my webpage.
How can I adjust the view in code to make my webpage appear below my navigation bar?
You should add a top constraint to your webview and give it a constant value that works for you (in case you want to add a margin)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: parentView.topAnchor, constant: 40).isActive = true
You should also add the remaining anchor values.
webView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor, constant: 0).isActive = true
webView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor, constant: 0).isActive = true
webView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor, constant: 0).isActive = true

Frame from iOs 9 constraints

I am having trouble with getting the actual width out of my view. I have added my UIView() as "progressBar" to the controller's view but I need to get the width in order to execute some other code.
Is there any possible way I can get the object's width out of those constraints?
Thank you for helping! Appreciate it.
progressBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(progressBar)
progressBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
progressBar.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -430).isActive = true
progressBar.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true
progressBar.heightAnchor.constraint(equalToConstant: 4).isActive = true

UIScrollView nested subviews not displayed using Auto Layout

I am trying to generate views displayed in a UIScrollView based on structured (XML) data at runtime. I generate all the views I need and add them to my scrollview afterwards, using Auto Layout to let the scrollview calculate its contentSize. Everything worked fine as long as I was only using UILabels and a custom UIImageView subclass, but now I want to add a nested view containing another view and a label to represent text with a vertical line on the left side.
The general layout code I'm using to add all generated views to the scrollview is as follows:
var previousAnchor = scrollView.topAnchor
views.forEach { (view) in
scrollView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
view.topAnchor.constraint(equalTo: previousAnchor,
constant: UI.defaultPadding).isActive = true
view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,
constant: UI.smallPadding).isActive = true
view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,
constant: -UI.smallPadding).isActive = true
previousAnchor = view.bottomAnchor
}
scrollView.bottomAnchor.constraint(equalTo: previousAnchor,
constant: UI.defaultPadding).isActive = true
And the layout code for my nested subview looks like this (it's a UIView subclass):
addSubview(label)
addSubview(line)
line.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
line.topAnchor.constraint(equalTo: topAnchor).isActive = true
line.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
line.widthAnchor.constraint(equalToConstant: 2).isActive = true
line.trailingAnchor.constraint(equalTo: label.leadingAnchor).isActive = true
line.backgroundColor = UIColor.green
label.topAnchor.constraint(equalTo: topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
label.numberOfLines = 0
label.text = "Here's to the crazy ones. The misfits. The rebels. The troublemakers."
If I use this code, I cannot see this view in my scrollview at all and the scrollview has a warning of ambiguous content size attached to it in the Debug View Hierarchy view. This is somewhat irritating, as using labels without being nested in a view like this does work like a charm. So I started playing around and what really puzzles me is that if I use the following code I can see the view itself (as I gave it a gray background color), but still can't see line and/or label, as both seem have a frame of (0,0,0,0) upon inspection:
addSubview(label)
addSubview(line)
line.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
line.topAnchor.constraint(equalTo: topAnchor, constant: 10).isActive = true
line.widthAnchor.constraint(equalToConstant: 20).isActive = true
line.heightAnchor.constraint(equalToConstant: 20).isActive = true
line.trailingAnchor.constraint(equalTo: label.leadingAnchor).isActive = true
line.backgroundColor = UIColor.green
label.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
heightAnchor.constraint(equalToConstant: 100).isActive = true
heightAnchor.constraint(equalTo: label.heightAnchor).isActive = true
label.numberOfLines = 0
label.text = "Here's to the crazy ones. The misfits. The rebels. The troublemakers."
What am I missing? I also tried putting all my views into a container view instead of using them as subviews of the scrollview directly, but this did not help with my nested view and brought up other problems.

Resources