Constraint Anchors are not working well in Swift 4 - swift

I cannot seem to figure out why there constraint anchors are not working
inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputsContainerView.heightAnchor.constraint(equalTo: view.heightAnchor, constant: 150).isActive = true
I have tried looking everywhere but cannot seem to find the issue.
I do not see any conflicting constraints or warnings, basically I need the container to look like a white rectangle that sits in the center of the screen.
let inputsContainerView = UIView()
inputsContainerView.backgroundColor = UIColor.white
inputsContainerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(inputsContainerView )
This is what it looks like:
This is what it should look like:

You want your inputsContainerView to have a height of 150. Right now you are setting it equal to view.height + 150.
You need to set your heightAnchor equal to a constant:
Change this constraint:
inputsContainerView.heightAnchor.constraint(equalTo: view.heightAnchor, constant: 150).isActive = true
to this:
inputsContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true

Related

How to set specific width to stackview child, swift?

I'm creating a stackview, inside which there are 5 sub views. (3 custom views divided by 2 separator views). Two separator views's width must be 1 and every sub views must be center and fill equally.
Here's my current code and result which doesn't look nice.
var stackView: UIStackView = {
let view = UIStackView()
view.axis = .horizontal
view.alignment = .center
view.distribution = .fillEqually
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
func setUpView() {
containerView.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 8).isActive = true
stackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -8).isActive = true
stackView.leadingAnchor.constraint(equalTo: homeLogoImageView.trailingAnchor , constant: 18).isActive = true
stackView.trailingAnchor.constraint(equalTo: awayLogoImageView.leadingAnchor, constant: -18).isActive = true
stackView.addArrangedSubview(homeWinView)
stackView.addArrangedSubview(seperator1)
stackView.addArrangedSubview(drawView)
stackView.addArrangedSubview(seperator2)
stackView.addArrangedSubview(awayWinView)
seperator1.widthAnchor.constraint(equalToConstant: 1).isActive = true
seperator1.heightAnchor.constraint(equalToConstant: 60).isActive = true
seperator2.widthAnchor.constraint(equalToConstant: 1).isActive = true
seperator2.heightAnchor.constraint(equalToConstant: 60).isActive = true
}
Output:
Expectation:
fillEqually doesn't work, when you just want some of your views in your stack view to fill equally.
Change fillEqually to fill, and add the "equally" part using constraints yourself.
NSLayoutConstraint.activate([
homeWinView.widthAnchor.constraint(equalTo: drawView.widthAnchor),
homeWinView.widthAnchor.constraint(equalTo: awayWinView.widthAnchor),
])

How do you adjust an image's size to NSImageView programmatically?

I have been trying to adjust an image's size in NSImageView programmatically. There doesn't seem to be any way to do so. The image ends up being quite large and there is no way to adjust it. I want to adjust it to a 40 (width) by 40 (height).
Here is the image view created programmatically:
let theImg: NSImageView = {
let imageView = NSImageView()
imageView.image = NSImage(named: "my-logo")
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
Here are the constraints for the image:
view.addSubview(theImg)
theImg.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 280).isActive = true
theImg.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
theImg.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
I'd appreciate those who would be willing to help or at least give some hints if possible.
You can add it to your constraints like this:
NSLayoutConstraint.activate([
theImg.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 280),
theImg.centerXAnchor.constraint(equalTo: view.centerXAnchor),
theImg.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
theImg.widthAnchor.constraint(equalToConstant: 40),
theImg.heightAnchor.constraint(equalToConstant: 40)
])
NSLayoutConstraint.activate is a better approach to activate/deactivate constraints, because you can use an array of constraints and deactivate/activate them, instead of setting isActive one by one.
Also, unless you want your left/leading constraint to be on the left, even on right to left languages, you should use leadingAnchor instead of leftAnchor.
More info

Button Autolayout programmatically?

Hey guys I want to position my Button at the lower part of the Screen but I don't get the correct code. The button is too small, too big, at the right or left corner,... but It should be centred in the middle of the lower screen.
I tried it with these codes:
nextButton.translatesAutoresizingMaskIntoConstraints = false
nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
nextButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
nextButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: 97)
nextButton.heightAnchor.constraint(equalTo: view.heightAnchor, constant: 50)
or
backButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
backButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
backButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
backButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
Can someone tell me what to do to make it work? I thought with the topAnchor it would be really easy:(
This will position it in bottom center of screen
nextButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
nextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant:-20),
nextButton.widthAnchor.constraint(equalToConstant: 50),
nextButton.heightAnchor.constraint(equalToConstant: 50)
])
The problem is that you are using centerYAnchor instead of bottomAnchor
Replace
nextButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
with
let spacingConstant = 10.0
nextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -spacingConstant)

Trying to get frame.height of one of the 2 views, that filled equally inside of a stackview

