In my swift code below I am attempting to use inheritance. When I go to class middle the constraints on the initial view controller are still being applied. Even though in middle class I attempt to attach new constraints to right button they are not being applied. You can see what is going wrong in the photo below.
import UIKit
class ViewController: UIViewController {
var right = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[right].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
$0.backgroundColor = UIColor(
red: .random(in: 0.0...1),
green: .random(in: 0.9...1),
blue: .random(in: 0.7...1),
alpha: 1
)
}
NSLayoutConstraint.activate([
right.bottomAnchor.constraint(equalTo: view.bottomAnchor),
right.leadingAnchor.constraint(equalTo: view.leadingAnchor),
right.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.1),
right.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
])
right.setTitle(">", for: .normal)
right.addTarget(self, action: #selector(nexte), for: .touchDown)
}
#objc func nexte(){
let vc = middle()
vc.modalPresentationStyle = .overCurrentContext // actually .fullScreen would be better
self.present(vc, animated: true)
}
}
class middle : ViewController{
var leftbtn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[leftbtn].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
$0.backgroundColor = UIColor(
red: .random(in: 0.0...1),
green: .random(in: 0.9...1),
blue: .random(in: 0.7...1),
alpha: 1
)
}
NSLayoutConstraint.activate([
leftbtn.bottomAnchor.constraint(equalTo: view.bottomAnchor),
leftbtn.leadingAnchor.constraint(equalTo: view.leadingAnchor),
leftbtn.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.1),
leftbtn.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 0.5 ),
right.bottomAnchor.constraint(equalTo: view.bottomAnchor),
right.leadingAnchor.constraint(equalTo: leftbtn.trailingAnchor),
right.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.1),
right.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 0.5 ),
])
}
}
You are saying super.viewDidLoad() in Middle. super is ViewController so ViewController's viewDidLoad is executed too. Thus "When I go to class middle the constraints on the initial view controller are still being applied".
You should rethink your whole architecture here.
Related
When the screen size changes, the textField moves out of its place. How to attach it in the same place depending on the screen size?
Grey background of the textField for clarity.
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor),
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
plateImage.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 50),
plateImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
plateImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
plateImage.heightAnchor.constraint(equalTo: plateImage.widthAnchor, multiplier: 0.6785162287),
inputTextField.topAnchor.constraint(equalTo: plateImage.topAnchor, constant: 25),
inputTextField.leadingAnchor.constraint(equalTo: plateImage.leadingAnchor, constant: 80),
inputTextField.trailingAnchor.constraint(equalTo: plateImage.trailingAnchor, constant: -28),
])
Here is my scrollView, containerView and texField. I think all variables are fine. Aren't they?
private lazy var scrollView: UIScrollView = {
var view = UIScrollView()
view.backgroundColor = UIColor(red: 37 / 255, green: 40 / 255, blue: 47 / 255, alpha: 1)
view.showsVerticalScrollIndicator = false
view.showsHorizontalScrollIndicator = false
view.autoresizingMask = .flexibleHeight
view.setContentHuggingPriority(.defaultLow, for: .vertical)
view.clipsToBounds = true
view.bounces = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var containerView: UIView = {
var view = UIView()
view.backgroundColor = UIColor(red: 37 / 255, green: 40 / 255, blue: 47 / 255, alpha: 1)
view.clipsToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var plateImage: UIImageView = {
var view = UIImageView()
view.image = UIImage(named: "plate")
view.clipsToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
public lazy var inputTextField: UITextField = {
var view = UITextField()
view.textAlignment = .center
view.textColor = .black
view.tintColor = .clear
view.font = UIFont(name: "Avenir-Heavy", size: 155)
view.keyboardType = .numberPad
view.addButtonsToKeyboard(search: #selector(self.resignFirstResponder))
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
Here is my controller full code.
final class PlatesView: UIView {
weak var delegate: PlatesViewDelegate?
init(subscriber: PlatesViewDelegate?) {
super.init(frame: .zero)
self.delegate = subscriber
addSubView()
setupLayout()
setupButtonAction()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func addSubView() {
addSubview(scrollView)
scrollView.addSubview(containerView)
containerView.addSubview(plateImage)
containerView.addSubview(inputTextField)
}
private lazy var scrollView: UIScrollView = {
var view = UIScrollView()
view.backgroundColor = UIColor(red: 37 / 255, green: 40 / 255, blue: 47 / 255, alpha: 1)
view.showsVerticalScrollIndicator = false
view.showsHorizontalScrollIndicator = false
view.setContentHuggingPriority(.defaultLow, for: .vertical)
view.bounces = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var containerView: UIView = {
var view = UIView()
view.backgroundColor = UIColor(red: 37 / 255, green: 40 / 255, blue: 47 / 255, alpha: 1)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var plateImage: UIImageView = {
var view = UIImageView()
view.image = UIImage(named: "plate")
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
public lazy var inputTextField: UITextField = {
var view = UITextField()
view.textAlignment = .center
view.textColor = .black
view.tintColor = .clear
view.font = UIFont(name: "Avenir-Heavy", size: 155)
view.keyboardType = .numberPad
view.addButtonsToKeyboard(search: #selector(self.resignFirstResponder))
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private func setupLayout() {
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor),
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
plateImage.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 50),
plateImage.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
plateImage.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
plateImage.heightAnchor.constraint(equalTo: plateImage.widthAnchor, multiplier: 0.6785162287),
inputTextField.topAnchor.constraint(equalTo: plateImage.topAnchor, constant: 33),
inputTextField.leadingAnchor.constraint(equalTo: plateImage.leadingAnchor, constant: 80),
inputTextField.trailingAnchor.constraint(equalTo: plateImage.trailingAnchor, constant: -28),
inputTextField.heightAnchor.constraint(equalToConstant: 130),
])
}
private func setupButtonAction() {
}
}
I want to use the slider slizer to change the size of the uiview pic. With Nslayout constraints it creates a fixed object so I added to constraints as vars. So I assume in the increase func the startCon will become deactivated and the changeCon will become activated. I have not used constraints as var in a while and dont know what to do. But I want to position pic using nslayout constraints and then change the width and height together using the slider.
import UIKit
class ViewController: UIViewController{
var pic = UIView();var slizer = UISlider()
var startCon: NSLayoutConstraint!
var changeCon: NSLayoutConstraint!
override func viewDidLoad() {
[pic,slizer].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
NSLayoutConstraint.activate([
pic.centerYAnchor.constraint(equalTo: view.centerYAnchor),
pic.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pic.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
pic.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 0.3),
slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),
slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
])
pic.backgroundColor = .orange
slizer.addTarget(self, action: #selector(increase), for: .touchDown)
}
#objc func increase(){
//increase decrease size of pic
}
}
It's impossible to modify an activated constraints. You have to disable your contraints and set a new one.
var pic = UIView()
var slizer = UISlider()
var slidermultiplier: CGFloat = 0.3
var widthConstraints: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
widthConstraints = pic.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: slidermultiplier)
[pic,slizer].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
NSLayoutConstraint.activate([
pic.centerYAnchor.constraint(equalTo: view.centerYAnchor),
pic.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pic.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
widthConstraints!,
slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),
slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
])
pic.backgroundColor = .orange
// changed to .valueChanged
slizer.addTarget(self, action: #selector(increase), for: .valueChanged)
}
#objc func increase() {
slidermultiplier = CGFloat(slizer.value)
widthConstraints?.isActive = false
widthConstraints = pic.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: slidermultiplier)
widthConstraints?.isActive = true
}
and you can do the same with the height.
You can also set min and max value to your UISlider to have a Range of multiplier.
You can hold properties that are responsible for image size, change those values in slider action. For example:
change value pic.heightAnchor.constraint's multiplier in method increase action.
I want to customize UINavigationBar for some view controllers. For some reasons, I cannot just simply extend UIViewController. So I was trying to do it by a protocol.
What I have tried:
protocol TransparentNavigationBarProtocol {
func makeNavigationBarTransparent()
}
extension TransparentNavigationBarProtocol where Self: UIViewController {
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.white
navController.navigationBar.barStyle = .blackTranslucent
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navController.navigationBar.backgroundColor = .clear
}
}
}
I added some breakpoints which show the function had been called successfully but the navigationBar didn't change. So I was wondering is it possible to achieve this by protocols?
For Xcode11, you need set a image, not nil
Also, in your viewcontroller's viewWillAppear, you need call makeNavigationBarTransparent()
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.init(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)
navController.navigationBar.barStyle = .default
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)]
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
makeNavigationBarTransparent()
}
I'm trying to implement a custom text input view, similar to what is used in most messaging apps like below:
Where the whole view appears at the bottom of the screen initially then above the keyboard when selected, the text box re-sizes based on the content and includes a button to upload text.
I assume I need to create a custom UIView that contain all these elements, but am unsure how to change the textbox size and move the view above a keyboard when pressed.
Can someone point me in the right direction
Have a look at MessageInputBar
https://github.com/MessageKit/MessageInputBar
It will make your like easy and will stop you from reinventing the wheel plus its highly customisable, you can run the example to see how it is working.
Edit
Just to give you an idea
import UIKit
import MessageInputBar
class CustomInputBar: MessageInputBar {
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure() {
backgroundView.backgroundColor = UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1)
let button = InputBarButtonItem()
button.setSize(CGSize(width: 36, height: 36), animated: false)
button.setImage(#imageLiteral(resourceName: "ic_up").withRenderingMode(.alwaysTemplate), for: .normal)
button.imageView?.contentMode = .scaleAspectFit
button.tintColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
inputTextView.backgroundColor = .white
inputTextView.placeholderTextColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
inputTextView.textContainerInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
inputTextView.placeholderLabelInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 20)
inputTextView.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1).cgColor
inputTextView.layer.borderWidth = 1.0
inputTextView.layer.cornerRadius = 4.0
inputTextView.layer.masksToBounds = true
inputTextView.scrollIndicatorInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
setLeftStackViewWidthConstant(to: 36, animated: false)
setStackViewItems([button], forStack: .left, animated: false)
sendButton.setSize(CGSize(width: 52, height: 36), animated: false)
}
}
which will look like this:
With all the feature you wanted plus more.
I've edited the code from the example project a little to make it look exactly as you added in the question.
And you ViewController will just be
import UIKit
import MessageInputBar
final class ExampleViewController: UITableViewController {
// MARK: - Properties
override var inputAccessoryView: UIView? {
return messageInputBar
}
override var canBecomeFirstResponder: Bool {
return true
}
// MARK: - MessageInputBar
private let messageInputBar = CustomInputBar()
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
tableView.keyboardDismissMode = .interactive
messageInputBar.delegate = self
}
}
And to listen to MessageInputBarDelegate simply add
extension ExampleViewController: MessageInputBarDelegate {
func messageInputBar(_ inputBar: MessageInputBar, didPressSendButtonWith text: String) {
// Use to send the message
messageInputBar.inputTextView.text = String()
messageInputBar.invalidatePlugins()
}
func messageInputBar(_ inputBar: MessageInputBar, textViewTextDidChangeTo text: String) {
// Use to send a typing indicator
}
func messageInputBar(_ inputBar: MessageInputBar, didChangeIntrinsicContentTo size: CGSize) {
// Use to change any other subview insets
}
}
Simple as that :)
If you want to do it programatically by yourself you can try this.
Custom textentry view which will containt text input and send button
import UIKit
class TextEntryView: UIView {
let tvMessage: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.textColor = Constants.charlie
textView.font = UIFont.systemFont(ofSize: 17)
textView.isScrollEnabled = false
return textView
}()
let btnSend: UIButton = {
let image: UIImage = UIImage(named: "send_icon")!
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(image, for: .normal)
button.setContentHuggingPriority(UILayoutPriority(rawValue: 250), for: .horizontal)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
self.addBorders(edges: .top, color: UIColor(red: 220/250, green: 220/250, blue: 220/250, alpha: 1))
setupLayout()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override class var requiresConstraintBasedLayout: Bool {
return true
}
private func setupLayout() {
self.addSubview(tvMessage)
self.addSubview(btnSend)
tvMessage.topAnchor.constraint(equalTo: self.topAnchor, constant: 6).isActive = true
tvMessage.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 12).isActive = true
tvMessage.trailingAnchor.constraint(equalTo: btnSend.leadingAnchor, constant: -12).isActive = true
tvMessage.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -6).isActive = true
btnSend.topAnchor.constraint(equalTo: self.topAnchor, constant: 6).isActive = true
btnSend.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -12).isActive = true
btnSend.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -6).isActive = true
btnSend.widthAnchor.constraint(equalToConstant: 40).isActive = true
}
}
Add custom view in controller
import UIKit
class ChatController: UIViewController, UITextViewDelegate {
let textEntry = TextEntryView()
var bottomConstraint: NSLayoutConstraint?
var textEntryHeightConstraint: NSLayoutConstraint?
override func viewWillAppear(_ animated: Bool) {
initViews()
setupLayout()
NotificationCenter.default.addObserver(self,
selector: #selector(self.keyboardNotification(notification:)),
name: NSNotification.Name.UIKeyboardWillChangeFrame,
object: nil)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
#objc func hideKeyboard() {
self.endEditing(true)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
#objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let endFrameY = keyboardFrame?.origin.y ?? 0
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
if endFrameY >= UIScreen.main.bounds.size.height {
bottomConstraint?.constant = 0
} else {
bottomConstraint?.constant = -(keyboardFrame?.size.height)!
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: { self.layoutIfNeeded() },
completion: nil)
}
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (textEntry.tvMessage.contentSize.height + 12 < (textEntryHeightConstraint?.constant)!) {
self.textEntry.tvMessage.isScrollEnabled = false
} else {
self.textEntry.tvMessage.isScrollEnabled = true
}
return true
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textEntry.tvMessage.textColor == .lightGray {
textEntry.tvMessage.text = nil
textEntry.tvMessage.textColor = Constants.tertiaryColor
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if (textEntry.tvMessage.text?.isEmpty)! {
textEntry.tvMessage.text = "Write a message"
textEntry.tvMessage.textColor = .lightGray
}
}
}
extension MessageView {
func initViews() {
if #available(iOS 11.0, *) {
bottomConstraint = NSLayoutConstraint(item: textEntry, attribute: .bottom, relatedBy: .equal, toItem: self.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1, constant: 0)
} else {
// Fallback on earlier versions
bottomConstraint = NSLayoutConstraint(item: textEntry, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)
}
textEntry.translatesAutoresizingMaskIntoConstraints = false
textEntry.tvMessage.text = "Write a message"
textEntry.tvMessage.textColor = .lightGray
textEntry.tvMessage.delegate = self
}
func setupLayout() {
self.addSubview(textEntry)
textEntry.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
textEntry.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
self.addConstraint(bottomConstraint!)
textEntryHeightConstraint = textEntry.heightAnchor.constraint(lessThanOrEqualToConstant: 150)
textEntryHeightConstraint?.isActive = true
}
}
I'm learning how to build a ViewController programmatically, but my one question is: Why can't I state view.addSubview(inputInfoContainerView) under func setupInputInforContainerView() at the end of the declaration of this function? Why do I have to have view.addSubview(inputInfoContainerView) under func viewDidLoad()?
import UIKit
class LoginViewController: UIViewController {
//CONTAINER VIEW
let inputInfoContainerView: UIView = {
let containerView = UIView()
containerView.backgroundColor = UIColor.white
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.layer.cornerRadius = 6
containerView.layer.masksToBounds = true
return containerView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(r: 60, g: 90, b: 150)
//I understand where this is where it should go but need clarification on why
setupInputInfoContainerView()
}
func setupInputInfoContainerView() {
//CONSTRAINTS: x, y, width, height
inputInfoContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputInfoContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 40) .isActive = true
inputInfoContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputInfoContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
view.addSubview(inputInfoContainerView)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return.lightContent
}
}
extension UIColor {
convenience init(r: CGFloat, g: CGFloat, b: CGFloat) {
self.init(red: r/255, green: g/255, blue: b/255, alpha: 1)
}
}
}
You need to add your subview to the superview before adding any constraints, like this:
func setupInputInfoContainerView() {
view.addSubview(inputInfoContainerView)
//CONSTRAINTS: x, y, width, height
inputInfoContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputInfoContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 40) .isActive = true
inputInfoContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputInfoContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
}