Skip to content

Commit

Permalink
- Converted to Swift 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
glenyi committed Sep 23, 2016
1 parent c01a331 commit 11b0c15
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 54 deletions.
80 changes: 40 additions & 40 deletions FloatRatingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,38 @@ import UIKit
/**
Returns the rating value when touch events end
*/
func floatRatingView(ratingView: FloatRatingView, didUpdate rating: Float)
func floatRatingView(_ ratingView: FloatRatingView, didUpdate rating: Float)

/**
Returns the rating value as the user pans
*/
optional func floatRatingView(ratingView: FloatRatingView, isUpdating rating: Float)
@objc optional func floatRatingView(_ ratingView: FloatRatingView, isUpdating rating: Float)
}

/**
A simple rating view that can set whole, half or floating point ratings.
*/
@IBDesignable
public class FloatRatingView: UIView {
open class FloatRatingView: UIView {

// MARK: Properties

public weak var delegate: FloatRatingViewDelegate?
open weak var delegate: FloatRatingViewDelegate?

/**
Array of empty image views
*/
private var emptyImageViews: [UIImageView] = []
fileprivate var emptyImageViews: [UIImageView] = []

/**
Array of full image views
*/
private var fullImageViews: [UIImageView] = []
fileprivate var fullImageViews: [UIImageView] = []

/**
Sets the empty image (e.g. a star outline)
*/
@IBInspectable public var emptyImage: UIImage? {
@IBInspectable open var emptyImage: UIImage? {
didSet {
// Update empty image views
for imageView in emptyImageViews {
Expand All @@ -57,7 +57,7 @@ public class FloatRatingView: UIView {
Sets the full image that is overlayed on top of the empty image.
Should be same size and shape as the empty image.
*/
@IBInspectable public var fullImage: UIImage? {
@IBInspectable open var fullImage: UIImage? {
didSet {
// Update full image views
for imageView in fullImageViews {
Expand All @@ -70,12 +70,12 @@ public class FloatRatingView: UIView {
/**
Sets the empty and full image view content mode.
*/
var imageContentMode: UIViewContentMode = UIViewContentMode.ScaleAspectFit
var imageContentMode: UIViewContentMode = UIViewContentMode.scaleAspectFit

/**
Minimum rating.
*/
@IBInspectable public var minRating: Int = 0 {
@IBInspectable open var minRating: Int = 0 {
didSet {
// Update current rating if needed
if rating < Float(minRating) {
Expand All @@ -88,7 +88,7 @@ public class FloatRatingView: UIView {
/**
Max rating value.
*/
@IBInspectable public var maxRating: Int = 5 {
@IBInspectable open var maxRating: Int = 5 {
didSet {
if maxRating != oldValue {
removeImageViews()
Expand All @@ -104,12 +104,12 @@ public class FloatRatingView: UIView {
/**
Minimum image size.
*/
@IBInspectable public var minImageSize: CGSize = CGSize(width: 5.0, height: 5.0)
@IBInspectable open var minImageSize: CGSize = CGSize(width: 5.0, height: 5.0)

/**
Set the current rating.
*/
@IBInspectable public var rating: Float = 0 {
@IBInspectable open var rating: Float = 0 {
didSet {
if rating != oldValue {
refresh()
Expand All @@ -120,17 +120,17 @@ public class FloatRatingView: UIView {
/**
Sets whether or not the rating view can be changed by panning.
*/
@IBInspectable public var editable: Bool = true
@IBInspectable open var editable: Bool = true

/**
Ratings change by 0.5. Takes priority over floatRatings property.
*/
@IBInspectable public var halfRatings: Bool = false
@IBInspectable open var halfRatings: Bool = false

/**
Ratings change by floating point values.
*/
@IBInspectable public var floatRatings: Bool = false
@IBInspectable open var floatRatings: Bool = false


// MARK: Initializations
Expand All @@ -149,7 +149,7 @@ public class FloatRatingView: UIView {

// MARK: Helper methods

private func initImageViews() {
fileprivate func initImageViews() {
guard emptyImageViews.isEmpty && fullImageViews.isEmpty else {
return
}
Expand All @@ -170,77 +170,77 @@ public class FloatRatingView: UIView {
}
}

private func removeImageViews() {
fileprivate func removeImageViews() {
// Remove old image views
for i in 0..<emptyImageViews.count {
var imageView = emptyImageViews[i]
imageView.removeFromSuperview()
imageView = fullImageViews[i]
imageView.removeFromSuperview()
}
emptyImageViews.removeAll(keepCapacity: false)
fullImageViews.removeAll(keepCapacity: false)
emptyImageViews.removeAll(keepingCapacity: false)
fullImageViews.removeAll(keepingCapacity: false)
}

// Refresh hides or shows full images
private func refresh() {
fileprivate func refresh() {
for i in 0..<fullImageViews.count {
let imageView = fullImageViews[i]

if rating >= Float(i+1) {
imageView.layer.mask = nil
imageView.hidden = false
imageView.isHidden = false
} else if rating > Float(i) && rating < Float(i+1) {
// Set mask layer for full image
let maskLayer = CALayer()
maskLayer.frame = CGRectMake(0, 0, CGFloat(rating-Float(i))*imageView.frame.size.width, imageView.frame.size.height)
maskLayer.backgroundColor = UIColor.blackColor().CGColor
maskLayer.frame = CGRect(x: 0, y: 0, width: CGFloat(rating-Float(i))*imageView.frame.size.width, height: imageView.frame.size.height)
maskLayer.backgroundColor = UIColor.black.cgColor
imageView.layer.mask = maskLayer
imageView.hidden = false
imageView.isHidden = false
} else {
imageView.layer.mask = nil;
imageView.hidden = true
imageView.isHidden = true
}
}
}

// Calculates the ideal ImageView size in a given CGSize
private func sizeForImage(image: UIImage, inSize size: CGSize) -> CGSize {
fileprivate func sizeForImage(_ image: UIImage, inSize size: CGSize) -> CGSize {
let imageRatio = image.size.width / image.size.height
let viewRatio = size.width / size.height

if imageRatio < viewRatio {
let scale = size.height / image.size.height
let width = scale * image.size.width

return CGSizeMake(width, size.height)
return CGSize(width: width, height: size.height)
} else {
let scale = size.width / image.size.width
let height = scale * image.size.height

return CGSizeMake(size.width, height)
return CGSize(width: size.width, height: height)
}
}

// Calculates new rating based on touch location in view
private func updateLocation(touch: UITouch) {
fileprivate func updateLocation(_ touch: UITouch) {
guard editable else {
return
}

let touchLocation = touch.locationInView(self)
let touchLocation = touch.location(in: self)
var newRating: Float = 0
for i in (maxRating-1).stride(through: 0, by: -1) {
for i in stride(from: (maxRating-1), through: 0, by: -1) {
let imageView = emptyImageViews[i]
guard touchLocation.x > imageView.frame.origin.x else {
continue
}

// Find touch point in image view
let newLocation = imageView.convertPoint(touchLocation, fromView: self)
let newLocation = imageView.convert(touchLocation, from: self)

// Find decimal value for float or half rating
if imageView.pointInside(newLocation, withEvent: nil) && (floatRatings || halfRatings) {
if imageView.point(inside: newLocation, with: nil) && (floatRatings || halfRatings) {
let decimalNum = Float(newLocation.x / imageView.frame.size.width)
newRating = Float(i) + decimalNum
if halfRatings {
Expand All @@ -263,7 +263,7 @@ public class FloatRatingView: UIView {
// MARK: UIView

// Override to calculate ImageView frames
override public func layoutSubviews() {
override open func layoutSubviews() {
super.layoutSubviews()

guard let emptyImage = emptyImage else {
Expand All @@ -273,12 +273,12 @@ public class FloatRatingView: UIView {
let desiredImageWidth = frame.size.width / CGFloat(emptyImageViews.count)
let maxImageWidth = max(minImageSize.width, desiredImageWidth)
let maxImageHeight = max(minImageSize.height, frame.size.height)
let imageViewSize = sizeForImage(emptyImage, inSize: CGSizeMake(maxImageWidth, maxImageHeight))
let imageViewSize = sizeForImage(emptyImage, inSize: CGSize(width: maxImageWidth, height: maxImageHeight))
let imageXOffset = (frame.size.width - (imageViewSize.width * CGFloat(emptyImageViews.count))) /
CGFloat((emptyImageViews.count - 1))

for i in 0..<maxRating {
let imageFrame = CGRectMake(i == 0 ? 0 : CGFloat(i)*(imageXOffset+imageViewSize.width), 0, imageViewSize.width, imageViewSize.height)
let imageFrame = CGRect(x: i == 0 ? 0 : CGFloat(i)*(imageXOffset+imageViewSize.width), y: 0, width: imageViewSize.width, height: imageViewSize.height)

var imageView = emptyImageViews[i]
imageView.frame = imageFrame
Expand All @@ -292,21 +292,21 @@ public class FloatRatingView: UIView {

// MARK: Touch events

override public func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
updateLocation(touch)
}

override public func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
updateLocation(touch)
}

override public func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// Update delegate
delegate?.floatRatingView(self, didUpdate: rating)
}
Expand Down
4 changes: 2 additions & 2 deletions Rating Demo/Rating Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.onthepursuit.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -281,7 +281,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.onthepursuit.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 2.3;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
12 changes: 6 additions & 6 deletions Rating Demo/Rating Demo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

Expand Down
4 changes: 2 additions & 2 deletions Rating Demo/Rating Demo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.3</string>
<string>2.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3</string>
<string>4</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
Expand Down
8 changes: 4 additions & 4 deletions Rating Demo/Rating Demo/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ViewController: UIViewController, FloatRatingViewDelegate {
self.floatRatingView.fullImage = UIImage(named: "StarFull")
// Optional params
self.floatRatingView.delegate = self
self.floatRatingView.contentMode = UIViewContentMode.ScaleAspectFit
self.floatRatingView.contentMode = UIViewContentMode.scaleAspectFit
self.floatRatingView.maxRating = 5
self.floatRatingView.minRating = 1
self.floatRatingView.rating = 2.5
Expand All @@ -47,18 +47,18 @@ class ViewController: UIViewController, FloatRatingViewDelegate {
// Dispose of any resources that can be recreated.
}

@IBAction func ratingTypeChanged(sender: UISegmentedControl) {
@IBAction func ratingTypeChanged(_ sender: UISegmentedControl) {
self.floatRatingView.halfRatings = sender.selectedSegmentIndex==1
self.floatRatingView.floatRatings = sender.selectedSegmentIndex==2
}

// MARK: FloatRatingViewDelegate

func floatRatingView(ratingView: FloatRatingView, isUpdating rating:Float) {
func floatRatingView(_ ratingView: FloatRatingView, isUpdating rating:Float) {
self.liveLabel.text = NSString(format: "%.2f", self.floatRatingView.rating) as String
}

func floatRatingView(ratingView: FloatRatingView, didUpdate rating: Float) {
func floatRatingView(_ ratingView: FloatRatingView, didUpdate rating: Float) {
self.updatedLabel.text = NSString(format: "%.2f", self.floatRatingView.rating) as String
}

Expand Down

0 comments on commit 11b0c15

Please sign in to comment.