I have 2 views inside a vertical stackview(bothalf and tophalf). Their constraints dependent on that stackview.I have a horizontal stackview(containerStackView3) inside the botHalfView. Its constraints leading,trailing and height dependent on botHalfView. In debugging window i can see also on console, height of the bothalfview.frame.height=0 which i added as a constraint for horizontalstackview. Therefore horizontalstackview inside the bothalfview not showing any dimension. To which constraint i should assign the horizontalstackview's height? Or any other solution to this?
let containerStackView3 = UIStackView()
containerStackView3.translatesAutoresizingMaskIntoConstraints = false
containerStackView3.axis = .vertical
containerStackView3.distribution = .fillEqually
containerStackView3.spacing = 1
//adding views
containerStackView1.addArrangedSubview(botHalfView2)
botHalfView2.addSubview(containerStackView3)
//constraints bothalfview
botHalfView2.bottomAnchor.constraint(equalTo:
containerStackView1.bottomAnchor, constant: 0).isActive = true
botHalfView2.leadingAnchor.constraint(equalTo:
containerStackView1.leadingAnchor, constant: 0).isActive = true
botHalfView2.trailingAnchor.constraint(equalTo:
containerStackView1.trailingAnchor, constant: 0).isActive = true
// Constraints of the stack view inside the bothalfview
containerStackView3.leadingAnchor.constraint(equalTo:
botHalfView2.leadingAnchor, constant: 0).isActive = true
containerStackView3.trailingAnchor.constraint(equalTo:
botHalfView2.trailingAnchor, constant: 0).isActive = true
containerStackView3.bottomAnchor.constraint(equalTo:
botHalfView2.bottomAnchor, constant: 0).isActive = true
containerStackView3.heightAnchor.constraint(equalToConstant:botHalfView2.frame.height).isActive = true
If you need container heigh same as bot half then do this
// Constraints of the stack view inside the bothalfview
containerStackView3.leadingAnchor.constraint(equalTo:
botHalfView2.leadingAnchor, constant: 0).isActive = true
containerStackView3.trailingAnchor.constraint(equalTo:
botHalfView2.trailingAnchor, constant: 0).isActive = true
containerStackView3.bottomAnchor.constraint(equalTo:
botHalfView2.bottomAnchor, constant: 0).isActive = true
containerStackView3.topAnchor(equalTo:
botHalfView2.topAnchor, constant: 0).isActive = true

container view constraint issues programmatically

I am trying to include a container UIView right above my tabBar however it doesnt seem to be displayed on my view because what i believe to be constraint issues. I would like my container view to look so in the view.
However my container is not showing in the view at all.
Here is my code:
self.mapContainer.layer.cornerRadius = 8
self.mapContainer.backgroundColor = UIColor.cyan
self.mapContainer.translatesAutoresizingMaskIntoConstraints = false
self.mapContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(self.mapContainer)
//constraints of the map view
let heightTabBar = self.tabBarController?.tabBar.frame.size.height
self.mapContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant : (heightTabBar)! + 220).isActive = true
self.mapContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
//self.topContainer.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
self.mapContainer.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3).isActive = true
//self.mapContainer.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
self.mapContainer.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 20).isActive = true
self.mapContainer.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40).isActive = true
where am I going wrong here to where my container is not displaying
?
Problem:
You push your view with a positive value at your bottom anchor outside of the view. That's the reason why you don't see it.
Solution:
Instead of adding with (equalTo: view.bottomAnchor, constant : (heightTabBar)! + 220) you should subtract with self.mapContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant : -(heightTabBar! + 220)).isActive = true at your bottomAnchor. You should also make your leading anchor of the container depend on the leading anchor of the view, the same for the trailing anchor. Also you need to set a negative value for your constant to your trailing anchor to add padding on the right side. Keep in mind: If you want to push from top and left then add and if you want to push from right and bottom then subtract
This should help you (Hints are in the code comments):
import UIKit
class ViewController: UIViewController {
var mapContainer:UIView!
override func loadView() {
super.loadView()
view.backgroundColor = .white
self.mapContainer = UIView()
self.mapContainer.layer.cornerRadius = 8
self.mapContainer.backgroundColor = UIColor.cyan
self.mapContainer.translatesAutoresizingMaskIntoConstraints = false
self.mapContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(self.mapContainer)
//constraints of the map view
let heightTabBar = self.tabBarController?.tabBar.frame.size.height
// You need to subtract to push from the bottom of the view
self.mapContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant : -(heightTabBar! + 220)).isActive = true
self.mapContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
self.mapContainer.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3).isActive = true
// Your leading anchor of map container should depend on the leading anchor of the view
self.mapContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
// Your trailingAnchor anchor of map container should depend on the trailingAnchor anchor of the view
// Here you need to subtract to push from the right
self.mapContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
}
}
Result should look similar to this:
Result on iPhone5S simulator: