From 45eab01a5e164ae5949e00902b057091a7ac86b7 Mon Sep 17 00:00:00 2001 From: kyyamagu Date: Tue, 29 Dec 2015 23:11:21 +0900 Subject: [PATCH] first commit. --- .../project.pbxproj | 176 +++++++++++++++++- .../xcschemes/KYNavigationProgress.xcscheme | 0 .../xcschemes/xcschememanagement.plist | 27 --- KYNavigationProgress/ProgressView.swift | 132 +++++++++++++ .../UINavigationController+Progress.swift | 122 ++++++++++++ Sample/AppDelegate.swift | 46 +++++ .../AppIcon.appiconset/Contents.json | 68 +++++++ Sample/Base.lproj/LaunchScreen.storyboard | 27 +++ Sample/Base.lproj/Main.storyboard | 77 ++++++++ Sample/Info.plist | 47 +++++ Sample/ViewController.swift | 42 +++++ 11 files changed, 735 insertions(+), 29 deletions(-) rename KYNavigationProgress.xcodeproj/{xcuserdata/01012237.xcuserdatad => xcshareddata}/xcschemes/KYNavigationProgress.xcscheme (100%) delete mode 100644 KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 KYNavigationProgress/ProgressView.swift create mode 100644 KYNavigationProgress/UINavigationController+Progress.swift create mode 100644 Sample/AppDelegate.swift create mode 100644 Sample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Sample/Base.lproj/LaunchScreen.storyboard create mode 100644 Sample/Base.lproj/Main.storyboard create mode 100644 Sample/Info.plist create mode 100644 Sample/ViewController.swift diff --git a/KYNavigationProgress.xcodeproj/project.pbxproj b/KYNavigationProgress.xcodeproj/project.pbxproj index f9bb3b7..c21982b 100644 --- a/KYNavigationProgress.xcodeproj/project.pbxproj +++ b/KYNavigationProgress.xcodeproj/project.pbxproj @@ -10,6 +10,15 @@ C2A91C171C32782F006D1CAE /* KYNavigationProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A91C161C32782F006D1CAE /* KYNavigationProgress.h */; settings = {ATTRIBUTES = (Public, ); }; }; C2A91C1E1C32782F006D1CAE /* KYNavigationProgress.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2A91C131C32782F006D1CAE /* KYNavigationProgress.framework */; }; C2A91C231C32782F006D1CAE /* KYNavigationProgressTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A91C221C32782F006D1CAE /* KYNavigationProgressTests.swift */; }; + C2A91C341C327872006D1CAE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A91C331C327872006D1CAE /* AppDelegate.swift */; }; + C2A91C361C327872006D1CAE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A91C351C327872006D1CAE /* ViewController.swift */; }; + C2A91C391C327872006D1CAE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2A91C371C327872006D1CAE /* Main.storyboard */; }; + C2A91C3B1C327872006D1CAE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C2A91C3A1C327872006D1CAE /* Assets.xcassets */; }; + C2A91C3E1C327872006D1CAE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2A91C3C1C327872006D1CAE /* LaunchScreen.storyboard */; }; + C2A91C441C3278F1006D1CAE /* UINavigationController+Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A91C431C3278F1006D1CAE /* UINavigationController+Progress.swift */; }; + C2A91C461C328184006D1CAE /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A91C451C328184006D1CAE /* ProgressView.swift */; }; + C2A91C471C328C1C006D1CAE /* KYNavigationProgress.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2A91C131C32782F006D1CAE /* KYNavigationProgress.framework */; }; + C2A91C481C328C1C006D1CAE /* KYNavigationProgress.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C2A91C131C32782F006D1CAE /* KYNavigationProgress.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -20,8 +29,29 @@ remoteGlobalIDString = C2A91C121C32782F006D1CAE; remoteInfo = KYNavigationProgress; }; + C2A91C491C328C1C006D1CAE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C2A91C0A1C32782F006D1CAE /* Project object */; + proxyType = 1; + remoteGlobalIDString = C2A91C121C32782F006D1CAE; + remoteInfo = KYNavigationProgress; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + C2A91C4B1C328C1D006D1CAE /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + C2A91C481C328C1C006D1CAE /* KYNavigationProgress.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ C2A91C131C32782F006D1CAE /* KYNavigationProgress.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KYNavigationProgress.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C2A91C161C32782F006D1CAE /* KYNavigationProgress.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KYNavigationProgress.h; sourceTree = ""; }; @@ -29,6 +59,15 @@ C2A91C1D1C32782F006D1CAE /* KYNavigationProgressTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KYNavigationProgressTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C2A91C221C32782F006D1CAE /* KYNavigationProgressTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KYNavigationProgressTests.swift; sourceTree = ""; }; C2A91C241C32782F006D1CAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C2A91C311C327872006D1CAE /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C2A91C331C327872006D1CAE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + C2A91C351C327872006D1CAE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + C2A91C381C327872006D1CAE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + C2A91C3A1C327872006D1CAE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C2A91C3D1C327872006D1CAE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + C2A91C3F1C327872006D1CAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C2A91C431C3278F1006D1CAE /* UINavigationController+Progress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Progress.swift"; sourceTree = ""; }; + C2A91C451C328184006D1CAE /* ProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -47,6 +86,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C2A91C2E1C327872006D1CAE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C2A91C471C328C1C006D1CAE /* KYNavigationProgress.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -55,6 +102,7 @@ children = ( C2A91C151C32782F006D1CAE /* KYNavigationProgress */, C2A91C211C32782F006D1CAE /* KYNavigationProgressTests */, + C2A91C321C327872006D1CAE /* Sample */, C2A91C141C32782F006D1CAE /* Products */, ); sourceTree = ""; @@ -64,6 +112,7 @@ children = ( C2A91C131C32782F006D1CAE /* KYNavigationProgress.framework */, C2A91C1D1C32782F006D1CAE /* KYNavigationProgressTests.xctest */, + C2A91C311C327872006D1CAE /* Sample.app */, ); name = Products; sourceTree = ""; @@ -71,6 +120,8 @@ C2A91C151C32782F006D1CAE /* KYNavigationProgress */ = { isa = PBXGroup; children = ( + C2A91C451C328184006D1CAE /* ProgressView.swift */, + C2A91C431C3278F1006D1CAE /* UINavigationController+Progress.swift */, C2A91C161C32782F006D1CAE /* KYNavigationProgress.h */, C2A91C181C32782F006D1CAE /* Info.plist */, ); @@ -86,6 +137,19 @@ path = KYNavigationProgressTests; sourceTree = ""; }; + C2A91C321C327872006D1CAE /* Sample */ = { + isa = PBXGroup; + children = ( + C2A91C331C327872006D1CAE /* AppDelegate.swift */, + C2A91C351C327872006D1CAE /* ViewController.swift */, + C2A91C371C327872006D1CAE /* Main.storyboard */, + C2A91C3A1C327872006D1CAE /* Assets.xcassets */, + C2A91C3C1C327872006D1CAE /* LaunchScreen.storyboard */, + C2A91C3F1C327872006D1CAE /* Info.plist */, + ); + path = Sample; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -136,6 +200,25 @@ productReference = C2A91C1D1C32782F006D1CAE /* KYNavigationProgressTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + C2A91C301C327872006D1CAE /* Sample */ = { + isa = PBXNativeTarget; + buildConfigurationList = C2A91C401C327872006D1CAE /* Build configuration list for PBXNativeTarget "Sample" */; + buildPhases = ( + C2A91C2D1C327872006D1CAE /* Sources */, + C2A91C2E1C327872006D1CAE /* Frameworks */, + C2A91C2F1C327872006D1CAE /* Resources */, + C2A91C4B1C328C1D006D1CAE /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + C2A91C4A1C328C1C006D1CAE /* PBXTargetDependency */, + ); + name = Sample; + productName = Sample; + productReference = C2A91C311C327872006D1CAE /* Sample.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -152,6 +235,9 @@ C2A91C1C1C32782F006D1CAE = { CreatedOnToolsVersion = 7.2; }; + C2A91C301C327872006D1CAE = { + CreatedOnToolsVersion = 7.2; + }; }; }; buildConfigurationList = C2A91C0D1C32782F006D1CAE /* Build configuration list for PBXProject "KYNavigationProgress" */; @@ -160,6 +246,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = C2A91C091C32782F006D1CAE; productRefGroup = C2A91C141C32782F006D1CAE /* Products */; @@ -168,6 +255,7 @@ targets = ( C2A91C121C32782F006D1CAE /* KYNavigationProgress */, C2A91C1C1C32782F006D1CAE /* KYNavigationProgressTests */, + C2A91C301C327872006D1CAE /* Sample */, ); }; /* End PBXProject section */ @@ -187,6 +275,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C2A91C2F1C327872006D1CAE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C2A91C3E1C327872006D1CAE /* LaunchScreen.storyboard in Resources */, + C2A91C3B1C327872006D1CAE /* Assets.xcassets in Resources */, + C2A91C391C327872006D1CAE /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -194,6 +292,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C2A91C441C3278F1006D1CAE /* UINavigationController+Progress.swift in Sources */, + C2A91C461C328184006D1CAE /* ProgressView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -205,6 +305,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C2A91C2D1C327872006D1CAE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C2A91C361C327872006D1CAE /* ViewController.swift in Sources */, + C2A91C341C327872006D1CAE /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -213,8 +322,32 @@ target = C2A91C121C32782F006D1CAE /* KYNavigationProgress */; targetProxy = C2A91C1F1C32782F006D1CAE /* PBXContainerItemProxy */; }; + C2A91C4A1C328C1C006D1CAE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C2A91C121C32782F006D1CAE /* KYNavigationProgress */; + targetProxy = C2A91C491C328C1C006D1CAE /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + C2A91C371C327872006D1CAE /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + C2A91C381C327872006D1CAE /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + C2A91C3C1C327872006D1CAE /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + C2A91C3D1C327872006D1CAE /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ C2A91C251C32782F006D1CAE /* Debug */ = { isa = XCBuildConfiguration; @@ -253,7 +386,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -295,7 +428,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.2; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -308,28 +441,33 @@ C2A91C281C32782F006D1CAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = KYNavigationProgress/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.kyo--hei.KYNavigationProgress"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; C2A91C291C32782F006D1CAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = KYNavigationProgress/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.kyo--hei.KYNavigationProgress"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -357,6 +495,32 @@ }; name = Release; }; + C2A91C411C327872006D1CAE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + INFOPLIST_FILE = Sample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.kyo--hei.Sample"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + C2A91C421C327872006D1CAE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + INFOPLIST_FILE = Sample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.kyo--hei.Sample"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -385,6 +549,14 @@ ); defaultConfigurationIsVisible = 0; }; + C2A91C401C327872006D1CAE /* Build configuration list for PBXNativeTarget "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C2A91C411C327872006D1CAE /* Debug */, + C2A91C421C327872006D1CAE /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; /* End XCConfigurationList section */ }; rootObject = C2A91C0A1C32782F006D1CAE /* Project object */; diff --git a/KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/KYNavigationProgress.xcscheme b/KYNavigationProgress.xcodeproj/xcshareddata/xcschemes/KYNavigationProgress.xcscheme similarity index 100% rename from KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/KYNavigationProgress.xcscheme rename to KYNavigationProgress.xcodeproj/xcshareddata/xcschemes/KYNavigationProgress.xcscheme diff --git a/KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/xcschememanagement.plist b/KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index a71e032..0000000 --- a/KYNavigationProgress.xcodeproj/xcuserdata/01012237.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - SchemeUserState - - KYNavigationProgress.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - C2A91C121C32782F006D1CAE - - primary - - - C2A91C1C1C32782F006D1CAE - - primary - - - - - diff --git a/KYNavigationProgress/ProgressView.swift b/KYNavigationProgress/ProgressView.swift new file mode 100644 index 0000000..cd320f0 --- /dev/null +++ b/KYNavigationProgress/ProgressView.swift @@ -0,0 +1,132 @@ +// +// ProgressView.swift +// KYNavigationProgress +// +// Created by 山口 恭兵 on 2015/12/29. +// Copyright © 2015年 kyo__hei. All rights reserved. +// + +import UIKit + +internal final class ProgressView: UIView { + + /* ====================================================================== */ + // MARK: - Properties + /* ====================================================================== */ + + internal var progress: Float = 0 { + didSet { + guard let superview = superview else { return } + progress = min(1, progress) + barWidthConstraint.constant = superview.frame.width * CGFloat(progress) + } + } + + internal let bar = UIView() + + private let defaultBarColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1) + + private let defaultTrackColor = UIColor.clearColor() + + private let barWidthConstraint: NSLayoutConstraint + + + /* ====================================================================== */ + // MARK: - initializer + /* ====================================================================== */ + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override init(frame: CGRect) { + barWidthConstraint = NSLayoutConstraint( + item: bar, + attribute: .Width, + relatedBy: .Equal, + toItem: nil, + attribute: .NotAnAttribute, + multiplier: 1, + constant: frame.width * CGFloat(progress)) + + super.init(frame: frame) + + NSNotificationCenter.defaultCenter().addObserver( + self, + selector: "deviceDidRotate:", + name: UIDeviceOrientationDidChangeNotification, + object: nil) + + let leftConstraint = NSLayoutConstraint( + item: bar, + attribute: .Left, + relatedBy: .Equal, + toItem: self, + attribute: .Left, + multiplier: 1, + constant: 0) + + let bottomConstraint = NSLayoutConstraint( + item: bar, + attribute: .Bottom, + relatedBy: .Equal, + toItem: self, + attribute: .Bottom, + multiplier: 1, + constant: 0) + + let topConstraint = NSLayoutConstraint( + item: bar, + attribute: .Top, + relatedBy: .Equal, + toItem: self, + attribute: .Top, + multiplier: 1, + constant: 0) + + addSubview(bar) + + backgroundColor = defaultTrackColor + + bar.backgroundColor = defaultBarColor + bar.translatesAutoresizingMaskIntoConstraints = false + addConstraints([ + barWidthConstraint, + leftConstraint, + topConstraint, + bottomConstraint]) + } + + deinit { + NSNotificationCenter.defaultCenter().removeObserver( + self, + name: UIDeviceOrientationDidChangeNotification, + object: nil) + } + + + /* ====================================================================== */ + // MARK: - Notification + /* ====================================================================== */ + + func deviceDidRotate(notification: NSNotification) { + let tmpProgress = progress + progress = tmpProgress + } + + + /* ====================================================================== */ + // MARK: - Method + /* ====================================================================== */ + + internal func setProgress(progress: Float, animated: Bool) { + let duration: NSTimeInterval = animated ? 0.1 : 0 + + self.progress = progress + + UIView.animateWithDuration(duration) { + self.layoutIfNeeded() + } + } + +} diff --git a/KYNavigationProgress/UINavigationController+Progress.swift b/KYNavigationProgress/UINavigationController+Progress.swift new file mode 100644 index 0000000..8273f8c --- /dev/null +++ b/KYNavigationProgress/UINavigationController+Progress.swift @@ -0,0 +1,122 @@ +// +// UINavigationController+Progress.swift +// KYNavigationProgress +// +// Created by 山口 恭兵 on 2015/12/29. +// Copyright © 2015年 kyo__hei. All rights reserved. +// + +import UIKit + +public extension UINavigationController { + + /* ====================================================================== */ + // MARK: - Properties + /* ====================================================================== */ + + /** + Default is 2.0 + */ + public var progressHeight: CGFloat { + get { return progressView.frame.height } + set { + var frame = progressView.frame + frame.size.height = newValue + frame.origin.y = navigationBar.frame.height - newValue + progressView.frame = frame + } + } + + /** + The color shown for the portion of the progress bar that is not filled. + default is clear color. + */ + public var trackTintColor: UIColor? { + get { return progressView.backgroundColor } + set { progressView.backgroundColor = newValue } + } + + /** + The color shown for the portion of the progress bar that is filled. + default is (r: 0, g: 122, b: 225, a: 255. + */ + public var progressTintColor: UIColor? { + get { return progressView.bar.backgroundColor } + set { progressView.bar.backgroundColor = newValue } + } + + /** + The current progress is represented by a floating-point value between 0.0 and 1.0, + inclusive, where 1.0 indicates the completion of the task. The default value is 0.0. + */ + public var progress: Float { + get { return progressView.progress } + set { progressView.progress = newValue } + } + + + private var progressView: ProgressView { + for subview in navigationBar.subviews { + if let progressView = subview as? ProgressView { + return progressView + } + } + + let defaultHeight = CGFloat(2) + + let frame = CGRect( + x: 0, + y: navigationBar.frame.height - defaultHeight, + width: navigationBar.frame.width, + height: defaultHeight + ) + let progressView = ProgressView(frame: frame) + + navigationBar.addSubview(progressView) + + return progressView + } + + + /* ====================================================================== */ + // MARK: - Public Method + /* ====================================================================== */ + + /** + Adjusts the current progress shown by the receiver, optionally animating the change. + + - parameter progress: The new progress value. + - parameter animated: true if the change should be animated, false if the change should happen immediately. + */ + public func setProgress(progress: Float, animated: Bool) { + progressView.bar.alpha = 1 + progressView.setProgress(progress, animated: animated) + } + + /** + While progress is changed to 1.0, the bar will fade out. After that, progress will be 0.0. + */ + public func finishProgress() { + progressView.setProgress(1, animated: true) + + UIView.animateWithDuration(0.25, + animations: { + self.progressView.bar.alpha = 0 + }, completion: { finished in + self.progressView.progress = 0 + } + ) + } + + /** + While progress is changed to 0.0, the bar will fade out. + */ + public func cancelProgress() { + progressView.setProgress(0, animated: true) + + UIView.animateWithDuration(0.25) { + self.progressView.bar.alpha = 0 + } + } + +} diff --git a/Sample/AppDelegate.swift b/Sample/AppDelegate.swift new file mode 100644 index 0000000..5be1f9e --- /dev/null +++ b/Sample/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// Sample +// +// Created by 山口 恭兵 on 2015/12/29. +// Copyright © 2015年 kyo__hei. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Sample/Base.lproj/LaunchScreen.storyboard b/Sample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..2e721e1 --- /dev/null +++ b/Sample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Base.lproj/Main.storyboard b/Sample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..76e4bc1 --- /dev/null +++ b/Sample/Base.lproj/Main.storyboard @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sample/Info.plist b/Sample/Info.plist new file mode 100644 index 0000000..40c6215 --- /dev/null +++ b/Sample/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Sample/ViewController.swift b/Sample/ViewController.swift new file mode 100644 index 0000000..8bd2a4e --- /dev/null +++ b/Sample/ViewController.swift @@ -0,0 +1,42 @@ +// +// ViewController.swift +// Sample +// +// Created by 山口 恭兵 on 2015/12/29. +// Copyright © 2015年 kyo__hei. All rights reserved. +// + +import UIKit +import KYNavigationProgress + +class ViewController: UIViewController { + + @IBAction func didTapUpButton(sender: UIButton) { + let progress = navigationController!.progress + navigationController!.setProgress(progress + 0.1, animated: true) + } + + @IBAction func didTapFinishButton(sender: UIButton) { + navigationController!.finishProgress() + } + + @IBAction func didTapCancelButton(sender: UIButton) { + navigationController!.cancelProgress() + } + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + navigationController!.progressTintColor = UIColor.redColor() + navigationController!.trackTintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.2) + navigationController!.progressHeight = 10 + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} +