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

Xcode 8 fixes #3

Merged
merged 2 commits into from
Sep 23, 2016
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ osx_image: xcode8
sudo: false
rvm: 2.3.1
install: bundle install --without=documentation --path ../travis_bundle_dir
script: xcodebuild -scheme SlidableImage -project SlidableImage.xcodeproj -enableCodeCoverage YES build test GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
script: xcodebuild -scheme SlidableImage -project SlidableImage.xcodeproj -enableCodeCoverage YES -destination 'platform=iOS Simulator,name=iPhone SE,OS=10.0' -configuration Debug ONLY_ACTIVE_ARCH=NO build test GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
after_success: slather
9 changes: 5 additions & 4 deletions SlidableImage/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var window: UIWindow?

private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
}

10 changes: 10 additions & 0 deletions SlidableImage/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
Expand Down
202 changes: 106 additions & 96 deletions SlidableImage/SlidableImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,122 +11,132 @@ import UIKit
/// Super easy Slider for before&after images
public class SlidableImage: UIView {

/**
First image container view. You can override it with your custom view.
*/
public var firstView: UIView

/**
Second image container view. You can override it with your custom view.
*/
public var secondView: UIView

/**
Circle view with icon for sliding images. You can override it with your custom view.
*/
public var sliderCircle: UIView

/**
Generic initializer with views

- parameter frame: Frame size
- parameter firstView: First view - should have size equal to frame and second view
- parameter secondView: Second view - should have size equal to frame and second view

- returns: instance
*/
public init(frame: CGRect, firstView: UIView, secondView: UIView) {
self.firstView = firstView
self.secondView = secondView
sliderCircle = SlidableImage.prepareSliderCircle()
super.init(frame: frame)

initializeView()
initializeGestureRecognizer()
}
/**
First image container view. You can override it with your custom view.
*/
public var firstView: UIView

/**
Short way to initialize SlidableView. You need target size and images.

- parameter frame: Frame size
- parameter firstImage: First image for sliding
- parameter secondImage: Second image for sliding

- returns: instance
*/
convenience public init(frame: CGRect, firstImage: UIImage, secondImage: UIImage) {
let firstView = UIImageView(frame: frame)
firstView.image = firstImage
firstView.contentMode = .scaleAspectFill

let secondView = UIImageView(frame: frame)
secondView.image = secondImage
secondView.contentMode = .scaleAspectFill

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

required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/**
Second image container view. You can override it with your custom view.
*/
public var secondView: UIView

/**
Circle view with icon for sliding images. You can override it with your custom view.
*/
public var sliderCircle: UIView

/**
Typicaly this method is used by gesture recognizer, but you can use it for first state or animations
/**
Generic initializer with views

- parameter maskLocation: x-axis location in frame, where image should be slided
*/
public func updateMask(_ maskLocation: CGFloat) {
let maskRectPath = UIBezierPath(rect: CGRect(x: self.bounds.minX, y: bounds.minY, width: maskLocation, height: bounds.height))
let mask = CAShapeLayer()
mask.path = maskRectPath.cgPath
secondView.layer.mask = mask
- parameter frame: Frame size
- parameter firstView: First view - should have size equal to frame and second view
- parameter secondView: Second view - should have size equal to frame and second view

sliderCircle.center.x = maskLocation
}
- returns: instance
*/
public init(frame: CGRect, firstView: UIView, secondView: UIView) {
self.firstView = firstView
self.secondView = secondView
sliderCircle = SlidableImage.setupSliderCircle()
super.init(frame: frame)

initializeView()
initializeGestureRecognizer()
}

/**
Short way to initialize SlidableView. You need target size and images.

- parameter frame: Frame size
- parameter firstImage: First image for sliding
- parameter secondImage: Second image for sliding

- returns: instance
*/
convenience public init(frame: CGRect, firstImage: UIImage, secondImage: UIImage) {
let firstView = SlidableImage.setup(image: firstImage, frame: frame)
let secondView = SlidableImage.setup(image: secondImage, frame: frame)

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

required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

/**
Typicaly this method is used by gesture recognizer, but you can use it for first state or animations

- parameter maskLocation: x-axis location in frame, where image should be slided
*/
public func updateMask(_ maskLocation: CGFloat) {
let maskRectPath = UIBezierPath(rect: CGRect(x: self.bounds.minX,
y: bounds.minY,
width: maskLocation,
height: bounds.height))
let mask = CAShapeLayer()
mask.path = maskRectPath.cgPath
secondView.layer.mask = mask

sliderCircle.center.x = maskLocation
}

/**
Private wrapper for setup view
*/
private func initializeView() {
clipsToBounds = true
sliderCircle.center = center
updateMask(center.x)

addSubview(firstView)
addSubview(secondView)
addSubview(sliderCircle)
}
private func initializeView() {
clipsToBounds = true
sliderCircle.center = center
updateMask(center.x)

addSubview(firstView)
addSubview(secondView)
addSubview(sliderCircle)
}

/**
Private wrapper for adding gesture recognizer
*/
private func initializeGestureRecognizer() {
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureHandler))
sliderCircle.addGestureRecognizer(panGestureRecognizer)
}
private func initializeGestureRecognizer() {
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureHandler))
sliderCircle.addGestureRecognizer(panGestureRecognizer)
}

