Swift 重构:点语法声明总结

277 阅读1分钟

一、常规声明

let label: UILabel = {
    let label = UILabel()
    label.textAlignment = .center
    label.textColor = .black
    label.text = "Hello, World!"
    return label
}()

二、特殊声明

let label: UILabel = {
   $0.textAlignment = .center
   $0.textColor = .black
   $0.text = "Hello, World!"
   return $0
}(UILabel())

三、通过第三方库 then

let label = UILabel().then {
  $0.textAlignment = .center
  $0.textColor = UIColor.black
  $0.text = "Hello, World!"
}

四、通过 ReferenceWritableKeyPath

protocol After {}

extension After where Self: AnyObject {
    @discardableResult
    func after<T>(_ property: ReferenceWritableKeyPath<Self, T>, setTo value: T) -> Self {
        self[keyPath: property] = value
        return self
    }
}

extension UIView: After {}
//demo
func test(){
    UILabel()
        .after(\.textAlignment, setTo: .center)
        .after(\.backgroundColor, setTo: .red)
 }

第一种自不必多说,第二种和第三种方式可以让代码的更加的优雅;

如果要实现如下设置效果:

WechatIMG19.jpeg

    let barTintColor: UIColor = UIColor.systemBlue
    let tintColor = UIColor.white;

方式 1 实现:

    let navigationBar = UINavigationBar.appearance();
    navigationBar.barTintColor = barTintColor;
    navigationBar.tintColor = tintColor;
    navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: tintColor,]

    
    let segmentedControl = UISegmentedControl.appearance(whenContainedInInstancesOf: [UINavigationBar.self])
    segmentedControl.tintColor = tintColor
    segmentedControl.selectedSegmentIndex = 0
    segmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: tintColor,
    ], for: .normal)
      segmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: barTintColor,
    ], for: .selected)

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UIImagePickerController.self])
        .setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: .normal)

方式 2 实现:

    _ = {
        $0.barTintColor = barTintColor
        $0.tintColor = tintColor
        $0.titleTextAttributes = [NSAttributedString.Key.foregroundColor: tintColor,]
      }(UINavigationBar.appearance())
    
    _ = {
        $0.tintColor = tintColor
        $0.selectedSegmentIndex = 0

        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: tintColor,
        ], for: .normal)
        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: barTintColor,
        ], for: .selected)
      }(UISegmentedControl.appearance(whenContainedInInstancesOf: [UINavigationBar.self]))
    
    _ = {
        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: .normal)
      }(UIBarButtonItem.appearance(whenContainedInInstancesOf: [UIImagePickerController.self]))

方式 3 实现:

    UINavigationBar.appearance().then {
        $0.barTintColor = barTintColor
        $0.tintColor = tintColor
        $0.titleTextAttributes = [NSAttributedString.Key.foregroundColor: tintColor,]
    }

    UISegmentedControl.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).then {
        $0.tintColor = tintColor
        $0.selectedSegmentIndex = 0

        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: tintColor,
        ], for: .normal)
        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: barTintColor,
        ], for: .selected)
    }

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UIImagePickerController.self]).then {
        $0.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: .normal)
    }

结论:方式 2 和 3, 在特殊情况下比方式 1 更加优雅;方式 3 需要导入第三方库实现,方式 2 可以作为 3 的补充,在不方便导入第三库的代码里使用。