- 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