diff --git a/Cosmos/CosmosAccessibility.swift b/Cosmos/CosmosAccessibility.swift index 3247205..90c39af 100644 --- a/Cosmos/CosmosAccessibility.swift +++ b/Cosmos/CosmosAccessibility.swift @@ -68,7 +68,7 @@ struct CosmosAccessibility { increment = ceil(rating) - rating if increment == 0 { increment = 1 } - case .half, .precise: + case .half, .precise, .quarter: increment = (ceil(rating * 2) - rating * 2) / 2 if increment == 0 { increment = 0.5 } } @@ -87,7 +87,7 @@ struct CosmosAccessibility { increment = rating - floor(rating) if increment == 0 { increment = 1 } - case .half, .precise: + case .half, .precise, .quarter: increment = (rating * 2 - floor(rating * 2)) / 2 if increment == 0 { increment = 0.5 } } diff --git a/Cosmos/CosmosRating.swift b/Cosmos/CosmosRating.swift index bcdcbfb..96120fe 100644 --- a/Cosmos/CosmosRating.swift +++ b/Cosmos/CosmosRating.swift @@ -47,6 +47,8 @@ struct CosmosRating { return Double(round(starFillLevel * 2) / 2) case .precise : return starFillLevel + case .quarter: + return Double(round(starFillLevel * 4) / 4) } } diff --git a/Cosmos/StarFillMode.swift b/Cosmos/StarFillMode.swift index 6261af2..d4bb7a1 100644 --- a/Cosmos/StarFillMode.swift +++ b/Cosmos/StarFillMode.swift @@ -14,4 +14,7 @@ public enum StarFillMode: Int { /// Fill star according to decimal rating. For example, fourth star will be 20% filled for 3.2. case precise = 2 + + /// Show fully filled and half-filled , quarter-filled stars. For example, fourth star will be quarter filled for 3.75. + case quarter = 3 } diff --git a/CosmosTests/CosmosRatingTests.swift b/CosmosTests/CosmosRatingTests.swift index fe27112..b4e2e4f 100644 --- a/CosmosTests/CosmosRatingTests.swift +++ b/CosmosTests/CosmosRatingTests.swift @@ -9,6 +9,9 @@ class CosmosDisplayedRatingTests: XCTestCase { var result = CosmosRating.displayedRatingFromPreciseRating(4.6, fillMode: .half, totalStars: 5) XCTAssertEqual(4.5, result) + result = CosmosRating.displayedRatingFromPreciseRating(4.6, fillMode: .quarter, totalStars: 5) + XCTAssertEqual(4.5, result) + result = CosmosRating.displayedRatingFromPreciseRating(4.6, fillMode: .full, totalStars: 5) XCTAssertEqual(5, result) @@ -22,10 +25,16 @@ class CosmosDisplayedRatingTests: XCTestCase { var result = CosmosRating.displayedRatingFromPreciseRating(7, fillMode: .half, totalStars: 5) XCTAssertEqual(5, result) + result = CosmosRating.displayedRatingFromPreciseRating(7, fillMode: .quarter, totalStars: 5) + XCTAssertEqual(5, result) + // Rating is less than zero result = CosmosRating.displayedRatingFromPreciseRating(-1, fillMode: .half, totalStars: 5) XCTAssertEqual(0, result) + + result = CosmosRating.displayedRatingFromPreciseRating(-1, fillMode: .quarter, totalStars: 5) + XCTAssertEqual(0, result) } // MARK: - Star fill level @@ -53,6 +62,12 @@ class CosmosDisplayedRatingTests: XCTestCase { XCTAssertEqual(0.5, result) } + + func testStarFillLevel_partiallyFileldQuarter() { + let result = CosmosRating.starFillLevel(ratingRemainder: 0.67, fillMode: .quarter) + + XCTAssertEqual(0.75, result) + } func testStarFillLevel_partiallyFileldFull() { let result = CosmosRating.starFillLevel(ratingRemainder: 0.67, fillMode: .full) @@ -80,6 +95,18 @@ class CosmosDisplayedRatingTests: XCTestCase { XCTAssertEqual(1, CosmosRating.roundFillLevel(0.9, fillMode: .half)) XCTAssertEqual(1, CosmosRating.roundFillLevel(1, fillMode: .half)) } + + func testRoundFillLevel_quarter() { + XCTAssertEqual(0, CosmosRating.roundFillLevel(0, fillMode: .quarter)) + XCTAssertEqual(0.0, CosmosRating.roundFillLevel(0.1, fillMode: .quarter)) + XCTAssertEqual(0.25, CosmosRating.roundFillLevel(0.25, fillMode: .quarter)) + XCTAssertEqual(0.25, CosmosRating.roundFillLevel(0.3, fillMode: .quarter)) + XCTAssertEqual(0.5, CosmosRating.roundFillLevel(0.5, fillMode: .quarter)) + XCTAssertEqual(0.5, CosmosRating.roundFillLevel(0.6, fillMode: .quarter)) + XCTAssertEqual(0.75, CosmosRating.roundFillLevel(0.75, fillMode: .quarter)) + XCTAssertEqual(1, CosmosRating.roundFillLevel(0.9, fillMode: .quarter)) + XCTAssertEqual(1, CosmosRating.roundFillLevel(1, fillMode: .quarter)) + } func testRoundFillLevel_precise() { XCTAssertEqual(0, CosmosRating.roundFillLevel(0, fillMode: .precise)) diff --git a/Distrib/CosmosDistrib.swift b/Distrib/CosmosDistrib.swift index 287e70c..2940d64 100644 --- a/Distrib/CosmosDistrib.swift +++ b/Distrib/CosmosDistrib.swift @@ -29,6 +29,9 @@ public enum StarFillMode: Int { /// Fill star according to decimal rating. For example, fourth star will be 20% filled for 3.2. case precise = 2 + + /// Show fully filled and half-filled , quarter-filled stars. For example, fourth star will be quarter filled for 3.75. + case quarter = 3 } @@ -275,7 +278,7 @@ struct CosmosAccessibility { increment = ceil(rating) - rating if increment == 0 { increment = 1 } - case .half, .precise: + case .half, .precise, .quarter: increment = (ceil(rating * 2) - rating * 2) / 2 if increment == 0 { increment = 0.5 } } @@ -294,7 +297,7 @@ struct CosmosAccessibility { increment = rating - floor(rating) if increment == 0 { increment = 1 } - case .half, .precise: + case .half, .precise, .quarter: increment = (rating * 2 - floor(rating * 2)) / 2 if increment == 0 { increment = 0.5 } } @@ -938,6 +941,8 @@ struct CosmosRating { return Double(round(starFillLevel * 2) / 2) case .precise : return starFillLevel + case .quarter: + return Double(round(starFillLevel * 4) / 4) } } diff --git a/README.md b/README.md index a3cc930..4105321 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ cosmosView.settings.updateOnTouch = false // Show only fully filled stars cosmosView.settings.fillMode = .full -// Other fill modes: .half, .precise +// Other fill modes: .half, .precise, .quarter // Change the size of the stars cosmosView.settings.starSize = 30