Swift ImagePicker Throws SIGNAL SIGABRT on AutoLayout Constraints - swift

I'm building a project in Swift5 and I need the user to upload a photo. I have it to the point where the user can open the ImagePicker and select a photo, but whenever they select the image and return to the original VC, I get a SIGNAL SIGABRT error (at bottom of post):
Here is where I add my constraints programatically:
func setupLayout(){
imgView.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imgView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
imgView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
imgView.heightAnchor.constraint(equalToConstant: 125).isActive = true
topLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
topLabel.topAnchor.constraint(equalTo: imgView.bottomAnchor, constant: 60).isActive = true
topLabel.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -50).isActive = true
topLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
topLabel.adjustsFontSizeToFitWidth = true
inputBox.topAnchor.constraint(equalTo: topLabel.bottomAnchor, constant: 30).isActive = true
inputBox.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
inputBox.heightAnchor.constraint(equalToConstant: 50).isActive = true
inputBox.widthAnchor.constraint(equalToConstant: 250).isActive = true
btn.topAnchor.constraint(equalTo: inputBox.bottomAnchor, constant: 40).isActive = true
btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
let navBarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
navBarImageView.contentMode = .scaleAspectFit
let navBarImage = UIImage(named: "bzaLogo")
navBarImageView.image = navBarImage
self.navigationController?.navigationItem.titleView = navBarImageView
}
And where I set the image back on the imageView:
func didSelect(image: UIImage?) {
self.imgView.image = image
self.global.uploadFile(imageView: self.uploadIcon.imageView!)
}
And where I add the subviews:
override func viewDidLoad() {
super.viewDidLoad()
currentState = 0
imgView.translatesAutoresizingMaskIntoConstraints = false
topLabel.translatesAutoresizingMaskIntoConstraints = false
inputBox.translatesAutoresizingMaskIntoConstraints = false
btn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imgView)
view.addSubview(topLabel)
view.addSubview(inputBox)
view.addSubview(btn)
inputBox.addTarget(self, action: #selector(inputBoxClicked(textField:)), for: .touchDown)
imagePicker = ImagePicker(presentationController: self, delegate: self)
viewModel.state = currentState
inputBox.delegate = self
setupLayout()
}
And here is the error getting thrown:
2019-06-12 13:22:16.635903-0600 bZa[39792:1836482] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors and because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'

Currently the problem is that you add constraints between views who has no comment ancestor so verify that you add
view.addSubview(imgView)
view.addSubview(topLabel)
view.addSubview(inputBox)
view.addSubview(btn)
Also don't forget
imgView.translatesAutoresizingMaskIntoConstraints = false
topLabel.translatesAutoresizingMaskIntoConstraints = false
inputBox.translatesAutoresizingMaskIntoConstraints = false
btn.translatesAutoresizingMaskIntoConstraints = false

Related

Scrollview not scrolling / Trying to add view to bottom of content

