.tag on slider not changing the alpha of imagview - swift

My swift code below has 2 different buttons which should effect the slider baised on the .tagnumber they initialize. B1 should effect the alhpa or transpency of the imageivew and b2 should decrease / increase the size. What b2 does works. What B1 does not work.My code does not use any storyboards. Also the uislider should only do one task it cannont resize the imageview and change the alpha at the same time. Only 1 task.
import UIKit
class ViewController: UIViewController {
var pzc = UIImageView()
var s = UISlider()
var b1 = UIButton()
var b2 = UIButton()
var jessicaAlba:Float = 50
var topConstraint: NSLayoutConstraint!
var heightConstraint: NSLayoutConstraint!
var leadingConstraint: NSLayoutConstraint!
var trailingConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
[pzc,s,b1,b2].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
[b1,b2].forEach {
$0.backgroundColor = .systemRed
}
pzc.backgroundColor = .systemGray
b1.frame = CGRect(x: view.center.x-115, y: view.center.y+200, width: 30, height: 30)
b2.frame = CGRect(x: view.center.x-115, y: view.center.y+250, width: 30, height: 30)
s.addTarget(self, action: #selector(moveRight), for: .touchUpInside)
b1.addTarget(self, action: #selector(mr1), for: .touchUpInside)
b2.addTarget(self, action: #selector(mr2), for: .touchUpInside)
NSLayoutConstraint.activate ([
b1.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant :37.5),
b1.topAnchor.constraint(equalTo: view.centerYAnchor, constant : 225),
b1.widthAnchor.constraint(equalToConstant: 75),
b1.heightAnchor.constraint(equalToConstant: 50),
b2.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant :130),
b2.topAnchor.constraint(equalTo: view.centerYAnchor, constant : 225),
b2.widthAnchor.constraint(equalToConstant: 75),
b2.heightAnchor.constraint(equalToConstant: 50),
])
s.minimumValue = 50
s.maximumValue = 200
s.setValue(jessicaAlba, animated: false)
view.addSubview(s)
s.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
s.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
s.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10).isActive = true
pzc.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pzc)
topConstraint = pzc.topAnchor.constraint(equalTo: view.topAnchor, constant: CGFloat(jessicaAlba))
topConstraint.isActive = true
heightConstraint = pzc.heightAnchor.constraint(equalTo: view.heightAnchor , multiplier: 0.5, constant: CGFloat(-jessicaAlba))
heightConstraint.isActive = true
leadingConstraint = pzc.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: CGFloat(jessicaAlba))
leadingConstraint.isActive = true
trailingConstraint = pzc.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: CGFloat(-jessicaAlba))
trailingConstraint.isActive = true
}
#objc func moveRight() {
if s.tag == 1 {
pzc.alpha = CGFloat(s.value)
}
if s.tag == 2 {
changeSize()
}
}
#objc func changeSize() {
UIView.animate(withDuration: 0.5, animations: {
self.jessicaAlba = self.s.value
self.topConstraint.constant = CGFloat(self.jessicaAlba)
self.heightConstraint.constant = CGFloat(-self.jessicaAlba)
self.leadingConstraint.constant = CGFloat(self.jessicaAlba)
self.trailingConstraint.constant = CGFloat(-self.jessicaAlba)
self.view.layoutIfNeeded()
}) { (finished) in
}
}
#objc func mr1() {
b1.backgroundColor = .brown
b2.backgroundColor = .systemPink
s.tag = 1
}
#objc func mr2() {
b2.backgroundColor = .brown
b1.backgroundColor = .systemPink
s.tag = 2
}
}

Here multiple target are added on your UISlider. Just modify your function.
#objc func moveRight() {
if s.tag == 1 {
let diff = s.maximumValue-s.minimumValue
pzc.alpha = CGFloat(s.value/diff)
}
if s.tag == 2 {
changeSize()
}
}
You can also modify your changeSize() function for animation.
#objc func changeSize() {
UIView.animate(withDuration: 0.5, animations: {
self.jessicaAlba = self.s.value
self.topConstraint.constant = CGFloat(self.jessicaAlba)
self.heightConstraint.constant = CGFloat(-self.jessicaAlba)
self.leadingConstraint.constant = CGFloat(self.jessicaAlba)
self.trailingConstraint.constant = CGFloat(-self.jessicaAlba)
self.view.layoutIfNeeded()
}) { (finished) in
}
}

Related

var constraints not appearing when assigned to a function that creates a view

