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
UIStackView
et 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.swift
Le 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