@objc private func gestureHandler(_ panGestureRecognizer: UIPanGestureRecognizer) {
let location = panGestureRecognizer.location(in: firstView)
@objc private func gestureHandler(_ panGestureRecognizer: UIPanGestureRecognizer) {
let location = panGestureRecognizer.location(in: firstView)

if !(self.bounds.minX ... self.bounds.maxX ~= location.x) {
return
}
if !(self.bounds.minX ... self.bounds.maxX ~= location.x) {
return
}

updateMask(location.x)
updateMask(location.x)

}
}

/**
Private wrapper for setup circle slider view
*/
private class func prepareSliderCircle() -> UIView {
// 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
private class func setupSliderCircle() -> UIView {
// 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"))
circle.addSubview(imageView)
let imageView = UIImageView(image: UIImage(named: "slider"))
circle.addSubview(imageView)

return circle
}

/**
Private wrapper for setup image view
*/
private class func setup(image: UIImage, frame: CGRect) -> UIImageView {
let imageView = UIImageView(frame: frame)
imageView.image = image
imageView.contentMode = .scaleAspectFill

return imageView
}

return circle
}
}
25 changes: 13 additions & 12 deletions SlidableImage/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let rect = CGRect(x: 0, y: 0, width: 300, height: 500)
guard let firstImage = UIImage(named: "photo"),
let secondImage = UIImage(named: "draw") else { return }

let slider = SlidableImage(frame: rect, firstImage: firstImage, secondImage: secondImage)

slider.center = view.center
view.addSubview(slider)
}
override func viewDidLoad() {
super.viewDidLoad()

let rect = CGRect(x: 0, y: 0, width: 300, height: 500)
guard let firstImage = UIImage(named: "photo"),
let secondImage = UIImage(named: "draw") else { return }

let slider = SlidableImage(frame: rect, firstImage: firstImage, secondImage: secondImage)

slider.center = view.center
view.addSubview(slider)
}

}

44 changes: 22 additions & 22 deletions SlidableImageTests/SlidableImageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,34 @@ import XCTest

class SlidableImageTests: XCTestCase {

let rect = CGRect(x: 0, y: 0, width: 300, height: 500)
let rect = CGRect(x: 0, y: 0, width: 300, height: 500)

func testStandardInit() {
guard let firstRawImage = UIImage(named: "photo"),
let secondRawImage = UIImage(named: "draw") else {
XCTFail()
return
}
func testStandardInit() {
guard let firstRawImage = UIImage(named: "photo"),
let secondRawImage = UIImage(named: "draw") else {
XCTFail()
return
}

let slider = SlidableImage(frame: rect, firstImage: firstRawImage, secondImage: secondRawImage)
let slider = SlidableImage(frame: rect, firstImage: firstRawImage, secondImage: secondRawImage)

XCTAssertNotNil(slider)
XCTAssertEqual(slider.frame, rect)
}
XCTAssertNotNil(slider)
XCTAssertEqual(slider.frame, rect)
}

func testAdvancedInit() {
func testAdvancedInit() {

let firstView = UIView(frame: rect)
firstView.backgroundColor = .green()
let firstView = UIView(frame: rect)
firstView.backgroundColor = .green

let secondView = UIView(frame: rect)
secondView.backgroundColor = .red()
let secondView = UIView(frame: rect)
secondView.backgroundColor = .red

let slider = SlidableImage(frame: rect, firstView: firstView, secondView: secondView)
let slider = SlidableImage(frame: rect, firstView: firstView, secondView: secondView)

XCTAssertEqual(slider.frame, rect)
XCTAssertEqual(slider.firstView, firstView)
XCTAssertEqual(slider.secondView, secondView)
}

XCTAssertEqual(slider.frame, rect)
XCTAssertEqual(slider.firstView, firstView)
XCTAssertEqual(slider.secondView, secondView)
}

}