Skip to content

Commit

Permalink
Merge pull request #3 from quver/swift-3
Browse files Browse the repository at this point in the history
Xcode 8 fixes
  • Loading branch information
quver authored Sep 23, 2016
2 parents 1d91988 + cffc871 commit 697ede8
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 135 deletions.
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)
}

}

0 comments on commit 697ede8

Please sign in to comment.