1
votes

Création d'une fonction pour créer par programme des étiquettes UIL à partir d'un tableau de chaînes dans Swift4

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


14 commentaires

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


3 Réponses :


0
votes

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)
            }
        }
    }


6 commentaires

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)



1
votes

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

sortie du code ci-dessus


1 commentaires

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.



1
votes

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]))
    }
}

 entrez la description de l'image ici


0 commentaires