I am using a horizontal UICollectionView. Each cell of it has assigned an image, the problem is that when I scroll the collectionView, the images are overlapping so they get new placed over the old right image of another cell, below you can see what I mean. Can someone tell what the problem is? Thanks in advance!
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "category", for: indexPath) as! CategoryCell
cell.setUpView(txt: categories[indexPath.row], image: symbols[indexPath.row]!)
return cell
}
Here is my setUp() function for the CategoryCell:
func setUpView(txt: String, image: UIImage) {
view.backgroundColor = CustomColor.soft_pink
view.layer.cornerRadius = 15
view.translatesAutoresizingMaskIntoConstraints = false
view.widthAnchor.constraint(equalToConstant: 140).isActive = true
view.heightAnchor.constraint(equalToConstant: 168).isActive = true
//Label
view.addSubview(label)
label.text = txt
label.font = UIFont(name: "DamascusBold", size: 15)
label.textColor = .white
label.textAlignment = .center
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10).isActive = true
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
label.widthAnchor.constraint(equalToConstant: 130).isActive = true
label.heightAnchor.constraint(equalToConstant: 50).isActive = true
let symbolView = UIImageView(image: image)
view.addSubview(symbolView)
symbolView.tintColor = .white
symbolView.contentMode = .scaleAspectFit
symbolView.translatesAutoresizingMaskIntoConstraints = false
symbolView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
symbolView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
symbolView.widthAnchor.constraint(equalToConstant: 70).isActive = true
symbolView.heightAnchor.constraint(equalToConstant: 80).isActive = true
}
Images in Cells overlapping
Related
Continuing to solve the task of UITableViewCell, almost everything is working correctly except the last header view which shows the cell contents in retracted mode as showed in green marked. This way allows a quick access to button tapped action.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = DetailViewCell(style: .default, reuseIdentifier: nil)
let vStackView = UIStackView()
vStackView.axis = .vertical
vStackView.backgroundColor = .white
vStackView.distribution = .fillEqually
vStackView.spacing = 12
vStackView.alignment = .top
var hStackView = UIStackView()
let data = sections[indexPath.section].data
for (index, item) in data.enumerated() {
let btn = UIButton()
btn.setTitle(item.title, for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 12)
btn.setTitleColor(.black, for: .normal)
btn.backgroundColor = UIColor(red: 220, green: 220, blue: 220)
btn.layer.cornerRadius = 15
btn.addTarget(self, action: #selector(btnTapped(_:)), for: .touchUpInside)
btn.accessibilityIdentifier = item.description
hStackView.addArrangedSubview(btn)
if index % 2 == 0 {
hStackView = UIStackView()
hStackView.axis = .horizontal
hStackView.spacing = 12
hStackView.alignment = .fill
hStackView.backgroundColor = .white
hStackView.distribution = .fillEqually
hStackView.addArrangedSubview(btn)
if (index + 1) == data.count {
vStackView.addArrangedSubview(hStackView)
hStackView.leadingAnchor.constraint(equalTo: vStackView.leadingAnchor).isActive = true
hStackView.widthAnchor.constraint(equalTo: vStackView.widthAnchor, multiplier: 0.5).isActive = true
}
}
else {
hStackView.addArrangedSubview(btn)
vStackView.addArrangedSubview(hStackView)
hStackView.leadingAnchor.constraint(equalTo: vStackView.leadingAnchor).isActive = true
hStackView.trailingAnchor.constraint(equalTo: vStackView.trailingAnchor).isActive = true
}
}
// Add the stack view to the cell's contentView
cell.contentView.addSubview(vStackView)
vStackView.translatesAutoresizingMaskIntoConstraints = false
vStackView.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 8).isActive = true
vStackView.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 8).isActive = true
vStackView.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: -8).isActive = true
vStackView.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: -8).isActive = true
return cell
}
my CollectionView's items do not scroll, when I scroll down the first items stay at their place, without any change, you can see what I mean on the image: collectionview
Here is the code of the collectionView:
func setUpCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 15, bottom: 20, right: 15)
layout.itemSize = CGSize(width: 100, height: 100)
myCollectionView = UICollectionView(frame: self.contentView.frame, collectionViewLayout: layout)
myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
myCollectionView?.backgroundColor = UIColor.clear
myCollectionView?.allowsSelection = true
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
contentView.addSubview(myCollectionView ?? UICollectionView())
myCollectionView?.register(SpendingCell.self, forCellWithReuseIdentifier: "Spending")
myCollectionView?.translatesAutoresizingMaskIntoConstraints = false
myCollectionView?.topAnchor.constraint(equalTo: contentView.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
myCollectionView?.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true
myCollectionView?.heightAnchor.constraint(equalToConstant: 350).isActive = true
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Spending", for: indexPath) as! SpendingCell
cell.setUpSpending(cost: categories[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 23
}
and the collectionView cell:
class SpendingCell: UICollectionViewCell {
let stackView = UIStackView()
let SpendingButton = UIImageView()
let nameLabel = UILabel()
let sumLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(stackView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setUpSpending(cost: Spending) {
stackView.alignment = .center
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.spacing = 5
stackView.addArrangedSubview(SpendingButton)
stackView.addArrangedSubview(nameLabel)
//Constraints
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalToConstant: 100).isActive = true
stackView.heightAnchor.constraint(equalToConstant: 100).isActive = true
SpendingButton.image = cost.image
SpendingButton.contentMode = .scaleAspectFit
SpendingButton.layer.cornerRadius = 40
SpendingButton.layer.masksToBounds = true
SpendingButton.translatesAutoresizingMaskIntoConstraints = false
SpendingButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
SpendingButton.heightAnchor.constraint(equalToConstant: 80).isActive = true
nameLabel.text = cost.title
nameLabel.textAlignment = .center
nameLabel.textColor = .black
nameLabel.font = UIFont.boldSystemFont(ofSize: 10)
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
nameLabel.heightAnchor.constraint(equalToConstant: 15).isActive = true
}
}
Could someone please help me how to change that? Thanks in advance!
func makeKeyboardCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: 70, height: 40)
layout.scrollDirection = .vertical
keyboardCollectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
contentView.addSubview(keyboardCollectionView)
keyboardCollectionView.snp.makeConstraints({ make in
make.top.equalTo(vocabularyLabel.snp.bottom).inset(-5)
make.left.equalToSuperview().inset(40)
make.right.equalToSuperview().inset(50)
make.height.equalTo(210)
})
keyboardCollectionView.backgroundColor = .clear
keyboardCollectionView.showsVerticalScrollIndicator = false
keyboardCollectionView.register(KeyboardCollectionViewCell.self, forCellWithReuseIdentifier: KeyboardCollectionViewCell.identifier)
keyboardCollectionView.dataSource = self
keyboardCollectionView.delegate = self
}
I'm trying to make a long text label, which lives inside of UI View, to multiple lines. I was searching for a solution for 2 hours, but I couldn't solve it, so I want to ask for some help. Here is the image of what I get now.
This is the View Hierarchy debugger.
In a table view cell, I put the repository name which I got from Github. In the third cell in the image, I want to make the repo name to two lines, since it's long. I saw this StackOverflow question, which sounds similar to my current problem and implemented in my code, but it didn't work.
Here is my code. It's too long but the point is, I have declared label.numberOfLines = 0 and label.adjustsFontSizeToFitWidth = true, and I tried to make my label convertible to multiple lines, but it didn't work. Could anyone please point me at what I'm doing wrong here?
import UIKit
class RepositoryCell: UITableViewCell {
//MARK: - Properties
let userImageView: UIImageView = {
let img = UIImageView()
img.contentMode = .scaleAspectFit
img.clipsToBounds = true
img.backgroundColor = .black
return img
}()
let containerView: UIView = {
let view = UIView()
view.clipsToBounds = true
view.backgroundColor = .systemPink
return view
}()
let userNameLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.font = UIFont.boldSystemFont(ofSize: 20)
label.numberOfLines = 0
label.adjustsFontSizeToFitWidth = true
return label
}()
let repositoryNameLabel: UILabel = {
let label = UILabel()
label.textColor = .gray
label.font = UIFont.systemFont(ofSize: 14)
label.numberOfLines = 0
label.adjustsFontSizeToFitWidth = true
return label
}()
let starNumLabel: UILabel = {
let label = UILabel()
label.textColor = .systemPink
label.font = UIFont.systemFont(ofSize: 14)
label.backgroundColor = .black
return label
}()
//MARK: - Init
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(userImageView)
containerView.addSubview(userNameLabel)
containerView.addSubview(repositoryNameLabel)
addSubview(containerView)
addSubview(starNumLabel)
configureUserNameLabel()
configureRepositoryNameLabel()
configureViewConstraints()
}
override func layoutSubviews() {
super.layoutSubviews()
userImageView.layer.cornerRadius = userImageView.frame.height / 2
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: - Helper functions
func configureCellView(repository: Repository) {
userImageView.image = UIImage(named: "001")
userNameLabel.text = repository.userName
repositoryNameLabel.text = repository.repositoryName
starNumLabel.text = "⭐️\(String(describing: repository.starNum))"
}
func configureUserNameLabel() {
userNameLabel.numberOfLines = 0
userNameLabel.adjustsFontSizeToFitWidth = true
}
func configureRepositoryNameLabel() {
repositoryNameLabel.numberOfLines = 0
repositoryNameLabel.adjustsFontSizeToFitWidth = true
}
func configureViewConstraints() {
setUserImageConstraints()
setContainerViewConstraints()
setUserNameLabelConstraints()
setRepositoryNameLabel()
setStarNumLabel()
}
func setUserImageConstraints() {
userImageView.translatesAutoresizingMaskIntoConstraints = false
userImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
userImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
userImageView.heightAnchor.constraint(equalToConstant: 70).isActive = true
userImageView.widthAnchor.constraint(equalTo: userImageView.heightAnchor, multiplier: 1).isActive = true
}
func setContainerViewConstraints() {
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
containerView.topAnchor.constraint(equalTo: topAnchor, constant: 10).isActive = true
containerView.leadingAnchor.constraint(equalTo: userImageView.trailingAnchor, constant: 10).isActive = true
containerView.trailingAnchor.constraint(equalTo: starNumLabel.leadingAnchor, constant: -10).isActive = true
}
func setUserNameLabelConstraints() {
userNameLabel.translatesAutoresizingMaskIntoConstraints = false
userNameLabel.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
userNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
// userNameLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
}
func setRepositoryNameLabel() {
repositoryNameLabel.translatesAutoresizingMaskIntoConstraints = false
repositoryNameLabel.topAnchor.constraint(equalTo: userNameLabel.bottomAnchor).isActive = true
repositoryNameLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
// repositoryNameLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
// this doesn't work...
// repositoryNameLabel.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor, constant: 5).isActive = true
}
func setStarNumLabel() {
starNumLabel.translatesAutoresizingMaskIntoConstraints = false
starNumLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
starNumLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10).isActive = true
}
}
My guess is the trailing constraints of your label is not set properly.
You can use the View Hierarchy debugger in Xcode to have a clear view of the size your view actually has at runtime.
If the trailing anchor is not set, wrapping text isn't possible as it doesn't reach the "end" of the view.
I want to change X position of a label inside a stackview, there is a button inside the stackview as well. However, I am not able to change the label's position as once I set constraints for the label, errors jump out and want me to delete the constraints.
This is an example of a stackview with a button and a label with changes to the label's x position.
import UIKit
class ViewController: UIViewController {
let stackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.alignment = .center
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
stackView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
let button = UIButton()
button.setTitle("Button", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
button.backgroundColor = UIColor.lightGray
stackView.addArrangedSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.leftAnchor.constraint(equalTo: stackView.leftAnchor).isActive = true
button.rightAnchor.constraint(equalTo: stackView.rightAnchor).isActive = true
let label = UILabel()
label.text = "Label"
label.textColor = UIColor.black
label.backgroundColor = UIColor.lightGray
stackView.addArrangedSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
// Modify left/right anchor constraints for label x position
label.leftAnchor.constraint(equalTo: stackView.leftAnchor, constant: 24).isActive = true
label.rightAnchor.constraint(equalTo: stackView.rightAnchor).isActive = true
}
}
I have a tableview and I want to have a UIStackView in every section header. Now, I want to give a little padding to this stackView: in particular, I want the stackView to take the entire space except for 2px for every side. Is this possible? This is what I tried:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sNumber = UILabel()
sNumber.backgroundColor = UIColor.yellowColor()
sNumber.text = String(section)+". "
let lbl = UILabel()
lbl.backgroundColor = UIColor.cyanColor()
lbl.text = (detailItem![section]["canary"] as! String)
let lbl2 = UILabel()
lbl2.backgroundColor = UIColor.greenColor()
lbl2.text = (detailItem![section]["tbd"] as! String)
let stackView = UIStackView()
stackView.axis = UILayoutConstraintAxis.Horizontal
stackView.distribution = UIStackViewDistribution.FillProportionally
stackView.alignment = UIStackViewAlignment.Center
stackView.spacing = 10
let margins = stackView.layoutMarginsGuide
stackView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 2).active = true
stackView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor, constant: 2).active = true
stackView.topAnchor.constraintEqualToAnchor(margins.topAnchor, constant: 2).active = true
stackView.bottomAnchor.constraintEqualToAnchor(margins.bottomAnchor, constant: 2).active = true
stackView.addArrangedSubview(sNumber)
stackView.addArrangedSubview(lbl)
stackView.addArrangedSubview(lbl2)
return stackView
}
Any help is appreciated.