J'appelle des alertes, des couleurs de vue, des spinners et des propriétés de composants, etc. à partir de la classe partagée. Est-ce une approche correcte. sinon quelle est la meilleure façon d'écrire du code commun et de l'utiliser dans tout le projet.
Ex: mon code de cours partagé est ...
import UIKit class SharedClass: NSObject { static let sharedInstance = SharedClass() var spinner = UIActivityIndicatorView() //Show activity indicator func activityIndicator() { DispatchQueue.main.async { if let window = UIApplication.shared.keyWindow {//Conditionally unwrap it instead of force unwrap // let window = UIApplication.shared.keyWindow! //Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value self.transparentView = UIView() self.transparentView?.frame = CGRect(x: 0, y: 0, width: window.frame.width, height: window.frame.height) self.transparentView?.backgroundColor = UIColor.black.withAlphaComponent(0.4) window.addSubview(self.transparentView!) if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad { // self.spinner = UIActivityIndicatorView(style: .whiteLarge) self.spinner = UIActivityIndicatorView(style: .whiteLarge) self.spinner.frame = CGRect(x: 0, y: 0, width: 60, height: 60) } else { // self.spinner = UIActivityIndicatorView(style: .white) self.spinner = UIActivityIndicatorView(style: .white) self.spinner.frame = CGRect(x: 0, y: 0, width: 40, height: 40) } self.spinner.center = window.center self.transparentView?.addSubview(self.spinner) self.spinner.startAnimating() DispatchQueue.main.asyncAfter(deadline: .now() + 40.0) {//Stop spinner after 40 Sec's self.stopActivityIndicator() } } } } //Stop activity indicator func stopActivityIndicator() { DispatchQueue.main.async { self.spinner.stopAnimating() self.spinner.removeFromSuperview() self.transparentView?.removeFromSuperview()//Some times getting error here } } //Email validation func isValidEmail(email: String) -> Bool { let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email) if valid { valid = !email.contains("Invalid email id") } return valid } //Mobile number validation func isValidPhone(phone: String) -> Bool { let phoneRegex = "^((0091)|(\\+91)|0?)[6789]{1}\\d{9}$"; // @"^((0091)|(\\+91)|0?)[6789]{1}\\d{9}$" "^[0-9]{6,14}$" let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex).evaluate(with: phone) return valid } private override init() { } } //Alert function extension UIViewController { func showAlert(title: String, msg: String) { DispatchQueue.main.async { let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) } } } //Set TF shadow in login VC extension UITextField { func TFProperties() { layer.shadowColor = UIColor(red: 199/255, green: 217/255, blue: 223/255, alpha: 1.0).cgColor layer.shadowOpacity = 1 layer.shadowOffset = CGSize.zero layer.shadowRadius = 5 layer.borderColor = UIColor(red: 199/255, green: 217/255, blue: 223/255, alpha: 1.0).cgColor layer.borderWidth = 1 layer.cornerRadius = 4 } } //Set View shadow in OTPVerify VC extension UIView { func subViewShadow() { layer.shadowColor = UIColor.white.cgColor layer.shadowOpacity = 1 layer.shadowOffset = CGSize.zero layer.shadowRadius = 3 layer.borderColor = UIColor.gray.cgColor layer.borderWidth = 1 layer.cornerRadius = 4 } func viewShadow() { layer.shadowColor = UIColor.gray.cgColor layer.shadowOpacity = 1 layer.shadowOffset = CGSize.zero layer.shadowRadius = 3 } func collectionViewCellBorder() { layer.cornerRadius = 5 layer.borderColor = UIColor UIColor.gray.cgColor layer.borderWidth = 1.0 } }
3 Réponses :
ce que vous faites est juste sachez que c'est un motif singleton. Pour les gestionnaires comme alertViewController, le contrôle du sélecteur, comme la connexion-déconnexion, etc., c'est une bonne utilisation. Il pourrait être appelé et utilisé plusieurs vues différentes. Cela réduit également les duplications de code. Par exemple, vous devez utiliser la feuille d'actions pour deux contrôleurs de vue différents. À ce stade, vous pouvez utiliser un modèle singleton et donner des paramètres extérieurs aux méthodes de cette instance partagée et l'appeler pour vos opérations spécifiques à partir d'un point. Vous n'aurez pas besoin de créer deux contrôleurs d'alerte différents dans chacun de vos contrôleurs :). Utilisez-le à bon escient :).
@ erkutbas, puis-je savoir ce qu'est login-logout
Par exemple, vous avez une application qui obtient une authentification utilisateur. Login, Register affiche les opérations d'arrière-plan telles que la connexion de l'utilisateur, la déconnexion de l'utilisateur, l'enregistrement de l'utilisateur, les opérations d'oubli de mot de passe peuvent être gérées dans une classe singleton pour toute la hiérarchie de l'application. Parce que dans ces cas, l'application de connexion utilisateur à partir de la vue A, mais la déconnexion de B. C'est pourquoi un modèle de singleton aide le développeur à gérer tout le travail du backend à un seul endroit.
C'est une approche correcte si vous pouvez également utiliser @IBDesignable
et @IBInspectable
pour votre travail lié à la vue, comme ajouter une ombre, un rayon de coin, etc. afin que vous puissiez changer il de votre storyboard également.
J'aime.
@IBDesignable extension UIView{ @IBInspectable public var viewCornerRadius: CGFloat{ set{ self.layer.cornerRadius = newValue }get{ return self.layer.cornerRadius } } @IBInspectable var borderColor: UIColor? { get { let color = UIColor(cgColor: layer.borderColor!) return color } set { layer.borderColor = newValue?.cgColor } } @IBInspectable var borderWidth: CGFloat { get { return layer.borderWidth } set { layer.borderWidth = newValue } } @IBInspectable var shadowRadius: CGFloat { get { return layer.shadowRadius } set { layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float { get { return layer.shadowOpacity } set { layer.shadowOpacity = newValue } } @IBInspectable var shadowOffset: CGSize { get { return layer.shadowOffset } set { layer.shadowOffset = newValue } } @IBInspectable var shadowColor: UIColor? { get { if let color = layer.shadowColor { return UIColor(cgColor: color) } return nil } set { if let color = newValue { layer.shadowColor = color.cgColor } else { layer.shadowColor = nil } } } }
@ Amit gupta, merci beaucoup. Mais cela semble très difficile, car c'est d'abord que je vois ce code.
ça ne marche pas .. j'ai ajouté un fichier rapide dans mon projet. puis copiez et collez votre code puis changez-le de stroyboard .. mais hors mais pas affiché en direct. quand je lance un projet ça marche bien
Créez un cadre commun:
Remarque: Vous devez utiliser des modificateurs de niveau d'accès sur le framework commun (privé, public, ouvert, etc.).
Modificateurs de niveau d'accès:
Source: Abhimuralidharan's Swift 4 - Article sur le contrôle d'accès
Public: Activer une entité à utiliser en dehors du module de définition (cible).
Privé: L'accès privé limite l'utilisation d'une entité à la déclaration englobante et aux extensions de cette déclaration qui se trouvent dans le même fichier.
@ Emre Ciftci, très belle réponse ... Aujourd'hui, j'ai appris un nouveau point de votre réponse ...
Salut @iOS. Je suis très reconnaissant pour votre commentaire. Si vous avez accepté, veuillez marquer comme accepté. Prendre plaisir.
@ Emre Ciftci, pouvez-vous expliquer ce qui se passe si nous utilisons private ou open dans la fonction ci-dessus myAppColor . pouvons-nous accéder à l'ensemble de notre projet.
Rebonjour @iOS. Veuillez vérifier ma modification. myAppColor juste un exemple. Si vous utilisez «privé», vous ne pouvez pas utiliser cette propriété dans un autre module. Si vous utilisez «open», vous pouvez utiliser cette propriété dans un autre module et vous pouvez la remplacer. Si vous utilisez 'public', vous pouvez utiliser cette propriété dans un autre module mais ne pouvez pas la remplacer.
@ Emre Ciftci, très sympa ... une dernière question est qu'il est obligatoire d'utiliser des modificateurs de niveau d'accès pour les fonctions ou les variables.
Si des fonctions ou des variables sont dans un module différent et doivent être utilisées en externe (public) ou non (privé), il est nécessaire de les utiliser. Au fait, si vous n'utilisez aucun modificateur de niveau d'accès, réglez swift le modificateur 'internal' sur votre variable / fonction / classe / struct / enum etc.
écrire des extensions aux classes qui devraient utiliser ce contenu, par exemple pour alert il devrait être
UIViewController
J'utilise déjà des extensions, mais je ne sais pas quelle est la meilleure approche. // Extension de fonction d'alerte UIViewController {func showAlert (titre: String, msg: String) {DispatchQueue.main.async {let alert = UIAlertController (titre: titre, message: msg, style préféré: .alert) alert.addAction (UIAlertAction (titre) : "OK", style:. Par défaut, gestionnaire: nil)) self.present (alerte, animé: vrai, complétion: nil)}}}
oui vous avez des extensions et que voudriez-vous faire d'autre?
@ Lu_, j'utilise cette fonction de la classe partagée func isValidEmail (email: String) -> Bool {} est-ce correct ou pas. Et j'utilise aussi spinner ...