Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the ability to pass in an image for the circle slider view. #4

Merged
merged 5 commits into from
Jan 4, 2017
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 70 additions & 19 deletions Sources/SlidableImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@

import UIKit

public enum SlideDirection: Int {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum should have comment

case left
case right
case top
case bottom
}

public struct SlidableImageBorder {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct also

var borderWidth: CGFloat
var borderColor: CGColor

public init(borderWidth width: CGFloat, borderColor color: CGColor) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This init is not necessary

self.borderWidth = width
self.borderColor = color
}
}

/// Super easy Slider for before&after images
open class SlidableImage: UIView {

Expand All @@ -20,16 +37,20 @@ open class SlidableImage: UIView {
/// Circle view with icon for sliding images. You can override it with your custom view.
open var sliderCircle: UIView

/// Enum that describes which direction the slider will slide from.
open var slideDirection: SlideDirection

/// Generic initializer with views
///
/// - Parameters:
/// - frame: Frame size
/// - firstView: First view - should have size equal to frame and second view
/// - secondView: Second view - should have size equal to frame and second view
public init(frame: CGRect, firstView: UIView, secondView: UIView) {
public init(frame: CGRect, firstView: UIView, secondView: UIView, sliderImage: UIImage? = nil, slideDirection: SlideDirection? = nil) {
self.firstView = firstView
self.secondView = secondView
sliderCircle = SlidableImage.setupSliderCircle()
self.sliderCircle = SlidableImage.setupSliderCircle(sliderImage: sliderImage)
self.slideDirection = slideDirection ?? .right
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of this it would be clearer if you move it to init declaration slideDirection: SlideDirection? = .right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I move it to the init declaration then you can not call the init without a slideDirection param. Since this is an optional pram, it made more since to do the defaulting in the optional coalescing.

super.init(frame: frame)

initializeViews()
Expand All @@ -42,11 +63,11 @@ open class SlidableImage: UIView {
/// - frame: Frame size
/// - firstImage: First image for sliding
/// - secondImage: Second image for sliding
convenience public init(frame: CGRect, firstImage: UIImage, secondImage: UIImage) {
convenience public init(frame: CGRect, firstImage: UIImage, secondImage: UIImage, sliderImage: UIImage? = nil, slideDirection: SlideDirection? = nil) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you should update comments

let firstView = SlidableImage.setup(image: firstImage, frame: frame)
let secondView = SlidableImage.setup(image: secondImage, frame: frame)

self.init(frame: frame, firstView: firstView, secondView: secondView)
self.init(frame: frame, firstView: firstView, secondView: secondView, sliderImage: sliderImage, slideDirection: slideDirection)
}

required public init?(coder aDecoder: NSCoder) {
Expand All @@ -57,23 +78,49 @@ open class SlidableImage: UIView {
///
/// - Parameter maskLocation: Position of slider
open func updateMask(location maskLocation: CGFloat) {
let maskRectPath = UIBezierPath(rect: CGRect(x: bounds.minX,
var maskRectPath: UIBezierPath
let mask = CAShapeLayer()
switch slideDirection {
case .left:
maskRectPath = UIBezierPath(rect: CGRect(x: maskLocation,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just CGRect declaration should be in case, it would be clearer what is really switching

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am unsure what you mean here. Can you elaborate?

y: bounds.minY,
width: bounds.width,
height: bounds.height))
case .right:
maskRectPath = UIBezierPath(rect: CGRect(x: bounds.minX,
y: bounds.minY,
width: maskLocation,
height: bounds.height))
let mask = CAShapeLayer()
case .top:
maskRectPath = UIBezierPath(rect: CGRect(x: bounds.minX,
y: maskLocation,
width: bounds.width,
height: bounds.height))
case .bottom:
maskRectPath = UIBezierPath(rect: CGRect(x: bounds.minX,
y: bounds.minY,
width: bounds.width,
height: maskLocation))
}
mask.path = maskRectPath.cgPath
secondView.layer.mask = mask

sliderCircle.center.x = maskLocation
if slideDirection == .left || slideDirection == .right {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be

switch slideDirection {
case .left, .right:
  sliderCircle.center.x = maskLocation
case .top, .bottom:
  sliderCircle.center.y = maskLocation
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

sliderCircle.center.x = maskLocation
} else {
sliderCircle.center.y = maskLocation
}
}

/// Private wrapper for setup view
fileprivate func initializeViews() {
clipsToBounds = true
sliderCircle.center = center
updateMask(location: center.x)

if slideDirection == .left || slideDirection == .right {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

updateMask(location: center.x)
} else {
updateMask(location: center.y)
}

addSubview(firstView)
addSubview(secondView)
addSubview(sliderCircle)
Expand All @@ -88,24 +135,28 @@ open class SlidableImage: UIView {
@objc private func gestureHandler(_ panGestureRecognizer: UIPanGestureRecognizer) {
let location = panGestureRecognizer.location(in: firstView)

guard (bounds.minX...bounds.maxX ~= location.x) else {
return
if slideDirection == .left || slideDirection == .right {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

guard (bounds.minX...bounds.maxX ~= location.x) else { return }
updateMask(location: location.x)
} else {
guard (bounds.minY...bounds.maxY ~= location.y) else { return }
updateMask(location: location.y)
}

updateMask(location: location.x)
}

/// Private wrapper for setup circle slider view
///
/// - Returns: Slider circle
private class func setupSliderCircle() -> UIView {
private class func setupSliderCircle(sliderImage: UIImage? = nil) -> UIView {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you change method declaration you should update comments

// Workaround - without this view, gesture recognizer doesn't work
let circle = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
circle.layer.cornerRadius = circle.bounds.width / 2

let imageView = UIImageView(image: UIImage(named: "slider"))

let imageView = UIImageView(image: sliderImage)
imageView.contentMode = .scaleAspectFill
circle.addSubview(imageView)

imageView.center = circle.center

return circle
}

Expand Down