Swift iOS -Push uiview down while typing inside textfield - ios

I have a textfield that I set to a height of >= 50. Underneath the textfield I have uiview that is anchored to the bottom of the textfield. Once the textfield gets past the 50 point height I want it to push the uiview down so the text continues downward. What's happening right now is it hits the bottom of itself and instead of pushing the uiview down it scrolls the text up and the uiview doesn't move.
How can i get the textfield to stop scrolling up and instead push the uiview down once the textfield goes past the 50 point height? I can use a textfield with number of lines to 0 instead but I'd rather use a textfield.
// imageView is pinned to the top of the screen
textView.topAnchor.constraint(equalTo: iamgeView.bottomAnchor, constant: 32).isActive = true
textView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8).isActive = true
textView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive = true
textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 50).isActive = true
bottomLine.topAnchor.constraint(equalTo: textView.bottomAnchor, constant: 8).isActive = true
bottomLine.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8).isActive = true
bottomLine.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive = true
bottomLine.heightAnchor.constraint(equalToConstant: 0.5).isActive = true

I had to disable scrolling on the textField
textView.isScrollEnabled = false

Related

Revert NSLayoutConstraint of UIView after changing the constraint

Currently, I am expanding a custom view inside a scrollview to
fullscreen after the user taps on it. But I want the View to come back
to the original position once the user taps on it again. Note:- I have
set the original custom view position inside the scrollview on Xib
visually, I haven't added the code programmatically to add views in
scroll view.
Here is my code to expand:-
let frameAnimator = UIViewPropertyAnimator(duration: 0.6, dampingRatio: 1) {
self.playerDescriptionView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
self.playerDescriptionView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
self.playerDescriptionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
self.playerDescriptionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
self.view.layoutIfNeeded()
}
frameAnimator.startAnimation()
So, how can I set the constraint back to the original position while minimizing the view, because I have not set the view constraint programmatically?

ios Swift tableView dynamic cells constraints for labels and image programatically

I have labels and an image. I want labels above image. And image without leading and trailing margin constraints.
I have tried the following constraints but can't seem to get it right. And the row height for the cells doesn't adjust accordingly in landscape mode.
addSubview(videolabel1)
videolabel1.translatesAutoresizingMaskIntoConstraints = false
videolabel1.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20).isActive = true
videolabel1.trailingAnchor.constraint(equalTo: trailingAnchor
, constant: 20).isActive = true
videolabel1.topAnchor.constraint(equalTo: topAnchor, constant: 20).isActive = true
videolabel1.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 20).isActive = true
addSubview(image)
image.translatesAutoresizingMaskIntoConstraints = false
image.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
image.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
image.heightAnchor.constraint(equalToConstant: 150).isActive = true
image.widthAnchor.constraint(equalTo: videoimage.heightAnchor
, multiplier: 16/9).isActive = true
image.topAnchor.constraint(equalTo: videodate.bottomAnchor, constant: 12).isActive = true
image.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 12).isActive = true
Try using UIStackView's when you want to arrange views in a horizontal or vertical fashion. The UIStackView can take care of most constraints for you.
You can try adding a parent UIStackView with vertical orientation, that contains another UIStackView with horizontal orientation (this UIStackView will contain two UILabel's), followed by the UIImageView, and another UILabel.
parentStackView = UIStackView()
parentStackView.axis = .vertical
parentStackView.distribution = .equalSpacing
parentStackView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(parentStackView)
parentStackView.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true
parentStackView.widthAnchor.constraint(equalTo: self.contentView.widthAnchor, multiplier: 1).isActive = true
parentStackView.heightAnchor.constraint(equalTo: self.contentView.heightAnchor, multiplier: 1).isActive = true
parentStackView.isLayoutMarginsRelativeArrangement = true
parentStackView.addArrangedSubview(stackView)
stackView.axis = .horizontal
stackView.distribution = .equalSpacing
stackView.spacing = 10
stackView.addArrangedSubview(label)
label.text = "First Label";
stackView.addArrangedSubview(label2)
label2.text = "Second Label";
parentStackView.addArrangedSubview(imageView);
imageView.image = UIImage(named: "imageview");
NSLayoutConstraint.activate([imageView.heightAnchor.constraint(equalToConstant:UIScreen.main.bounds.width / 2) ]);
imageView.contentMode = .scaleAspectFill;
imageView.clipsToBounds = true;
parentStackView.addArrangedSubview(label3)
label3.text = "Vertical Label below Image";
The result will look something like:
Set bottom and top anchor according to sequential view on top and bottom. Here, you are setting bottom anchor of both videolabel1 and videodate to bottom anchor which is wrong:-
set videoLabel trailing and top anchor and remove bottom anchor:-
videolabel1.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20).isActive = true
videolabel1.topAnchor.constraint(equalTo: topAnchor, constant: 20).isActive = true
set videoLabel trailing anchor as below and remove bottom anchor:-
videodate.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20).isActive = true
Also, remove bottom anchor of imagview and set bottom anchor constant as shown below:-
videotitle.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12).isActive = true

Programmatic constraints cut the bottom of my label off

