diff --git a/PickerDialog.swift b/PickerDialog.swift index ae83fb1..47ba5fa 100644 --- a/PickerDialog.swift +++ b/PickerDialog.swift @@ -8,32 +8,42 @@ import Foundation import UIKit import QuartzCore +extension UIColor { + convenience init(hex: Int, alpha: Float = 1.0){ + let r = Float((hex >> 16) & 0xFF) + let g = Float((hex >> 8) & 0xFF) + let b = Float((hex) & 0xFF) + + self.init(red: CGFloat(r / 255.0), green: CGFloat(g / 255.0), blue:CGFloat(b / 255.0), alpha: CGFloat(alpha)) + } +} + class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { - typealias PickerCallback = (value: String) -> Void + typealias PickerCallback = (_ value: String) -> Void /* Constants */ - private let kPickerDialogDefaultButtonHeight: CGFloat = 50 - private let kPickerDialogDefaultButtonSpacerHeight: CGFloat = 1 - private let kPickerDialogCornerRadius: CGFloat = 7 - private let kPickerDialogDoneButtonTag: Int = 1 + fileprivate let kPickerDialogDefaultButtonHeight: CGFloat = 50 + fileprivate let kPickerDialogDefaultButtonSpacerHeight: CGFloat = 1 + fileprivate let kPickerDialogCornerRadius: CGFloat = 7 + fileprivate let kPickerDialogDoneButtonTag: Int = 1 /* Views */ - private var dialogView: UIView! - private var titleLabel: UILabel! - private var picker: UIPickerView! - private var cancelButton: UIButton! - private var doneButton: UIButton! + fileprivate var dialogView: UIView! + fileprivate var titleLabel: UILabel! + fileprivate var picker: UIPickerView! + fileprivate var cancelButton: UIButton! + fileprivate var doneButton: UIButton! /* Variables */ - private var pickerData = [[String: String]]() - private var selectedPickerValue: String? - private var callback: PickerCallback? + fileprivate var pickerData = [[String: String]]() + fileprivate var selectedPickerValue: String? + fileprivate var callback: PickerCallback? /* Overrides */ init() { - super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height)) + super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)) setupView() } @@ -46,10 +56,10 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { self.dialogView = createContainerView() self.dialogView!.layer.shouldRasterize = true - self.dialogView!.layer.rasterizationScale = UIScreen.mainScreen().scale + self.dialogView!.layer.rasterizationScale = UIScreen.main.scale self.layer.shouldRasterize = true - self.layer.rasterizationScale = UIScreen.mainScreen().scale + self.layer.rasterizationScale = UIScreen.main.scale self.dialogView!.layer.opacity = 0.5 self.dialogView!.layer.transform = CATransform3DMakeScale(1.3, 1.3, 1) @@ -62,26 +72,26 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* Handle device orientation changes */ - func deviceOrientationDidChange(notification: NSNotification) { + func deviceOrientationDidChange(_ notification: Notification) { close() // For now just close it } /* Required UIPickerView functions */ - func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { + func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } - func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return pickerData.count } - func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return pickerData[row]["display"] } /* Helper to find row of selected value */ - func findIndexForValue(value: String, array: [[String: String]]) -> Int? { - for (index, dictionary) in array.enumerate() { + func findIndexForValue(_ value: String, array: [[String: String]]) -> Int? { + for (index, dictionary) in array.enumerated() { if dictionary["value"] == value { return index } @@ -91,11 +101,11 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* Create the dialog view, and animate opening the dialog */ - func show(title: String, doneButtonTitle: String = "Done", cancelButtonTitle: String = "Cancel", options: [[String: String]], selected: String? = nil, callback: PickerCallback) { + func show(_ title: String, doneButtonTitle: String = "Done", cancelButtonTitle: String = "Cancel", options: [[String: String]], selected: String? = nil, callback: @escaping PickerCallback) { self.titleLabel.text = title self.pickerData = options - self.doneButton.setTitle(doneButtonTitle, forState: .Normal) - self.cancelButton.setTitle(cancelButtonTitle, forState: .Normal) + self.doneButton.setTitle(doneButtonTitle, for: UIControlState()) + self.cancelButton.setTitle(cancelButtonTitle, for: UIControlState()) self.callback = callback if selected != nil { @@ -105,16 +115,16 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* */ - UIApplication.sharedApplication().windows.first!.addSubview(self) - UIApplication.sharedApplication().windows.first!.endEditing(true) + UIApplication.shared.windows.first!.addSubview(self) + UIApplication.shared.windows.first!.endEditing(true) - NSNotificationCenter.defaultCenter().addObserver(self, selector: "deviceOrientationDidChange:", name: UIDeviceOrientationDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(PickerDialog.deviceOrientationDidChange(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) /* Anim */ - UIView.animateWithDuration( - 0.2, + UIView.animate( + withDuration: 0.2, delay: 0, - options: UIViewAnimationOptions.CurveEaseInOut, + options: UIViewAnimationOptions(), animations: { () -> Void in self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4) self.dialogView!.layer.opacity = 1 @@ -125,21 +135,21 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* Dialog close animation then cleaning and removing the view from the parent */ - private func close() { - NSNotificationCenter.defaultCenter().removeObserver(self) + fileprivate func close() { + NotificationCenter.default.removeObserver(self) let currentTransform = self.dialogView.layer.transform - let startRotation = (self.valueForKeyPath("layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0 + let startRotation = (self.value(forKeyPath: "layer.transform.rotation.z") as? NSNumber) as? Double ?? 0.0 let rotation = CATransform3DMakeRotation((CGFloat)(-startRotation + M_PI * 270 / 180), 0, 0, 0) self.dialogView.layer.transform = CATransform3DConcat(rotation, CATransform3DMakeScale(1, 1, 1)) self.dialogView.layer.opacity = 1 - UIView.animateWithDuration( - 0.2, + UIView.animate( + withDuration: 0.2, delay: 0, - options: UIViewAnimationOptions.TransitionNone, + options: UIViewAnimationOptions(), animations: { () -> Void in self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0) self.dialogView.layer.transform = CATransform3DConcat(currentTransform, CATransform3DMakeScale(0.6, 0.6, 1)) @@ -154,56 +164,56 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* Creates the container view here: create the dialog, then add the custom content and buttons */ - private func createContainerView() -> UIView { + fileprivate func createContainerView() -> UIView { let screenSize = countScreenSize() - let dialogSize = CGSizeMake( - 300, - 230 + let dialogSize = CGSize( + width: 300, + height: 230 + kPickerDialogDefaultButtonHeight + kPickerDialogDefaultButtonSpacerHeight) // For the black background - self.frame = CGRectMake(0, 0, screenSize.width, screenSize.height) + self.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height) // This is the dialog's container; we attach the custom content and the buttons to this one - let dialogContainer = UIView(frame: CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height)) + let dialogContainer = UIView(frame: CGRect(x: (screenSize.width - dialogSize.width) / 2, y: (screenSize.height - dialogSize.height) / 2, width: dialogSize.width, height: dialogSize.height)) // First, we style the dialog to match the iOS8 UIAlertView >>> let gradient: CAGradientLayer = CAGradientLayer(layer: self.layer) gradient.frame = dialogContainer.bounds - gradient.colors = [UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor, - UIColor(red: 233/255, green: 233/255, blue: 233/255, alpha: 1).CGColor, - UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).CGColor] + gradient.colors = [UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).cgColor, + UIColor(red: 233/255, green: 233/255, blue: 233/255, alpha: 1).cgColor, + UIColor(red: 218/255, green: 218/255, blue: 218/255, alpha: 1).cgColor] let cornerRadius = kPickerDialogCornerRadius gradient.cornerRadius = cornerRadius - dialogContainer.layer.insertSublayer(gradient, atIndex: 0) + dialogContainer.layer.insertSublayer(gradient, at: 0) dialogContainer.layer.cornerRadius = cornerRadius - dialogContainer.layer.borderColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1).CGColor + dialogContainer.layer.borderColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1).cgColor dialogContainer.layer.borderWidth = 1 dialogContainer.layer.shadowRadius = cornerRadius + 5 dialogContainer.layer.shadowOpacity = 0.1 - dialogContainer.layer.shadowOffset = CGSizeMake(0 - (cornerRadius + 5) / 2, 0 - (cornerRadius + 5) / 2) - dialogContainer.layer.shadowColor = UIColor.blackColor().CGColor - dialogContainer.layer.shadowPath = UIBezierPath(roundedRect: dialogContainer.bounds, cornerRadius: dialogContainer.layer.cornerRadius).CGPath + dialogContainer.layer.shadowOffset = CGSize(width: 0 - (cornerRadius + 5) / 2, height: 0 - (cornerRadius + 5) / 2) + dialogContainer.layer.shadowColor = UIColor.black.cgColor + dialogContainer.layer.shadowPath = UIBezierPath(roundedRect: dialogContainer.bounds, cornerRadius: dialogContainer.layer.cornerRadius).cgPath // There is a line above the button - let lineView = UIView(frame: CGRectMake(0, dialogContainer.bounds.size.height - kPickerDialogDefaultButtonHeight - kPickerDialogDefaultButtonSpacerHeight, dialogContainer.bounds.size.width, kPickerDialogDefaultButtonSpacerHeight)) + let lineView = UIView(frame: CGRect(x: 0, y: dialogContainer.bounds.size.height - kPickerDialogDefaultButtonHeight - kPickerDialogDefaultButtonSpacerHeight, width: dialogContainer.bounds.size.width, height: kPickerDialogDefaultButtonSpacerHeight)) lineView.backgroundColor = UIColor(red: 198/255, green: 198/255, blue: 198/255, alpha: 1) dialogContainer.addSubview(lineView) // ˆˆˆ //Title - self.titleLabel = UILabel(frame: CGRectMake(10, 10, 280, 30)) - self.titleLabel.textAlignment = NSTextAlignment.Center + self.titleLabel = UILabel(frame: CGRect(x: 10, y: 10, width: 280, height: 30)) + self.titleLabel.textAlignment = NSTextAlignment.center self.titleLabel.textColor = UIColor(hex: 0x333333) self.titleLabel.font = UIFont(name: "AvenirNext-Medium", size: 16) dialogContainer.addSubview(self.titleLabel) - self.picker = UIPickerView(frame: CGRectMake(0, 30, 0, 0)) + self.picker = UIPickerView(frame: CGRect(x: 0, y: 30, width: 0, height: 0)) self.picker.setValue(UIColor(hex: 0x333333), forKeyPath: "textColor") - self.picker.autoresizingMask = UIViewAutoresizing.FlexibleRightMargin + self.picker.autoresizingMask = UIViewAutoresizing.flexibleRightMargin self.picker.frame.size.width = 300 dialogContainer.addSubview(self.picker) @@ -215,44 +225,44 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { } /* Add buttons to container */ - private func addButtonsToView(container: UIView) { + fileprivate func addButtonsToView(_ container: UIView) { let buttonWidth = container.bounds.size.width / 2 - self.cancelButton = UIButton(type: UIButtonType.Custom) as UIButton - self.cancelButton.frame = CGRectMake( - 0, - container.bounds.size.height - kPickerDialogDefaultButtonHeight, - buttonWidth, - kPickerDialogDefaultButtonHeight + self.cancelButton = UIButton(type: UIButtonType.custom) as UIButton + self.cancelButton.frame = CGRect( + x: 0, + y: container.bounds.size.height - kPickerDialogDefaultButtonHeight, + width: buttonWidth, + height: kPickerDialogDefaultButtonHeight ) - self.cancelButton.setTitleColor(UIColor(hex: 0x555555), forState: UIControlState.Normal) - self.cancelButton.setTitleColor(UIColor(hex: 0x555555), forState: UIControlState.Highlighted) + self.cancelButton.setTitleColor(UIColor(hex: 0x555555), for: UIControlState.normal) + self.cancelButton.setTitleColor(UIColor(hex: 0x555555), for: UIControlState.highlighted) self.cancelButton.titleLabel!.font = UIFont(name: "AvenirNext-Medium", size: 15) self.cancelButton.layer.cornerRadius = kPickerDialogCornerRadius - self.cancelButton.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside) + self.cancelButton.addTarget(self, action: #selector(PickerDialog.buttonTapped(_:)), for: UIControlEvents.touchUpInside) container.addSubview(self.cancelButton) - self.doneButton = UIButton(type: UIButtonType.Custom) as UIButton - self.doneButton.frame = CGRectMake( - buttonWidth, - container.bounds.size.height - kPickerDialogDefaultButtonHeight, - buttonWidth, - kPickerDialogDefaultButtonHeight + self.doneButton = UIButton(type: UIButtonType.custom) as UIButton + self.doneButton.frame = CGRect( + x: buttonWidth, + y: container.bounds.size.height - kPickerDialogDefaultButtonHeight, + width: buttonWidth, + height: kPickerDialogDefaultButtonHeight ) self.doneButton.tag = kPickerDialogDoneButtonTag - self.doneButton.setTitleColor(UIColor(hex: 0x555555), forState: UIControlState.Normal) - self.doneButton.setTitleColor(UIColor(hex: 0x555555), forState: UIControlState.Highlighted) + self.doneButton.setTitleColor(UIColor(hex: 0x555555), for: UIControlState.normal) + self.doneButton.setTitleColor(UIColor(hex: 0x555555), for: UIControlState.highlighted) self.doneButton.titleLabel!.font = UIFont(name: "AvenirNext-Medium", size: 15) self.doneButton.layer.cornerRadius = kPickerDialogCornerRadius - self.doneButton.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside) + self.doneButton.addTarget(self, action: #selector(PickerDialog.buttonTapped(_:)), for: UIControlEvents.touchUpInside) container.addSubview(self.doneButton) } - func buttonTapped(sender: UIButton!) { + func buttonTapped(_ sender: UIButton!) { if sender.tag == kPickerDialogDoneButtonTag { - let selectedIndex = self.picker.selectedRowInComponent(0) + let selectedIndex = self.picker.selectedRow(inComponent: 0) let selectedValue = self.pickerData[selectedIndex]["value"] - self.callback?(value: selectedValue!) + self.callback?(selectedValue!) } close() @@ -260,9 +270,10 @@ class PickerDialog: UIView, UIPickerViewDataSource, UIPickerViewDelegate { /* Helper function: count and return the screen's size */ func countScreenSize() -> CGSize { - let screenWidth = UIScreen.mainScreen().applicationFrame.size.width - let screenHeight = UIScreen.mainScreen().bounds.size.height + let screenWidth = UIScreen.main.applicationFrame.size.width + let screenHeight = UIScreen.main.bounds.size.height - return CGSizeMake(screenWidth, screenHeight) + return CGSize(width: screenWidth, height: screenHeight) } } +