Snapkit: Feature request: Priority enum

Created on 20 Sep 2016  ·  7Comments  ·  Source: SnapKit/SnapKit

New Issue Checklist

  • [x] I have looked at the Documentation
  • [x] I have read the F.A.Q.
  • [x] I have filled out this issue template.

    Issue Info

| Info | Value |
| --- | --- |
| Platform | ios/osx/tvos |
| Platform Version | 9.0 |
| SnapKit Version | 3.0.0 |
| Integration Method | carthage/cocoapods/manually (all) |

Issue Description

It's not too obvious on how priorities should be used and what values corresponded to the old priorityLow - priorityRequired without searching through the implementation.

In my opinion creating an enum as simple as:

 public enum Priority: Float {
        case low              = 200.0
        case medium      = 600.0
        case high            = 800.0
        case required     = 1000.0
    }

would remove a lot of ambiguity for what constitutes relative priority and what makes something required. I do think having the flexibility of being able to put on any priority yourself is very helpful, but not knowing the threshold for a constraint being required is unhelpful, so having these enums as just a wrapper for specific values could alleviate that problem.

Additionally adding more documentation around priorities would be helpful as well as there is currently only one example

enhancement help wanted

Most helpful comment

I like the idea of using an enum but IMHO it's often needed to use other priorities:
e.g low + 1, 700.

With this approach we would need to have 2 sets of APIs one that takes Priority and the other that takes a float and to create priorities like low + 1 you would probably need: .low.rawValue + 1... not a fan of this...

So I would enhance the proposed enum in this way:

public enum Priority: Strideable, RawRepresentable, Equatable {
    case low
    case medium
    case high
    case required
    case custom(value: Float)

    public init?(rawValue: Float) {
        // maybe needs some constarints like 0 <= x <= 1000 ?
        self = .custom(value: rawValue)
    }

    public var rawValue: Float {
       // eventually different in iOS & macOS
        switch self {
        case .low:
            return 250
        case .medium:
            return 500
        case .high:
            return 750
        case .required:
            return 1000
        case let .custom(value):
            return value
        }
    }

    public func advanced(by n: Float) -> Priority {
        return .custom(value: self.rawValue + n)
    }

    public func distance(to other: Priority) -> Float {
        return other.rawValue - self.rawValue
    }
}

public func ==(lhs: Priority, rhs: Priority) -> Bool {
    return lhs.rawValue == rhs.rawValue
}

Now you can use : .low +1 🎉

All 7 comments

@Shehryar interesting, I specifically removed the priorityLow/High etc… because they mean very different things on macOS and iOS.

An enum may solve that though because it could be specific to the platform.

@robertjpayne I would be happy to open a PR for it myself. If you have a specific way you would like it to be implemented I'd love to help out and contribute

I like the idea of using an enum but IMHO it's often needed to use other priorities:
e.g low + 1, 700.

With this approach we would need to have 2 sets of APIs one that takes Priority and the other that takes a float and to create priorities like low + 1 you would probably need: .low.rawValue + 1... not a fan of this...

So I would enhance the proposed enum in this way:

public enum Priority: Strideable, RawRepresentable, Equatable {
    case low
    case medium
    case high
    case required
    case custom(value: Float)

    public init?(rawValue: Float) {
        // maybe needs some constarints like 0 <= x <= 1000 ?
        self = .custom(value: rawValue)
    }

    public var rawValue: Float {
       // eventually different in iOS & macOS
        switch self {
        case .low:
            return 250
        case .medium:
            return 500
        case .high:
            return 750
        case .required:
            return 1000
        case let .custom(value):
            return value
        }
    }

    public func advanced(by n: Float) -> Priority {
        return .custom(value: self.rawValue + n)
    }

    public func distance(to other: Priority) -> Float {
        return other.rawValue - self.rawValue
    }
}

public func ==(lhs: Priority, rhs: Priority) -> Bool {
    return lhs.rawValue == rhs.rawValue
}

Now you can use : .low +1 🎉

@Shehryar as @MP0w has labeled above this would be perfect in a PR, granted you may want to have a #if os check to swap it out on macOS.

You'll want to add a method to ConstraintMakerPriortizable to take the Priority enum as an argument and convert it to a raw value as well as the same thing in Constraint.

Unfortunately you can't just make it conform to ConstraintPriorityTarget otherwise there will be ambiguous API issues.

👍 if @Shehryar is not working on it I can do it!

@MP0w help review https://github.com/SnapKit/SnapKit/pull/345? And possibly contribute if you're still interested?

@shehryar any update on the Strideable thing?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mkoppanen picture mkoppanen  ·  3Comments

danieleggert picture danieleggert  ·  3Comments

swiftli picture swiftli  ·  9Comments

aeves313 picture aeves313  ·  4Comments

chengkaizone picture chengkaizone  ·  3Comments