So I have a pretty simple layout for a view that I have created, basically what i want it to look like after I'm done with adding constraints is as follows,
However, what I end up with is something else, and Im not sure why this behavior is happening.
So just a quick rundown of what I did in an attempt to achieve the layouts I wanted.
Center the X position of the "/" label
Set the the indexLabel that can be seen towards the left that says "1"
Constraint the "reps" label to the left of "/" label
Finally constraint the "reps field" to the right of indexLabel and left of "reps" label
private func setupDividerLabelLayout() {
addSubview(dividerLabel)
dividerLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
dividerLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
private func setupIndexLabelBackgroundLayout() {
addSubview(indexLabelBackground)
indexLabelBackground.leftAnchor.constraint(equalTo: leftAnchor, constant: 24).isActive = true
indexLabelBackground.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
indexLabelBackground.heightAnchor.constraint(equalToConstant: 24).isActive = true
indexLabelBackground.widthAnchor.constraint(equalToConstant: 24).isActive = true
}
private func setupRepsLabelLayout() {
addSubview(repsLabel)
repsLabel.rightAnchor.constraint(equalTo: dividerLabel.leftAnchor, constant: -16).isActive = true
repsLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
}
private func setupRepsFieldLayout() {
addSubview(repsField)
repsField.rightAnchor.constraint(equalTo: repsLabel.leftAnchor, constant: -8).isActive = true
repsField.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
repsField.leftAnchor.constraint(equalTo: indexLabelBackground.rightAnchor, constant: 8).isActive = true
}
In order let you anchors work you should add _ViewName_.translatesAutoresizingMaskIntoConstraints = false. so the code becomes as followsCode to Use
private func setupDividerLabelLayout() {
addSubview(dividerLabel)
dividerLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
dividerLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
dividerLabel.translatesAutoresizingMaskIntoConstraints = false
}
private func setupIndexLabelBackgroundLayout() {
addSubview(indexLabelBackground)
indexLabelBackground.leftAnchor.constraint(equalTo: leftAnchor, constant: 24).isActive = true
indexLabelBackground.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
indexLabelBackground.heightAnchor.constraint(equalToConstant: 24).isActive = true
indexLabelBackground.widthAnchor.constraint(equalToConstant: 24).isActive = true
indexLabelBackground.translatesAutoresizingMaskIntoConstraints = false
}
private func setupRepsLabelLayout() {
addSubview(repsLabel)
repsLabel.rightAnchor.constraint(equalTo: dividerLabel.leftAnchor, constant: -16).isActive = true
repsLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
repsLabel.translatesAutoresizingMaskIntoConstraints = false
}
private func setupRepsFieldLayout() {
addSubview(repsField)
repsField.rightAnchor.constraint(equalTo: repsLabel.leftAnchor, constant: -8).isActive = true
repsField.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
repsField.leftAnchor.constraint(equalTo:
indexLabelBackground.rightAnchor, constant: 8).isActive = true
repsField.translatesAutoresizingMaskIntoConstraints = false
indexLabelBackground.translatesAutoresizingMaskIntoConstraints = false
}
Related
I want to set UITableViewCell with two UILabels in the same line. For Example:
Tom Ford.
I know how to do it in hardcoded style, but how to do it depending on the length of the first name? I mean first names vary in length and I want to set the last name UILabel in the same length on the right same of the name UILabel. How to do it?
FirstName and LastName:
func setFirstnameLabel() {
firstNameLabel.translatesAutoresizingMaskIntoConstraints = false
firstNameLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
firstNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12).isActive = true
firstNameLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
firstNameLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
}
func setLastNameLabel() {
lastNameLabel.translatesAutoresizingMaskIntoConstraints = false
lastNameLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
lastNameLabel.leadingAnchor.constraint(equalTo: firstNameLabel.trailingAnchor, constant: 20).isActive = true
lastNameLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
lastNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12).isActive = true
}
I have a vertical UIScrollView, allScrollView, and a horizontal UIScrollView, hourlyScrollView, nested inside the vertical UIScrollView. In each of the scroll views I have 10 other UIViews that will show data. Each of the views are assigned a UITapGestureRecognizer. I'm able to tap the views that are only in the vertical scroll, but none of the views in the nested horizontal scroll do anything when tapped. If anyone can help me it would be greatly appreciated as I've tried a lot of suggestions on here with no luck.
my view hierarchy:
-allScrollView (vertical)
-allContentView
-hourlyScrollView (horizontal)
-hourlyContentView
-10 UIViews
-dailyContentView
-10 UIViews
viewDidLoad()
let dailyContentView = UIView()
let hourlyContentView = UIView()
let hourlyScrollView = UIScrollView()
let allContentView = UIView()
let allScrollView = UIScrollView()
override func viewDidLoad() {
super.viewDidLoad()
hourlyScrollView.translatesAutoresizingMaskIntoConstraints = false
hourlyContentView.translatesAutoresizingMaskIntoConstraints = false
allContentView.translatesAutoresizingMaskIntoConstraints = false
allScrollView.translatesAutoresizingMaskIntoConstraints = false
dailyContentView.translatesAutoresizingMaskIntoConstraints = false
layoutHourlyViews()
layoutDailyViews()
finishLayout()
}
create horizontal scroll content
func layoutHourlyViews() {
for subview in hourlyScrollView.subviews {
subview.removeFromSuperview()
}
for subView in hourlyContentView.subviews {
subView.removeFromSuperview()
}
var previousHour : UIView? = nil
for count in 1...10 {
let hourlyUIView = UIView()
hourlyUIView.backgroundColor = .blue
hourlyUIView.isUserInteractionEnabled = true
hourlyUIView.tag = count
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hourlyTap(_:)))
hourlyUIView.addGestureRecognizer(tapGesture)
let descriptionLabel = UILabel()
let borderView = UIView()
let borderViewTop = UIView()
let borderViewBottom = UIView()
borderViewTop.backgroundColor = .black
borderViewBottom.backgroundColor = .black
borderViewTop.translatesAutoresizingMaskIntoConstraints = false
borderViewBottom.translatesAutoresizingMaskIntoConstraints = false
borderView.translatesAutoresizingMaskIntoConstraints = false
hourlyUIView.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.text = "test"
borderView.backgroundColor = .black
hourlyUIView.addSubview(borderViewBottom)
hourlyUIView.addSubview(borderViewTop)
hourlyUIView.addSubview(descriptionLabel)
hourlyUIView.addSubview(borderView)
borderViewBottom.leadingAnchor.constraint(equalTo: hourlyUIView.leadingAnchor).isActive = true
borderViewBottom.trailingAnchor.constraint(equalTo: hourlyUIView.trailingAnchor).isActive = true
borderViewBottom.bottomAnchor.constraint(equalTo: hourlyUIView.bottomAnchor).isActive = true
borderViewBottom.heightAnchor.constraint(equalToConstant: 2).isActive = true
borderViewTop.leadingAnchor.constraint(equalTo: hourlyUIView.leadingAnchor).isActive = true
borderViewTop.trailingAnchor.constraint(equalTo: hourlyUIView.trailingAnchor).isActive = true
borderViewTop.topAnchor.constraint(equalTo: hourlyUIView.topAnchor).isActive = true
borderViewTop.heightAnchor.constraint(equalToConstant: 2).isActive = true
hourlyUIView.widthAnchor.constraint(equalToConstant: 160).isActive = true
hourlyUIView.heightAnchor.constraint(equalToConstant: 240).isActive = true
descriptionLabel.topAnchor.constraint(equalTo: hourlyUIView.topAnchor, constant: 16).isActive = true
descriptionLabel.centerXAnchor.constraint(equalTo: hourlyUIView.centerXAnchor, constant: 0).isActive = true
hourlyContentView.addSubview(hourlyUIView)
if previousHour == nil {
hourlyUIView.topAnchor.constraint(equalTo: hourlyContentView.topAnchor, constant: 0).isActive = true
hourlyUIView.leadingAnchor.constraint(equalTo: hourlyContentView.leadingAnchor, constant: 2).isActive = true
}
else {
hourlyUIView.topAnchor.constraint(equalTo: hourlyContentView.topAnchor, constant: 0).isActive = true
hourlyUIView.leadingAnchor.constraint(equalTo: previousHour!.trailingAnchor, constant: 0).isActive = true
borderView.bottomAnchor.constraint(equalTo: hourlyUIView.bottomAnchor).isActive = true
borderView.topAnchor.constraint(equalTo: hourlyUIView.topAnchor).isActive = true
borderView.widthAnchor.constraint(equalToConstant: 2).isActive = true
borderView.leadingAnchor.constraint(equalTo: hourlyUIView.leadingAnchor).isActive = true
}
previousHour = hourlyUIView
}
let borderViewTop = UIView()
let borderViewBottom = UIView()
borderViewTop.backgroundColor = .black
borderViewBottom.backgroundColor = .black
borderViewTop.translatesAutoresizingMaskIntoConstraints = false
borderViewBottom.translatesAutoresizingMaskIntoConstraints = false
hourlyScrollView.addSubview(hourlyContentView)
hourlyContentView.leadingAnchor.constraint(equalTo: hourlyScrollView.leadingAnchor, constant: 0).isActive = true
hourlyContentView.topAnchor.constraint(equalTo: hourlyScrollView.topAnchor, constant: 0).isActive = true
hourlyContentView.trailingAnchor.constraint(equalTo: hourlyScrollView.trailingAnchor, constant: 0).isActive = true
hourlyContentView.bottomAnchor.constraint(equalTo: hourlyScrollView.bottomAnchor, constant: 0).isActive = true
allContentView.addSubview(hourlyScrollView)
hourlyScrollView.isScrollEnabled = true
hourlyScrollView.topAnchor.constraint(equalTo: allContentView.topAnchor, constant: 20).isActive = true
hourlyScrollView.leadingAnchor.constraint(equalTo: allContentView.leadingAnchor, constant: 0).isActive = true
hourlyScrollView.trailingAnchor.constraint(equalTo: allContentView.trailingAnchor, constant: 0).isActive = true
}
create vertical scroll content
func layoutDailyViews() {
for subview in dailyContentView.subviews {
subview.removeFromSuperview()
}
var previousDay : UIView? = nil
for count in 1...10 {
let dailyUIView = UIView()
//dailyUIView.isUserInteractionEnabled = true
dailyUIView.tag = count
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dailyTap(_:)))
dailyUIView.addGestureRecognizer(tapGesture)
//hourlyUIView.frame.size = CGSize(width: 500, height: 50)
let descriptionLabel = UILabel()
dailyUIView.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.text = "daily test"
let borderView = UIView()
borderView.translatesAutoresizingMaskIntoConstraints = false
borderView.backgroundColor = .black
dailyUIView.addSubview(descriptionLabel)
dailyUIView.addSubview(borderView)
borderView.bottomAnchor.constraint(equalTo: dailyUIView.bottomAnchor).isActive = true
borderView.heightAnchor.constraint(equalToConstant: 2).isActive = true
borderView.leadingAnchor.constraint(equalTo: dailyUIView.leadingAnchor).isActive = true
borderView.trailingAnchor.constraint(equalTo: dailyUIView.trailingAnchor).isActive = true
dailyUIView.heightAnchor.constraint(equalToConstant: 100).isActive = true
descriptionLabel.leadingAnchor.constraint(equalTo: dailyUIView.leadingAnchor, constant: 16).isActive = true
descriptionLabel.centerYAnchor.constraint(equalTo: dailyUIView.centerYAnchor, constant: 0).isActive = true
dailyContentView.addSubview(dailyUIView)
if previousDay == nil {
dailyUIView.topAnchor.constraint(equalTo: dailyContentView.topAnchor, constant: 0).isActive = true
}
else {
dailyUIView.topAnchor.constraint(equalTo: previousDay!.bottomAnchor, constant: 0).isActive = true
}
dailyUIView.widthAnchor.constraint(equalToConstant: view.frame.width - 4).isActive = true
dailyUIView.centerXAnchor.constraint(equalTo: dailyContentView.centerXAnchor).isActive = true
previousDay = dailyUIView
}
allContentView.addSubview(dailyContentView)
}
func finishLayout() {
hourlyScrollView.bottomAnchor.constraint(equalTo: dailyContentView.bottomAnchor, constant: 0).isActive = true
dailyContentView.topAnchor.constraint(equalTo: allContentView.topAnchor, constant: 260).isActive = true
dailyContentView.centerXAnchor.constraint(equalTo: allContentView.centerXAnchor, constant: 0).isActive = true
dailyContentView.leadingAnchor.constraint(equalTo: allContentView.leadingAnchor).isActive = true
dailyContentView.trailingAnchor.constraint(equalTo: allContentView.trailingAnchor, constant: 0).isActive = true
dailyContentView.bottomAnchor.constraint(equalTo: allContentView.bottomAnchor).isActive = true
allScrollView.addSubview(allContentView)
allContentView.topAnchor.constraint(equalTo: allScrollView.topAnchor).isActive = true
allContentView.leadingAnchor.constraint(equalTo: allScrollView.leadingAnchor).isActive = true
allContentView.trailingAnchor.constraint(equalTo: allScrollView.trailingAnchor).isActive = true
allContentView.bottomAnchor.constraint(equalTo: allScrollView.bottomAnchor).isActive = true
allContentView.centerXAnchor.constraint(equalTo: allScrollView.centerXAnchor).isActive = true
allContentView.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
allContentView.heightAnchor.constraint(equalToConstant: 1500).isActive = true
view.addSubview(allScrollView)
allScrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
allScrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
allScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
allScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
tapped functions
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
hourlyScrollView.contentSize = CGSize(width:160 * 10 + 2, height:240)
allScrollView.contentSize = CGSize(width: view.frame.width, height:1500)
}
#objc func hourlyTap(_ sender: UITapGestureRecognizer) {
let tappedView = sender.view
print("hourly: \(tappedView!.tag)")
}
#objc func dailyTap(_ sender: UITapGestureRecognizer) {
let tappedView = sender.view
print("daily: \(tappedView!.tag)")
}
You haven't set all the required constraints on your hourlyContentView so the horizontal scrollView's size is (0,0) and as such it can't be scrolled or tapped. You can use Debug View Hierarchy in Xcode to see this.
The constraints you need to add are:
Between your last hourlyUIView's trailingAnchor and hourlyContentView's trailing anchor:
...
previousHour = hourlyUIView
}
previousHour?.trailingAnchor.constraint(equalTo: hourlyContentView.trailingAnchor).isActive = true
let borderViewTop = UIView()
let borderViewBottom = UIView()
...
Setting your hourlyContentView heightAnchor equal to the hourlyScrollView height anchor:
hourlyContentView.heightAnchor.constraint(equalTo: hourlyScrollView.heightAnchor).isActive = true
UPDATE AT THE BOTTOM
Inside my ViewController I have a TableView with CustomCells. The content being presented in those cells is depending on the userInput. I think the best way to explain the problem is to actually show it:
1. adding cells to the tableView:
looking as expected
2. Problem: after dismissing the ViewController and going back to it:
showing views that should actually be hidden in the first cell
By the way, when I open the View-Hirarchy in the Debugger, it is being displayed correctly !
Here is also another video for a better understanding: video
In this case I didn't add an image, but when going back to the viewController it still shows the imageContainerView(shadow) and also the content for the first cell.
Code:
My code is quite complex and messy so I you can follow me here:
setupViews in CustomCell:
I don't think that this is quite helpful, but I also don't think that the setup is the issue here.
func setupViews(){
contentView.addSubview(checkButton)
contentView.addSubview(mainStackView)
// main StackView
mainStackView.addArrangedSubview(label)
mainStackView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
mainStackView.leadingAnchor.constraint(equalTo: checkButton.trailingAnchor, constant: 15).isActive = true
mainStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -30).isActive = true
mainStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
//constrain wish label
labelHeightConatraint = label.heightAnchor.constraint(equalToConstant: 50)
labelHeightConatraint.priority = .defaultHigh
labelHeightConatraint.isActive = true
// constrain checkButton
checkButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 30).isActive = true
checkButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
checkButton.widthAnchor.constraint(equalToConstant: 40).isActive = true
checkButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
mainStackView.addArrangedSubview(secondaryStackView)
secondaryStackViewHeightConstraint = secondaryStackView.heightAnchor.constraint(equalToConstant: 90)
secondaryStackViewHeightConstraint.priority = .defaultHigh
secondaryStackViewHeightConstraint.isActive = true
secondaryStackView.addArrangedSubview(imageContainerView)
imageContainerWidthConstraint = imageContainerView.widthAnchor.constraint(equalToConstant: 90)
imageContainerWidthConstraint.priority = .defaultHigh
imageContainerWidthConstraint.isActive = true
imageContainerView.addSubview(shadowLayer)
shadowLayer.widthAnchor.constraint(equalToConstant: 80).isActive = true
shadowLayer.heightAnchor.constraint(equalToConstant: 80).isActive = true
shadowLayer.topAnchor.constraint(equalTo: imageContainerView.topAnchor).isActive = true
shadowLayer.trailingAnchor.constraint(equalTo: imageContainerView.trailingAnchor, constant: -10).isActive = true
imageContainerView.addSubview(wishImage)
wishImage.widthAnchor.constraint(equalToConstant: 80).isActive = true
wishImage.heightAnchor.constraint(equalToConstant: 80).isActive = true
wishImage.topAnchor.constraint(equalTo: imageContainerView.topAnchor).isActive = true
wishImage.trailingAnchor.constraint(equalTo: imageContainerView.trailingAnchor, constant: -10).isActive = true
secondaryStackView.addArrangedSubview(thirdHelperView)
thirdHelperView.addSubview(thirdStackView)
thirdHelperViewHeightConstraint = thirdHelperView.heightAnchor.constraint(equalToConstant: 90)
thirdHelperViewHeightConstraint.priority = .defaultHigh
thirdHelperViewHeightConstraint.isActive = true
thirdStackView.addArrangedSubview(priceView)
priceView.heightAnchor.constraint(equalToConstant: 30).isActive = true
priceView.addSubview(priceImage)
priceView.addSubview(priceLabel)
thirdStackView.addArrangedSubview(linkView)
linkView.heightAnchor.constraint(equalToConstant: 30).isActive = true
linkView.addSubview(linkImage)
linkView.addSubview(linkTextView)
thirdStackView.addArrangedSubview(noteView)
noteView.heightAnchor.constraint(equalToConstant: 30).isActive = true
noteView.addSubview(noteImage)
noteView.addSubview(noteLabel)
priceImage.topAnchor.constraint(equalTo: priceView.topAnchor).isActive = true
priceImage.leadingAnchor.constraint(equalTo: thirdStackView.leadingAnchor).isActive = true
priceImage.heightAnchor.constraint(equalToConstant: 20).isActive = true
priceImage.widthAnchor.constraint(equalToConstant: 20).isActive = true
priceLabel.topAnchor.constraint(equalTo: priceView.topAnchor).isActive = true
priceLabel.leadingAnchor.constraint(equalTo: priceImage.trailingAnchor, constant: 10).isActive = true
priceLabel.trailingAnchor.constraint(equalTo: priceView.trailingAnchor, constant: -10).isActive = true
linkImage.topAnchor.constraint(equalTo: linkView.topAnchor).isActive = true
linkImage.leadingAnchor.constraint(equalTo: thirdStackView.leadingAnchor).isActive = true
linkImage.heightAnchor.constraint(equalToConstant: 20).isActive = true
linkImage.widthAnchor.constraint(equalToConstant: 20).isActive = true
linkTextView.topAnchor.constraint(equalTo: linkView.topAnchor).isActive = true
linkTextView.leadingAnchor.constraint(equalTo: linkImage.trailingAnchor, constant: 10).isActive = true
linkTextView.trailingAnchor.constraint(equalTo: linkView.trailingAnchor, constant: -10).isActive = true
noteImage.topAnchor.constraint(equalTo: noteView.topAnchor).isActive = true
noteImage.leadingAnchor.constraint(equalTo: thirdStackView.leadingAnchor).isActive = true
noteImage.heightAnchor.constraint(equalToConstant: 20).isActive = true
noteImage.widthAnchor.constraint(equalToConstant: 20).isActive = true
noteLabel.topAnchor.constraint(equalTo: noteView.topAnchor).isActive = true
noteLabel.leadingAnchor.constraint(equalTo: noteImage.trailingAnchor, constant: 10).isActive = true
noteLabel.trailingAnchor.constraint(equalTo: noteView.trailingAnchor, constant: -10).isActive = true
}
more importantly: cellForRowAt, where I actually hide/show the different views depending on the content. As you can see I actually call .isHidden on the ImageContainerView, priceView, linkView & noteView , if there content is empty ( which it is in the first cell )
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: WhishCell.reuseID, for: indexPath) as! WhishCell
cell.label.text = ""
cell.linkTextView.text = ""
cell.priceLabel.text = ""
cell.noteLabel.text = ""
cell.wishImage.image = UIImage()
let currentWish = self.wishData[indexPath.row]
cell.label.text = currentWish.name
cell.linkTextView.hyperLink(originalText: "Link öffnen", hyperLink: "Link öffnen", urlString: currentWish.link)
cell.priceLabel.text = currentWish.price
cell.noteLabel.text = currentWish.note
cell.wishImage.image = currentWish.image
cell.setupSuccessAnimation()
cell.noteView.isHidden = false
cell.priceView.isHidden = false
cell.linkView.isHidden = false
cell.imageContainerView.isHidden = false
cell.secondaryStackViewHeightConstraint.constant = 0
cell.thirdHelperViewHeightConstraint.constant = 0
if currentWish.image == nil || !currentWish.image!.hasContent {
cell.imageContainerView.isHidden = true
print("but its truue: \(cell.imageContainerView.isHidden)")
if currentWish.price != "" {
cell.thirdHelperViewHeightConstraint.constant += 30
cell.secondaryStackViewHeightConstraint.constant += 30
}
if currentWish.link != "" {
cell.thirdHelperViewHeightConstraint.constant += 30
cell.secondaryStackViewHeightConstraint.constant += 30
}
if currentWish.note != "" {
cell.thirdHelperViewHeightConstraint.constant += 30
cell.secondaryStackViewHeightConstraint.constant += 30
}
} else {
cell.secondaryStackViewHeightConstraint.constant = 90
cell.thirdHelperViewHeightConstraint.constant = 90
}
if currentWish.price == "" {
cell.priceView.isHidden = true
}
if currentWish.link == "" {
cell.linkView.isHidden = true
}
if currentWish.note == "" {
cell.noteView.isHidden = true
}
return cell
}
I have no idea why this happens. I don't think something is wrong with the setup as it works if I actually add the cells. It is simply not hiding the views when it actually should. The cellheight is also working as expected. Just the damn hiding...
I know this is a lot but I hope my problem is clear. If you need any thing more just let me know!
Update:
I added two print-statements inside cellForRowAt and is actually printing this:
print("but its truue: \(cell.imageContainerView.isHidden)")
print("but its truue: \(cell.shadowLayer.isHidden)")
but its truue: true
but its truue: false
so it is hiding the imageConatinerView correctly but not shadowLayer even though shadowLayer is a subView of imageContainerView??! Im stuck here...
You can use UIView debugging method to debug your UI.
There are four useful methods to debug:
hasAmbiguousLayout:
exerciseAmbiguityInLayout:
exerciseAmbiguityInLayout:
_autolayoutTrace:
And then you can use Xcode UI Debug to review your UI
what i am trying to do is simple. let me explain what i have first, in the mainviewcontroller i have 3 main view at the beginning navbar, content,and bottombtn. i have a sidebar btn that then trigger a function in the mainviewcontroller, each function is suppose to remove the middle view (the content) and then place a new subview to take the content place.
the problem: it work at first the function delete contentTxt and replace it with one of the new view example: connectView, but the problem is when i try to trigger another function let say addAchievementView() it will not delete connectView and then add achievementview instead it let add achievementview below the connect View
my Goal: is for the function to delete the previous view(whichever view that is taking the contentplace) and then adding a new view. is there a way to get around this? or is there a better way to do this?
here is the mainViewController code:
class mainViewController: UIViewController {
let navbar:navbarView = {
let content = navbarView()
return content
}()
let contentTxt:UITextView = {
let content = UITextView()
content.backgroundColor = UIColor.green
content.font = UIFont(name: "copperplate", size: 20)
return content
}()
let bottomBtn:UIButton = {
let content = UIButton()
content.backgroundColor = UIColor.blue
return content
}()
override func viewDidLoad() {
super.viewDidLoad()
navbar.translatesAutoresizingMaskIntoConstraints = false
contentTxt.translatesAutoresizingMaskIntoConstraints = false
bottomBtn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(navbar)
view.addSubview(contentTxt)
view.addSubview(bottomBtn)
navbar.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
navbar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
navbar.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
navbar.heightAnchor.constraint(equalToConstant: 50).isActive = true
contentTxt.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
contentTxt.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
contentTxt.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
contentTxt.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
bottomBtn.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant:-10).isActive = true
bottomBtn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
bottomBtn.widthAnchor.constraint(equalToConstant: 70).isActive = true
bottomBtn.heightAnchor.constraint(equalToConstant: 70).isActive = true
}
#objc func addConnectView(){
print("addConnectView")
self.contentTxt.removeFromSuperview()
let connect:connectView = {
let content = connectView()
content.backgroundColor = UIColor.red
return content
}()
connect.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(connect)
self.view.sendSubview(toBack: connect)
connect.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
connect.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
connect.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
connect.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addTemplateView(){
print("addTemplateView")
self.contentTxt.removeFromSuperview()
let content:templateView = {
let content = templateView()
content.backgroundColor = UIColor.blue
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addSettingView(){
print("addSettingView")
self.contentTxt.removeFromSuperview()
let content:settingView = {
let content = settingView()
content.backgroundColor = UIColor.green
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addAchievementView(){
print("addAchievementView")
self.contentTxt.removeFromSuperview()
let content:achievementView = {
let content = achievementView()
content.backgroundColor = UIColor.gray
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addCommandView(){
print("addCommandView")
self.contentTxt.removeFromSuperview()
let content:commandView = {
let content = commandView()
content.backgroundColor = UIColor.cyan
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addListView(){
print("addListView")
self.contentTxt.removeFromSuperview()
let content:commandView = {
let content = commandView()
content.backgroundColor = UIColor.red
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func addNavbarView(){
print("addNavbarView")
self.contentTxt.removeFromSuperview()
let content:navbarListView = {
let content = navbarListView()
content.backgroundColor = UIColor.red
return content
}()
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
self.view.sendSubview(toBack: content)
content.topAnchor.constraint(equalTo: navbar.bottomAnchor, constant: 5).isActive = true
content.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
content.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
content.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
#objc func sideController(){
let next = self.storyboard?.instantiateViewController(withIdentifier: "sideViewController") as! sideViewController
self.present(next, animated: true, completion: nil)
}
#objc func profileController(){
let next = self.storyboard?.instantiateViewController(withIdentifier: "profileViewController") as! profileViewController
self.present(next, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Before add any view make sure to remove all other , as you don't know what is currently displayed so
self.contentTxt.removeFromSuperview()
self.content.removeFromSuperview() //
self.content.removeFromSuperview() // for settings
Also this line is the problem
self.view.sendSubview(toBack: content)
as by default the added view is placed above all childs of the parentView
I vote for creating placeHolderView and remove it's subviews before any addition , this will prevent headache of knowing which one is currently displayed , or you may give a tag to any added view and do this before any new addition
self.view.subviews.forEach { if $0.tag == 11 {
$0.removeFromSuperview()
}}
I am using this code to create a UITextView that is suppose to fit within a UIView container:
// Make the cellTextView.
let cellTextView = UITextView()
cellTextView.backgroundColor = UIColor.clearColor()
cellTextView.translatesAutoresizingMaskIntoConstraints = false
cellTextView.scrollEnabled = false
superview.addSubview(cellTextView)
// Constrain the cellTextView.
cellTextView.topAnchor.constraintEqualToAnchor(superview.topAnchor, constant: 8).active = true
cellTextView.bottomAnchor.constraintEqualToAnchor(superview.bottomAnchor, constant: -8).active = true
cellTextView.leadingAnchor.constraintEqualToAnchor(superview.leadingAnchor, constant: 8).active = true
cellTextView.trailingAnchor.constraintEqualToAnchor(superview.trailingAnchor, constant: -8).active = true
But it is producing this result:
This is what it should look like:
I have tried a lot of different things, but nothing fixes it.
Any suggestions will be greatly appreciated.
Just get rid of the constants that you're using as margins. That will fix it.
// Make the cellTextView.
let cellTextView = UITextView()
cellTextView.backgroundColor = UIColor.clearColor()
cellTextView.translatesAutoresizingMaskIntoConstraints = false
cellTextView.scrollEnabled = false
superview.addSubview(cellTextView)
// Constrain the cellTextView.
cellTextView.topAnchor.constraintEqualToAnchor(superview.topAnchor).active = true
cellTextView.bottomAnchor.constraintEqualToAnchor(superview.bottomAnchor).active = true
cellTextView.leadingAnchor.constraintEqualToAnchor(superview.leadingAnchor).active = true
cellTextView.trailingAnchor.constraintEqualToAnchor(superview.trailingAnchor).active = true
I think you have to set height constraint
// Constrain the cellTextView.
cellTextView.topAnchor.constraintEqualToAnchor(superview.topAnchor, constant: 0).active = true
cellTextView.bottomAnchor.constraintEqualToAnchor(superview.bottomAnchor, constant: 0).active = true
cellTextView.leadingAnchor.constraintEqualToAnchor(superview.leadingAnchor, constant: 0).active = true
cellTextView.trailingAnchor.constraintEqualToAnchor(superview.trailingAnchor, constant: 0).active = true
cellTextView.sizeToFit()
cellTextView.heightAnchor.constraintEqualToConstant(self.cellTextView.contentSize.height).active = true
also you may try to call
self.view.setNeedsLayout()
self.view.layoutIfNeeded()