So I've added a scrollview to my view controller programmatically and added some views.
func setupScrollView() {
view.addSubview(scrollView)
scrollView.addSubview(contentView)
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
scrollView.contentSize = contentView.frame.size
}
func addUserAndFollowView(id: String) {
userAndFollow = UserPfAndFollow(id: id)
if let userAndFollow = userAndFollow {
userAndFollow.view.isUserInteractionEnabled = true
contentView.addSubview(userAndFollow.view)
self.contentView.bringSubviewToFront(userAndFollow.view)
userAndFollow.view.translatesAutoresizingMaskIntoConstraints = false
userAndFollow.view.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
userAndFollow.view.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true
userAndFollow.view.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
}
func setImageViewConstraints() {
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.heightAnchor.constraint(equalToConstant: 300).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 300).isActive = true
imageView.centerXAnchor.constraint(equalTo: self.contentView.centerXAnchor).isActive = true
if let userAndFollow = userAndFollow?.view {
imageView.topAnchor.constraint(equalTo: userAndFollow.bottomAnchor, constant: 5).isActive = true
}
}
func addLabelConstraints() {
self.albumTitle?.translatesAutoresizingMaskIntoConstraints = false
self.albumDescription?.translatesAutoresizingMaskIntoConstraints = false
albumTitle?.numberOfLines = 2
albumDescription?.numberOfLines = 3
albumDescription?.adjustsFontSizeToFitWidth = false
albumTitle?.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 14).isActive = true
albumTitle?.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10).isActive = true
albumTitle?.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true
albumTitle?.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10).isActive = true
albumDescription?.lineBreakMode = .byTruncatingTail
albumDescription?.topAnchor.constraint(equalTo: albumTitle!.bottomAnchor, constant: 9).isActive = true
albumDescription?.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10).isActive = true
albumDescription?.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true
}
All these views show up the way I want them to with the scrollview not scrolling but when I add this next view (which is a tableview in a view controller) at the bottom of the rest of my views it doesn't show up. Possibly why the scrollview isn't scrolling.
func addViewController() {
if let viewController = viewController {
contentView.addSubview(viewController.view)
setVCConstraints()
}
}
func setVCConstraints() {
viewController?.view.translatesAutoresizingMaskIntoConstraints = false
viewController?.view.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
viewController?.view.topAnchor.constraint(equalTo: albumDescription!.bottomAnchor, constant: 7).isActive = true
viewController?.view.widthAnchor.constraint(equalTo: self.contentView.widthAnchor).isActive = true
}
What can I do to make this view appear and have my scrollview scroll all the way down this view controller and it's array content and no more or less?
Before you add the view, you have
contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
scrollView.contentSize = contentView.frame.size
So, of course, the contentView has a size of the scrollView and thus will not scroll. It is the same size.
After you add the view, you have
viewController?.view.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
viewController?.view.topAnchor.constraint(equalTo: albumDescription!.bottomAnchor, constant: 7).isActive = true
viewController?.view.widthAnchor.constraint(equalTo: self.contentView.widthAnchor).isActive = true
Note, above, that you define a top bottom and width -- there is no LEFT-TO-RIGHT indication where the viewController.view should start on the horizontal path. This can result in some VERY weird behaviors.
Yet, you STILL don't modify the contentView.contentSize to be any bigger than the scrollView size.
To make something scroll, you need the contentView.contentSize to be bigger than the frame.size.

UIStackView with custom size elements and item in the center - Swift - Programmatically

I want to set a UIStackView with 3 views to the bottom of my so that the centre view is positioned in the centre and the other views are adjusted accordingly, I want also to be able to set the width and height anchors for all 3 views.
This is the desired outcome:
This is what I'm getting:
This is the code I'm using:
bottomStackView = UIStackView(arrangedSubviews: [pickerView, downloadContentButton, shareButton])
bottomStackView.alignment = .center
bottomStackView.distribution = .fill
bottomStackView.axis = .horizontal
bottomStackView.spacing = 5
bottomStackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(bottomStackView)
bottomStackView.anchor(top: nil, leading: view.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: view.trailingAnchor)
bottomStackView.heightAnchor.constraint(equalToConstant: 150).isActive = true
bottomStackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
pickerView.heightAnchor.constraint(equalToConstant: 120).isActive = true
shareButton.heightAnchor.constraint(equalToConstant: 150).isActive = true
shareButton.widthAnchor.constraint(equalTo: pickerView.widthAnchor).isActive = true
downloadContentButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
downloadContentButton.widthAnchor.constraint(equalToConstant: 30).isActive = true
shareButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
shareButton.heightAnchor.constraint(equalToConstant: 80).isActive = true
I think you are after this kind of thing:
Or, if we get wider:
If that's the idea, then one key mistake is when you say:
bottomStackView.distribution = .fill
You actually want .equalDistribution. To demonstrate, I created the example entirely in code, so you can see all the settings:
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(sv)
sv.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
sv.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
sv.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20).isActive = true
sv.heightAnchor.constraint(equalToConstant: 160).isActive = true
sv.distribution = .equalSpacing
sv.alignment = .center
let v1 = UIView()
v1.translatesAutoresizingMaskIntoConstraints = false
v1.widthAnchor.constraint(equalToConstant: 120).isActive = true
v1.heightAnchor.constraint(equalToConstant: 150).isActive = true
v1.backgroundColor = .red
sv.addArrangedSubview(v1)
let v2 = UIView()
v2.translatesAutoresizingMaskIntoConstraints = false
v2.widthAnchor.constraint(equalToConstant: 80).isActive = true
v2.heightAnchor.constraint(equalToConstant: 80).isActive = true
v2.backgroundColor = .yellow
sv.addArrangedSubview(v2)
let v3 = UIView()
v3.translatesAutoresizingMaskIntoConstraints = false
v3.widthAnchor.constraint(equalToConstant: 120).isActive = true
v3.heightAnchor.constraint(equalToConstant: 150).isActive = true
v3.backgroundColor = .blue
sv.addArrangedSubview(v3)

Adding Image to view in swift

