Skip to content

Commit

Permalink
ver 1.0 done
Browse files Browse the repository at this point in the history
  • Loading branch information
Ed committed Nov 18, 2020
1 parent 3e6c546 commit c1a9218
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
18 changes: 18 additions & 0 deletions InstaProgressView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@

/* Begin PBXBuildFile section */
262EA1ED2565D4BD00F16CC9 /* InstaProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = 262EA1EB2565D4BD00F16CC9 /* InstaProgressView.h */; settings = {ATTRIBUTES = (Public, ); }; };
262EA1F52565D4E700F16CC9 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262EA1F42565D4E700F16CC9 /* Int+Extension.swift */; };
262EA1F82565D51100F16CC9 /* InstaProgressViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262EA1F72565D51100F16CC9 /* InstaProgressViewDelegate.swift */; };
262EA1FB2565D53900F16CC9 /* InstaProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262EA1FA2565D53900F16CC9 /* InstaProgressView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
262EA1E82565D4BD00F16CC9 /* InstaProgressView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = InstaProgressView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
262EA1EB2565D4BD00F16CC9 /* InstaProgressView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InstaProgressView.h; sourceTree = "<group>"; };
262EA1EC2565D4BD00F16CC9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
262EA1F42565D4E700F16CC9 /* Int+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Extension.swift"; sourceTree = "<group>"; };
262EA1F72565D51100F16CC9 /* InstaProgressViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstaProgressViewDelegate.swift; sourceTree = "<group>"; };
262EA1FA2565D53900F16CC9 /* InstaProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstaProgressView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -48,6 +54,9 @@
children = (
262EA1EB2565D4BD00F16CC9 /* InstaProgressView.h */,
262EA1EC2565D4BD00F16CC9 /* Info.plist */,
262EA1F42565D4E700F16CC9 /* Int+Extension.swift */,
262EA1F72565D51100F16CC9 /* InstaProgressViewDelegate.swift */,
262EA1FA2565D53900F16CC9 /* InstaProgressView.swift */,
);
path = InstaProgressView;
sourceTree = "<group>";
Expand Down Expand Up @@ -94,6 +103,7 @@
TargetAttributes = {
262EA1E72565D4BD00F16CC9 = {
CreatedOnToolsVersion = 12.0;
LastSwiftMigration = 1200;
};
};
};
Expand Down Expand Up @@ -130,6 +140,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
262EA1FB2565D53900F16CC9 /* InstaProgressView.swift in Sources */,
262EA1F82565D51100F16CC9 /* InstaProgressViewDelegate.swift in Sources */,
262EA1F52565D4E700F16CC9 /* Int+Extension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -261,6 +274,7 @@
262EA1F12565D4BD00F16CC9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 9875BH6JL2;
Expand All @@ -269,6 +283,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = InstaProgressView/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -277,6 +292,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "Eduard-Siniakov.InstaProgressView";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand All @@ -285,6 +301,7 @@
262EA1F22565D4BD00F16CC9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 9875BH6JL2;
Expand All @@ -293,6 +310,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = InstaProgressView/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
129 changes: 129 additions & 0 deletions InstaProgressView/InstaProgressView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//
// InstaProgressView.swift
// InstaProgressView
//
// Created by Eduard Sinyakov on 11/19/20.
//

import UIKit

public class InstaProgressView: UIStackView {
private var currentAnimationIndex = 0
private var animator = UIViewPropertyAnimator()
private var duration: TimeInterval!

weak var delegate: InstaProgressViewDelegate?

private var isValid: Bool {
currentAnimationIndex < arrangedSubviews.count
}

init(progressTintColor: UIColor, trackTintColor: UIColor, segmentsCount: Int, spaceBetweenSegments: CGFloat, duration: TimeInterval) {
super.init(frame: CGRect.zero)
self.duration = duration
axis = NSLayoutConstraint.Axis.horizontal
distribution = UIStackView.Distribution.fillEqually
alignment = UIStackView.Alignment.fill
spacing = spaceBetweenSegments

for _ in segmentsCount {
addArrangedSubview(createProgressView(progressTintColor, trackTintColor))
}
}

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

public func startAnimation() {
next()
}

public func pauseAnimation() {
animator.pauseAnimation()
}

public func continueAnimation() {
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
}

public func skip() {
if currentAnimationIndex <= arrangedSubviews.count && currentAnimationIndex > 0 {
if let currentSegment = arrangedSubviews[currentAnimationIndex - 1] as? UIProgressView {
animator.stopAnimation(true)
currentSegment.setProgress(1, animated: false)
currentSegment.layer.removeAllAnimations()
next()
}
} else {
next()
}
}

public func back() {
if currentAnimationIndex > 0 {
currentAnimationIndex -= 1

if let currentSegment = arrangedSubviews[currentAnimationIndex] as? UIProgressView {
animator.stopAnimation(true)
currentSegment.setProgress(0, animated: false)
currentSegment.layer.removeAllAnimations()
}
}

if currentAnimationIndex > 0 {
currentAnimationIndex -= 1

if let currentSegment = arrangedSubviews[currentAnimationIndex] as? UIProgressView {
animator.stopAnimation(true)
currentSegment.setProgress(0, animated: false)
currentSegment.layer.removeAllAnimations()
}
}

let catchedIndex = currentAnimationIndex
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
guard let self = self else { return }
if catchedIndex == self.currentAnimationIndex {
self.next()
}
}
}

/// Show progress and when load finished show next load progressView (white string)
/// - Parameter progressView: current progressView gets from currentAnimationIndex
private func handleProgress(_ progressView: UIProgressView) {
let catchedIndex = currentAnimationIndex
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let self = self else { return }
if catchedIndex == self.currentAnimationIndex {
self.currentAnimationIndex += 1
self.animator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: self.duration, delay: 0, options: .curveEaseInOut) {
progressView.setProgress(1, animated: true)
} completion: { [weak self] _ in
self?.next()
}
self.animator.startAnimation()
}
}
}

private func next() {
if isValid {
if let v = arrangedSubviews[currentAnimationIndex] as? UIProgressView {
delegate?.instaProgressViewChangedIndex(index: currentAnimationIndex)
handleProgress(v)
}
} else {
delegate?.instaProgressViewFinished()
}
}

private func createProgressView(_ progressTintColor: UIColor, _ trackTintColor: UIColor) -> UIProgressView {
let progressView = UIProgressView()
progressView.progressTintColor = progressTintColor
progressView.trackTintColor = trackTintColor
progressView.setProgress(0, animated: true)
return progressView
}
}
13 changes: 13 additions & 0 deletions InstaProgressView/InstaProgressViewDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// InstaProgressViewDelegate.swift
// InstaProgressView
//
// Created by Eduard Sinyakov on 11/19/20.
//

import Foundation

protocol InstaProgressViewDelegate: class {
func instaProgressViewChangedIndex(index: Int)
func instaProgressViewFinished()
}
13 changes: 13 additions & 0 deletions InstaProgressView/Int+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Int+Extension.swift
// InstaProgressView
//
// Created by Eduard Sinyakov on 11/19/20.
//

import Foundation
extension Int: Sequence {
public func makeIterator() -> CountableRange<Int>.Iterator {
return (0..<self).makeIterator()
}
}

0 comments on commit c1a9218

Please sign in to comment.