Je suis capable de créer un UILabel par programmation, mais lorsque je crée une fonction, dois-je la mettre dans la méthode viewDidLoad () ? Je dois ajouter l'étiquette à la vue en utilisant self.view.addSubview (label) mais cela génère une erreur, et ma construction échoue alors lorsqu'elle est en dehors de viewDidLoad () .
Chaque fois que j'essaye de créer la fonction en dehors de la méthode viewDidLoad , cela indique "l'utilisation de l'identifiant non résolu self". Y a-t-il quelque chose autour de ça?
De plus, quand je mets la fonction dans le viewDidLoad , tout fonctionne bien, et les étiquettes sont créées, mais elles sont créées les unes sur les autres. Je veux que les libellés soient côte à côte si possible?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func createALabel(inputtedString: String) -> Void {
let string = inputtedString
let test = string.components(separatedBy: " ")
for element in test {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 60, height: 35))
label.center = CGPoint(x: 160, y: 285)
label.textAlignment = .center
label.textColor = UIColor.blue
label.text = element
label.layer.borderColor = UIColor.blue.cgColor
label.layer.borderWidth = 3.0
self.view.addSubview(label)
}
}
}
Même avec le changement de position, mes étiquettes sont toujours empilées
3 Réponses :
Vous devez ajouter une variable Integer pour définir la position x. Ici, j'ai défini la variable xPos en fonction de la position x définie
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func createALabel(inputtedString: String) -> Void {
let string = inputtedString
let test = string.components(separatedBy: " ")
let xPos = 0
for element in test {
let label = UILabel(frame: CGRect(x: xPos, y: 0, width: 60, height: 35))
// label.center = CGPoint(x: 160, y: 285)
label.textAlignment = .center
xPos = xPos + 60 + 10 // Update xPos width 60 & 10 is gap between two label
label.textColor = UIColor.blue
label.text = element
label.layer.borderColor = UIColor.blue.cgColor
label.layer.borderWidth = 3.0
self.view.addSubview(label)
}
}
}
Lorsque vous utilisez self en dehors de viewdidLoad (), cela n'a-t-il pas généré d'erreur pour vous?
@Jazzin Cela générera une erreur uniquement si vous avez la méthode createALabel en dehors de la classe ViewController
@RajeshKumarR ma fonction est dans la classe viewcontroller et j'obtiens toujours l'erreur
@Jazzin Pouvez-vous mettre à jour la question avec une capture d'écran
@Jazzin Vous avez l'erreur dans label.swift pas dans ViewController.swift
Supprimer label.center = CGPoint (x: 160, y: 285)
Pour gérer une telle géométrie, UIStackView pourrait être utile.
De plus, vous n'avez pas besoin d'appeler cette méthode dans viewDidLoad, la méthode de cycle de vie loadView est plus appropriée pour cela, lorsque vous souhaitez initialiser et gérer vos vues
par programme.
class ViewController: UIViewController {
private let vstackView = UIStackView()
private let horizontal_spacing = 20.0
private let spaceConstantForLetter = 10.0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
vstackView.axis = .vertical
vstackView.translatesAutoresizingMaskIntoConstraints = false
vstackView.alignment = .center
vstackView.spacing = 10
self.view.addSubview(vstackView)
vstackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
vstackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
createALabel(inputtedString: "this is a long test string that exceeds screen width")//
// Do any additional setup after loading the view.
}
func createALabel(inputtedString: String) -> Void {
let string = inputtedString
let test = string.components(separatedBy: " ")
var horizontalStackList = [UILabel] ()
for (index, element) in test.enumerated() {
let label = UILabel()
label.textAlignment = .center
label.textColor = UIColor.blue
label.text = element
label.layer.borderColor = UIColor.blue.cgColor
label.layer.borderWidth = 1.0
horizontalStackList.append(label)
let totalLetterNumber = horizontalStackList.map { $0.text!.count }.reduce(0, +)
let contentWidth = Double(totalLetterNumber) * spaceConstantForLetter //constant for a letter that takes how much space from screen
let spacingWidth = Double(horizontalStackList.count - 1) * horizontal_spacing
/*add left and right margins if exist*/
if((CGFloat(spacingWidth + contentWidth) > UIScreen.main.bounds.width) || index == test.count - 1) {
let exceedingLabel = horizontalStackList.popLast()
let hstackView = UIStackView(arrangedSubviews: horizontalStackList)
hstackView.axis = .horizontal
hstackView.translatesAutoresizingMaskIntoConstraints = false
hstackView.spacing = CGFloat(horizontal_spacing)
hstackView.alignment = .center
vstackView.addArrangedSubview(hstackView)
horizontalStackList.removeAll(keepingCapacity: false)
horizontalStackList.append(exceedingLabel!)
}
}
}
}
Edit: L'habillage Word a été ajouté comme Jazzin le souhaite
Lorsque la phrase est longue, les mots sortent de l'écran, ils ne sont pas renvoyés à la ligne. J'ai besoin d'un enveloppement de mots.
Utiliser une vue de collection est la meilleure option. Cela facilite votre travail. Essayez ceci
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
var wordsArr = [String]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
collectionView.backgroundColor = .white
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(WordCell.self, forCellWithReuseIdentifier: "WordCell")
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[collectionView]-(5)-|", options: [], metrics: nil, views: ["collectionView":collectionView]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(5)-[collectionView]-(5)-|", options: [], metrics: nil, views: ["collectionView":collectionView]))
createALabel(inputtedString: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam")
}
func createALabel(inputtedString: String) -> Void {
wordsArr = inputtedString.components(separatedBy: " ")
collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return wordsArr.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WordCell", for: indexPath) as? WordCell ?? WordCell()
cell.label.text = wordsArr[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (wordsArr[indexPath.row] as NSString).boundingRect(with: CGSize.zero, options: .usesLineFragmentOrigin, attributes: [.font: UIFont.systemFont(ofSize: 16.0)], context: nil).size.width
let size = CGSize(width: width + 10
, height: 35)
return size
}
}
class WordCell: UICollectionViewCell {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
backgroundColor = .white
label.font = UIFont.systemFont(ofSize: 16.0)
label.textAlignment = .center
label.textColor = UIColor.blue
label.layer.borderColor = UIColor.blue.cgColor
label.layer.borderWidth = 3.0
label.translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[label(35)]|", options: [], metrics: nil, views: ["label":label]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[label]|", options: [], metrics: nil, views: ["label":label]))
}
}
Utilisez un
UIStackViewet ajoutez les étiquettes à la vue de la pile.Qu'essayez-vous de réaliser exactement?
Les étiquettes se chevaucheront si vous leur donnez toutes le même cadre.
@Jazzin L'erreur se trouve dans un autre fichier:
label.swiftLe but est d'avoir du texte, et pour chaque mot avoir une étiquette qui lui est associée. Les étiquettes ne peuvent cependant pas être superposées, elles doivent être à côté.
@Jazzin Si vous ne voulez pas que les étiquettes ne soient pas superposées, changez les x ou y des étiquettes. Vérifiez la réponse de Bhavisha Khatri
@Jazzin Qu'avez-vous dans le fichier Label.swift? Mettez à jour son code ici
Ma faute, j'avais cette fonction dans mon fichier label.swift, et c'était ce qui provoquait l'erreur, mais mes étiquettes se chevauchent toujours même avec le changement de position.
@Jazzin Avez-vous supprimé label.center = CGPoint (x: 160, y: 285)
@RajeshKumarR supprimer le label.center était parfait, donc maintenant si la phrase est trop longue, elle sort de l'écran. Diriez-vous placer les étiquettes dans un UITextView ou ScrollView?
@Jazzin Utiliser la vue collection est la meilleure option. Cela facilite votre travail. Vérifiez ce github.com/riteshhgupta/TagCellLayout
@RajeshKumarR savez-vous pourquoi, lorsque dans la vue de la pile, les étiquettes ne sont pas enveloppées à l'écran?
@Jazzin Stackview est unidirectionnel. Lorsque vous ajoutez une étiquette à une vue de pile horizontale, elle ne s'aligne pas sur la ligne suivante.
@Jazzin Vérifier la réponse mise à jour