I want my swift code to use var constraints to let the objects added to the code. I have added a gif below of what I am looking for. Right now the code below compiles but the black view you can see in the gif below is not appearing in the code below. In my code below the black box is not appearing at all.
import UIKit
public class ViewController : UIViewController {
var slider = UISlider()
var image1Width2: NSLayoutConstraint!
var iHieght: NSLayoutConstraint!
public override func viewDidLoad() {
super.viewDidLoad()
slider.value = 0.5
slider.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(slider)
slider.isUserInteractionEnabled = true
slider.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
slider.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
slider.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.1).isActive = true
slider.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1).isActive = true
button.frame = .init(x: self.view.bounds.midX,
y: 0,
width: 100,
height: 100)
self.view.addSubview(button)
image1Width2 = view.widthAnchor.constraint(equalTo: view.widthAnchor ,multiplier: 0.06)
iHieght = view.widthAnchor.constraint(equalTo: view.heightAnchor ,multiplier: 0.06)
slider.addTarget(self, action: #selector(increase), for: .allEvents)
}
private lazy var button: UIButton = {
let button = UIButton()
button.backgroundColor = .blue
button.setTitleColor(.white, for: .normal)
button.setTitle("add", for: .normal)
button.addTarget(self,
action: #selector(addBlackView),
for: .touchUpInside)
return button
}()
private func getBlackView() -> UIView {
let view = UIView()
view.backgroundColor = .black
image1Width2 = view.widthAnchor.constraint(equalTo: view.widthAnchor ,multiplier: 0.06)
iHieght = view.widthAnchor.constraint(equalTo: view.heightAnchor ,multiplier: 0.06)
let recognizer = UIPanGestureRecognizer(target: self, action: #selector(moveView(_:)))
view.addGestureRecognizer(recognizer)
return view
}
#objc
private func addBlackView() {
let view = getBlackView()
self.view.addSubview(view)
}
#objc
private func moveView(_ recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .began:
print("gesture began")
case .changed:
let translation = recognizer.translation(in: self.view)
recognizer.view!.center = .init(x: recognizer.view!.center.x + translation.x,
y: recognizer.view!.center.y + translation.y)
recognizer.setTranslation(.zero, in: self.view)
default:
break
}
}
#objc func increase() {
image1Width2.constant = CGFloat(slider.value) * view.frame.size.width * 0.10
iHieght.constant = CGFloat(slider.value) * view.frame.size.width * 0.10
}
}
You are doing couple of mistakes when writing this code.Mainly iOS basic principles
Please refer this modified code, modify it and get your result.
class sampleViewController: UIViewController {
var image1Width2: NSLayoutConstraint!
var iHieght: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(slider)
slider.translatesAutoresizingMaskIntoConstraints = false
slider.value = 0.5
slider.isUserInteractionEnabled = true
NSLayoutConstraint.activate([
slider.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
slider.leadingAnchor.constraint(equalTo: view.leadingAnchor),
slider.heightAnchor.constraint(equalToConstant: 100),
slider.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
])
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
button.widthAnchor.constraint(equalToConstant: 100),
button.heightAnchor.constraint(equalToConstant: 80),
])
button.addTarget(self,action: #selector(addBlackView),for: .touchUpInside)
slider.addTarget(self, action: #selector(increase), for: .allEvents)
}
let slider:UISlider = {
let slider = UISlider(frame: .zero)
return slider
}()
private lazy var button: UIButton = {
let button = UIButton()
button.backgroundColor = .blue
button.setTitleColor(.white, for: .normal)
button.setTitle("add", for: .normal)
return button
}()
let blackView: UIView = {
let view = UIView()
view.backgroundColor = .black
return view
}()
#objc
private func addBlackView() {
self.view.addSubview(blackView)
blackView.translatesAutoresizingMaskIntoConstraints = false
blackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
blackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
image1Width2 = blackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.1)
image1Width2.isActive = true
iHieght = blackView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1)
iHieght.isActive = true
view.layoutIfNeeded()
let recognizer = UIPanGestureRecognizer(target: self, action: #selector(moveView(_:)))
blackView.addGestureRecognizer(recognizer)
}
#objc private func moveView(_ recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .began:
print("gesture began")
case .changed:
let translation = recognizer.translation(in: self.view)
recognizer.view!.center = .init(x: recognizer.view!.center.x + translation.x,
y: recognizer.view!.center.y + translation.y)
recognizer.setTranslation(.zero, in: self.view)
default:
break
}
}
#objc func increase() {
image1Width2.constant = CGFloat(slider.value) * view.frame.size.width * 0.10
iHieght.constant = CGFloat(slider.value) * view.frame.size.width * 0.10
}}

UIView Animation just work one time than it doesn't work

