[SWIFT] Extension UITextField, problème de z-index ?
Bonjour tout le monde,
Je galère avec un truc qui a l'air tout bête mais je ne m'en sort pas..
Je m'explique, j'essaie de créer une extension à UITextField pour pouvoir placer une image (à droite ou à gauche) du champs, histoire de faire plus beau
Voila mon code :
extension UITextField {
enum Direction {
case Left
case Right
}
// met une image dans un textfield
func withImage(direction: Direction, image: UIImage, colorSeparator: UIColor, colorBorder: UIColor){
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.frame = CGRect(x: 12.0, y: 10.0, width: 24.0, height: 24.0)
imageView.layer.zPosition = 1000
let view = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 45))
view.layer.cornerRadius = 5
view.layer.borderWidth = 0.5
view.layer.borderColor = colorBorder.cgColor // ici : noir
view.backgroundColor = .white
view.layer.zPosition = 0
if(Direction.Left == direction){ // image left
let seperatorView = UIView(frame: CGRect(x: 45, y: 0, width: 5, height: 50))
seperatorView.backgroundColor = colorSeparator
view.addSubview(seperatorView)
self.leftViewMode = .always
view.addSubview(imageView)
self.leftViewMode = UITextFieldViewMode.always
self.leftView = view
}
else{ // image right
let seperatorView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 50))
seperatorView.backgroundColor = colorSeparator
view.addSubview(seperatorView)
self.rightViewMode = .always
view.addSubview(imageView)
self.rightViewMode = UITextFieldViewMode.always
self.rightView = view
}
self.layer.borderColor = colorBorder.cgColor // ne fonctionne pas :/
}
}
et voila le résultat :
J'ai mis en noir le contour de ma "view" pour bien qu'on voit qu'il passe par dessus le séparateur (orange).
J'ai bien essayé de mettre des z-index (zPosition) mais ça ne change pas le soucis, le orange reste toujours en dessous alors que j'aimerai qu'il soit au dessus..
Une idée de comment faire ?
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Tu mets ton séparateurView à l'intérieur de ta view et le contenu ne pourra pas être au dessus du "border color" du contenant.
Euhmmm.. j'dois avoir le cerveau qui fume parce que j'ai pas compris ce que tu voulais dire
Pour moi j'ai une vue (view) et je lui ai rajouté 2 vues dedans (imageView & seperatorView).
Et cette première vue (view), je l'a met à droite ou à gauche du textfield.
Du coup, mon seperatorView est déjà dans la vue (view) nan ?
T'as un bout de code pour que je test ce que tu veux dire de mon côté ? ^^
Toi tu veux que ton rectangle orange soit au-dessus du bord noir ?
Yes, c'est ça
En l'état ça ne pourra pas fonctionner car ton seperatorView est à l'intérieur de la vue qui a le bord noir. Il faudrait que tu fasses une stack comme ça :
-- LeftView
-- View -> (pas de border)
---- SeparatorView
---- ImageView -> (borderColor, borderWidth et corner radius)
-------- UIImage
En gros dans ton code :
imageView.layer.cornerRadius = 5
imageView.layer.borderWidth = 0.5
imageView.layer.borderColor = colorBorder.cgColor
et tu dégages les lignes :
view.layer.cornerRadius = 5
view.layer.borderWidth = 0.5
view.layer.borderColor = colorBorder.cgColor
En faite c'est ça que j'arrive pas à faire via le code
Tu copies colles le code que je t'ai filé, ça devrait pas être très loin du résultat que tu cherches.
Le code n'est pas du tout optimisé (on peut faire bien plus court) mais tu devrais avoir quelque chose qui correspond à ce que tu cherches. J'ai codé directement sur le forum, je n'ai pas testé ce que je te donne.
Peace
Et on arrêterai pas d'utiliser des views pour utiliser des layers à place ?
Si si si, d'où ma phrase => "Le code n'est pas du tout optimisé".
Jérémy >> Ah bah c'est bien ce que j'avais fait alors..
Je pensais avoir mal compris un truc mais on a sensiblement le même code et voila le résultat :
Le trait fait le tour de l'image maintenant
Pyroh >> Si t'as une solution plus propre, c'est pas de refus
Ah mince ! J'avais pas vu que ton image était plus petite...
Je t'ai apporté un correctif qui se base encore sur les UIView afin de voir si ça s'approche de ce que tu cherches. Si c'est okay, on passera par des Layers.
N'ayant pas de Xcode sous la main, je ne sais pas si le code compile...
J'ai corrigé pour que ça compile mais maintenant il n'y a plus rien, juste l'UITextField
Les corrections étaient simples (ouf lol) :
addSubView = addSubview
main.addSubView(imageView) = mainView.addSubview(imageView)
Je vais faire des tests en entrant chez moi. Coder sur le forum c’est pas simple. Je te tiens au jus.
Tu peux me filer le code de l’extension que tu as créé ?
Ca marche ^^
Merci de prendre le temps de regarder en tout cas
De rien
J'ai apporté les correctifs nécessaires, tu devrais obtenir quelque chose qui s'apparente à ce que tu recherches. Je ne te cache pas, comme l'a dit @Pyroh, qu'il serait plus léger de passer par des layers, du moins pour le cadre noir et la barre de séparation. Je te laisse prendre le soin de tester le code ci-dessous.
Je viens de tester et ça fonctionne parfaitement, merci ^^
Et le code et compréhensible, il fallait rajouter une vue principale (mainView) qui contient une vue (view) qui elle même contient l'image (imageView) et le séparateur va dans la vue principale (mainView) .. nickel ^^
Histoire d'être pointilleux et de rendre ça cohérent.. Comment je peux faire pour que la couleur du cadre noir (colorBorder), s'applique aussi au TextField ?
J'ai essayé un truc comme :
Mais sans grand succès.. je dois louper un truc..
C'est bien cette propriété qu'il faut utiliser pour appliquer une couleur sur le contour du TextField. Mais tu n'as pas du setter une largeur au "border" (self.layer.borderWidth = CGFloat(0.5)). Mais attention, ton séparateur ne sera pas au dessus (tu auras forcément un trait noir en bas et en haut de la vue seperatorView).
Je suis en train de te faire une petite playground (Xcode 9.4b vu que Xcode 9.3 casse les PG) qui explique tout.
Stay tuned.
Je ne sais pas si ça vient du fait que ma machine est trop vieille mais de mon côté ça ne fonctionne pas du tout.
Ah bah oui, j'avais bien loupé un truc.. vu que la bordure était visible, je pensais qu'elle avait déjà une largeur.. en faite nan.. c'était une illusion d'optique lol
Bon c'est résolu, c'est pas grave si ça passe pas au dessus du séparateur.. ça rend très bien comme ça ^^
Merci encore ^^
@Pyroh Ok, on stay tuned
(il faut obligatoirement Xcode 9.4b pour tester ce que tu nous prépare ?)
Il n'y a pas de quoi !
Non non non, tu pourras tester. Mais je te conseille de passer par les layers. Si @Pyroh ne te file pas la solution, je t'en donnerai une ce weekend.
ça change quoi concrètement de passer par des layers ?
Qu'est ce que tu entendais quand tu disais que c'est plus "léger" de passer par des layers ?
Plus léger = moins de code ?
En gros le rectangle noir et la ligne de séparation n'ont pas d’intérêt d'être sous forme de view. Chaque vue encapsule un layer et tu n'utilises que ce dernier. Moralité, tu te retrouves à employer des classes (plus lourde d'un point de vue mémoire vive) avec tout t'un tas de propriétés que tu n'utilises pas. D'un point de vue graphique ça ne change rien, c'est juste pas très optimisé.
Ok je vois, rendu visuel c'est pareil mais niveau consommation c'est moins gourmand.. alors autant utilisé des layers si on peut ^^
Oui enfin bon il faut tout de même relativiser. Il est vrai que tu vas y gagner mais ça ne sera pas non plus le jour et la nuit. Peut être en vitesse de chargement, et encore, ça se chiffrera en micro secondes.
Emprunte mémoire surtout. C'est pas énorme sur un contrôle de ce type mais sur une application complète ça commence à faire. Puis y'a pas de mal à faire les choses proprement 😉
Quand ma journée de travail est terminée j'en profite pour finir la playground (mais elle termine tard...)
+1
+1000