Swift - Come impostare la visualizzazione personalizzata in base alla lunghezza del testo

Aug 19 2020

Ecco il mio codice,

func bannerNotification(text: String){
    let container = UIView()
    let image = UIImageView()
    let label = UILabel()
    container.frame = CGRect(x: 0, y:0, width: self.view.frame.size.width, height: 100)
    container.backgroundColor = .blue
    image.frame = CGRect(x: 15, y: 50, width: 30, height: 30)
    image.image = UIImage(named: "passport")
    label.frame = CGRect(x: image.bounds.maxX + 35, y: 50, width: container.frame.size.width - 100, height: 50)
    label.backgroundColor = .red
    label.numberOfLines = 0
    label.font = UIFont(name:"Helvetica Neue", size: 15)
    label.text = text
    container.addSubview(image)
    container.addSubview(label)
    self.view.addSubview(container)
}

Secondo questo codice il contenitore e l'immagine stanno arrivando nella giusta posizione, ma se passo un testo piccolo in modo che il mio testo non sia in linea con l'immagine, significa che la mia posizione superiore dell'immagine e la posizione superiore del testo dovrebbero essere uguali .

Se passerò un testo grande, la parte inferiore del contenitore e la parte inferiore dell'etichetta dovrebbero essere uguali e tutto il testo non dovrebbe essere troncato e l' immagine e l'etichetta dovrebbero essere in linea dall'alto .

Risposte

2 DonMag Aug 20 2020 at 16:00

Vuoi davvero usare il layout automatico per questo, in particolare perché stai usando un'etichetta multilinea, il che significa che varierà in altezza.

Ecco un esempio: leggi i commenti per comprendere i vincoli del layout automatico:

class KingViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        bannerNotification(text: "Banner Test")
        //bannerNotification(text: "Banner Test with lots of text to wrap onto multiple lines. Of the many advantages with using auto-layout, notice that the banner will stretch when you rotate the device.")
    }

    func bannerNotification(text: String){
        let container = UIView()
        let image = UIImageView()
        let label = UILabel()
        container.addSubview(image)
        container.addSubview(label)
        self.view.addSubview(container)
        
        [image, label, container].forEach {
            $0.translatesAutoresizingMaskIntoConstraints = false
        }

        container.backgroundColor = UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1.0)
        //image.image = UIImage(named: "passport")
        image.image = UIImage(named: "swiftRed")
        label.backgroundColor = .yellow
        label.numberOfLines = 0
        label.font = UIFont(name:"Helvetica Neue", size: 15)
        label.text = text

        // respect the safe area
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // constrain container Top / Leading / Trailing
            container.topAnchor.constraint(equalTo: view.topAnchor),
            container.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            container.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            
            // we'll use the label height to determine the container height
            
            // image view Top = 8 / Leading = 15
            image.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
            image.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 15.0),
            
            // image view width = 30 / height == width (1:1 ratio)
            image.widthAnchor.constraint(equalToConstant: 30.0),
            image.heightAnchor.constraint(equalTo: image.widthAnchor),
            
            // label Top aligned to Top of image view
            label.topAnchor.constraint(equalTo: image.topAnchor),
            
            // label Leading == image view Trailing + 20
            label.leadingAnchor.constraint(equalTo: image.trailingAnchor, constant: 20.0),
            
            // label Trailing = container Trailing - 15
            label.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -15.0),

            // container bottom should be
            //  At Least 8-pts below the image view bottom
            // AND
            //  At Least 8-pts below the label bottom
            container.bottomAnchor.constraint(greaterThanOrEqualTo: image.bottomAnchor, constant: 8.0),
            container.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor, constant: 8.0),

        ])
        
    }

}

Risultato, con testo breve:

Risultato con testo lungo:

Tieni presente che si regola automaticamente quando le dimensioni cambiano, ad esempio con la rotazione del dispositivo: