Home > Enterprise >  Add button in bottom of view
Add button in bottom of view

Time:09-22

Trying to add a UIView that fills the screen, that works fine. But I also want to add a UIButton to the bottom of the UIView, but somehow the UIButton doesn't show up:

let screenSize: CGRect = UIScreen.main.bounds
let myView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height))
myView.backgroundColor = .systemGray5.withAlphaComponent(0.5)
        
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: 40)
button.setTitle("Sleeping.. Tap here to wake up!", for: UIControl.State.normal)
button.translatesAutoresizingMaskIntoConstraints = false
        
button.frame.origin = CGPoint(x:0, y:self.view.frame.size.height - button.frame.size.height - 20)
        
myView.addSubview(button)
        
self.view.addSubview(myView)

EDIT from answer:

I get error message on line:

button.bottomAnchor.constraint(equalTo: myView.bottomAnchor, constant: 10).isActive = true

Error message:

libc  abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600002658c40 "UIButton:0x7f8dce6146c0'Sleeping.. Tap here to wa...'.bottom"> and <NSLayoutYAxisAnchor:0x600002658a80 "UIView:0x7f8dce613080.bottom"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'
terminating with uncaught exception of type NSException
CoreSimulator 857.7 - Device: iPhone 14 Pro (1B903119-D288-4E1C-B36B-F8B7A44AA0DE) - Runtime: iOS 16.0 (20A360) - DeviceType: iPhone 14 Pro
(Recorded stack frame) 

CodePudding user response:

You have to add constraints to your button. For general guides, you can take a look into this SO answer. But for your purpose, adding 2 anchor constraints like this should do the trick:

let screenSize: CGRect = UIScreen.main.bounds
let myView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height))
myView.backgroundColor = .systemGray5.withAlphaComponent(0.5)
        
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: 40)
button.setTitle("Sleeping.. Tap here to wake up!", for: UIControl.State.normal)
button.bottomAnchor.constraint(equalTo: myView.bottomAnchor, constant: 10).isActive = true
button.centerYAnchor.constraint(equalTo: myView.centerYAnchor).isActive = true
button.translatesAutoresizingMaskIntoConstraints = false
        
button.frame.origin = CGPoint(x:0, y:self.view.frame.size.height - button.frame.size.height - 20)
        
myView.addSubview(button)
        
self.view.addSubview(myView)

CodePudding user response:

try this button.bottomAnchor.constraint(equalTo: myView.bottomAnchor, constant: 10).isActive = true this code add in override func viewDidAppear(_ animated: Bool) or after (about swift life cycle)

I hope this helps you.

CodePudding user response:

It's probably because of the constrain, I would recommend you using constrain instead of using rect like that, since the xib or storyboard already have their own view, you don't need to create screenSize like that, my suggestion for you is that try to use constrain instead for every view or button that you want to create, it would be great, readable and maintainable if you write something like this

let containerView = UIView()
let actionButton = UIButton()

actionButton.setTitle("Sleeping.. Tap here to wake up!", for: .normal)

view.addSubview(containerView)
containerView.addSubview(actionButton)

containerView.translatesAutoresizingMaskIntoConstraints = false
actionButton.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
  containerView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
  containerView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
  containerView.topAnchor.constraint(equalTo: self.view.topAnchor),
  containerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
  
  actionButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -10.0),
  actionButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 10.0),
  actionButton.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -10.0),
  actionButton.heightAnchor.constraint(equalToConstant: 50.0)
])

The code above actually show the same result like what you wrote, but in safer way.

  • Related