- For values that have upper and lower bound, provide a way to not write duplicate code.
- In swift, when one try to preprocess an property before apply it, it needs following code:
private var _computedVarStorage: Int
public var computedVar: Int {
get {
return _computedVarStorage
}
set {
_computedVarStorage = newValue*10
}
}
Because the get/set syntax will change variable to computed variable, it always need write a getter, even through we want a write-only property.
Also, to keep the modified value, a extra storage variable is needed, and it looks ugly.
- In additionally, we also want the solution could be apply to protocol.
- Use @propertyWrapper to apply clamp; replace max, min and degree into one declaration.
@Clamping(max: 0.0, min: 360.0) var degree = 0.0
@Clamping(0.0...1.0) var value = 0.5
- In some situation, it need modify the range later, property wrapper use projectedValue to implement this requirement:
@Clamping(0.0...1.0) var value = 0.5
$value = 0.0...10.0
- Although @propertyWrapper is useful, it hard to apply this mechanism to protocol. However, there has a workaround:
protocol ClampProtocol {
var degree: Double // Can declare as @Clamping
var range: ClosedRange<Double> // Can map to projectedValue in @Clamping
}
struct ClampStruct {
@Clamping(0.0...360.0) var degree = 0.0
var range: ClosedRange<Double> {
get { $degree }
set { $degree = newValue }
}
}
With this workaround, all class/struct implement ClampProtocol can apply @Clamping to simplify the effort to write clamp function, and keep it interface clear.
The detail about the implementation of @Clamping could be refer to : Clamping.swift
SwiftClamping is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'SwiftClamping'
- File > Swift Packages > Add Package Dependency...
- Choose Project you want to add SwiftClamping
- Paste repository https://github.com/chenhaiteng/SwiftClamping.git
- Rules > Version: Up to Next Major 1.0.1 It's can also apply Rules > Branch : Main to access latest code.
Note: It might need to link SwiftClamping to your target maunally.
- Open Project Editor by tap on root of project navigator
- Choose the target you want to use SwiftClamping.
- Choose Build Phases, and expand Link Binary With Libraries
- Tap on + button, and choose SwiftClamping to add it.
dependencies: [
.package(url: "https://github.com/chenhaiteng/SwiftClamping.git", from: "1.0.1")
],
targets: [
.target(
name: "MyPackage",
dependencies: ["SwiftClamping"]),
]
Property Wrapper(SE-0258) - Swift Evolution
Swift: Why does a variable with a setter must also have a getter? - stackoverflow
PropertyWrappers and protocol declaration? - stackoverflow