I try to do an animation for my view but if just work in first time which is isOpen = true it work but when I call my function again isOpen = false nothing changes?
Perent view is self (UIView). Child is label(UILabel).
private func expansionView(isOpen: Bool) {
if isOpen {
label.backgroundColor = .white
NSLayoutConstraint.activate([
label.centerYAnchor.constraint(equalTo: self.topAnchor),
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15),
])
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
}) { (_) in
}
} else {
label.backgroundColor = .clear
NSLayoutConstraint.activate([
label.centerYAnchor.constraint(equalTo: self.centerYAnchor),
label.leadingAnchor.constraint(equalTo: self.leadingAnchor , constant: 15),
])
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
}) { (_) in
print("Animation Completed!!!")
}
}
}
You need to have two constraints to make one of them active.
You can also animate changing label's background color to clear. And you can simplify your function like below.
// define both vertical constraints
var constraintToCenterYAnchor: NSLayoutConstraint!
var constraintToTopAnchor: NSLayoutConstraint!
// where you init your view..
init() {
// init your constraints
constraintToTopAnchor = label.centerYAnchor.constraint(equalTo: topAnchor)
constraintToCenterYAnchor = label.centerYAnchor.constraint(equalTo: centerYAnchor)
// set and activate other constraints once.
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15).isActive = true
// update background color of the label
label.backgroundColor = .clear
label.layer.backgroundColor = UIColor.white.cgColor
}
// simplify your function
private func expansionView(_ isOpen: Bool) {
constraintToTopAnchor.isActive = isOpen
constraintToCenterYAnchor.isActive = !isOpen
UIView.animate(withDuration: 1) {
self.label.layer.opacity = isOpen ? 1.0 : 0.0
self.layoutIfNeeded()
}
}
You need to have two contraints to activate and deactivate ...
lazy var centerXConstraint = label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
lazy var topConstraint = label.leadingAnchor.constraint(equalTo: self.leadingAnchor , constant: 15)
init() {
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15).isActive = true
}
private func expansionView(isOpen: Bool) {
if isOpen {
label.backgroundColor = .white
centerXConstraint.isActive = false
topConstraint.isActive = true
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
}) { (_) in
}
} else {
label.backgroundColor = .clear
centerXConstraint.isActive = true
topConstraint.isActive = false
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
}) { (_) in
print("Animation Completed!!!")
}
}
}

why NSLayoutConstraint animation works only one time?

in my project I have a someView(of type UIView), that inside holderView(of type UIView).
someView have 2 state.
in state 1 the someView become large and in the step 2 the someView become small.
when some condition where right, someView show in state 1 and when it's not someView show in state 2.
I want to do this with animation and I use NSLayoutConstraint in my project. I'm using this codes(someViewHeight and someViewWidth are of type NSLayoutConstraint):
func minimizeSomeView() {
someViewHeight.constant = holderView.frame.width
someViewWidth.constant = holderView.frame.height
UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded()
}
}
func maximizeSomeView() {
someViewHeight.constant = holderView.frame.width/4
someViewWidth.constant = holderView.frame.height/4
UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded()
}
}
if someTextField.text != nil {
minimizeSomeView()
} else. {
maximizeSomeView()
}
I define someViewHeight and someViewWidth inside viewDidLayoutSubviews(), this is my codes:
class ViewController: UIViewController {
private var holderView, someView: UIView!
private var someViewHeight,someViewWidth: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
super.viewDidLoad()
view.backgroundColor = .white
// Holder View
holderView = UIView()
holderView.backgroundColor = .red
holderView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(holderView)
NSLayoutConstraint.activate([
holderView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
holderView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
holderView.topAnchor.constraint(equalTo: view.topAnchor, constant: 120),
holderView.heightAnchor.constraint(equalToConstant: view.frame.height * 40 / 100)
])
// Some View
someView = UIView()
someView.backgroundColor = .blue
someView.translatesAutoresizingMaskIntoConstraints = false
holderView.addSubview(someView)
someView.topAnchor.constraint(equalTo: holderView.topAnchor).isActive = true
someView.trailingAnchor.constraint(equalTo: holderView.trailingAnchor).isActive = true
// Some TextField
let someTextField = UITextField()
someTextField.backgroundColor = .yellow
someTextField.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(someTextField)
NSLayoutConstraint.activate([
someTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
someTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
someTextField.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -100),
someTextField.heightAnchor.constraint(equalToConstant: 50)
])
someTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
}
override func viewDidLayoutSubviews() {
someViewHeight = someView.heightAnchor.constraint(equalToConstant: holderView.frame.width)
someViewHeight.isActive = true
someViewWidth = someView.widthAnchor.constraint(equalToConstant: holderView.frame.width)
someViewWidth.isActive = true
}
func minimizeSomeView() {
someViewHeight.constant = holderView.frame.width/4
someViewWidth.constant = holderView.frame.height/4
UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded()
}
}
func maximizeSomeView() {
someViewHeight.constant = holderView.frame.width
someViewWidth.constant = holderView.frame.height
UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded()
}
}
#objc func textFieldDidChange(_ textfield: UITextField) {
if textfield.text!.count > 0 {
self.minimizeSomeView()
} else {
self.maximizeSomeView()
}
}
}
You should not update the constraints in viewDidLayoutSubviews, specifically when you are using auto layout. You don't need this block
When you add constraint you can initialize and make them active.
Here we can specify the constraint in proportion. i.e Height of someView is 0.4 of the holderView. Similarly, Width of someView is 0.4 of the holderView.
To fix the issue , you can perform below changes
// Your some View Constraints
someView.topAnchor.constraint(equalTo: holderView.topAnchor).isActive = true
someView.trailingAnchor.constraint(equalTo: holderView.trailingAnchor).isActive = true
maximizeSomeView()
Remove the viewDidLayouSubView Code
Update your maximize and minimize events. Here I have to remove the existing constraints as .multiplier is a readonly property.
func minimizeSomeView() {
removeExistingConstriant()
UIView.animate(withDuration: 1.0) { [unowned self] in
self.someViewWidth = self.someView.widthAnchor.constraint(equalTo: self.holderView.widthAnchor, multiplier: 1.0)
self.someViewWidth.isActive = true
self.someViewHeight = self.someView.heightAnchor.constraint(equalTo:
self.holderView.heightAnchor, multiplier: 1.0)
self.someViewHeight.isActive = true
self.view.layoutIfNeeded()
}
}
func maximizeSomeView() {
removeExistingConstriant()
UIView.animate(withDuration: 1.0) { [unowned self] in
self.someViewWidth = self.someView.widthAnchor.constraint(equalTo: self.holderView.widthAnchor, multiplier: 0.4)
self.someViewWidth.isActive = true
self.someViewHeight = self.someView.heightAnchor.constraint(equalTo:
self.holderView.heightAnchor, multiplier: 0.4)
self.someViewHeight.isActive = true
self.view.layoutIfNeeded()
}
}
func removeExistingConstriant(){
if self.someViewHeight != nil {
self.someViewHeight.isActive = false
}
if self.someViewWidth != nil {
self.someViewWidth.isActive = false
}
}

