【问题标题】:How can I optimize my code to use one method instead of multiple of same in different classes?如何优化我的代码以在不同的类中使用一种方法而不是多个相同的方法?
【发布时间】:2017-06-26 11:52:54
【问题描述】:

我在不同的视图控制器类中有相同的方法,基本上它为视图控制器添加了模糊效果。现在我正在尝试使用其他 swift 类型来简化我的代码,但我很困惑如何实现这一点,以便添加子视图正常工作。处理这种情况的好方法是什么?扩展、协议、结构、类或其他函数?

这是一个视图控制器(这里是简化的):

import UIKit
class MyClass: UIViewController { 
     weak var blurEffectView : UIVisualEffectView?

     .... other methods .... 
       func addBlurrEffect() {

        let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
        let blurEffectVw = UIVisualEffectView(effect: blurEffect)
        blurEffectVw.frame = self.view.bounds
        blurEffectVw.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
        self.view.addSubview(blurEffectVw)
        blurEffectView = blurEffectVw
    }
    ... other methods .... 
} 

我还有其他类似的视图控制器。如何将它们重构为仅在整个项目中使用 addBlurEffect() 一次?

【问题讨论】:

  • 你试过扩展吗?检查这个:stackoverflow.com/questions/30953201/…
  • @DharmeshKheni 这是个好主意,我想我必须把我的问题写得更笼统一些,因为我并不是真的只在寻找这个案例的答案。一种更通用的方法,但非常感谢有帮助
  • 欢迎您.. :)
  • @TheeBen 为什么是UIVisualEffectView weak?
  • @TheeBen MyClass 与 blurEffectView 没有拥有关系吗?

标签: ios objective-c swift optimization


【解决方案1】:

在您的项目中为模糊功能创建 NSObject 类,并在其中添加您的方法。

要调用方法,首先在您的 VC 中创建该模型类的对象并像这样使用 obj.addBlur()。

注意:如果您需要 vc 中的任何变量,则将该变量作为 addBlur 函数的参数发送。

示例:addBlur(self.Viewblur)

【讨论】:

  • 那么我在 addSubView() 方面不会有困难吗?
  • 检查我现在添加的答案的注释。
  • 考虑到扩展扩展到所有 uiviewcontrollers 并且编写协议只是要添加更多代码而不是简化,我发现这是最简单的方法。
【解决方案2】:

你应该为 UIViewController 创建一个扩展:

extension UIViewController {
    func addBlurrEffect() {
        //layout for the pool of clnts that can be selected to add files
        let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
        let blurEffectVw = UIVisualEffectView(effect: blurEffect)
        blurEffectVw.frame = self.view.bounds
        blurEffectVw.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
        self.view.addSubview(blurEffectVw)
        blurEffectView = blurEffectVw

    }
}

请注意,您不能在扩展中添加实例变量。您可能应该重构您的函数以返回生成的模糊效果视图,而不是依赖于实例变量。