I have a Nib file with a root UITableViewCell and child UILabel that I anchor at run time using programmatic constraints
lblAccountItemTitle.translatesAutoresizingMaskIntoConstraints = false
lblAccountItemTitle.topAnchor.constraint(lessThanOrEqualTo: self.topAnchor, constant: 16).isActive = true
lblAccountItemTitle.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -16).isActive = true
lblAccountItemTitle.leadingAnchor.constraint(equalTo: imgAccountItemLeft.trailingAnchor, constant: 16).isActive = true
lblAccountItemTitle.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -32).isActive = true
lblAccountItemTitle.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
Also, I've noticed that the shorter I make my bottom anchor, the less clipped the text is
How can I get rid of the clipping while still maintaining the equal 16 vertical padding?
change the both image and label bottom anchor from equalTo to lessThanOrEqualTo
lblAccountItemTitle.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -16).isActive = true
I was programmatically pinning the label to the cell and not to the Content View
self.topAnchor
should've been
self.contentView.topAnchor

Issue with constraints inside a UITableViewCell

I have a custom cell for a UITableView. I'd like the following elements inside the cell:
1) UITextView with the following constraints:
it starts at the top left corner of the cell
it goes from the left side of the cell + 10 until the right side of the cell - 10.
its bottom should be 5 points above the next element (see 2 below)
2) UIButton with the following constraints:
it is X and Y centered in the cell
it goes from the left side of the cell + 20 until the right side of
the cell - 20.
it has a height of 60
The cell itself is defined with a height of 100.
However it seems my constraints have some conflicts according to the errors I get but I don't see where. Here is my code:
// constraints for the UIButton
answerTextButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
answerTextButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20).isActive = true
answerTextButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20).isActive = true
answerTextButton.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
answerTextButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
// constraints for the UITextView
answerTextView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
answerTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10).isActive = true
answerTextView.topAnchor.constraint(equalTo: topAnchor).isActive = true
answerTextView.bottomAnchor.constraint(equalTo: answerTextButton.topAnchor, constant: -5).isActive = true
What's the conflict here?
Thanks.
EDIT : I don't believe my mistake. While you are all right that the X-center constraint is useless, it was not the issue. The issue was... that I forgot to add "answerTextView.translatesAutoresizingMaskIntoConstraints = false".
Sorry for that, never happened before! So basically all my constraints for the UITextView were messy because of that. Adding it fixed everything but I kept your recommendation by removing the X-center constraint on the UIButton.
Copy and paste. It will work
// constraints for the UIButton
answerTextButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
answerTextButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20).isActive = true
answerTextButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20).isActive = true
answerTextButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
// constraints for the UITextView
answerTextView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
answerTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10).isActive = true
answerTextView.topAnchor.constraint(equalTo: topAnchor).isActive = true
answerTextView.bottomAnchor.constraint(equalTo: answerTextButton.topAnchor, constant: -5).isActive = true

UIScrollView nested subviews not displayed using Auto Layout

I am trying to generate views displayed in a UIScrollView based on structured (XML) data at runtime. I generate all the views I need and add them to my scrollview afterwards, using Auto Layout to let the scrollview calculate its contentSize. Everything worked fine as long as I was only using UILabels and a custom UIImageView subclass, but now I want to add a nested view containing another view and a label to represent text with a vertical line on the left side.
The general layout code I'm using to add all generated views to the scrollview is as follows:
var previousAnchor = scrollView.topAnchor
views.forEach { (view) in
scrollView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
view.topAnchor.constraint(equalTo: previousAnchor,
constant: UI.defaultPadding).isActive = true
view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,
constant: UI.smallPadding).isActive = true
view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,
constant: -UI.smallPadding).isActive = true
previousAnchor = view.bottomAnchor
}
scrollView.bottomAnchor.constraint(equalTo: previousAnchor,
constant: UI.defaultPadding).isActive = true
And the layout code for my nested subview looks like this (it's a UIView subclass):
addSubview(label)
addSubview(line)
line.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
line.topAnchor.constraint(equalTo: topAnchor).isActive = true
line.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
line.widthAnchor.constraint(equalToConstant: 2).isActive = true
line.trailingAnchor.constraint(equalTo: label.leadingAnchor).isActive = true
line.backgroundColor = UIColor.green
label.topAnchor.constraint(equalTo: topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
label.numberOfLines = 0
label.text = "Here's to the crazy ones. The misfits. The rebels. The troublemakers."
If I use this code, I cannot see this view in my scrollview at all and the scrollview has a warning of ambiguous content size attached to it in the Debug View Hierarchy view. This is somewhat irritating, as using labels without being nested in a view like this does work like a charm. So I started playing around and what really puzzles me is that if I use the following code I can see the view itself (as I gave it a gray background color), but still can't see line and/or label, as both seem have a frame of (0,0,0,0) upon inspection:
addSubview(label)
addSubview(line)
line.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
line.topAnchor.constraint(equalTo: topAnchor, constant: 10).isActive = true
line.widthAnchor.constraint(equalToConstant: 20).isActive = true
line.heightAnchor.constraint(equalToConstant: 20).isActive = true
line.trailingAnchor.constraint(equalTo: label.leadingAnchor).isActive = true
line.backgroundColor = UIColor.green
label.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
heightAnchor.constraint(equalToConstant: 100).isActive = true
heightAnchor.constraint(equalTo: label.heightAnchor).isActive = true
label.numberOfLines = 0
label.text = "Here's to the crazy ones. The misfits. The rebels. The troublemakers."
What am I missing? I also tried putting all my views into a container view instead of using them as subviews of the scrollview directly, but this did not help with my nested view and brought up other problems.

Resources