add 2 image views to a uiscrollview func every time it is called

My swift code below goal is to add 2 image views every time. Ass you can in the gif below only one image view is being added. I just need to add 2 image views. The image views are lastImage and lastImage2. you can see only lastImage is being shown. It seems I can only add 1 imageview when func didclickadd is called.
import UIKit
class ViewController: UIViewController {
fileprivate var lastImage:UIImageView?
fileprivate var lastImage2:UIImageView?
fileprivate var mainViewBootom:NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupVIew()
}
override func viewDidAppear(_ animated: Bool) {
scrollView.contentSize = CGSize(width: view.frame.width, height: mainView.frame.height)
view.layoutIfNeeded()
}
//MARK: Components
let scrollView:UIScrollView = {
let sv = UIScrollView(frame: .zero)
return sv
}()
let mainView:UIView = {
let uv = UIView()
uv.backgroundColor = .white
return uv
}()
let btnAdd:UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Add", for: .normal)
return btn
}()
let textField:UITextField = {
let jake = UITextField()
return jake
}()
//MARK: Setup UI
func setupVIew() {
view.addSubview(scrollView)
view.addSubview(btnAdd)
view.addSubview(textField)
scrollView.translatesAutoresizingMaskIntoConstraints = false
btnAdd.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
btnAdd.centerXAnchor.constraint(equalTo: view.centerXAnchor),
btnAdd.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -12),
btnAdd.widthAnchor.constraint(equalToConstant: 100),
btnAdd.heightAnchor.constraint(equalToConstant: 45),
//
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
textField.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 25),
textField.widthAnchor.constraint(equalToConstant: 100),
textField.heightAnchor.constraint(equalToConstant: 45),
//
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: btnAdd.topAnchor , constant: -12),
])
btnAdd.addTarget(self, action: #selector(didClickedAdd), for: .touchUpInside)
scrollView.addSubview(mainView)
mainView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mainView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mainView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mainView.topAnchor.constraint(equalTo: scrollView.topAnchor),
])
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 100))
imgView.backgroundColor = .red
mainView.addSubview(imgView)
let samsam = UIImageView(frame: CGRect(x: 0, y: 200, width: 40, height: 100))
samsam.backgroundColor = .blue
mainView.addSubview(samsam)
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: 150).isActive = true
imgView.heightAnchor.constraint(equalToConstant: 100).isActive = true
samsam.translatesAutoresizingMaskIntoConstraints = false
samsam.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
samsam.topAnchor.constraint(equalTo: imgView.bottomAnchor).isActive = true
samsam.widthAnchor.constraint(equalToConstant: 75).isActive = true
samsam.heightAnchor.constraint(equalToConstant: 100).isActive = true
if lastImage != nil {
imgView.topAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 20).isActive = true
}else{
imgView.topAnchor.constraint(equalTo: mainView.topAnchor , constant: 12).isActive = true
}
lastImage = samsam
mainViewBootom = mainView.bottomAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 12)
mainViewBootom!.isActive = true
}
#objc func didClickedAdd(){
let imgView = UIImageView(frame: CGRect(x: 20, y: 0, width: 30, height: 20))
imgView.backgroundColor = .orange
mainView.addSubview(imgView)
let ss = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 50))
imgView.backgroundColor = .green
mainView.addSubview(ss)
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: 40).isActive = true
imgView.heightAnchor.constraint(equalToConstant: 60).isActive = true
ss.translatesAutoresizingMaskIntoConstraints = false
ss.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = false
ss.widthAnchor.constraint(equalToConstant: 80).isActive = true
ss.heightAnchor.constraint(equalToConstant: 90).isActive = true
if lastImage != nil {
ss.topAnchor.constraint(equalTo: imgView.topAnchor , constant: 20).isActive = true
imgView.topAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 50).isActive = true
}else{
imgView.topAnchor.constraint(equalTo: mainView.topAnchor , constant: 10).isActive = true
ss.bottomAnchor.constraint(equalTo: imgView.bottomAnchor , constant: 25).isActive = true
}
lastImage = imgView
lastImage2 = ss
mainView.removeConstraint(mainViewBootom!)
mainViewBootom = mainView.bottomAnchor.constraint(equalTo: lastImage2!.bottomAnchor , constant: 40)
mainViewBootom!.isActive = true
view.layoutIfNeeded()
scrollView.contentSize = CGSize(width: view.frame.width, height: mainView.frame.height)
view.layoutIfNeeded()
}
}
Couple notes...
With proper constraint setup, auto-layout handles the UIScrollView content size all by itself. No need to ever set scrollView.contentSize = ...
You have several instances of adding a subview (image view) to your mainView, which is a subview of your scroll view, but then you add constraints from that subview to your controller's view. Make sure you are constraining elements to the proper other elements.
Here's your code, with commented changes:
class BenViewController: UIViewController {
fileprivate var lastImage:UIImageView?
// 1) don't need this
// fileprivate var lastImage2:UIImageView?
fileprivate var mainViewBootom:NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupVIew()
}
// 2) don't need this
// override func viewDidAppear(_ animated: Bool) {
// scrollView.contentSize = CGSize(width: view.frame.width, height: mainView.frame.height)
// view.layoutIfNeeded()
// }
//MARK: Components
let scrollView:UIScrollView = {
let sv = UIScrollView(frame: .zero)
return sv
}()
let mainView:UIView = {
let uv = UIView()
uv.backgroundColor = .white
return uv
}()
let btnAdd:UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Add", for: .normal)
return btn
}()
let textField:UITextField = {
let jake = UITextField()
return jake
}()
//MARK: Setup UI
func setupVIew() {
view.addSubview(scrollView)
view.addSubview(btnAdd)
view.addSubview(textField)
scrollView.translatesAutoresizingMaskIntoConstraints = false
btnAdd.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
btnAdd.centerXAnchor.constraint(equalTo: view.centerXAnchor),
btnAdd.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -12),
btnAdd.widthAnchor.constraint(equalToConstant: 100),
btnAdd.heightAnchor.constraint(equalToConstant: 45),
//
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
textField.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 25),
textField.widthAnchor.constraint(equalToConstant: 100),
textField.heightAnchor.constraint(equalToConstant: 45),
//
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: btnAdd.topAnchor , constant: -12),
])
btnAdd.addTarget(self, action: #selector(didClickedAdd), for: .touchUpInside)
scrollView.addSubview(mainView)
mainView.translatesAutoresizingMaskIntoConstraints = false
// 3) change this:
// NSLayoutConstraint.activate([
// mainView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
// mainView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// mainView.topAnchor.constraint(equalTo: scrollView.topAnchor),
// ])
//
// to this
NSLayoutConstraint.activate([
mainView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
mainView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
mainView.topAnchor.constraint(equalTo: scrollView.topAnchor),
mainView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
mainView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
])
// end of change 3)
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 100))
imgView.backgroundColor = .red
mainView.addSubview(imgView)
let samsam = UIImageView(frame: CGRect(x: 0, y: 200, width: 40, height: 100))
samsam.backgroundColor = .blue
mainView.addSubview(samsam)
imgView.translatesAutoresizingMaskIntoConstraints = false
// 4) change view.centerXAnchor to mainView.centerXAnchor
// imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imgView.centerXAnchor.constraint(equalTo: mainView.centerXAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: 150).isActive = true
imgView.heightAnchor.constraint(equalToConstant: 100).isActive = true
samsam.translatesAutoresizingMaskIntoConstraints = false
// 5) change view.centerXAnchor to mainView.centerXAnchor
// samsam.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
samsam.centerXAnchor.constraint(equalTo: mainView.centerXAnchor).isActive = true
samsam.topAnchor.constraint(equalTo: imgView.bottomAnchor).isActive = true
samsam.widthAnchor.constraint(equalToConstant: 75).isActive = true
samsam.heightAnchor.constraint(equalToConstant: 100).isActive = true
if lastImage != nil {
imgView.topAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 20).isActive = true
}else{
imgView.topAnchor.constraint(equalTo: mainView.topAnchor , constant: 12).isActive = true
}
lastImage = samsam
mainViewBootom = mainView.bottomAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 12)
mainViewBootom!.isActive = true
}
#objc func didClickedAdd(){
let imgView = UIImageView(frame: CGRect(x: 20, y: 0, width: 30, height: 20))
imgView.backgroundColor = .orange
mainView.addSubview(imgView)
let ss = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 50))
// 6) typo or copy/paste mistake
// imgView.backgroundColor = .green
ss.backgroundColor = .green
mainView.addSubview(ss)
imgView.translatesAutoresizingMaskIntoConstraints = false
// 7) change view.centerXAnchor to mainView.centerXAnchor
// imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imgView.centerXAnchor.constraint(equalTo: mainView.centerXAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: 40).isActive = true
imgView.heightAnchor.constraint(equalToConstant: 60).isActive = true
ss.translatesAutoresizingMaskIntoConstraints = false
// 8) change view.leadingAnchor to mainView.leadingAnchor
// ss.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = false
ss.leadingAnchor.constraint(equalTo: mainView.leadingAnchor).isActive = false
ss.widthAnchor.constraint(equalToConstant: 80).isActive = true
ss.heightAnchor.constraint(equalToConstant: 90).isActive = true
// 9) always need to do this ... but did you mean imgView.bottomAnchor?
ss.topAnchor.constraint(equalTo: imgView.topAnchor , constant: 20).isActive = true
if lastImage != nil {
// 9a) instead of only here
//ss.topAnchor.constraint(equalTo: imgView.topAnchor , constant: 20).isActive = true
imgView.topAnchor.constraint(equalTo: lastImage!.bottomAnchor , constant: 50).isActive = true
}else{
imgView.topAnchor.constraint(equalTo: mainView.topAnchor , constant: 10).isActive = true
}
// 10) always need to do this
// deactivate bottom constraint
mainViewBootom?.isActive = false
lastImage = ss
mainViewBootom = mainView.bottomAnchor.constraint(equalTo: lastImage!.bottomAnchor, constant: 40)
mainViewBootom?.isActive = true
// 11) don't need any of this
// lastImage = imgView
// lastImage2 = ss
// mainView.removeConstraint(mainViewBootom!)
//
//
// mainViewBootom = mainView.bottomAnchor.constraint(equalTo: lastImage2!.bottomAnchor , constant: 40)
//
//
//
//
// mainViewBootom!.isActive = true
// view.layoutIfNeeded()
//
// scrollView.contentSize = CGSize(width: view.frame.width, height: mainView.frame.height)
// view.layoutIfNeeded()
}
}
Use Xcode’s “view debugger” (the button is circled in red in my screen snapshot below) and you’ll see what’s going on:
Your ss view has no background color. Note, that when you created that view, you accidentally reset the imgView background color a second time rather than setting the ss.backgroundColor.
Fix that and you’ll see your both imgView and ss:
The view debugger is your best friend when trying to diagnose issues like this. Now, obviously, the green view probably isn’t where you intended it, but you should now be able to see it and diagnose that issue very easily.
All of this having been said, a few observations:
You’re making life much harder than you need to. If you just set the constraints for the scroll view and a stack view within that scroll view, you then only need to add an arranged subview. For example:
#objc func didTapButton(_ sender: UIButton) {
stackView.addArrangedSubview(randomView())
stackView.addArrangedSubview(randomView())
}
Note, once the stack view and scroll view have been set up (see below), then you don’t need to mess around with contentSize or constraints for these subviews at all (other than the widthAnchor and heightAnchor). The auto layout engine, combined with the constraints between the stack view and the scroll view, will take care of everything for you.
So, a full working example:
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
let stackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = 10
return stackView
}()
let button: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Add", for: .normal)
button.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
}
// MARK: - Actions
extension ViewController {
#objc func didTapButton(_ sender: UIButton) {
stackView.addArrangedSubview(randomView())
stackView.addArrangedSubview(randomView())
}
}
// MARK: - Private utility methods
private extension ViewController {
func configure() {
view.addSubview(scrollView)
view.addSubview(button)
scrollView.addSubview(stackView)
NSLayoutConstraint.activate([
// define frame of `scrollView`
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: button.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// define frame of `button`
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.bottomAnchor.constraint(equalTo: view.bottomAnchor),
// define contentSize of `scrollView` based upon size of `stackView`
stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
// but define width of `stackView` relative to the _main view_
stackView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor)
])
button.setContentHuggingPriority(.required, for: .vertical)
}
func randomView() -> UIView {
let widthRange = view.bounds.width * 0.1 ... view.bounds.width * 0.9
let heightRange = view.bounds.width * 0.1 ... view.bounds.width * 0.25
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
view.widthAnchor.constraint(equalToConstant: .random(in: widthRange)),
view.heightAnchor.constraint(equalToConstant: .random(in: heightRange))
])
view.backgroundColor = UIColor(red: .random(in: 0.25...1), green: .random(in: 0.25...1), blue: .random(in: 0.25...1), alpha: 1)
return view
}
}
Even better, I’d personally set up the scroll view, stack view, button, and all the associated constraints in Interface Builder, and then that hairy configure method in my example goes away completely. It’s fun to learn how to create views programmatically, but in real-world projects, it’s rarely the most productive way to do it. Do programmatic views where needed (e.g. adding arranged subviews to the stack view on the click of a button), but otherwise, for those views that should be there when you first run the app, Interface Builder is worth considering.
E.g. It dramatically reduces the amount of code above, leaving us simply with:
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var stackView: UIStackView!
#IBAction func didTapButton(_ sender: UIButton) {
stackView.addArrangedSubview(randomView())
stackView.addArrangedSubview(randomView())
}
}
// MARK: - Private utility methods
private extension ViewController {
func randomView() -> UIView { ... }
}
Clearly, it takes a while to get used to designing views and configuring constraints in IB, but it’s worth the effort. It distills our code down the the bare essentials.
In your code, you’re setting frames for these image views and then setting translatesAutoresizingMaskIntoConstraints. There’s absolutely no point in setting the frame in that case, because translatesAutoresizingMaskIntoConstraints says “ignore my frame, use constraints instead.”
I’m assuming you’re doing all of this just to become familiar with scroll views, but it’s worth noting that, especially when adding lots of image views, that the scroll view is an inherently inefficient approach.
For example, let’s say you’ve added 100 image views, but you can see only 8 at a time. Do you really want to hold all 100 image views in memory at the same time? No.
But, UITableView, which is a subclass of UIScrollView, takes care of this. You end up only keeping the currently visible image views in memory. It’s a far better approach.
This is especially true when you start using actual UIImage objects, because they require a lot of memory. We get lulled into a sense of security, looking at reasonably sized PNG/JPG assets, but when they’re loaded into memory, they’re uncompressed and require a disproportionate amount of memory.