I am trying to add an image to a subview. but whenever I run a simulation I cant see the image while I have label that shows up on the same view
let View:UIView = UIView()
let CheckImageView:UIImageView = UIImageView(image: UIImage(named: "Checked 1"))
view.addSubview(View)
View.backgroundColor = .white
View.translatesAutoresizingMaskIntoConstraints = false
View.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor,constant: -20).isActive = true
View.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
View.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: 0).isActive = true
View.heightAnchor.constraint(equalToConstant: 200).isActive = true
View.layer.cornerRadius = 25
View.layer.shadowOpacity = 0.15
View.layer.shadowRadius = 20
View.layer.shadowOffset = .zero
View.layer.shadowColor = UIColor.black.cgColor
View.addSubview(CheckImageView)
CheckImageView.translatesAutoresizingMaskIntoConstraints = false
CheckImageView.heightAnchor.constraint(equalTo: CheckImageView.widthAnchor).isActive = true
CheckImageView.topAnchor.constraint(equalTo: View.topAnchor, constant: 30).isActive = true
CheckImageView.centerXAnchor.constraint(equalTo: View.centerXAnchor).isActive = true
CheckImageView.widthAnchor.constraint(equalToConstant: 50).isActive = true
It seems like your image size is smaller than expected.
Try to change your image width Anchor
CheckImageView.widthAnchor.constraint(equalToConstant: 100).isActive = true

UITextField inside UIScrollView freeze the app when click on the textfield to edit

swifters!
I am trying to add a many textfields inside a scrollview , and its working fine and the scrollview is scrolling just fine, but when I click on the any textfield to type any text he app freezing.
and I got this message on debug area XPC connection interrupted
can anyone help me!
here is my code for creating the scrollview and for the dynamic textfields
func setupScrollView() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(scrollView)
scrollView.addSubview(contentView)
scrollView.centerXAnchor.constraint(equalTo: container.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor , multiplier: 0.75).isActive = true
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
}
this is how I am adding the textfields :
let questionContainer = UIView()
questionContainer.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(questionContainer)
if latestView == nil {
questionContainer.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
}
else {
questionContainer.topAnchor.constraint(equalTo: latestView!.bottomAnchor, constant: 32).isActive = true
}
questionContainer.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
questionContainer.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true
questionContainer.heightAnchor.constraint(equalToConstant: 100).isActive = true
questionContainer.backgroundColor = .red
let question = UITextField()
question.translatesAutoresizingMaskIntoConstraints = false
questionContainer.addSubview(question)
question.text = "Test Test Test"
question.topAnchor.constraint(equalTo: questionContainer.topAnchor, constant: 8).isActive = true
question.trailingAnchor.constraint(equalTo: questionContainer.trailingAnchor, constant: -8).isActive = true
question.bottomAnchor.constraint(equalTo: questionContainer.bottomAnchor, constant: -8).isActive = true
question.leadingAnchor.constraint(equalTo: questionContainer.leadingAnchor, constant: 8).isActive = true

Button is showing on screen but textField is not appearing every time. what is the error in my code?

I am setting textfied and a button programmatically. The button is showing when we run the code but not textfield. is there any problem with constraints or any other please help.
let submitButton: UIButton = {
let btn = UIButton(type:.system)
btn.backgroundColor = .blue
btn.setTitle("Login", for: .normal)
btn.tintColor = .white
btn.layer.cornerRadius = 5
btn.clipsToBounds = true
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
let textBox: UITextView = {
let textView = UITextView()
textView.text = "we are learning iOs"
textView.font = UIFont.boldSystemFont(ofSize: 18)
textView.textAlignment = .center
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textBox)
setupTexBoxLayout()
view.addSubview(submitButton)
setupSubmitBUttonLayout()
}
private func setupTexBoxLayout(){
textBox.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
textBox.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
textBox.widthAnchor.constraint(equalToConstant: 100).isActive = true
}
private func setupSubmitBUttonLayout(){
submitButton.topAnchor.constraint(equalTo: textBox.bottomAnchor, constant: 100).isActive = true
submitButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 100).isActive = true
}
}
I have checked your code and debug it.
You have not specified height for textview so it is not showing it.
You can check the below code. I have added height constraint to it and it is displaying your textfield.
If you do not specify a height for textfield then it will take 0 height by default.
private func setupTexBoxLayout(){
textBox.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
textBox.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
textBox.widthAnchor.constraint(equalToConstant: 300).isActive = true
textBox.heightAnchor.constraint(equalToConstant: 40).isActive = true
}