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

converted to swift 5 and fixed bugs #52

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
52 changes: 29 additions & 23 deletions DGRunkeeperSwitch/DGRunkeeperSwitch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import UIKit
// MARK: - DGRunkeeperSwitchRoundedLayer

open class DGRunkeeperSwitchRoundedLayer: CALayer {

override open var bounds: CGRect {
didSet { cornerRadius = bounds.height / 2.0 }
}
Expand Down Expand Up @@ -106,6 +106,10 @@ open class DGRunkeeperSwitch: UIControl {

fileprivate var initialSelectedBackgroundViewFrame: CGRect?

// MARK: - KVO properties

private var selectedBackgroundViewFrameObserver: NSKeyValueObservation?

// MARK: - Constructors

public init(titles: [String]) {
Expand Down Expand Up @@ -150,7 +154,7 @@ open class DGRunkeeperSwitch: UIControl {
selectedBackgroundColor = .white
titleColor = .white
selectedTitleColor = .black

// Gestures
tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
addGestureRecognizer(tapGesture)
Expand All @@ -159,27 +163,28 @@ open class DGRunkeeperSwitch: UIControl {
panGesture.delegate = self
addGestureRecognizer(panGesture)

addObserver(self, forKeyPath: "selectedBackgroundView.frame", options: .new, context: nil)
}

override open func awakeFromNib() {
super.awakeFromNib()
// Observers

selectedBackgroundViewFrameObserver = selectedBackgroundView.observe(\.frame, options: NSKeyValueObservingOptions.new) { [weak self] (object, changes) in
if let newValue = changes.newValue {
self?.titleMaskView.frame = newValue
}
}

self.titleFont = UIFont(name: self.titleFontFamily, size: self.titleFontSize)
}

// MARK: - Destructor

deinit {
removeObserver(self, forKeyPath: "selectedBackgroundView.frame")
if #available(iOS 11.0, *) {

} else {
selectedBackgroundViewFrameObserver?.invalidate()
}
}

// MARK: - Observer

override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "selectedBackgroundView.frame" {
titleMaskView.frame = selectedBackgroundView.frame
}
override open func awakeFromNib() {
super.awakeFromNib()

self.titleFont = UIFont(name: self.titleFontFamily, size: self.titleFontSize)
}

// MARK: -
Expand All @@ -188,13 +193,13 @@ open class DGRunkeeperSwitch: UIControl {
return DGRunkeeperSwitchRoundedLayer.self
}

func tapped(_ gesture: UITapGestureRecognizer!) {
@objc func tapped(_ gesture: UITapGestureRecognizer!) {
let location = gesture.location(in: self)
let index = Int(location.x / (bounds.width / CGFloat(titleLabels.count)))
setSelectedIndex(index, animated: true)
}

func pan(_ gesture: UIPanGestureRecognizer!) {
@objc func pan(_ gesture: UIPanGestureRecognizer!) {
if gesture.state == .began {
initialSelectedBackgroundViewFrame = selectedBackgroundView.frame
} else if gesture.state == .changed {
Expand Down Expand Up @@ -222,9 +227,9 @@ open class DGRunkeeperSwitch: UIControl {
if (!catchHalfSwitch) {
self.sendActions(for: .valueChanged)
}
UIView.animate(withDuration: animationDuration, delay: 0.0, usingSpringWithDamping: animationSpringDamping, initialSpringVelocity: animationInitialSpringVelocity, options: [UIViewAnimationOptions.beginFromCurrentState, UIViewAnimationOptions.curveEaseOut], animations: { () -> Void in
UIView.animate(withDuration: animationDuration, delay: 0.0, usingSpringWithDamping: animationSpringDamping, initialSpringVelocity: animationInitialSpringVelocity, options: [UIView.AnimationOptions.beginFromCurrentState, UIView.AnimationOptions.curveEaseOut], animations: { () -> Void in
self.layoutSubviews()
}, completion: nil)
}, completion: nil)
} else {
layoutSubviews()
sendActions(for: .valueChanged)
Expand All @@ -245,11 +250,11 @@ open class DGRunkeeperSwitch: UIControl {
let titleLabelMaxHeight = bounds.height - selectedBackgroundInset * 2.0

zip(titleLabels, selectedTitleLabels).forEach { label, selectedLabel in
let index = titleLabels.index(of: label)!
let index = titleLabels.firstIndex(of: label)!

var size = label.sizeThatFits(CGSize(width: titleLabelMaxWidth, height: titleLabelMaxHeight))
size.width = min(size.width, titleLabelMaxWidth)

let x = floor((bounds.width / CGFloat(titleLabels.count)) * CGFloat(index) + (bounds.width / CGFloat(titleLabels.count) - size.width) / 2.0)
let y = floor((bounds.height - size.height) / 2.0)
let origin = CGPoint(x: x, y: y)
Expand All @@ -274,3 +279,4 @@ extension DGRunkeeperSwitch: UIGestureRecognizerDelegate {
}

}

13 changes: 7 additions & 6 deletions DGRunkeeperSwitchExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -289,7 +290,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand Down Expand Up @@ -329,7 +330,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
Expand All @@ -343,7 +344,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.gatafan.DGRunkeeperSwitchExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
Expand All @@ -357,7 +358,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.gatafan.DGRunkeeperSwitchExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
Expand All @@ -378,7 +379,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.gatafan.DGRunkeeperSwitch;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand All @@ -401,7 +402,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.gatafan.DGRunkeeperSwitch;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
42 changes: 10 additions & 32 deletions DGRunkeeperSwitchExample/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="JqM-JB-8mi">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="JqM-JB-8mi">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Navigation Controller-->
<scene sceneID="Neg-Mx-UB6">
<objects>
<navigationController id="JqM-JB-8mi" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="NN4-ot-C6m">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
Expand All @@ -30,37 +34,11 @@
<viewControllerLayoutGuide type="bottom" id="SNu-9N-SF3"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="tVs-3B-QU8">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EFc-Vj-jEB" customClass="DGRunkeeperSwitch" customModule="DGRunkeeperSwitchExample" customModuleProvider="target">
<rect key="frame" x="20" y="530" width="560" height="50"/>
<color key="backgroundColor" red="0.47843137254901957" green="0.79607843137254897" blue="0.42352941176470588" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Ukk-Qo-fpC"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="titleFontFamily" value="Times New Roman"/>
<userDefinedRuntimeAttribute type="number" keyPath="titleFontSize">
<real key="value" value="17"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="switchValueDidChange:" destination="6an-zX-QAJ" eventType="valueChanged" id="PQ5-rv-cZ8"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="EFc-Vj-jEB" firstAttribute="leading" secondItem="tVs-3B-QU8" secondAttribute="leading" constant="20" id="MH9-53-swC"/>
<constraint firstAttribute="trailing" secondItem="EFc-Vj-jEB" secondAttribute="trailing" constant="20" id="VaE-8p-81t"/>
<constraint firstItem="SNu-9N-SF3" firstAttribute="top" secondItem="EFc-Vj-jEB" secondAttribute="bottom" constant="20" id="iGl-SR-06F"/>
</constraints>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<navigationItem key="navigationItem" id="hlk-SI-d0e"/>
<connections>
<outlet property="runkeeperSwitch4" destination="EFc-Vj-jEB" id="z8c-lE-BQ4"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="7Rp-S3-jKX" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
Expand Down
2 changes: 1 addition & 1 deletion DGRunkeeperSwitchExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.4</string>
<string>1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
15 changes: 1 addition & 14 deletions DGRunkeeperSwitchExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ import UIKit

class ViewController: UIViewController {

// MARK: -
// MARK: Vars

@IBOutlet weak var runkeeperSwitch4: DGRunkeeperSwitch?

// MARK: -
// MARK: Lifecycle

Expand Down Expand Up @@ -57,15 +52,7 @@ class ViewController: UIViewController {
runkeeperSwitch3.frame = CGRect(x: 50.0, y: 70.0, width: view.bounds.width - 100.0, height: 30.0)
runkeeperSwitch3.autoresizingMask = [.flexibleWidth]
view.addSubview(runkeeperSwitch3)

if let runkeeperSwitch4 = runkeeperSwitch4 {
runkeeperSwitch4.titles = ["Apple", "Google"]
runkeeperSwitch4.backgroundColor = UIColor(red: 122/255.0, green: 203/255.0, blue: 108/255.0, alpha: 1.0)
runkeeperSwitch4.selectedBackgroundColor = .white
runkeeperSwitch4.titleColor = .white
runkeeperSwitch4.selectedTitleColor = UIColor(red: 135/255.0, green: 227/255.0, blue: 120/255.0, alpha: 1.0)
runkeeperSwitch4.titleFont = UIFont(name: "HelveticaNeue-Light", size: 17.0)
}

}

// MARK: -
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
# DGRunkeeperSwitch
Runkeeper design switch control (two part segment control) developed in Swift 2.0
Runkeeper design switch control (two part segment control) developed in Swift 2.0 and I (@aakpro) changed it to swift 5.0 and still waiting for main repository owner to merge it.
#### So here is new version of DGRunkeeper in swift 5
#
#
#

![Preview 1](https://raw.githubusercontent.com/gontovnik/DGRunkeeperSwitch/master/DGRunkeeperSwitch.png)
![Preview 2](https://raw.githubusercontent.com/gontovnik/DGRunkeeperSwitch/master/DGRunkeeperSwitch.gif)

## Requirements
* Xcode 7-beta or higher
* iOS 8.0 or higher (May work on previous versions, just did not test it. Feel free to edit it).
* Xcode 10.2 or higher
* iOS 10.0 or higher (May work on previous versions, just did not test it. Feel free to edit it).
* ARC
* Swift 3.0 (old versions are in different releases)

* Swift 5.0
## Demo

Open and run the DGRunkeeperSwitchExample project in Xcode to see DGRunkeeperSwitch in action.
Expand Down