diff --git a/ScalePicker/ScalePicker.swift b/ScalePicker/ScalePicker.swift index d0bfc7e..8a2cb23 100644 --- a/ScalePicker/ScalePicker.swift +++ b/ScalePicker/ScalePicker.swift @@ -19,65 +19,66 @@ public enum ScalePickerValuePosition { public protocol ScalePickerDelegate { func didChangeScaleValue(_ picker: ScalePicker, value: CGFloat) + func willChangeScaleValue(_ picker: ScalePicker, value: CGFloat) } @IBDesignable open class ScalePicker: UIView, SlidePickerDelegate { - + open var delegate: ScalePickerDelegate? - + open var valueChangeHandler: ValueChangeHandler = {(value: CGFloat) in - + } - + open var valuePosition = ScalePickerValuePosition.top { didSet { layoutSubviews() } } - + @IBInspectable open var title: String = "" { didSet { titleLabel.text = title } } - + @IBInspectable open var gradientMaskEnabled: Bool = false { didSet { picker.gradientMaskEnabled = gradientMaskEnabled } } - + @IBInspectable open var invertValues: Bool = false { didSet { picker.invertValues = invertValues } } - + @IBInspectable open var trackProgress: Bool = false { didSet { progressView.alpha = trackProgress ? 1.0 : 0.0 } } - + @IBInspectable open var invertProgress: Bool = false { didSet { layoutProgressView(currentProgress) } } - + @IBInspectable open var fillSides: Bool = false { didSet { picker.fillSides = fillSides } } - + @IBInspectable open var elasticCurrentValue: Bool = false @@ -94,24 +95,24 @@ open class ScalePicker: UIView, SlidePickerDelegate { picker.allTicksWithSameSize = allTicksWithSameSize } } - + @IBInspectable open var showCurrentValue: Bool = false { didSet { valueLabel.alpha = showCurrentValue ? 1.0 : 0.0 - + showTickLabels = !showTickLabels showTickLabels = !showTickLabels } } - + @IBInspectable open var blockedUI: Bool = false { didSet { picker.blockedUI = blockedUI } } - + @IBInspectable open var numberOfTicksBetweenValues: UInt = 4 { didSet { @@ -119,7 +120,7 @@ open class ScalePicker: UIView, SlidePickerDelegate { reset() } } - + @IBInspectable open var minValue: CGFloat = -3.0 { didSet { @@ -127,7 +128,7 @@ open class ScalePicker: UIView, SlidePickerDelegate { reset() } } - + @IBInspectable open var maxValue: CGFloat = 3.0 { didSet { @@ -135,7 +136,7 @@ open class ScalePicker: UIView, SlidePickerDelegate { reset() } } - + @IBInspectable open var spaceBetweenTicks: CGFloat = 10.0 { didSet { @@ -143,7 +144,7 @@ open class ScalePicker: UIView, SlidePickerDelegate { reset() } } - + @IBInspectable open var centerViewWithLabelsYOffset: CGFloat = 15.0 { didSet { @@ -157,14 +158,14 @@ open class ScalePicker: UIView, SlidePickerDelegate { updateCenterViewOffset() } } - + @IBInspectable open var pickerOffset: CGFloat = 0.0 { didSet { layoutSubviews() } } - + @IBInspectable open var tickColor: UIColor = UIColor.white { didSet { @@ -180,17 +181,17 @@ open class ScalePicker: UIView, SlidePickerDelegate { progressView.backgroundColor = progressColor } } - + @IBInspectable open var progressViewSize: CGFloat = 3.0 { didSet { progressView.frame = CGRect(x: 0, y: 0, width: progressViewSize, height: progressViewSize) progressView.layer.cornerRadius = progressViewSize / 2 - + layoutProgressView(currentProgress) } } - + @IBInspectable open var centerArrowImage: UIImage? { didSet { @@ -198,93 +199,93 @@ open class ScalePicker: UIView, SlidePickerDelegate { reset() } } - + @IBInspectable open var showTickLabels: Bool = true { didSet { picker.showTickLabels = showTickLabels - + updateCenterViewOffset() - + layoutSubviews() } } - + @IBInspectable open var snapEnabled: Bool = false { didSet { picker.snapEnabled = snapEnabled } } - + @IBInspectable open var showPlusForPositiveValues: Bool = true { didSet { picker.showPlusForPositiveValues = showPlusForPositiveValues } } - + @IBInspectable open var fireValuesOnScrollEnabled: Bool = true { didSet { picker.fireValuesOnScrollEnabled = fireValuesOnScrollEnabled } } - + @IBInspectable open var bounces: Bool = false { didSet { picker.bounces = bounces } } - + @IBInspectable open var sidePadding: CGFloat = 0.0 { didSet { layoutSubviews() } } - + open var currentTransform: CGAffineTransform = CGAffineTransform.identity { didSet { applyCurrentTransform() } } - + open func applyCurrentTransform() { picker.currentTransform = currentTransform - + if valuePosition == .left { valueLabel.transform = currentTransform } } - + open var values: [CGFloat]? { didSet { guard let values = values, values.count > 1 else { return; } - + picker.values = values - + maxValue = values[values.count - 1] minValue = values[0] initialValue = values[0] } } - + open var valueFormatter: ValueFormatter = {(value: CGFloat) -> NSAttributedString in let attrs = [NSForegroundColorAttributeName: UIColor.white, NSFontAttributeName: UIFont.systemFont(ofSize: 15.0)] - + return NSMutableAttributedString(string: value.format(".2"), attributes: attrs) } - + open var rightView: UIView? { willSet(newRightView) { if let view = rightView { view.removeFromSuperview() } } - + didSet { if let view = rightView { addSubview(view) @@ -300,16 +301,16 @@ open class ScalePicker: UIView, SlidePickerDelegate { view.removeFromSuperview() } } - + didSet { if let view = leftView { addSubview(view) } - + layoutSubviews() } } - + fileprivate let centerImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 10, height: 10)) fileprivate let centerView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 10)) fileprivate let titleLabel = UILabel() @@ -323,64 +324,64 @@ open class ScalePicker: UIView, SlidePickerDelegate { open var currentValue: CGFloat = 0.0 { didSet { if shouldUpdatePicker { - picker.scrollToValue(currentValue, animated: true) + picker.scrollToValue(currentValue, animated: true) } - + valueLabel.attributedText = valueFormatter(currentValue) layoutValueLabel() updateProgressAsync() } } - + fileprivate func updateProgressAsync() { let popTime = DispatchTime.now() + Double(Int64(1.0 * CGFloat(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) - + DispatchQueue.main.asyncAfter(deadline: popTime) { self.picker.updateCurrentProgress() - + if self.trackProgress { UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: UIViewAnimationOptions(), animations: { () -> Void in - + self.progressView.alpha = 1.0 }, completion: nil) } } } - + public override init(frame: CGRect) { super.init(frame: frame) - + commonInit() } - + public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - + commonInit() } - + open func commonInit() { isUserInteractionEnabled = true - + titleLabel.textColor = tickColor titleLabel.textAlignment = .center titleLabel.font = UIFont.systemFont(ofSize: 13.0) - + addSubview(titleLabel) - + valueLabel.textColor = tickColor valueLabel.textAlignment = .center valueLabel.font = UIFont.systemFont(ofSize: 13.0) - + addSubview(valueLabel) - + centerImageView.contentMode = .center centerImageView.center = CGPoint(x: centerView.frame.size.width / 2, y: centerView.frame.size.height / 2 + 5) - + centerView.addSubview(centerImageView) - + picker = SlidePicker(frame: CGRect(x: sidePadding, y: 0, width: frame.size.width - sidePadding * 2, height: frame.size.height)) - + picker.numberOfTicksBetweenValues = numberOfTicksBetweenValues picker.minValue = minValue picker.maxValue = maxValue @@ -392,11 +393,11 @@ open class ScalePicker: UIView, SlidePickerDelegate { picker.tickColor = tickColor picker.centerView = centerView picker.spaceBetweenTicks = spaceBetweenTicks - + updateCenterViewOffset() - + addSubview(picker) - + progressView.frame = CGRect(x: 0, y: 0, width: progressViewSize, height: progressViewSize) progressView.backgroundColor = UIColor.white progressView.alpha = 0.0 @@ -406,32 +407,32 @@ open class ScalePicker: UIView, SlidePickerDelegate { addSubview(progressView) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ScalePicker.onDoubleTap(_:))) - + tapGesture.numberOfTapsRequired = 2 - + addGestureRecognizer(tapGesture) } - + open override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() - + layoutSubviews() reset() } - + open override func layoutSubviews() { super.layoutSubviews() picker.frame = CGRect(x: sidePadding, y: pickerOffset, width: frame.size.width - sidePadding * 2, height: frame.size.height) picker.layoutSubviews() - + let xOffset = gradientMaskEnabled ? picker.frame.size.width * 0.05 : 0.0 if let view = rightView { view.center = CGPoint(x: frame.size.width - xOffset - sidePadding / 2, y: picker.center.y + 5) } - + if let view = leftView { if valuePosition == .left { view.center = CGPoint(x: xOffset + sidePadding / 2, y: ((frame.size.height / 2) - view.frame.height / 4) + 5) @@ -449,58 +450,61 @@ open class ScalePicker: UIView, SlidePickerDelegate { layoutValueLabel() } } - + open func onDoubleTap(_ recognizer: UITapGestureRecognizer) { reset() } - + + open func onValueChangeAndPropagateToDelegate(_ newValue: CGFloat) { + if currentValue != newValue { + delegate?.willChangeScaleValue(self, value: newValue) + currentValue = newValue + delegate?.didChangeScaleValue(self, value: currentValue) + valueChangeHandler(currentValue) + } + } + open func reset() { - currentValue = initialValue - delegate?.didChangeScaleValue(self, value: currentValue) - valueChangeHandler(currentValue) + onValueChangeAndPropagateToDelegate(initialValue) progressView.alpha = 0.0 updateProgressAsync() } - + open func increaseValue() { picker.increaseValue() } - + open func decreaseValue() { picker.decreaseValue() } - + open func setInitialCurrentValue(_ value: CGFloat) { shouldUpdatePicker = false - + currentValue = value initialValue = value - + picker.scrollToValue(value, animated: false) shouldUpdatePicker = true - + progressView.alpha = 0.0 } - + open func didSelectValue(_ value: CGFloat) { shouldUpdatePicker = false - - if value != currentValue { - currentValue = value - delegate?.didChangeScaleValue(self, value: value) - valueChangeHandler(value) - } - + + onValueChangeAndPropagateToDelegate(value) + shouldUpdatePicker = true } - + open func didChangeContentOffset(_ offset: CGFloat, progress: CGFloat) { layoutProgressView(progress) guard elasticCurrentValue else { return } - + let minScale: CGFloat = 0.0 let maxScale: CGFloat = 0.25 let maxOffset: CGFloat = 50.0 @@ -515,9 +519,9 @@ open class ScalePicker: UIView, SlidePickerDelegate { } var value = min(maxScale, max(minScale, offsetValue * (maxScale / maxOffset))) - + value += scaleShift - + if offset < 0 { if value < 0 { if invertValues { @@ -531,17 +535,17 @@ open class ScalePicker: UIView, SlidePickerDelegate { value = 1 - (value - scaleShift) } } - + valueLabel.transform = currentTransform.scaledBy(x: value, y: value) } - + fileprivate func updateCenterViewOffset() { picker.centerViewOffsetY = showTickLabels ? centerViewWithLabelsYOffset : centerViewWithoutLabelsYOffset } - + fileprivate func layoutProgressView(_ progress: CGFloat) { currentProgress = progress - + let updatedProgress = invertProgress ? 1.0 - progress : progress let xOffset = gradientMaskEnabled ? picker.frame.origin.x + (picker.frame.size.width * 0.1) : picker.frame.origin.x let progressWidth = gradientMaskEnabled ? picker.frame.size.width * 0.8 : picker.frame.size.width @@ -551,24 +555,24 @@ open class ScalePicker: UIView, SlidePickerDelegate { if title.isEmpty && valuePosition == .left { yOffset -= 6 } - + progressView.center = CGPoint(x: xOffset + scaledValue, y: yOffset) } - + fileprivate func layoutValueLabel() { let text = valueLabel.attributedText - + guard let textValue = text else { return } let textWidth = valueWidth(textValue) var signOffset: CGFloat = 0 - + if textValue.string.contains("+") || textValue.string.contains("-") { signOffset = 2 } - + let xOffset = gradientMaskEnabled ? picker.frame.size.width * 0.05 : 0.0 - + if valuePosition == .left { if let view = leftView { valueLabel.frame = CGRect(x: view.center.x - signOffset - textWidth / 2, y: 5 + frame.size.height / 2, width: textWidth, height: 16) @@ -581,10 +585,10 @@ open class ScalePicker: UIView, SlidePickerDelegate { valueLabel.center = CGPoint(x: xOffset + sidePadding / 2, y: frame.size.height / 2 - 5) } } - + fileprivate func valueWidth(_ text: NSAttributedString) -> CGFloat { let rect = text.boundingRect(with: CGSize(width: 1024, height: frame.size.width), options: NSStringDrawingOptions.usesLineFragmentOrigin, context: nil) - + return rect.width + 10 } } diff --git a/ScalePicker/SlidePicker.swift b/ScalePicker/SlidePicker.swift index 5281ba2..3b4ed38 100644 --- a/ScalePicker/SlidePicker.swift +++ b/ScalePicker/SlidePicker.swift @@ -22,86 +22,86 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection open var gradientMaskEnabled: Bool = false { didSet { layer.mask = gradientMaskEnabled ? maskLayer : nil - + layoutSubviews() } } - + @IBInspectable open var invertValues: Bool = false { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var fillSides: Bool = false { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var allTicksWithSameSize: Bool = false { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var blockedUI: Bool = false { didSet { uiBlockView.removeFromSuperview() - + if blockedUI { addSubview(uiBlockView) } - + layoutSubviews() } } - + @IBInspectable open var showPlusForPositiveValues: Bool = true { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var snapEnabled: Bool = true - + @IBInspectable open var fireValuesOnScrollEnabled: Bool = true - + @IBInspectable open var showTickLabels: Bool = true { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var highlightCenterTick: Bool = true { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var bounces: Bool = false { didSet { collectionView.bounces = bounces } } - + @IBInspectable open var spaceBetweenTicks: CGFloat = 20.0 { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var centerViewOffsetY: CGFloat = 0.0 { didSet { @@ -114,7 +114,7 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection fileprivate var flowLayout = SlidePickerFlowLayout() fileprivate var collectionView: UICollectionView! fileprivate var tickValue: CGFloat = 1.0 - + fileprivate var maskLayer: CALayer! fileprivate var maskLeftLayer: CAGradientLayer! fileprivate var maskRightLayer: CAGradientLayer! @@ -125,16 +125,16 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection didSet { if let centerView = centerView { centerViewOffsetY = 0.0 - + addSubview(centerView) } } } - + open var values: [CGFloat]? { didSet { guard let values = values , values.count > 1 else { return; } - + updateSectionsCount() requestCollectionViewReloading() @@ -147,43 +147,43 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection requestCollectionViewReloading() } } - + fileprivate var sectionsCount: Int = 0 { didSet { requestCollectionViewReloading() } } - + @IBInspectable open var minValue: CGFloat = 0.0 { didSet { updateSectionsCount() } } - + @IBInspectable open var maxValue: CGFloat = 0.0 { didSet { updateSectionsCount() } } - + fileprivate func updateSectionsCount() { guard minValue < maxValue else { return } - + if let values = values { var sections = (values.count / Int(numberOfTicksBetweenValues + 1)) + 2 - + if values.count % Int(numberOfTicksBetweenValues + 1) > 0 { sections += 1 } - + sectionsCount = sections } else { let items = maxValue - minValue + 1.0 - + if items > 1 { sectionsCount = Int(items) + 2 } else { @@ -191,43 +191,43 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection } } } - + @IBInspectable open var numberOfTicksBetweenValues: UInt = 2 { didSet { tickValue = 1.0 / CGFloat(numberOfTicksBetweenValues + 1) - + updateSectionsCount() } } - + open var currentTransform: CGAffineTransform = CGAffineTransform.identity { didSet { requestCollectionViewReloading() } } - + public override init(frame: CGRect) { super.init(frame: frame) - + commonInit() } - + public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - + commonInit() } - + open func commonInit() { isUserInteractionEnabled = true - + flowLayout.scrollDirection = .horizontal flowLayout.minimumInteritemSpacing = 0.0 flowLayout.minimumLineSpacing = 0.0 collectionView = UICollectionView(frame: frame, collectionViewLayout: flowLayout) - + collectionView.delegate = self collectionView.dataSource = self collectionView.backgroundColor = UIColor.clear @@ -237,14 +237,14 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection collectionView.delaysContentTouches = true collectionView.register(SlidePickerCell.self, forCellWithReuseIdentifier: cellId) - + addSubview(collectionView) - + maskLayer = CALayer() - + maskLayer.frame = CGRect.zero maskLayer.backgroundColor = UIColor.clear.cgColor - + maskLeftLayer = CAGradientLayer() maskLeftLayer.frame = maskLayer.bounds @@ -253,7 +253,7 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection maskLeftLayer.endPoint = CGPoint(x: 0.9, y: 0.0) maskRightLayer = CAGradientLayer() - + maskRightLayer.frame = maskLayer.bounds maskRightLayer.colors = [UIColor.black.cgColor, UIColor.black.withAlphaComponent(0.0).cgColor] maskRightLayer.startPoint = CGPoint(x: 0.1, y: 0.0) @@ -261,32 +261,32 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection maskLayer.addSublayer(maskLeftLayer) maskLayer.addSublayer(maskRightLayer) - + uiBlockView = UIView(frame: self.bounds) } - + fileprivate func requestCollectionViewReloading() { reloadTimer?.invalidate() - + reloadTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(SlidePicker.reloadCollectionView), userInfo: nil, repeats: false) } - + func reloadCollectionView() { reloadTimer?.invalidate() collectionView.reloadData() } - + open override func layoutSubviews() { super.layoutSubviews() - + collectionView.frame = bounds - + centerView?.center = CGPoint(x: frame.size.width / 2, y: centerViewOffsetY + (frame.size.height / 2) - 2) if gradientMaskEnabled { let gradientMaskWidth = frame.size.width / 2 - + maskLayer.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height) maskLeftLayer.frame = CGRect(x: 0, y: 0, width: gradientMaskWidth, height: frame.size.height) maskRightLayer.frame = CGRect(x: frame.size.width - gradientMaskWidth, y: 0, width: gradientMaskWidth, height: frame.size.height) @@ -295,31 +295,31 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection maskLeftLayer.frame = maskLayer.bounds maskRightLayer.frame = maskLayer.bounds } - + uiBlockView.frame = bounds } - + open override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() - + layoutSubviews() } - + open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - + guard sectionsCount > 2 else { return CGSize.zero } - + let regularCellSize = CGSize(width: spaceBetweenTicks, height: bounds.height) - + if ((indexPath as NSIndexPath).section == 0) || ((indexPath as NSIndexPath).section == (sectionsCount - 1)) { if fillSides { let sideItems = (Int(frame.size.width / spaceBetweenTicks) + 2) / 2 if ((indexPath as NSIndexPath).section == 0 && (indexPath as NSIndexPath).row == 0) || ((indexPath as NSIndexPath).section == sectionsCount - 1 && (indexPath as NSIndexPath).row == sideItems - 1) { - + return CGSize(width: (spaceBetweenTicks / 2) - SlidePickerCell.strokeWidth, height: bounds.height) } else { return regularCellSize @@ -328,24 +328,24 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection return CGSize(width: (bounds.width / 2) - (spaceBetweenTicks / 2), height: bounds.height) } } - + return regularCellSize } - + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { guard sectionsCount > 2 else { return 0 } - + if (section == 0) || (section >= (sectionsCount - 1)) { let sideItems = Int(frame.size.width / spaceBetweenTicks) + 2 - + return fillSides ? sideItems / 2 : 1 } else { if let values = values { let elements = (section - 1) * Int(numberOfTicksBetweenValues + 1) let rows = values.count - elements - + if rows > 0 { return min(rows, Int(numberOfTicksBetweenValues + 1)) } else { @@ -362,9 +362,9 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection } open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SlidePickerCell - + cell.indexPath = indexPath cell.tickColor = tickColor cell.showTickLabels = showTickLabels @@ -379,10 +379,10 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection } else { if let values = values { cell.highlightTick = false - + let index = ((indexPath as NSIndexPath).section - 1) * Int(numberOfTicksBetweenValues + 1) + (indexPath as NSIndexPath).row let currentValue = values[index] - + cell.updateValue(currentValue, type: allTicksWithSameSize || (indexPath as NSIndexPath).row == 0 ? .bigStroke : .smallStroke) } else { let currentValue = invertValues ? maxValue - CGFloat((indexPath as NSIndexPath).section - 1) : minValue + CGFloat((indexPath as NSIndexPath).section - 1) @@ -393,7 +393,7 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection } else { cell.highlightTick = false } - + cell.updateValue(currentValue, type: .bigStroke) } else { let value = invertValues ? currentValue - tickValue * CGFloat((indexPath as NSIndexPath).row) : currentValue + tickValue * CGFloat((indexPath as NSIndexPath).row) @@ -402,31 +402,31 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection } } } - + return cell } - + open func numberOfSections(in collectionView: UICollectionView) -> Int { return sectionsCount } - + open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { updateSelectedValue(true) } - + open func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { updateSelectedValue(true) } - + open func scrollViewDidScroll(_ scrollView: UIScrollView) { updateSelectedValue(false) updateCurrentProgress() } - + open func updateCurrentProgress() { let offset = collectionView.contentOffset.x let contentSize = collectionView.contentSize.width - + if offset <= 0 { delegate?.didChangeContentOffset(offset, progress: 0) } else if offset >= contentSize - frame.size.width { @@ -435,32 +435,32 @@ open class SlidePicker: UIView, UICollectionViewDelegateFlowLayout, UICollection delegate?.didChangeContentOffset(0, progress: offset / (collectionView.contentSize.width - frame.size.width)) } } - + open func scrollToValue(_ value: CGFloat, animated: Bool) { var indexPath: IndexPath? - + guard sectionsCount > 0 else { return } - + if let values = values { var valueIndex = 0 - + for index in 0.. 0.00001 && showPlusForPositiveValues { valueLabel.text = "+" + strValue } else { @@ -590,28 +590,28 @@ open class SlidePickerCell: UICollectionViewCell { } } } - + open var indexPath: IndexPath? - + fileprivate let strokeView = UIView() fileprivate let valueLabel = UILabel() fileprivate let strokeWidth: CGFloat = SlidePickerCell.strokeWidth fileprivate var bigStrokePaddind: CGFloat = 4.0 fileprivate var smallStrokePaddind: CGFloat = 8.0 - + open var currentTransform: CGAffineTransform = CGAffineTransform.identity { didSet { valueLabel.transform = currentTransform } } - + open var tickColor = UIColor.white { didSet { strokeView.backgroundColor = tickColor valueLabel.textColor = tickColor } } - + public override init(frame: CGRect) { super.init(frame: frame) commonInit() @@ -621,29 +621,29 @@ open class SlidePickerCell: UICollectionViewCell { super.init(coder: aDecoder) commonInit() } - + open override func prepareForReuse() { super.prepareForReuse() - + strokeView.alpha = 0.0 valueLabel.alpha = 0.0 - + indexPath = nil } - + open func updateValue(_ value: CGFloat, type: SlidePickerCellType) { self.value = value self.type = type - + layoutSubviews() } - + fileprivate func commonInit() { strokeView.backgroundColor = UIColor.white strokeView.alpha = 0.0 strokeView.layer.masksToBounds = true strokeView.layer.cornerRadius = strokeWidth / 2 - + valueLabel.textAlignment = .center valueLabel.font = UIFont.systemFont(ofSize: 12.0) valueLabel.textColor = UIColor.white @@ -652,55 +652,55 @@ open class SlidePickerCell: UICollectionViewCell { contentView.addSubview(strokeView) contentView.addSubview(valueLabel) } - + open override func layoutSubviews() { super.layoutSubviews() - + let height = frame.size.height let xShift: CGFloat = (showPlusForPositiveValues && value > 0.0001) || value < -0.0001 ? SlidePickerCell.signWidth : 0.0 - + switch type { case .empty: strokeView.alpha = 0.0 valueLabel.alpha = 0.0 break - + case .bigStroke: let widthAddition: CGFloat = highlightTick ? 0.5 : 0.0 strokeView.alpha = 1.0 valueLabel.alpha = showTickLabels ? 1.0 : 0.0 - + if showTickLabels { valueLabel.frame = CGRect(x: -5 - xShift, y: 0, width: frame.size.width + 10, height: height / 3) } else { valueLabel.frame = CGRect.zero } - + strokeView.frame = CGRect(x: (frame.size.width / 2) - (strokeWidth / 2) - widthAddition, y: (height / 3) + bigStrokePaddind, width: strokeWidth + widthAddition * 2, height: (height / 2) - (bigStrokePaddind * 2)) strokeView.layer.cornerRadius = strokeView.frame.width - + break case .smallStroke: strokeView.alpha = 1.0 valueLabel.alpha = 0.0 - + if showTickLabels { valueLabel.frame = CGRect(x: -xShift, y: 0, width: frame.size.width, height: height / 2) } else { valueLabel.frame = CGRect.zero } - + strokeView.frame = CGRect(x: (frame.size.width / 2) - (strokeWidth / 2), y: (height / 3) + smallStrokePaddind, width: strokeWidth, height: (height / 2) - (smallStrokePaddind * 2)) - + strokeView.layer.cornerRadius = strokeView.frame.width - + break } } @@ -709,27 +709,27 @@ open class SlidePickerCell: UICollectionViewCell { internal extension UIImage { internal func tintImage(_ color: UIColor) -> UIImage { let scale: CGFloat = 2.0 - + UIGraphicsBeginImageContextWithOptions(size, false, scale) - + let context = UIGraphicsGetCurrentContext() - + context?.translateBy(x: 0, y: size.height) context?.scaleBy(x: 1.0, y: -1.0) - + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) - + context?.setBlendMode(.normal) context?.draw(cgImage!, in: rect) - + context?.setBlendMode(.sourceIn) color.setFill() context?.fill(rect) - + let coloredImage = UIGraphicsGetImageFromCurrentImageContext() - + UIGraphicsEndImageContext() - + return coloredImage!.withRenderingMode(.alwaysOriginal) } }