Collapsed large title navigation bar becomes expanded after back navigation to root view controller - swift

I have UIViewController with vertical UIScrollView that has UIView as a container for all it's subviews. Here are my scrollView & contentView constraints:
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.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
When I scroll down my navigation bar gets smaller as it should be:
Then I click on tableviewcell, navigate to detailVC and back. That's where the problem comes in. Somehow my navigation bar gets big until I scroll it in any direction, and then it jumps to it's normal state. Why is that happening and what could be the reason?
Here is the gist with my ViewController code
Thanks!

I configured my constraints and fixed that issue.
New constraints:
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// contentView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = would be true if horizontal
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

Related

How to set specific width to stackview child, swift?

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

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