Can the transition from the selection UITextField press to another UITextField cause the UIView to reload in Swift?

I have the following view as soon as my app loads:
As soon as I click on the Full name text field, the keyboard shows and shifts the elements a little bit to allow the register button stays appearing.
The problem appears when I move to the second text field. It causes the view to reload entirely and place all the elements in the view to their original place which makes the key board to hide the lowest elements. which is shown in the next figure
I have searched and checked if the problem comes from the fact that the keyboard loads keyboardwillshow() and keyboardwillhide do not get called at all when this problem happens as I have verified.
Can the transition from the selection UITextField press to another UITextField cause the UIView to reload Xcode? Please not that the UIText fields are in a
import UIKit
import SendBirdSDK
class LoginController: UIViewController {
var keyboardShowing = false
let inputsContainerView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.white
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 5
view.layer.masksToBounds = true
return view
}()
lazy var loginRegisterButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor(r: 88, g: 101, b: 161)
button.setTitle("Register", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
button.addTarget(self, action: #selector(handleLoginRegister), for: .touchUpInside)
return button
}()
func handleLoginRegister() {
if loginRegisterSegmentedControl.selectedSegmentIndex == 0 {
handleLogin()
} else {
handleRegister()
}
}
func handleLogin(){
guard let userid = fullNameTextField.text, (passwordTextField.text != nil) else {
print ("Form is not valid")
return
}
SBDMain.connect(withUserId: userid, completionHandler: { (user, error) in
if error != nil {
print (error)
return
}
//successfully loggedin user
self.dismiss(animated: true, completion: nil)
})
}
let nameTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Full Name"
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
let nameSeperatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let fullNameTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Username"
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
let fullNameSeperatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let passwordTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Password"
tf.translatesAutoresizingMaskIntoConstraints = false
tf.isSecureTextEntry = true
return tf
}()
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "gameofthrones_splash")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView)))
imageView.isUserInteractionEnabled = true
return imageView
}()
lazy var loginRegisterSegmentedControl: UISegmentedControl = {
let sc = UISegmentedControl(items: ["Login", "Register"])
sc.translatesAutoresizingMaskIntoConstraints = false
sc.tintColor = UIColor.white
sc.selectedSegmentIndex = 1
sc.addTarget(self, action: #selector(handleLoginRegisterChange), for: .valueChanged)
return sc
}()
func handleLoginRegisterChange() {
if keyboardShowing == true {
view.endEditing(true)
}
/*else {
view.endEditing(false)
}*/
let title = loginRegisterSegmentedControl.titleForSegment(at: loginRegisterSegmentedControl.selectedSegmentIndex)
loginRegisterButton.setTitle(title, for: UIControlState())
// change height of inputContainerView, but how???
inputsContainerViewHeightAnchor?.constant = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 100 : 150
// change height of nameTextField
nameTextFieldHeightAnchor?.isActive = false
nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 0 : 1/3)
nameTextFieldHeightAnchor?.isActive = true
nameTextField.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0
fullNameTextFieldHeightAnchor?.isActive = false
fullNameTextFieldHeightAnchor = fullNameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/3)
fullNameTextFieldHeightAnchor?.isActive = true
passwordTextFieldHeightAnchor?.isActive = false
passwordTextFieldHeightAnchor = passwordTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/3)
passwordTextFieldHeightAnchor?.isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(r: 61, g: 91, b: 151)
view.addSubview(inputsContainerView)
view.addSubview(loginRegisterButton)
view.addSubview(profileImageView)
view.addSubview(loginRegisterSegmentedControl)
setupInputsContainerView()
setupLoginRegisterButton()
setupProfileImageView()
setupLoginRegisterSegmentedControl()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
//connecting to the application
SBDMain.initWithApplicationId("1662A8E8-F45F-454B-9E5E-02362342ECC5")
}
func keyboardWillShow(notification: NSNotification) {
print ("keyboardwillshow was called")
if self.keyboardShowing {
return
}
if self.keyboardShowing == false {
self.inputsContainerView.frame.origin.y -= 58
self.loginRegisterButton.frame.origin.y -= 58
self.loginRegisterSegmentedControl.frame.origin.y -= 58
self.profileImageView.frame.origin.y -= 58
}
self.keyboardShowing = true
}
func keyboardWillHide(notification: NSNotification) {
print ("keyboardwillhide was called")
if !self.keyboardShowing {
return
}
if self.keyboardShowing == true {
self.inputsContainerView.frame.origin.y += 58
self.loginRegisterButton.frame.origin.y += 58
self.loginRegisterSegmentedControl.frame.origin.y += 58
self.profileImageView.frame.origin.y += 58
}
self.keyboardShowing = false
}
func setupLoginRegisterSegmentedControl() {
//need x, y, width, height constraints
loginRegisterSegmentedControl.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
loginRegisterSegmentedControl.bottomAnchor.constraint(equalTo: inputsContainerView.topAnchor, constant: -12).isActive = true
loginRegisterSegmentedControl.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor, multiplier: 1).isActive = true
loginRegisterSegmentedControl.heightAnchor.constraint(equalToConstant: 36).isActive = true
}
func setupProfileImageView(){
//need x, y, width, height constraints
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageView.bottomAnchor.constraint(equalTo: loginRegisterSegmentedControl.topAnchor, constant: -12).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 150).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true
}
var inputsContainerViewHeightAnchor: NSLayoutConstraint?
var nameTextFieldHeightAnchor: NSLayoutConstraint?
var fullNameTextFieldHeightAnchor: NSLayoutConstraint?
var passwordTextFieldHeightAnchor: NSLayoutConstraint?
func setupInputsContainerView(){
//need x, y, width, height constraints
inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
print(self.inputsContainerView.frame.origin.y)
inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputsContainerViewHeightAnchor = inputsContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerViewHeightAnchor?.isActive = true
inputsContainerView.addSubview(nameTextField)
inputsContainerView.addSubview(nameSeperatorView)
inputsContainerView.addSubview(fullNameTextField)
inputsContainerView.addSubview(fullNameSeperatorView)
inputsContainerView.addSubview(passwordTextField)
//need x, y, width, height constraints
nameTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
nameTextField.topAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
nameTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)
nameTextFieldHeightAnchor?.isActive = true
//need x, y, width, height constraints
nameSeperatorView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
nameSeperatorView.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true
nameSeperatorView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
nameSeperatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true
//need x, y, width, height constraints
fullNameTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
fullNameTextField.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true
fullNameTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
fullNameTextFieldHeightAnchor = fullNameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)
fullNameTextFieldHeightAnchor?.isActive = true
//need x, y, width, height constraints
fullNameSeperatorView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
fullNameSeperatorView.topAnchor.constraint(equalTo: fullNameTextField.bottomAnchor).isActive = true
fullNameSeperatorView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
fullNameSeperatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true
//need x, y, width, height constraints
passwordTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
passwordTextField.topAnchor.constraint(equalTo: fullNameTextField.bottomAnchor).isActive = true
passwordTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
passwordTextFieldHeightAnchor = passwordTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)
passwordTextFieldHeightAnchor?.isActive = true
}
func setupLoginRegisterButton(){
//need x, y, width, height constraints
loginRegisterButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
loginRegisterButton.topAnchor.constraint(equalTo: inputsContainerView.bottomAnchor, constant: 12).isActive = true
loginRegisterButton.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
loginRegisterButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
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)
}
}
Instead of moving the elements of the UIView move the whole view frame like this:
func keyboardWillShow(notification: NSNotification) {
print ("keyboardwillshow was called")
if self.keyboardShowing {
return
}
if self.keyboardShowing == false {
/*self.inputsContainerView.frame.origin.y -= 58
self.loginRegisterButton.frame.origin.y -= 58
self.loginRegisterSegmentedControl.frame.origin.y -= 58
self.profileImageView.frame.origin.y -= 58*/
self.view.frame.origin.y -= 58
}
self.keyboardShowing = true
}
func keyboardWillHide(notification: NSNotification) {
print ("keyboardwillhide was called")
if !self.keyboardShowing {
return
}
if self.keyboardShowing == true {
/* self.inputsContainerView.frame.origin.y += 58
self.loginRegisterButton.frame.origin.y += 58
self.loginRegisterSegmentedControl.frame.origin.y += 58
self.profileImageView.frame.origin.y += 58*/
self.view.frame.origin.y += 58
}
self.keyboardShowing = false
}