【讨论】:

    【解决方案3】:

    您可以使用子类化。

    创建一个作为 UIViewController 子类的类,如下所示:

    class CustomViewController: UIViewController {
    
        weak var blurEffectView : UIVisualEffectView?
    
        func addBlurrEffect() {
            //layout for the pool of clnts that can be selected to add files
            let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
            let blurEffectVw = UIVisualEffectView(effect: blurEffect)
            blurEffectVw.frame = self.view.bounds
            blurEffectVw.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
            self.view.addSubview(blurEffectVw)
            blurEffectView = blurEffectVw
    
        }
    }
    

    然后您可以将此类用于所有视图控制器并访问addBlurrEffect 函数,如下所示:

    class ViewControllerOne: CustomViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            addBlurrEffect()
    
        }
    }
    
    class ViewControllerTwo: CustomViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            addBlurrEffect()
    
        }
    } 
    

    【讨论】:

    • 要求一个子类只是为了获得这个方法是非常有限的。协议或扩展会更合适。
    • @Alexander,你说的限制是什么意思?如果您不介意扩展一下,限制是多少,非常感谢
    • @TheeBen 如果我想继承 SomeOtherViewController,但仍然使用模糊效果怎么办?
    • 让SomeOtherViewController 成为CustomViewController 的子类
    • @KennyGunderman,你是对的,可以回答这个问题,但我认为这是我的错,我正在寻找一个更普遍的回答一般问题,我正在尝试编辑问题更笼统
    【解决方案4】:

    在协议中声明此行为:

    protocol Blurrable {
          var view: UIView { get set }
          var blurEffectView: UIVisualEffectView? { get set }
    
          func addBlurrEffect()
    }
    

    在该协议的扩展中定义行为:

    extension Blurrable {
          func addBlurrEffect()
            //layout for the pool of clnts that can be selected to add files
            let blurEffect = UIBlurEffect(style: .dark)
            blurEffectView = UIVisualEffectView(effect: blurEffect)
            blurEffectView.frame = self.view.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
            self.view.addSubview(blurEffectView)
        }
    }
    

    并将对该协议的一致性添加到所有相关的 ViewController:

    class MyVC1: UIViewController, Blurrable {
        weak var blurEffectView : UIVisualEffectView?
    
        // ...
    }
    
    class MyVC2: UIViewController, Blurrable {
        weak var blurEffectView : UIVisualEffectView?
    
        // ...
    }
    

    【讨论】:

    • 感谢您的回复,我只是不确定您如何在其中一个原始课程中使用它?
    • @TheeBen 你是什么意思?您只需正常拨打addBlurrEffect即可
    • 您不能使用扩展将存储的属性添加到类中。您的 weak var blurEffectView 将无法正常工作。那必须写成一个计算属性。
    • @DuncanC 哦,你是对的。我想了一会儿你可以,如果你扩展的类是你自己的。我现在就解决这个问题。
    • @TheeBen 没关系,只是在类声明中声明一致性,而不是扩展。我已经更新了我的答案。
    【解决方案5】:

    这样的事情会奏效。你也可以使用@IBInspectable。

    import UIKit
    
    extension UIView {
      weak var blurEffectView : UIVisualEffectView?
    
      .... other methods .... 
             func addBlurrEffect() {
              //layout for the pool of clnts that can be selected to add files
              let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
              let blurEffectVw = UIVisualEffectView(effect: blurEffect)
              blurEffectVw.frame = self.view.bounds
              blurEffectVw.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
              self.view.addSubview(blurEffectVw)
              blurEffectView = blurEffectVw
          }
          ... other methods .... 
      } 
    }
    

    【讨论】:

    • 你不能像这样在 UIView 的扩展中添加存储的属性
    • 对不起,我的代码有点不完整。您需要创建 setter 和 getter。很好的呼唤@Alexander
    【解决方案6】:

    你可以像这样开第二课

    class BlurManager {
         weak var blurEffectView: UIVisualEffectView?
         weak var viewController: UIViewController
         var isBlurred:Bool = false
    
         init(viewController:UIViewController){
            self.viewController = viewController
         }
    
         func addBlurEffect() {
            if !isBlurred {
                isBlurred = true
                let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
                let blurEffectVw = UIVisualEffectView(effect: blurEffect)
                blurEffectVw.frame = self.view.bounds
                blurEffectVw.autoresizingMask = [.flexibleWidth, .flexibleHeight]     // for supporting device rotation
                viewController.view.addSubview(blurEffectVw)
                blurEffectView = blurEffectVw
            }
        }     
    
        func removeBlurEffect() {
           if isBlurred {
               isBlurred = false
               ...cleanup...
           }
        }
    }
    
    class MyClass: UIViewController { 
         lazy var blurManager: BlurManager = {
             return BlurManager(viewController:self)
         }()
    
         .... other methods .... 
        blueManager.addBlurEffect()
         ... other methods .... 
    } 
    

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 2013-08-30
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 2023-03-24
      • 2014-03-23
      • 2011-04-17
      相关资源
      最近更新 更多