【问题标题】:What is the best way to write common code and use it entire project编写通用代码并在整个项目中使用它的最佳方法是什么
【发布时间】:2019-11-12 01:51:09
【问题描述】:

我正在从 Shared 类中调用警报、视图的颜色、微调器和组件属性等。是不是正确的做法。如果不是,那么编写通用代码并在整个项目中使用它的最佳方式是什么。

例如:我的共享课程代码是...

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

【问题讨论】:

  • 为应该使用此内容的类编写扩展,例如警报应该是UIViewController
  • 我已经在使用扩展,但我不知道什么是最好的方法。 //警报功能扩展 UIViewController { func showAlert(title: String, msg: String) { DispatchQueue.main.async { let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert) alert.addAction(UIAlertAction(title :“OK”,样式:.default,处理程序:nil)) self.present(alert, animated: true, completion: nil) } } }
  • 是的,您有扩展程序,您还想做什么?
  • @Lu_,我正在使用共享类 func isValidEmail(email: String) -> Bool { } 中的此功能是否可以。我也在使用微调器......

标签: ios swift cocoa-touch design-patterns singleton


【解决方案1】:

你正在做的是正确的知道是一个单例模式。对于像 alertViewController 这样的管理器,选择器控件,比如登录-注销等,这是一个很好的使用。它可以被调用和使用几个不同的视图。它也减少了代码重复。例如,您需要为两个不同的视图控制器使用操作表。此时,您可以使用单例模式并从该共享实例的方法之外提供一些参数,并从某一点为您的特定操作调用它。您不需要在每个控制器中创建两个不同的警报控制器:)。明智地使用它:)。

【讨论】:

  • @erkutbas,我可以知道什么是登录-注销
  • 例如,您有一个应用程序正在获取用户身份验证。 Login、Register 视图后台操作,例如用户登录、用户注销、用户注册、忘记密码操作可以在一个单例类中处理整个应用程序层次结构。因为在这些情况下,用户从视图 A 登录应用程序,但从 B 注销。这就是为什么单例模式可以帮助开发人员在一个地方管理所有后端工作。
【解决方案2】:

如果您也可以将@IBDesignable@IBInspectable 用于与视图相关的工作,例如添加阴影、圆角半径等,那么这是一种正确的方法,这样您也可以从情节提要中更改它。 喜欢。

@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,非常感谢。但它看起来非常困难,因为这是我第一次看到这段代码。
  • 它不起作用.. 我在我的项目中添加了一个 swift 文件。然后复制并粘贴您的代码,然后从 stroyboard 更改它.. 但不会实时显示。当我运行项目时,它工作正常
【解决方案3】:

创建一个通用框架:

  • XCode>文件>新建>项目>

  • Cocoa 触控框架>

  • 设置您的框架名称(通用等)>

  • 在“添加到”和“组”部分选择您的主要工作区并创建>

  • 您应该将您的框架链接到主要目标链接库>

  • 您可以在框架中创建类>

  • 并使用主项目,只需像“import Common”一样导入这个框架。

注意:您应该在通用框架(私有、公共、开放等)上使用访问级别修饰符。

访问级别修饰符:

来源: Abhimuralidharan's Swift 4— Access Control Article

  1. 公开: 使实体能够在定义模块(目标)之外使用。

  2. 私人: 私有访问将实体的使用限制为封闭声明,以及同一文件中该声明的扩展。

【讨论】:

  • @Emre Ciftci,非常好的回答...今天我从您的回答中学到了一个新点...
  • 嗨@iOS。我非常感谢您的评论。如果您接受,请标记为已接受。享受吧。
  • @Emre Ciftci,你能解释一下如果我们在上述函数 myAppColor 中使用 private 或 open 会发生什么。我们可以访问我们的整个项目吗?
  • 你好@iOS。请检查我的编辑。 myAppColor 只是一个例子。如果您使用“私有”,则不能在其他模块中使用此属性。如果你使用'open',你可以在其他模块中使用这个属性,你可以覆盖它。如果你使用'public',你可以在其他模块中使用这个属性,但不能覆盖它。
  • 如果函数或变量在不同的模块中并且要在外部(公共)或不(私有)使用,则必须使用它们。顺便说一句,如果您不使用任何访问级别修饰符,请快速将“内部”修饰符设置为您的变量/函数/类/结构/枚举等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多