web-dev-qa-db-fra.com

IOS 13: Problème d'espacement avec UITextField rightView

Je suis confronté à un problème d'espacement avec une vue droite de UITextField dans IOS 13, voir mon code suivant et capture d'écran d'ios 13 et d'ios 12.4

Dans IOS 12.4 le simulateur affiche l'espace approprié dans la vue de droite (UIButton) de UITextField

Dans IOS 13.0 le simulateur a un problème d'espacement dans la vue de droite (UIButton) de UITextField

let dropdownButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: txtField.frame.height))
dropdownButton.backgroundColor = UIColor.clear
dropdownButton.setImage(UIImage(named: "ic_DownArrow"), for: UIControl.State())            
txtField.rightView = dropdownButton           
txtField.rightViewMode = .always

enter image description hereenter image description here

19
AtulParmar

Apparemment, cela a changé la façon dont rightViewRect (forBounds :) se comporte dans iOS 13 Beta 5.

À partir des notes de version iOS et iPadOS 13 Developer Beta 5:

UIKit - Problèmes résolus

Avant iOS 13, UITextField supposait que les cadres de ses leftView et rightView étaient correctement définis lors de leur affectation et ne changeraient jamais. À partir d'iOS 13, l'implémentation de leftViewRect (forBounds :) et rightViewRect (forBounds :) demande maintenant la vue pour son systemLayoutSizeFitting (:). Pour obtenir le comportement précédent lors de la liaison et de l'exécution sur iOS 13, ajoutez des contraintes de dimensionnement explicites à la vue, enveloppez-la dans une vue UIV simple ou sous-classe la vue et implémentez systemLayoutSizeFitting (:). (51787798)

Ajoutez donc des contraintes de mise en page automatique à votre vue personnalisée que vous avez ajoutée à la vue de droite

Exemple:-

override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.width - 30, y: 0, width: 20 , height: bounds.height)
    }
23
Bruno Vaillant

Définissez la contrainte de largeur pour la vue gauche ou droite que vous ajoutez.

leftImageView.widthAnchor.set(to: 30.0)
textField.leftView = leftImageView
textField.leftViewMode = .always

Voici l'extension que j'utilise pour définir la contrainte de largeur:

extension NSLayoutDimension {

@discardableResult
func set(
        to constant: CGFloat,
        priority: UILayoutPriority = .required
        ) -> NSLayoutConstraint {

        let cons = constraint(equalToConstant: constant)
        cons.priority = priority
        cons.isActive = true
        return cons
    }
}
6
Abdurrahman

Votre image est probablement plus petite que width: 50, height: txtField.frame.height, donc votre bouton est réduit.

Vous pouvez essayer d'ajouter un conteneur:

let dropdownButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: txtField.frame.height))
dropdownButton.backgroundColor = .clear
dropdownButton.setImage(UIImage(named: "ic_DownArrow"), for: UIControl.State())
let container = UIView(frame: dropdownButton.frame)
container.backgroundColor = .clear
container.addSubview(dropdownButton)
txtField.rightView = container
txtField.rightViewMode = .always
3
Michcio

Je l'ai fait fonctionner en utilisant la méthode de Bruno.

1) Créez une vue de conteneur et définissez sa largeur et sa hauteur à l'aide de la disposition automatique. La largeur et la hauteur doivent inclure la taille de la sous-vue + l'espacement requis.

2) Créez la sous-vue que vous souhaitez afficher dans le champ de texte. Définissez la largeur, la hauteur et la disposition à l'aide de la disposition automatique. Ajoutez-le à la vue du conteneur.

3) Ajoutez la vue conteneur au champ de texte

Vous pouvez voir que mon conteneur correspond à la hauteur du champ de texte. La largeur est la largeur du bouton (44), plus l'espacement que je veux (16). Lorsque j'ajoute ma sous-vue, je l'aligne à gauche du conteneur. Cela me donnera un espacement de 16 pixels entre la droite du bouton et le bord du champ de texte.

let forgotButtonContainer = UIView()
forgotButtonContainer.translatesAutoresizingMaskIntoConstraints = false
forgotButtonContainer.widthAnchor.constraint(equalToConstant: 44.0 + 16.0).isActive = true
forgotButtonContainer.heightAnchor.constraint(equalToConstant: 48.0).isActive = true

forgotButton = PFSecondaryButton(link: "Forgot?")
forgotButton.translatesAutoresizingMaskIntoConstraints = false
forgotButtonContainer.addSubview(forgotButton)

forgotButton.topAnchor.constraint(equalTo: forgotButtonContainer.topAnchor).isActive = true
forgotButton.leftAnchor.constraint(equalTo: forgotButtonContainer.leftAnchor).isActive = true
forgotButton.bottomAnchor.constraint(equalTo: forgotButtonContainer.bottomAnchor).isActive = true

passwordField.rightView = forgotButtonContainer
2
Michael Rose

Cela a fonctionné pour moi et résout également le problème qui se produit dans l'iPhone X/11, lorsque le rightView occupe toute la largeur du champ textField:

txtField.rightView = dropdownButton
txtField.translatesAutoresizingMaskIntoConstraints = false
txtField.rightView?.widthAnchor.constraint(equalToConstant: 50).isActive = true
1
Faisal Arefin

J'ai résolu le même problème en définissant ceci:

remplacer textField rightViewRectForBounds: méthode,

- (CGRect)rightViewRectForBounds:(CGRect)bounds {
    if (self.rightView) {
        CGRect rightFrame = self.rightView.frame;
        return CGRectMake(bounds.size.width - rightFrame.size.width, 0, rightFrame.size.width, bounds.size.height);
    }
    return CGRectZero;
}
0
Yingbo Wang