diff --git a/BTNavigationDropdownMenu.podspec b/BTNavigationDropdownMenu.podspec index bae1e446..453250cb 100644 --- a/BTNavigationDropdownMenu.podspec +++ b/BTNavigationDropdownMenu.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "BTNavigationDropdownMenu" - s.version = "0.4.1" + s.version = "1.0.2" s.summary = "The elegent navigation dropdown menu" s.description = <<-DESC The elegant **dropdown menu**, written in **Swift**, appears underneath **navigation bar** to display a list of related items when a user click on the navigation title. @@ -10,9 +10,10 @@ Pod::Spec.new do |s| s.license = "MIT" s.author = { "Pham Ba Tho" => "phambatho@gmail.com" } s.social_media_url = "https://www.facebook.com/phambatho" - s.platform = :ios, '8.0' + s.platform = :ios, '9.3' s.source = { :git => "https://github.com/PhamBaTho/BTNavigationDropdownMenu.git", :tag => s.version.to_s } s.source_files = "Source/*.swift" s.resources = "Source/*.bundle" - s.requires_arc = true + s.requires_arc = true + s.dependency 'DYBadge' end diff --git a/Demo/BTNavigationDropdownMenu/BTNavigationDropdownMenu.h b/Demo/BTNavigationDropdownMenu/BTNavigationDropdownMenu.h new file mode 100644 index 00000000..78d304f4 --- /dev/null +++ b/Demo/BTNavigationDropdownMenu/BTNavigationDropdownMenu.h @@ -0,0 +1,19 @@ +// +// BTNavigationDropdownMenu.h +// BTNavigationDropdownMenu +// +// Created by Dominik Butz on 10.04.18. +// Copyright © 2018 PHAM BA THO. All rights reserved. +// + +#import + +//! Project version number for BTNavigationDropdownMenu. +FOUNDATION_EXPORT double BTNavigationDropdownMenuVersionNumber; + +//! Project version string for BTNavigationDropdownMenu. +FOUNDATION_EXPORT const unsigned char BTNavigationDropdownMenuVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Demo/BTNavigationDropdownMenu/Info.plist b/Demo/BTNavigationDropdownMenu/Info.plist new file mode 100644 index 00000000..1007fd9d --- /dev/null +++ b/Demo/BTNavigationDropdownMenu/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Demo/Cartfile b/Demo/Cartfile new file mode 100644 index 00000000..f1a5bc9e --- /dev/null +++ b/Demo/Cartfile @@ -0,0 +1 @@ +github "DominikButz/DYBadge" ~> 2.0 diff --git a/Demo/Cartfile.resolved b/Demo/Cartfile.resolved new file mode 100644 index 00000000..9cedac63 --- /dev/null +++ b/Demo/Cartfile.resolved @@ -0,0 +1 @@ +github "DominikButz/DYBadge" "2.0.1" diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadge.podspec b/Demo/Carthage/Checkouts/DYBadge/DYBadge.podspec new file mode 100644 index 00000000..44e7d5da --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadge.podspec @@ -0,0 +1,41 @@ +# +# Be sure to run `pod lib lint DYBadgeButton.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'DYBadge' + s.version = '2.0.1' + s.summary = 'Pop up badge, written in Swift. Add as subview to any UIView object.' + s.swift_version = '4.0' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC + Pop up badge which can be added to any UIView or UIView subclass (written in Swift 4.0). + DESC + + s.homepage = 'https://github.com/DominikButz/DYBadge' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'dominikbutz' => 'dominikbutz@gmail.com' } + s.source = { :git => 'https://github.com/DominikButz/DYBadge.git', :tag => s.version.to_s } + + + s.ios.deployment_target = '9.3' + + s.source_files = 'DYBadgeExample/DYBadge/**/*' + + # s.resource_bundles = { + # 'DYBadge' => ['DYBadge/Assets/*.png'] + # } + + s.public_header_files = 'DYBadge/**/*.h' + +end diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.h b/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.h new file mode 100644 index 00000000..68afadf1 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.h @@ -0,0 +1,19 @@ +// +// DYBadge.h +// DYBadge +// +// Created by Dominik Butz on 09.04.18. +// Copyright © 2018 Duoyun. All rights reserved. +// + +#import + +//! Project version number for DYBadge. +FOUNDATION_EXPORT double DYBadgeVersionNumber; + +//! Project version string for DYBadge. +FOUNDATION_EXPORT const unsigned char DYBadgeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.swift b/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.swift new file mode 100644 index 00000000..22d9a82a --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadge/DYBadge.swift @@ -0,0 +1,262 @@ +// +// DYBadge.swift +// Flat Chat +// +// Created by Dominik Butz on 08.04.18. +// Copyright © 2018 Duoyun. All rights reserved. +// + +import UIKit + +@IBDesignable public class DYBadge: UILabel { + + /// The text of the badge + @IBInspectable open var badgeString:String? { + didSet{ + + let wasNullishBefore = self.isNullish(self.text) + + self.text = badgeString + + self.setBadgeSizeAndFrame(animated: !wasNullishBefore) + + var transform: CGAffineTransform? + var shouldHide: Bool? + + if self.isHidden && self.isNullish(badgeString) == false { + // is hidden but should appear + self.transform = CGAffineTransform(scaleX: 0.01, y: 0.01) + transform = CGAffineTransform.identity + shouldHide = false + + } + + else if self.isHidden == false && self.isNullish(badgeString) { + // should disappear + transform = CGAffineTransform(scaleX: 0.01, y: 0.01) + shouldHide = true + + } else { + + return + } + + self.animateBadgeTransform(shouldHide: shouldHide!,transform: transform!) + + } + } + + + /* + // Only override draw() if you perform custom drawing. + // An empty implementation adversely affects performance during animation. + override func draw(_ rect: CGRect) { + // Drawing code + } + */ + public override func awakeFromNib() { + super.awakeFromNib() + + self.setupBadge() + } + + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + self.setupBadge() + } + + public override init(frame: CGRect) { + super.init(frame: frame) + self.setupBadge() + } + + private func setupBadge() { + + self.textAlignment = .center + + self.setBadgeSizeAndFrame(animated: false) + + self.isHidden = self.isNullish(badgeString) + + + } + + private func setBadgeSizeAndFrame(animated: Bool) { + + if self.isNullish(badgeString) { + return + } + + let sizeLabel = UILabel() + sizeLabel.text = self.badgeString! + sizeLabel.font = self.font + sizeLabel.sizeToFit() + let badgeSize = sizeLabel.frame.size + + self.transform = CGAffineTransform.identity + + let frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: badgeSize.width + 8.0, height: badgeSize.height + 2.0) + + if animated { + UIView.animate(withDuration: 0.1) { + self.set(frame: frame) + } + } else { + + self.set(frame: frame) + + } + + self.clipsToBounds = true + + } + + private func set(frame: CGRect) { + + self.frame = frame + self.layer.cornerRadius = self.bounds.height / 2.0 + + } + + + private func animateBadgeTransform(shouldHide: Bool, transform: CGAffineTransform) { + + let springValue:CGFloat = shouldHide ? 0 : 0.4 + + if shouldHide == false { + + self.isHidden = false + + } + + UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: springValue, initialSpringVelocity: 0, options: [], animations: { + self.transform = transform + + }) { (completed) in + + if shouldHide { + self.isHidden = true + } + } + } + + + + /// Checks if the badge string is "nullish" (nil, empty string or Int value == 0). overridable + /// + /// - Parameters: + /// - stringValue: a String + open func isNullish(_ stringValue: String?)-> Bool { + + if stringValue == nil { + return true + } + + let stringWithoutWhitespaces = stringValue!.components(separatedBy: .whitespaces).joined() + + if stringWithoutWhitespaces == "" { + return true + } + + let intValue = Int(stringWithoutWhitespaces) + + if intValue == 0 { + return true + } + + return false + + } + + /// Finds the first occurence of a DYBadge if it exists among the superview's subviews + /// + /// - Parameters: + /// - superview: the superview that hopefully has a DYBadge as one of its subviews + /// - Returns: a DYBadge object + class func findBadge(in superview: UIView)->DYBadge? { + + let subviews = superview.subviews + + for view in subviews { + if let badge = view as? DYBadge { + return badge + } + } + return nil + } + +} + + +public extension UIView { + + /// Finds the first occurence of a DYBadge if it exists among the view's subviews + /// - Returns: a DYBadge object + public func getBadge()->DYBadge? { + + for view in self.subviews { + if let badge = view as? DYBadge { + return badge + } + } + return nil + + } + +} + +public extension UIButton { + + private func alignImageAndTitleVertically(padding: CGFloat = 6.0) { + + let imageSize = self.imageView!.frame.size + self.titleLabel?.sizeToFit() + self.titleLabel?.textAlignment = .center + + let titleSize = self.titleLabel!.frame.size + let totalHeight = imageSize.height + titleSize.height + padding +// print("image height: \(imageSize.height)") +// print("total height: \(totalHeight)") + + self.imageEdgeInsets = UIEdgeInsets( + top: -(totalHeight - imageSize.height), + left: 0, + bottom: 0, + right: -titleSize.width + ) + + self.titleEdgeInsets = UIEdgeInsets( + top: 0, + left: -imageSize.width, + bottom: -(totalHeight - titleSize.height), + right: 0 + ) + } + + + /// Create a UIButton with an image and title - the title is placed underneath the image + /// + /// - Parameters: + /// - image: a UIImage object + /// - title: the title, placed underneath the image. + /// - font: the font of the title + /// - frame: the frame of the button's image view. the tint color + /// - Returns: a UIButton + public class func createImageTitleButton(image: UIImage, title: String, font: UIFont, frame: CGRect, tintColor: UIColor)->UIButton { + + let button = UIButton(frame: frame) + button.contentMode = .scaleAspectFit + button.setImage(image, for: .normal) + button.imageView!.contentMode = .scaleAspectFit + button.setTitle(title, for: .normal) + button.titleLabel?.font = font + button.tintColor = tintColor + button.setTitleColor(tintColor, for: .normal) + button.alignImageAndTitleVertically(padding: 0) + return button + + } + + +} diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadge/Info.plist b/Demo/Carthage/Checkouts/DYBadge/DYBadge/Info.plist new file mode 100644 index 00000000..12c94a4e --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadge/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.1 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.pbxproj b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..315e7b1c --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.pbxproj @@ -0,0 +1,520 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + B4085CAB207C6C19009BB7BF /* DYBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4085CAA207C6C19009BB7BF /* DYBadge.swift */; }; + B4085CAD207C6C26009BB7BF /* DYBadge.h in Headers */ = {isa = PBXBuildFile; fileRef = B4085CAC207C6C26009BB7BF /* DYBadge.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B4A44179207B5552008A868E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4A44178207B5552008A868E /* AppDelegate.swift */; }; + B4A4417B207B5552008A868E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4A4417A207B5552008A868E /* ViewController.swift */; }; + B4A4417E207B5552008A868E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4A4417C207B5552008A868E /* Main.storyboard */; }; + B4A44180207B5553008A868E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4A4417F207B5553008A868E /* Assets.xcassets */; }; + B4A44183207B5553008A868E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4A44181207B5553008A868E /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B4A44194207B5580008A868E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B4A4416D207B5552008A868E /* Project object */; + proxyType = 1; + remoteGlobalIDString = B4A4418E207B5580008A868E; + remoteInfo = DYBadge; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + B4A4419B207B5580008A868E /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + B4085CAA207C6C19009BB7BF /* DYBadge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DYBadge.swift; sourceTree = ""; }; + B4085CAC207C6C26009BB7BF /* DYBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DYBadge.h; sourceTree = ""; }; + B4A44175207B5552008A868E /* DYBadgeExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DYBadgeExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B4A44178207B5552008A868E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + B4A4417A207B5552008A868E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + B4A4417D207B5552008A868E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + B4A4417F207B5553008A868E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + B4A44182207B5553008A868E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + B4A44184207B5553008A868E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B4A4418F207B5580008A868E /* DYBadge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DYBadge.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B4A44192207B5580008A868E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B4A44172207B5552008A868E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4A4418B207B5580008A868E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B4A4416C207B5552008A868E = { + isa = PBXGroup; + children = ( + B4A44177207B5552008A868E /* DYBadgeExample */, + B4A44190207B5580008A868E /* DYBadge */, + B4A44176207B5552008A868E /* Products */, + ); + sourceTree = ""; + }; + B4A44176207B5552008A868E /* Products */ = { + isa = PBXGroup; + children = ( + B4A44175207B5552008A868E /* DYBadgeExample.app */, + B4A4418F207B5580008A868E /* DYBadge.framework */, + ); + name = Products; + sourceTree = ""; + }; + B4A44177207B5552008A868E /* DYBadgeExample */ = { + isa = PBXGroup; + children = ( + B4A44178207B5552008A868E /* AppDelegate.swift */, + B4A4417A207B5552008A868E /* ViewController.swift */, + B4A4417C207B5552008A868E /* Main.storyboard */, + B4A4417F207B5553008A868E /* Assets.xcassets */, + B4A44181207B5553008A868E /* LaunchScreen.storyboard */, + B4A44184207B5553008A868E /* Info.plist */, + ); + path = DYBadgeExample; + sourceTree = ""; + }; + B4A44190207B5580008A868E /* DYBadge */ = { + isa = PBXGroup; + children = ( + B4085CAC207C6C26009BB7BF /* DYBadge.h */, + B4085CAA207C6C19009BB7BF /* DYBadge.swift */, + B4A44192207B5580008A868E /* Info.plist */, + ); + path = DYBadge; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + B4A4418C207B5580008A868E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B4085CAD207C6C26009BB7BF /* DYBadge.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + B4A44174207B5552008A868E /* DYBadgeExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = B4A44187207B5553008A868E /* Build configuration list for PBXNativeTarget "DYBadgeExample" */; + buildPhases = ( + B4A44171207B5552008A868E /* Sources */, + B4A44172207B5552008A868E /* Frameworks */, + B4A44173207B5552008A868E /* Resources */, + B4A4419B207B5580008A868E /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B4A44195207B5580008A868E /* PBXTargetDependency */, + ); + name = DYBadgeExample; + productName = DYBadgeExample; + productReference = B4A44175207B5552008A868E /* DYBadgeExample.app */; + productType = "com.apple.product-type.application"; + }; + B4A4418E207B5580008A868E /* DYBadge */ = { + isa = PBXNativeTarget; + buildConfigurationList = B4A44198207B5580008A868E /* Build configuration list for PBXNativeTarget "DYBadge" */; + buildPhases = ( + B4A4418A207B5580008A868E /* Sources */, + B4A4418B207B5580008A868E /* Frameworks */, + B4A4418C207B5580008A868E /* Headers */, + B4A4418D207B5580008A868E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DYBadge; + productName = DYBadge; + productReference = B4A4418F207B5580008A868E /* DYBadge.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B4A4416D207B5552008A868E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = Duoyun; + TargetAttributes = { + B4A44174207B5552008A868E = { + CreatedOnToolsVersion = 9.3; + }; + B4A4418E207B5580008A868E = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 0930; + }; + }; + }; + buildConfigurationList = B4A44170207B5552008A868E /* Build configuration list for PBXProject "DYBadgeExample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B4A4416C207B5552008A868E; + productRefGroup = B4A44176207B5552008A868E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B4A44174207B5552008A868E /* DYBadgeExample */, + B4A4418E207B5580008A868E /* DYBadge */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B4A44173207B5552008A868E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B4A44183207B5553008A868E /* LaunchScreen.storyboard in Resources */, + B4A44180207B5553008A868E /* Assets.xcassets in Resources */, + B4A4417E207B5552008A868E /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4A4418D207B5580008A868E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B4A44171207B5552008A868E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B4A4417B207B5552008A868E /* ViewController.swift in Sources */, + B4A44179207B5552008A868E /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B4A4418A207B5580008A868E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B4085CAB207C6C19009BB7BF /* DYBadge.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B4A44195207B5580008A868E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B4A4418E207B5580008A868E /* DYBadge */; + targetProxy = B4A44194207B5580008A868E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + B4A4417C207B5552008A868E /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B4A4417D207B5552008A868E /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + B4A44181207B5553008A868E /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B4A44182207B5553008A868E /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B4A44185207B5553008A868E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + B4A44186207B5553008A868E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B4A44188207B5553008A868E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 76FXG652LY; + INFOPLIST_FILE = DYBadgeExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.DYBadgeExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B4A44189207B5553008A868E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 76FXG652LY; + INFOPLIST_FILE = DYBadgeExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.DYBadgeExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + B4A44199207B5580008A868E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 76FXG652LY; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = DYBadge/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.DYBadge; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B4A4419A207B5580008A868E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 76FXG652LY; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = DYBadge/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.DYBadge; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_INSTALL_OBJC_HEADER = YES; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B4A44170207B5552008A868E /* Build configuration list for PBXProject "DYBadgeExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B4A44185207B5553008A868E /* Debug */, + B4A44186207B5553008A868E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B4A44187207B5553008A868E /* Build configuration list for PBXNativeTarget "DYBadgeExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B4A44188207B5553008A868E /* Debug */, + B4A44189207B5553008A868E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B4A44198207B5580008A868E /* Build configuration list for PBXNativeTarget "DYBadge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B4A44199207B5580008A868E /* Debug */, + B4A4419A207B5580008A868E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = B4A4416D207B5552008A868E /* Project object */; +} diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..4e2d8ee8 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/xcshareddata/xcschemes/DYBadge.xcscheme b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/xcshareddata/xcschemes/DYBadge.xcscheme new file mode 100644 index 00000000..b14d5cad --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample.xcodeproj/xcshareddata/xcschemes/DYBadge.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/AppDelegate.swift b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/AppDelegate.swift new file mode 100644 index 00000000..5c12dc35 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// DYBadgeExample +// +// Created by Dominik Butz on 09.04.18. +// Copyright © 2018 Duoyun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> 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 invalidate graphics rendering callbacks. 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 active 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/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "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" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "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" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/Contents.json b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/Contents.json b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/Contents.json new file mode 100644 index 00000000..c750f8ae --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "IMG_0022.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/IMG_0022.jpg b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/IMG_0022.jpg new file mode 100644 index 00000000..65b384a1 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/IMG_0022.imageset/IMG_0022.jpg differ diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/Contents.json b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/Contents.json new file mode 100644 index 00000000..1752cc84 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "filterButton.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/filterButton.pdf b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/filterButton.pdf new file mode 100644 index 00000000..48df11e1 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/filterButton.imageset/filterButton.pdf differ diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/Contents.json b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/Contents.json new file mode 100644 index 00000000..d90f074b --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sendButton.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/sendButton.pdf b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/sendButton.pdf new file mode 100644 index 00000000..92bb9738 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Assets.xcassets/sendButton.imageset/sendButton.pdf differ diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/LaunchScreen.storyboard b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f83f6fd5 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/Main.storyboard b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f2835184 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Base.lproj/Main.storyboard @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Info.plist b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Info.plist new file mode 100644 index 00000000..16be3b68 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/ViewController.swift b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/ViewController.swift new file mode 100644 index 00000000..a973c979 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/DYBadgeExample/ViewController.swift @@ -0,0 +1,94 @@ +// +// ViewController.swift +// DYBadgeExample +// +// Created by Dominik Butz on 09.04.18. +// Copyright © 2018 Duoyun. All rights reserved. +// + +import UIKit +import DYBadge + +class ViewController: UIViewController { + + @IBOutlet weak var firstSlider: UISlider! + @IBOutlet weak var secondSlider: UISlider! + + @IBOutlet weak var firstButton: UIButton! + @IBOutlet weak var secondButtonItem: UIBarButtonItem! + + @IBOutlet weak var dogImageView: UIImageView! + + @IBOutlet weak var dogBadge: DYBadge! + + override func viewDidLoad() { + super.viewDidLoad() + + self.firstSlider.isContinuous = false + self.firstSlider.value = 0 + + let frame = CGRect(x: self.firstButton.frame.size.width - 3.0, y: -5.0, width: 8.0, height: 5.0) + let firstBadge = DYBadge(frame: frame) + + let font = UIFont(name: "HelveticaNeue-Bold", size: 10.0)! + + firstBadge.font = font + firstBadge.backgroundColor = UIColor.red + firstBadge.textColor = UIColor.white + + self.firstButton.addSubview(firstBadge) + + + self.secondSlider.isContinuous = false + + let buttonFrame = CGRect(x: 0, y: 0, width: 25.0, height: 26.0) + + let filterButton = UIButton.createImageTitleButton(image: #imageLiteral(resourceName: "filterButton"), title: "Filter", font: font, frame: buttonFrame, tintColor: self.view.tintColor) + + let secondBadgeFrame = CGRect(x: buttonFrame.size.width, y: -5.0, width: 8.0, height: 5.0) + + let secondBadge = DYBadge(frame: secondBadgeFrame) + secondBadge.backgroundColor = self.view.tintColor + secondBadge.textColor = UIColor.white + secondBadge.font = font + filterButton.addSubview(secondBadge) + + self.secondButtonItem.customView = filterButton + + // dog badge + self.dogBadge.badgeString = "0" + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + + @IBAction func sliderValueDidChange(_ sender: UISlider) { + print("slider value changed") + if sender == self.firstSlider { + let intValue = Int(sender.value) + print("first slider value") + if let badge = self.firstButton.getBadge() { + print("badge first button found") + badge.badgeString = "\(intValue)" + } + + self.dogBadge.badgeString = intValue > 0 ? "update" : "0" + + } else { + // second slider + let filterButton = self.secondButtonItem.customView as! UIButton + if let badge = filterButton.getBadge() { + print("badge second button found") + badge.badgeString = "\(Int(sender.value))" + } + + } + + } + +} + diff --git a/Demo/Carthage/Checkouts/DYBadge/LICENSE b/Demo/Carthage/Checkouts/DYBadge/LICENSE new file mode 100644 index 00000000..485605bc --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 dominikbutz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Demo/Carthage/Checkouts/DYBadge/README.md b/Demo/Carthage/Checkouts/DYBadge/README.md new file mode 100644 index 00000000..cc667f46 --- /dev/null +++ b/Demo/Carthage/Checkouts/DYBadge/README.md @@ -0,0 +1,138 @@ +# DYBadge + +[![Version](https://img.shields.io/cocoapods/v/DYBadge.svg?style=flat)](http://cocoapods.org/pods/DYBadge) +[![License](https://img.shields.io/cocoapods/l/DYBadge.svg?style=flat)](http://cocoapods.org/pods/DYBadge) +[![Platform](https://img.shields.io/cocoapods/p/DYBadge.svg?style=flat)](http://cocoapods.org/pods/DYBadge) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) + + + DYBadge (written in Swift) is a UILabel subclass that can be added as subview to any UIView and its subclasses (except for UIImageView). If the string value of the badge changes from nil (or "nullish") to a valid string value at runtime the badge will appear with a pop up effect. If it switches back to a "nullish" value, it will shrink and disappear. +The class also includes a UIButton class function (extension) to create a button with an image and a title, which is positioned underneath the image. +**since version 2.0, the xOffset and yOffset values have been removed, as well as badgeFont, badgeColor and badgeTextColor. Simply use the UILabel properties to set these values (don't use badge.text directly!).** + +## Example + +To checkout the example project, simply clone the repo or download the zip file. + +## Features + +* Create in code or get a UILabel in Interface Builder and change its class to DYBadge +* UIDesignable class with badgeString as UIInspectable +* Create a UIButton with image and a button title placed underneath the image and add a DYBadge (see the extension). + +## Installation + + +Installation through Cocoapods or Carthage is recommended. + +Carthage: Simply add the following line to your Cartfile. + +github "DominikButz/DYBadge" ~> 2.0 + +Check out the version history below for the current version. + +Afterwards, run "carthage update DYBadge --platform iOS" in the root directory of your project. Follow the steps described in the carthage project on github (click on the carthage compatible shield above). + +Alternatively, install through Cocoapods: + +target '[project name]' do + pod 'DYBadge', '~> 2.0 +end + +Make sure to import DYBadge into your View Controller subclass: + +```Swift +import DYBadge +``` + +## Usage + +Check out the following examples. + +### Code example: Creating a button with a DYBadge + + +```Swift + @IBOutlet weak var firstButton: UIButton! + + + override func viewDidLoad() { + super.viewDidLoad() + + + let frame = CGRect(x: self.firstButton.frame.size.width - 3.0, y: -5.0, width: 8.0, height: 5.0) + let firstBadge = DYBadge(frame: frame) + + let font = UIFont(name: "HelveticaNeue-Bold", size: 10.0)! + firstBadge.font = font + firstBadge.backgroundColor = UIColor.red + firstBadge.textColor = UIColor.white + + // set a start value if required + firstBadge.badgeString = "7" + + self.firstButton.addSubview(firstBadge) + + + + } + +``` + +![DYBadgeButton example](./gitResources/DYBadgeExample1-small.gif "Badge Button example 1") + +### Code example: Creating a button with image and title + + +```Swift + + @IBOutlet weak var secondButtonItem: UIBarButtonItem! + + override func viewDidLoad() { + super.viewDidLoad() + + let buttonFrame = CGRect(x: 0, y: 0, width: 25.0, height: 26.0) + + let filterButton = UIButton.createImageTitleButton(image: imageLiteral(resourceName: "filterButton"), title: "Filter", font: font, frame: buttonFrame, tintColor: self.view.tintColor) // see extension + + let secondBadge = DYBadge(frame: secondBadgeFrame) + secondBadge.backgroundColor = self.view.tintColor + secondBadge.textColor = UIColor.white + secondBadge.font = font + filterButton.addSubview(secondBadge) + + self.secondButtonItem.customView = filterButton + } +``` +![DYBadgeButton example](./gitResources/DYBadgeExample2-small.gif "Badge Button example 2") + +## Change log +#### [Version 2.0.1](https://github.com/DominikButz/DYBadge/releases/tag/2.0.1) +source file path correction in podspec file. +#### [Version 2.0](https://github.com/DominikButz/DYBadge/releases/tag/2.0) +xOffset and yOffset values have been removed, as well as badgeFont, badgeColor and badgeTextColor. Simply use the UILabel properties (font, color, backgroundColor) to set these values. +#### [Version 1.1.1](https://github.com/DominikButz/DYBadge/releases/tag/1.1.1) +Minor build fix. +#### [Version 1.1](https://github.com/DominikButz/DYBadge/releases/tag/1.1) +The badge is now placed by default at the origin of the superview. Adjust your offsetX and offsetY values accordingly - see the example above. +#### [Version 1.0.3](https://github.com/DominikButz/DYBadge/releases/tag/1.0.3) +public header fix for carthage +#### [Version 1.0.2](https://github.com/DominikButz/DYBadge/releases/tag/1.0.2) +adding podfile, readme update + +#### [Version 1.0.1](https://github.com/DominikButz/DYBadge/releases/tag/1.0.1) +missing source files in example - fix + +#### [Version 1.0](https://github.com/DominikButz/DYBadge/releases/tag/1.0) +see deprecated project DYBadgeButton for previous versions. + + +## Author + +dominikbutz@gmail.com + +## License + +DYBadge is available under the MIT license. See the LICENSE file for more info. + + diff --git a/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1-small.gif b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1-small.gif new file mode 100644 index 00000000..a8623899 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1-small.gif differ diff --git a/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1.gif b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1.gif new file mode 100644 index 00000000..df2acf18 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample1.gif differ diff --git a/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2-small.gif b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2-small.gif new file mode 100644 index 00000000..b1332fbf Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2-small.gif differ diff --git a/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2.gif b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2.gif new file mode 100644 index 00000000..6def7461 Binary files /dev/null and b/Demo/Carthage/Checkouts/DYBadge/gitResources/DYBadgeExample2.gif differ diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj index 09012133..37fbf64b 100755 --- a/Demo/Demo.xcodeproj/project.pbxproj +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -12,23 +12,40 @@ 2E44D6AF1B4C326300C9C49E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6AD1B4C326300C9C49E /* Main.storyboard */; }; 2E44D6B11B4C326300C9C49E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6B01B4C326300C9C49E /* Images.xcassets */; }; 2E44D6B41B4C326300C9C49E /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6B21B4C326300C9C49E /* LaunchScreen.xib */; }; - 2E44D6C01B4C326300C9C49E /* DemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E44D6BF1B4C326300C9C49E /* DemoTests.swift */; }; 2E44D6CC1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6CA1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle */; }; - 2E44D6CD1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6CA1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle */; }; 2E44D6CE1B4C336600C9C49E /* BTNavigationDropdownMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E44D6CB1B4C336600C9C49E /* BTNavigationDropdownMenu.swift */; }; - 2E44D6CF1B4C336600C9C49E /* BTNavigationDropdownMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E44D6CB1B4C336600C9C49E /* BTNavigationDropdownMenu.swift */; }; + B4085CF3207CB39A009BB7BF /* BTNavigationDropdownMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = B4085CF1207CB39A009BB7BF /* BTNavigationDropdownMenu.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B4085CF6207CB39A009BB7BF /* BTNavigationDropdownMenu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4085CEF207CB39A009BB7BF /* BTNavigationDropdownMenu.framework */; }; + B4085CF7207CB39A009BB7BF /* BTNavigationDropdownMenu.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B4085CEF207CB39A009BB7BF /* BTNavigationDropdownMenu.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + B4085CFC207CB3AD009BB7BF /* BTNavigationDropdownMenu.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2E44D6CA1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle */; }; + B4085CFD207CB3AD009BB7BF /* BTNavigationDropdownMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E44D6CB1B4C336600C9C49E /* BTNavigationDropdownMenu.swift */; }; + B429590A207DF9870057007B /* DYBadge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4295909207DF9870057007B /* DYBadge.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 2E44D6BA1B4C326300C9C49E /* PBXContainerItemProxy */ = { + B4085CF4207CB39A009BB7BF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2E44D69C1B4C326300C9C49E /* Project object */; proxyType = 1; - remoteGlobalIDString = 2E44D6A31B4C326300C9C49E; - remoteInfo = Demo; + remoteGlobalIDString = B4085CEE207CB39A009BB7BF; + remoteInfo = BTNavigationDropdownMenu; }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + B4085CFB207CB39A009BB7BF /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + B4085CF7207CB39A009BB7BF /* BTNavigationDropdownMenu.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 2E44D6A41B4C326300C9C49E /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2E44D6A81B4C326300C9C49E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -37,11 +54,14 @@ 2E44D6AE1B4C326300C9C49E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 2E44D6B01B4C326300C9C49E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 2E44D6B31B4C326300C9C49E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 2E44D6B91B4C326300C9C49E /* DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 2E44D6BE1B4C326300C9C49E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2E44D6BF1B4C326300C9C49E /* DemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoTests.swift; sourceTree = ""; }; 2E44D6CA1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = BTNavigationDropdownMenu.bundle; sourceTree = ""; }; 2E44D6CB1B4C336600C9C49E /* BTNavigationDropdownMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BTNavigationDropdownMenu.swift; sourceTree = ""; }; + B4085CEF207CB39A009BB7BF /* BTNavigationDropdownMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BTNavigationDropdownMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B4085CF1207CB39A009BB7BF /* BTNavigationDropdownMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTNavigationDropdownMenu.h; sourceTree = ""; }; + B4085CF2207CB39A009BB7BF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B4295909207DF9870057007B /* DYBadge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DYBadge.framework; path = Carthage/Build/iOS/DYBadge.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,13 +69,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B4085CF6207CB39A009BB7BF /* BTNavigationDropdownMenu.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 2E44D6B61B4C326300C9C49E /* Frameworks */ = { + B4085CEB207CB39A009BB7BF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B429590A207DF9870057007B /* DYBadge.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -68,7 +90,9 @@ 2E44D6A61B4C326300C9C49E /* Demo */, 2E44D6BC1B4C326300C9C49E /* DemoTests */, 2E44D6C91B4C336600C9C49E /* Source */, + B4085CF0207CB39A009BB7BF /* BTNavigationDropdownMenu */, 2E44D6A51B4C326300C9C49E /* Products */, + B4295908207DF9870057007B /* Frameworks */, ); sourceTree = ""; }; @@ -76,7 +100,7 @@ isa = PBXGroup; children = ( 2E44D6A41B4C326300C9C49E /* Demo.app */, - 2E44D6B91B4C326300C9C49E /* DemoTests.xctest */, + B4085CEF207CB39A009BB7BF /* BTNavigationDropdownMenu.framework */, ); name = Products; sourceTree = ""; @@ -129,8 +153,36 @@ path = ../Source; sourceTree = ""; }; + B4085CF0207CB39A009BB7BF /* BTNavigationDropdownMenu */ = { + isa = PBXGroup; + children = ( + B4085CF1207CB39A009BB7BF /* BTNavigationDropdownMenu.h */, + B4085CF2207CB39A009BB7BF /* Info.plist */, + ); + path = BTNavigationDropdownMenu; + sourceTree = ""; + }; + B4295908207DF9870057007B /* Frameworks */ = { + isa = PBXGroup; + children = ( + B4295909207DF9870057007B /* DYBadge.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ +/* Begin PBXHeadersBuildPhase section */ + B4085CEC207CB39A009BB7BF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B4085CF3207CB39A009BB7BF /* BTNavigationDropdownMenu.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + /* Begin PBXNativeTarget section */ 2E44D6A31B4C326300C9C49E /* Demo */ = { isa = PBXNativeTarget; @@ -139,33 +191,36 @@ 2E44D6A01B4C326300C9C49E /* Sources */, 2E44D6A11B4C326300C9C49E /* Frameworks */, 2E44D6A21B4C326300C9C49E /* Resources */, + B4085CFB207CB39A009BB7BF /* Embed Frameworks */, + B429590D207DFCDE0057007B /* ShellScript */, ); buildRules = ( ); dependencies = ( + B4085CF5207CB39A009BB7BF /* PBXTargetDependency */, ); name = Demo; productName = Demo; productReference = 2E44D6A41B4C326300C9C49E /* Demo.app */; productType = "com.apple.product-type.application"; }; - 2E44D6B81B4C326300C9C49E /* DemoTests */ = { + B4085CEE207CB39A009BB7BF /* BTNavigationDropdownMenu */ = { isa = PBXNativeTarget; - buildConfigurationList = 2E44D6C61B4C326300C9C49E /* Build configuration list for PBXNativeTarget "DemoTests" */; + buildConfigurationList = B4085CFA207CB39A009BB7BF /* Build configuration list for PBXNativeTarget "BTNavigationDropdownMenu" */; buildPhases = ( - 2E44D6B51B4C326300C9C49E /* Sources */, - 2E44D6B61B4C326300C9C49E /* Frameworks */, - 2E44D6B71B4C326300C9C49E /* Resources */, + B4085CEA207CB39A009BB7BF /* Sources */, + B4085CEB207CB39A009BB7BF /* Frameworks */, + B4085CEC207CB39A009BB7BF /* Headers */, + B4085CED207CB39A009BB7BF /* Resources */, ); buildRules = ( ); dependencies = ( - 2E44D6BB1B4C326300C9C49E /* PBXTargetDependency */, ); - name = DemoTests; - productName = DemoTests; - productReference = 2E44D6B91B4C326300C9C49E /* DemoTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = BTNavigationDropdownMenu; + productName = BTNavigationDropdownMenu; + productReference = B4085CEF207CB39A009BB7BF /* BTNavigationDropdownMenu.framework */; + productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -175,15 +230,16 @@ attributes = { LastSwiftMigration = 0700; LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = "PHAM BA THO"; TargetAttributes = { 2E44D6A31B4C326300C9C49E = { CreatedOnToolsVersion = 6.4; + LastSwiftMigration = 0900; }; - 2E44D6B81B4C326300C9C49E = { - CreatedOnToolsVersion = 6.4; - TestTargetID = 2E44D6A31B4C326300C9C49E; + B4085CEE207CB39A009BB7BF = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; }; }; }; @@ -201,7 +257,7 @@ projectRoot = ""; targets = ( 2E44D6A31B4C326300C9C49E /* Demo */, - 2E44D6B81B4C326300C9C49E /* DemoTests */, + B4085CEE207CB39A009BB7BF /* BTNavigationDropdownMenu */, ); }; /* End PBXProject section */ @@ -218,16 +274,33 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2E44D6B71B4C326300C9C49E /* Resources */ = { + B4085CED207CB39A009BB7BF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2E44D6CD1B4C336600C9C49E /* BTNavigationDropdownMenu.bundle in Resources */, + B4085CFC207CB3AD009BB7BF /* BTNavigationDropdownMenu.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + B429590D207DFCDE0057007B /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Carthage/Build/iOS/DYBadge.framework", + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 2E44D6A01B4C326300C9C49E /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -239,22 +312,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2E44D6B51B4C326300C9C49E /* Sources */ = { + B4085CEA207CB39A009BB7BF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2E44D6C01B4C326300C9C49E /* DemoTests.swift in Sources */, - 2E44D6CF1B4C336600C9C49E /* BTNavigationDropdownMenu.swift in Sources */, + B4085CFD207CB3AD009BB7BF /* BTNavigationDropdownMenu.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 2E44D6BB1B4C326300C9C49E /* PBXTargetDependency */ = { + B4085CF5207CB39A009BB7BF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 2E44D6A31B4C326300C9C49E /* Demo */; - targetProxy = 2E44D6BA1B4C326300C9C49E /* PBXContainerItemProxy */; + target = B4085CEE207CB39A009BB7BF /* BTNavigationDropdownMenu */; + targetProxy = B4085CF4207CB39A009BB7BF /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -286,13 +358,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -315,11 +397,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -331,13 +414,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -353,9 +446,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; VALIDATE_PRODUCT = YES; }; name = Release; @@ -363,54 +458,121 @@ 2E44D6C41B4C326300C9C49E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = Demo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "phambatho.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; 2E44D6C51B4C326300C9C49E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = Demo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "phambatho.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; - 2E44D6C71B4C326300C9C49E /* Debug */ = { + B4085CF8207CB39A009BB7BF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", ); - INFOPLIST_FILE = DemoTests/Info.plist; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = BTNavigationDropdownMenu/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "phambatho.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo.app/Demo"; + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.BTNavigationDropdownMenu; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 2E44D6C81B4C326300C9C49E /* Release */ = { + B4085CF9207CB39A009BB7BF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = DemoTests/Info.plist; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = BTNavigationDropdownMenu/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "phambatho.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo.app/Demo"; + PRODUCT_BUNDLE_IDENTIFIER = me.duoyun.BTNavigationDropdownMenu; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Release; }; @@ -435,11 +597,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2E44D6C61B4C326300C9C49E /* Build configuration list for PBXNativeTarget "DemoTests" */ = { + B4085CFA207CB39A009BB7BF /* Build configuration list for PBXNativeTarget "BTNavigationDropdownMenu" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2E44D6C71B4C326300C9C49E /* Debug */, - 2E44D6C81B4C326300C9C49E /* Release */, + B4085CF8207CB39A009BB7BF /* Debug */, + B4085CF9207CB39A009BB7BF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Demo/Demo.xcodeproj/xcshareddata/xcschemes/BTNavigationDropdownMenu.xcscheme b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/BTNavigationDropdownMenu.xcscheme new file mode 100644 index 00000000..b8e54cd7 --- /dev/null +++ b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/BTNavigationDropdownMenu.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme index 9e00268b..38605563 100755 --- a/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme +++ b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme @@ -1,6 +1,6 @@ Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Set white status bar - UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true) + UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true) + return true } - func applicationWillResignActive(application: UIApplication) { + 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) { + 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) { + 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) { + 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) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/Demo/Demo/Base.lproj/Main.storyboard b/Demo/Demo/Base.lproj/Main.storyboard index f183891c..39b3e636 100755 --- a/Demo/Demo/Base.lproj/Main.storyboard +++ b/Demo/Demo/Base.lproj/Main.storyboard @@ -1,9 +1,13 @@ - - + + + + + - + + @@ -15,23 +19,32 @@ - + + + + + + + + - + - - + + + + @@ -71,17 +84,17 @@ - + - + @@ -103,7 +116,7 @@ - + @@ -115,4 +128,7 @@ + + + diff --git a/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json b/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json index 118c98f7..b8236c65 100755 --- a/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", diff --git a/Demo/Demo/Images.xcassets/Contents.json b/Demo/Demo/Images.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Demo/Demo/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/DSC_0007.imageset/Contents.json b/Demo/Demo/Images.xcassets/DSC_0007.imageset/Contents.json new file mode 100644 index 00000000..b2083ac5 --- /dev/null +++ b/Demo/Demo/Images.xcassets/DSC_0007.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "DSC_0007.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/DSC_0007.imageset/DSC_0007.jpg b/Demo/Demo/Images.xcassets/DSC_0007.imageset/DSC_0007.jpg new file mode 100644 index 00000000..c16172f1 Binary files /dev/null and b/Demo/Demo/Images.xcassets/DSC_0007.imageset/DSC_0007.jpg differ diff --git a/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/Contents.json b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/Contents.json new file mode 100644 index 00000000..55fde746 --- /dev/null +++ b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "accountSettingsMenuItemButton.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "accountSettingsMenuItemButton@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "accountSettingsMenuItemButton@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton.png b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton.png new file mode 100644 index 00000000..b155facf Binary files /dev/null and b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton.png differ diff --git a/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@2x.png b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@2x.png new file mode 100644 index 00000000..004de112 Binary files /dev/null and b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@2x.png differ diff --git a/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@3x.png b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@3x.png new file mode 100644 index 00000000..d92e16a9 Binary files /dev/null and b/Demo/Demo/Images.xcassets/accountSettingsMenuItemButton.imageset/accountSettingsMenuItemButton@3x.png differ diff --git a/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/Contents.json b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/Contents.json new file mode 100644 index 00000000..6fef81ce --- /dev/null +++ b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "adsMenuItemButton.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "adsMenuItemButton@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "adsMenuItemButton@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton.png b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton.png new file mode 100644 index 00000000..79049885 Binary files /dev/null and b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton.png differ diff --git a/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@2x.png b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@2x.png new file mode 100644 index 00000000..f498bf1b Binary files /dev/null and b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@2x.png differ diff --git a/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@3x.png b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@3x.png new file mode 100644 index 00000000..df0bd097 Binary files /dev/null and b/Demo/Demo/Images.xcassets/adsMenuItemButton.imageset/adsMenuItemButton@3x.png differ diff --git a/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/Contents.json b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/Contents.json new file mode 100644 index 00000000..d11c1b14 --- /dev/null +++ b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "chatsMenuItemButton.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "chatsMenuItemButton@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "chatsMenuItemButton@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton.png b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton.png new file mode 100644 index 00000000..eea14312 Binary files /dev/null and b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton.png differ diff --git a/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@2x.png b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@2x.png new file mode 100644 index 00000000..58efdd9a Binary files /dev/null and b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@2x.png differ diff --git a/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@3x.png b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@3x.png new file mode 100644 index 00000000..c9584efe Binary files /dev/null and b/Demo/Demo/Images.xcassets/chatsMenuItemButton.imageset/chatsMenuItemButton@3x.png differ diff --git a/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/Contents.json b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/Contents.json new file mode 100644 index 00000000..5a6213fb --- /dev/null +++ b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "favoritesMenuItemButton.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "favoritesMenuItemButton@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "favoritesMenuItemButton@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton.png b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton.png new file mode 100644 index 00000000..38c4640a Binary files /dev/null and b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton.png differ diff --git a/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@2x.png b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@2x.png new file mode 100644 index 00000000..080c3f08 Binary files /dev/null and b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@2x.png differ diff --git a/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@3x.png b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@3x.png new file mode 100644 index 00000000..6d7ac872 Binary files /dev/null and b/Demo/Demo/Images.xcassets/favoritesMenuItemButton.imageset/favoritesMenuItemButton@3x.png differ diff --git a/Demo/Demo/Images.xcassets/menuButton.imageset/Contents.json b/Demo/Demo/Images.xcassets/menuButton.imageset/Contents.json new file mode 100644 index 00000000..6b5f7571 --- /dev/null +++ b/Demo/Demo/Images.xcassets/menuButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "menuButton.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "menuButton@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "menuButton@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton.png b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton.png new file mode 100644 index 00000000..4642aee8 Binary files /dev/null and b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton.png differ diff --git a/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@2x.png b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@2x.png new file mode 100644 index 00000000..0454d8bf Binary files /dev/null and b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@2x.png differ diff --git a/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@3x.png b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@3x.png new file mode 100644 index 00000000..595dd0c8 Binary files /dev/null and b/Demo/Demo/Images.xcassets/menuButton.imageset/menuButton@3x.png differ diff --git a/Demo/Demo/ViewController.swift b/Demo/Demo/ViewController.swift index 523eed1d..122776e1 100755 --- a/Demo/Demo/ViewController.swift +++ b/Demo/Demo/ViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import BTNavigationDropdownMenu class ViewController: UIViewController { @@ -15,30 +16,60 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - let items = ["Most Popular", "Latest", "Trending", "Nearest", "Top Picks"] - self.selectedCellLabel.text = items.first - self.navigationController?.navigationBar.translucent = false - self.navigationController?.navigationBar.barTintColor = UIColor(red: 0.0/255.0, green:180/255.0, blue:220/255.0, alpha: 1.0) - self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()] - - menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, containerView: self.navigationController!.view, title: "Dropdown Menu", items: items) - menuView.cellHeight = 50 + + let items = [BTNavigationDropdownMenu.MenuItem(title:"Favorites", image: UIImage(named:"favoritesMenuItemButton")!), BTNavigationDropdownMenu.MenuItem(title:"Ads", image: UIImage(named:"adsMenuItemButton")),BTNavigationDropdownMenu.MenuItem(title:"Chats", image: UIImage(named:"chatsMenuItemButton")!), BTNavigationDropdownMenu.MenuItem(title:"Settings", image: UIImage(named:"accountSettingsMenuItemButton")!), BTNavigationDropdownMenu.MenuItem(title:"Other stuff", image: UIImage(named:"menuButton")!)] + + + self.selectedCellLabel.text = items.first?.title + + self.navigationController?.navigationBar.isTranslucent = false + self.navigationController?.navigationBar.barTintColor = UIColor.darkGray + self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white] + + menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, containerView: self.navigationController!.view, title: items.first!.title, items: items as [BTNavigationDropdownMenu.MenuItem], backgroundViewMode: .blur, blurStyle: .light, dimBackgroundColor:nil) + menuView.cellBackgroundColor = self.navigationController?.navigationBar.barTintColor - menuView.cellSelectionColor = UIColor(red: 0.0/255.0, green:160.0/255.0, blue:195.0/255.0, alpha: 1.0) + menuView.cellSelectionColor = UIColor.gray + menuView.cellSeparatorColor = self.navigationController?.navigationBar.barTintColor + + menuView.cellTextLabelHorizontalMargin = 150.0 + + menuView.cellTintColor = UIColor(red: 105/255, green: 220/255, blue: 95/255, alpha: 1.0) // light green + + menuView.arrowTintColor = UIColor(red: 105/255, green: 220/255, blue: 95/255, alpha: 1.0) // light green + menuView.arrowPadding = 20.0 + menuView.shouldKeepSelectedCellColor = true - menuView.cellTextLabelColor = UIColor.whiteColor() - menuView.cellTextLabelFont = UIFont(name: "Avenir-Heavy", size: 17) - menuView.cellTextLabelAlignment = .Left // .Center // .Right // .Left + menuView.cellTextLabelColor = UIColor(red: 105/255, green: 220/255, blue: 95/255, alpha: 1.0) // light green + if #available(iOS 9.0, *) { + menuView.cellTextLabelFont = UIFont.preferredFont(forTextStyle: UIFontTextStyle.title2) + } else { + menuView.cellTextLabelFont = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline) + } + menuView.cellTextLabelAlignment = .right// .center // .right // .left menuView.arrowPadding = 15 - menuView.animationDuration = 0.5 - menuView.maskBackgroundColor = UIColor.blackColor() - menuView.maskBackgroundOpacity = 0.3 - menuView.didSelectItemAtIndexHandler = {(indexPath: Int) -> () in - print("Did select item at index: \(indexPath)") - self.selectedCellLabel.text = items[indexPath] + menuView.animationDuration = 0.4 + + menuView.delegate = self + + menuView.didSelectItemAtIndexHandler = {(index: Int) -> () in + print("Did select item at index: \(index)") + self.selectedCellLabel.text = items[index].title + self.menuView.updateBadge(text: "\(index + 1)", at: index) } self.navigationItem.titleView = menuView } } +extension ViewController: BTNavigationDropdownMenuDelegate { + + func menuDidShow() { + print("menu did show") + } + + func menuDidHide() { + print("menu did hide") + } + +} diff --git a/Demo/DemoTests/DemoTests.swift b/Demo/DemoTests/DemoTests.swift index dbfb4bed..d5e87738 100755 --- a/Demo/DemoTests/DemoTests.swift +++ b/Demo/DemoTests/DemoTests.swift @@ -28,7 +28,7 @@ class DemoProjectTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } } diff --git a/Source/BTNavigationDropdownMenu.swift b/Source/BTNavigationDropdownMenu.swift index fe497cd8..e2b11549 100755 --- a/Source/BTNavigationDropdownMenu.swift +++ b/Source/BTNavigationDropdownMenu.swift @@ -25,12 +25,36 @@ // SOFTWARE. import UIKit +import DYBadge + +public protocol BTNavigationDropdownMenuDelegate { + + func menuDidShow() + func menuDidHide() + +} // MARK: BTNavigationDropdownMenu -public class BTNavigationDropdownMenu: UIView { +open class BTNavigationDropdownMenu: UIView { + + public class MenuItem { + var title:String + var image:UIImage? + public var badgeString: String? + + public init(title: String, image:UIImage?) { + self.title = title + self.image = image + } + + } + + public enum BackgroundViewMode { + case dim, blur + } // The color of menu title. Default is darkGrayColor() - public var menuTitleColor: UIColor! { + open var menuTitleColor: UIColor! { get { return self.configuration.menuTitleColor } @@ -38,19 +62,32 @@ public class BTNavigationDropdownMenu: UIView { self.configuration.menuTitleColor = value } } - + // The height of the cell. Default is 50 - public var cellHeight: NSNumber! { + open var cellHeight: NSNumber! { get { - return CGFloat(self.configuration.cellHeight) + // return CGFloat(self.configuration.cellHeight) + return NSNumber(value:Float(self.configuration.cellHeight)) } set(value) { - self.configuration.cellHeight = CGFloat(value) + self.configuration.cellHeight = CGFloat(truncating: value) } } - + + + // the color of the images and the checkmark. Default value is nil. If this value is nil, png images and checkmark have their original colours + open var cellTintColor: UIColor? { + get { + return self.configuration.cellTintColor + } + set(color) { + self.configuration.cellTintColor = color + } + } + + // The color of the cell background. Default is whiteColor() - public var cellBackgroundColor: UIColor! { + open var cellBackgroundColor: UIColor! { get { return self.configuration.cellBackgroundColor } @@ -60,7 +97,7 @@ public class BTNavigationDropdownMenu: UIView { } // The tint color of the arrow. Default is whiteColor() - public var arrowTintColor: UIColor! { + open var arrowTintColor: UIColor! { get { return self.menuArrow.tintColor } @@ -69,7 +106,7 @@ public class BTNavigationDropdownMenu: UIView { } } - public var cellSeparatorColor: UIColor! { + open var cellSeparatorColor: UIColor! { get { return self.configuration.cellSeparatorColor } @@ -79,7 +116,7 @@ public class BTNavigationDropdownMenu: UIView { } // The color of the text inside cell. Default is darkGrayColor() - public var cellTextLabelColor: UIColor! { + open var cellTextLabelColor: UIColor! { get { return self.configuration.cellTextLabelColor } @@ -89,7 +126,7 @@ public class BTNavigationDropdownMenu: UIView { } // The color of the text inside a selected cell. Default is darkGrayColor() - public var selectedCellTextLabelColor: UIColor! { + open var selectedCellTextLabelColor: UIColor! { get { return self.configuration.selectedCellTextLabelColor } @@ -99,7 +136,7 @@ public class BTNavigationDropdownMenu: UIView { } // The font of the text inside cell. Default is HelveticaNeue-Bold, size 17 - public var cellTextLabelFont: UIFont! { + open var cellTextLabelFont: UIFont! { get { return self.configuration.cellTextLabelFont } @@ -108,8 +145,46 @@ public class BTNavigationDropdownMenu: UIView { } } + // distance of text label from cell edge. + open var cellTextLabelHorizontalMargin: CGFloat! { + get { + return self.configuration.cellTextLabelHorizontalMargin + } + set(value) { + self.configuration.cellTextLabelHorizontalMargin = value + } + + } + + + // height and width of the image (square shaped) + open var cellImageSize: CGFloat! { + get { + return self.configuration.cellImageSize + } + + set(value) { + self.configuration.cellImageSize = value + } + + } + + + // margin between image and text label + open var cellLabelImageDistance: CGFloat! { + get { + return self.configuration.cellLabelImageDistance + } + + set(value) { + self.configuration.cellLabelImageDistance = value + } + + } + + // The font of the navigation bar title. Default is HelveticaNeue-Bold, size 17 - public var navigationBarTitleFont: UIFont! { + open var navigationBarTitleFont: UIFont! { get { return self.configuration.navigationBarTitleFont } @@ -120,7 +195,7 @@ public class BTNavigationDropdownMenu: UIView { } // The alignment of the text inside cell. Default is .Left - public var cellTextLabelAlignment: NSTextAlignment! { + open var cellTextLabelAlignment: NSTextAlignment! { get { return self.configuration.cellTextLabelAlignment } @@ -130,7 +205,7 @@ public class BTNavigationDropdownMenu: UIView { } // The color of the cell when the cell is selected. Default is lightGrayColor() - public var cellSelectionColor: UIColor! { + open var cellSelectionColor: UIColor! { get { return self.configuration.cellSelectionColor } @@ -140,7 +215,7 @@ public class BTNavigationDropdownMenu: UIView { } // The checkmark icon of the cell - public var checkMarkImage: UIImage! { + open var checkMarkImage: UIImage! { get { return self.configuration.checkMarkImage } @@ -150,7 +225,7 @@ public class BTNavigationDropdownMenu: UIView { } // The boolean value that decides if selected color of cell is visible when the menu is shown. Default is false - public var shouldKeepSelectedCellColor: Bool! { + open var shouldKeepSelectedCellColor: Bool! { get { return self.configuration.shouldKeepSelectedCellColor } @@ -160,7 +235,7 @@ public class BTNavigationDropdownMenu: UIView { } // The animation duration of showing/hiding menu. Default is 0.3 - public var animationDuration: NSTimeInterval! { + open var animationDuration: TimeInterval! { get { return self.configuration.animationDuration } @@ -168,20 +243,20 @@ public class BTNavigationDropdownMenu: UIView { self.configuration.animationDuration = value } } - + // The arrow next to navigation title - public var arrowImage: UIImage! { + open var arrowImage: UIImage! { get { return self.configuration.arrowImage } set(value) { - self.configuration.arrowImage = value.imageWithRenderingMode(.AlwaysTemplate) + self.configuration.arrowImage = value.withRenderingMode(.alwaysTemplate) self.menuArrow.image = self.configuration.arrowImage } } // The padding between navigation title and arrow - public var arrowPadding: CGFloat! { + open var arrowPadding: CGFloat! { get { return self.configuration.arrowPadding } @@ -190,28 +265,22 @@ public class BTNavigationDropdownMenu: UIView { } } - // The color of the mask layer. Default is blackColor() - public var maskBackgroundColor: UIColor! { - get { - return self.configuration.maskBackgroundColor - } - set(value) { - self.configuration.maskBackgroundColor = value - } - } + // The opacity of the mask layer. Default is 0.3 - public var maskBackgroundOpacity: CGFloat! { + open var dimBackgroundOpacity: CGFloat! { get { - return self.configuration.maskBackgroundOpacity + return self.configuration.dimBackgroundOpacity } set(value) { - self.configuration.maskBackgroundOpacity = value + self.configuration.dimBackgroundOpacity = value } } + + // The boolean value that decides if you want to change the title text when a cell is selected. Default is true - public var shouldChangeTitleText: Bool! { + open var shouldChangeTitleText: Bool! { get { return self.configuration.shouldChangeTitleText } @@ -220,28 +289,33 @@ public class BTNavigationDropdownMenu: UIView { } } - public var didSelectItemAtIndexHandler: ((indexPath: Int) -> ())? - public var isShown: Bool! - - private weak var navigationController: UINavigationController? - private var configuration = BTConfiguration() - private var topSeparator: UIView! - private var menuButton: UIButton! - private var menuTitle: UILabel! - private var menuArrow: UIImageView! - private var backgroundView: UIView! - private var tableView: BTTableView! - private var items: [AnyObject]! - private var menuWrapper: UIView! + + + open var didSelectItemAtIndexHandler: ((_ indexPath: Int) -> ())! + open var isShown: Bool! + + fileprivate weak var navigationController: UINavigationController? + fileprivate var configuration = BTConfiguration() + fileprivate var topSeparator: UIView! + fileprivate var menuButton: UIButton! + fileprivate var menuTitle: UILabel! + fileprivate var menuArrow: UIImageView! + fileprivate var backgroundView: UIView! + fileprivate var tableView: BTTableView! + public var items: [MenuItem]! + fileprivate var menuWrapper: UIView! + fileprivate var backgroundViewMode: BackgroundViewMode! + + public var delegate: BTNavigationDropdownMenuDelegate? required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - public init(navigationController: UINavigationController? = nil, containerView: UIView = UIApplication.sharedApplication().keyWindow!, title: String, items: [AnyObject]) { + public init(navigationController: UINavigationController? = nil, containerView: UIView = UIApplication.shared.keyWindow!, title: String, items: [MenuItem], backgroundViewMode: BackgroundViewMode?, blurStyle: UIBlurEffectStyle?, dimBackgroundColor:UIColor? ) { // Key window - guard let window = UIApplication.sharedApplication().keyWindow else { - super.init(frame: CGRectZero) + guard let window = UIApplication.shared.keyWindow else { + super.init(frame: CGRect.zero) return } @@ -252,11 +326,29 @@ public class BTNavigationDropdownMenu: UIView { self.navigationController = window.rootViewController?.topMostViewController?.navigationController } + // Get titleSize - let titleSize = (title as NSString).sizeWithAttributes([NSFontAttributeName:self.configuration.navigationBarTitleFont]) + // get longest title + + var titleLength = CGFloat(0) + var longestTitle = title + + for item in items { + + let titleWidth = (item.title as NSString).size(withAttributes: [NSAttributedStringKey.font:self.configuration.navigationBarTitleFont]).width + + if titleWidth > titleLength { + titleLength = titleWidth + longestTitle = item.title + print("longest title is \(item.title)") + } + + } + + let titleSize = (longestTitle as NSString).size(withAttributes: [NSAttributedStringKey.font:self.configuration.navigationBarTitleFont]) // Set frame - let frame = CGRectMake(0, 0, titleSize.width + (self.configuration.arrowPadding + self.configuration.arrowImage.size.width)*2, self.navigationController!.navigationBar.frame.height) + let frame = CGRect(x: 0, y: 0, width: titleSize.width + (self.configuration.arrowPadding + self.configuration.arrowImage.size.width)*2, height: self.navigationController!.navigationBar.frame.height) super.init(frame:frame) @@ -265,9 +357,9 @@ public class BTNavigationDropdownMenu: UIView { // Init button as navigation title self.menuButton = UIButton(frame: frame) - self.menuButton.addTarget(self, action: #selector(BTNavigationDropdownMenu.menuButtonTapped(_:)), forControlEvents: UIControlEvents.TouchUpInside) + self.menuButton.addTarget(self, action: #selector(BTNavigationDropdownMenu.menuButtonTapped(_:)), for: UIControlEvents.touchUpInside) self.addSubview(self.menuButton) - + self.menuTitle = UILabel(frame: frame) self.menuTitle.text = title self.menuTitle.textColor = self.menuTitleColor @@ -275,83 +367,119 @@ public class BTNavigationDropdownMenu: UIView { self.menuTitle.textAlignment = self.configuration.cellTextLabelAlignment self.menuButton.addSubview(self.menuTitle) - self.menuArrow = UIImageView(image: self.configuration.arrowImage.imageWithRenderingMode(.AlwaysTemplate)) + self.menuArrow = UIImageView(image: self.configuration.arrowImage.withRenderingMode(.alwaysTemplate)) self.menuButton.addSubview(self.menuArrow) let menuWrapperBounds = window.bounds // Set up DropdownMenu - self.menuWrapper = UIView(frame: CGRectMake(menuWrapperBounds.origin.x, 0, menuWrapperBounds.width, menuWrapperBounds.height)) + self.menuWrapper = UIView(frame: CGRect(x: menuWrapperBounds.origin.x, y: 0, width: menuWrapperBounds.width, height: menuWrapperBounds.height)) self.menuWrapper.clipsToBounds = true - self.menuWrapper.autoresizingMask = [ .FlexibleWidth, .FlexibleHeight ] + self.menuWrapper.autoresizingMask = [ .flexibleWidth, .flexibleHeight ] + + + // Init properties + self.setupDefaultConfiguration() // Init background view (under table view) - self.backgroundView = UIView(frame: menuWrapperBounds) - self.backgroundView.backgroundColor = self.configuration.maskBackgroundColor - self.backgroundView.autoresizingMask = [ .FlexibleWidth, .FlexibleHeight ] + + if backgroundViewMode == .dim { + + self.backgroundView = self.getdimView(frame: menuWrapperBounds, dimColor: dimBackgroundColor) + self.backgroundViewMode = .dim + } + + else if backgroundViewMode == .blur { + self.backgroundView = self.getBlurView(frame: menuWrapperBounds,blurStyle: blurStyle) + self.backgroundViewMode = .blur + } + + // self.backgroundView.backgroundColor = self.configuration.dimBackgroundColor + self.backgroundView.autoresizingMask = [ .flexibleWidth, .flexibleHeight ] + let backgroundTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(BTNavigationDropdownMenu.hideMenu)); self.backgroundView.addGestureRecognizer(backgroundTapRecognizer) - // Init properties - self.setupDefaultConfiguration() + // Init table view let navBarHeight = self.navigationController?.navigationBar.bounds.size.height ?? 0 - let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height ?? 0 - self.tableView = BTTableView(frame: CGRectMake(menuWrapperBounds.origin.x, menuWrapperBounds.origin.y + 0.5, menuWrapperBounds.width, menuWrapperBounds.height + 300 - navBarHeight - statusBarHeight), items: items, title: title, configuration: self.configuration) + let statusBarHeight = UIApplication.shared.statusBarFrame.height + self.tableView = BTTableView(frame: CGRect(x: menuWrapperBounds.origin.x, y: menuWrapperBounds.origin.y + 0.5, width: menuWrapperBounds.width, height: menuWrapperBounds.height + 300 - navBarHeight - statusBarHeight), items: items, title: title, configuration: self.configuration) self.tableView.selectRowAtIndexPathHandler = { [weak self] (indexPath: Int) -> () in guard let selfie = self else { return } - selfie.didSelectItemAtIndexHandler!(indexPath: indexPath) + selfie.didSelectItemAtIndexHandler!(indexPath) if selfie.shouldChangeTitleText! { - selfie.setMenuTitle("\(selfie.tableView.items[indexPath])") + selfie.setMenuTitle("\(selfie.tableView.items[indexPath].title)") } self?.hideMenu() self?.layoutSubviews() } + // Add background view & table view to container view self.menuWrapper.addSubview(self.backgroundView) self.menuWrapper.addSubview(self.tableView) + // Add Line on top - self.topSeparator = UIView(frame: CGRectMake(0, 0, menuWrapperBounds.size.width, 0.5)) - self.topSeparator.autoresizingMask = UIViewAutoresizing.FlexibleWidth + self.topSeparator = UIView(frame: CGRect(x: 0, y: 0, width: menuWrapperBounds.size.width, height: 0.5)) + self.topSeparator.autoresizingMask = UIViewAutoresizing.flexibleWidth self.menuWrapper.addSubview(self.topSeparator) // Add Menu View to container view containerView.addSubview(self.menuWrapper) // By default, hide menu view - self.menuWrapper.hidden = true + self.menuWrapper.isHidden = true + } + + fileprivate func getdimView(frame:CGRect, dimColor: UIColor?)->UIView { + let dimView = UIView(frame:frame) + dimView.backgroundColor = dimColor ?? self.configuration.dimBackgroundColor + return dimView + } + + fileprivate func getBlurView(frame:CGRect, blurStyle: UIBlurEffectStyle?)->UIVisualEffectView{ + + let blurEffect = UIBlurEffect(style: blurStyle ?? self.configuration.blurStyle) + let blurredView = UIVisualEffectView(effect: blurEffect) + + blurredView.frame = frame + blurredView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + return blurredView + } - override public func layoutSubviews() { + override open func layoutSubviews() { self.menuTitle.sizeToFit() - self.menuTitle.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2) - self.menuTitle.textColor = self.configuration.menuTitleColor + self.menuTitle.center = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2) + self.menuTitle.textColor = self.menuTitleColor self.menuArrow.sizeToFit() - self.menuArrow.center = CGPointMake(CGRectGetMaxX(self.menuTitle.frame) + self.configuration.arrowPadding, self.frame.size.height/2) + self.menuArrow.center = CGPoint(x: self.menuTitle.frame.maxX + self.configuration.arrowPadding, y: self.frame.size.height/2) self.menuWrapper.frame.origin.y = self.navigationController!.navigationBar.frame.maxY + self.tableView.reloadData() } - public func show() { + open func show() { if self.isShown == false { self.showMenu() } } - public func hide() { + open func hide() { if self.isShown == true { self.hideMenu() } } - - public func toggle() { + + open func toggle() { if(self.isShown == true) { self.hideMenu(); } else { @@ -359,7 +487,7 @@ public class BTNavigationDropdownMenu: UIView { } } - public func updateItems(items: [AnyObject]) { + open func updateItems(_ items: [MenuItem]) { if !items.isEmpty { self.tableView.items = items self.tableView.reloadData() @@ -367,10 +495,10 @@ public class BTNavigationDropdownMenu: UIView { } func setupDefaultConfiguration() { - self.menuTitleColor = self.navigationController?.navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + self.menuTitleColor = self.navigationController?.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor self.cellBackgroundColor = self.navigationController?.navigationBar.barTintColor - self.cellSeparatorColor = self.navigationController?.navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor - self.cellTextLabelColor = self.navigationController?.navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + self.cellSeparatorColor = self.navigationController?.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor + self.cellTextLabelColor = self.navigationController?.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor self.arrowTintColor = self.configuration.arrowTintColor } @@ -381,17 +509,18 @@ public class BTNavigationDropdownMenu: UIView { self.isShown = true // Table view header - let headerView = UIView(frame: CGRectMake(0, 0, self.frame.width, 300)) + let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: 300)) headerView.backgroundColor = self.configuration.cellBackgroundColor self.tableView.tableHeaderView = headerView self.topSeparator.backgroundColor = self.configuration.cellSeparatorColor + // Rotate arrow self.rotateArrow() // Visible menu view - self.menuWrapper.hidden = false + self.menuWrapper.isHidden = false // Change background alpha self.backgroundView.alpha = 0 @@ -401,72 +530,100 @@ public class BTNavigationDropdownMenu: UIView { // Reload data to dismiss highlight color of selected cell self.tableView.reloadData() + + self.menuWrapper.superview?.bringSubview(toFront: self.menuWrapper) - self.menuWrapper.superview?.bringSubviewToFront(self.menuWrapper) + self.delegate?.menuDidShow() - UIView.animateWithDuration( - self.configuration.animationDuration * 1.5, + UIView.animate( + withDuration: self.configuration.animationDuration * 1.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: [], animations: { self.tableView.frame.origin.y = CGFloat(-300) - self.backgroundView.alpha = self.configuration.maskBackgroundOpacity - }, completion: nil + if self.backgroundViewMode == .dim { + self.backgroundView.alpha = self.configuration.dimBackgroundOpacity + } else { + print("showing menu - animating blur view to 1.0 alpha") + self.backgroundView.alpha = 1.0 + } + }, completion: nil ) } - func hideMenu() { + @objc func hideMenu() { // Rotate arrow self.rotateArrow() self.isShown = false // Change background alpha - self.backgroundView.alpha = self.configuration.maskBackgroundOpacity - - UIView.animateWithDuration( - self.configuration.animationDuration * 1.5, + if self.backgroundViewMode == .dim { + self.backgroundView.alpha = self.configuration.dimBackgroundOpacity + } else { + self.backgroundView.alpha = 1.0 + } + self.delegate?.menuDidHide() + UIView.animate( + withDuration: self.configuration.animationDuration * 1.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: [], animations: { self.tableView.frame.origin.y = CGFloat(-200) - }, completion: nil + }, completion: nil ) // Animation - UIView.animateWithDuration( - self.configuration.animationDuration, + UIView.animate( + withDuration: self.configuration.animationDuration, delay: 0, - options: UIViewAnimationOptions.TransitionNone, + options: UIViewAnimationOptions(), animations: { self.tableView.frame.origin.y = -CGFloat(self.items.count) * self.configuration.cellHeight - 300 self.backgroundView.alpha = 0 - }, completion: { _ in - if self.isShown == false && self.tableView.frame.origin.y == -CGFloat(self.items.count) * self.configuration.cellHeight - 300 { - self.menuWrapper.hidden = true - } + }, completion: { _ in + if self.isShown == false && self.tableView.frame.origin.y == -CGFloat(self.items.count) * self.configuration.cellHeight - 300 { + self.menuWrapper.isHidden = true + } }) } func rotateArrow() { - UIView.animateWithDuration(self.configuration.animationDuration, animations: {[weak self] () -> () in + UIView.animate(withDuration: self.configuration.animationDuration, animations: {[weak self] () -> () in if let selfie = self { - selfie.menuArrow.transform = CGAffineTransformRotate(selfie.menuArrow.transform, 180 * CGFloat(M_PI/180)) + selfie.menuArrow.transform = selfie.menuArrow.transform.rotated(by: 180 * CGFloat(Double.pi/180)) } - }) + }) } - func setMenuTitle(title: String) { + func setMenuTitle(_ title: String) { self.menuTitle.text = title } - func menuButtonTapped(sender: UIButton) { + @objc func menuButtonTapped(_ sender: UIButton) { self.isShown == true ? hideMenu() : showMenu() } + + open func setSelectedItem(at index: Int){ + + let indexPath = IndexPath(row: index, section: 0) + self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none) + self.tableView.tableView(self.tableView, didSelectRowAt: indexPath) + } + + public func updateBadge(text: String, at index: Int) { + + self.items[index].badgeString = text + + let cell = self.tableView.cellForRow(at: IndexPath(row: index, section: 0)) as! BTTableViewCell + cell.badge.badgeString = text + + } + } // MARK: BTConfiguration @@ -480,15 +637,21 @@ class BTConfiguration { var cellTextLabelFont: UIFont! var navigationBarTitleFont: UIFont! var cellTextLabelAlignment: NSTextAlignment! + var cellTextLabelHorizontalMargin: CGFloat! + var cellImageSize:CGFloat! + var cellLabelImageDistance: CGFloat! var cellSelectionColor: UIColor? + var cellTintColor: UIColor? var checkMarkImage: UIImage! var shouldKeepSelectedCellColor: Bool! var arrowTintColor: UIColor? var arrowImage: UIImage! var arrowPadding: CGFloat! - var animationDuration: NSTimeInterval! - var maskBackgroundColor: UIColor! - var maskBackgroundOpacity: CGFloat! + var animationDuration: TimeInterval! + var dimBackgroundColor: UIColor! + var dimBackgroundOpacity: CGFloat! + var blurStyle:UIBlurEffectStyle! + var shouldChangeTitleText: Bool! init() { @@ -497,31 +660,35 @@ class BTConfiguration { func defaultValue() { // Path for image - let bundle = NSBundle(forClass: BTConfiguration.self) - let url = bundle.URLForResource("BTNavigationDropdownMenu", withExtension: "bundle") - let imageBundle = NSBundle(URL: url!) - let checkMarkImagePath = imageBundle?.pathForResource("checkmark_icon", ofType: "png") - let arrowImagePath = imageBundle?.pathForResource("arrow_down_icon", ofType: "png") - + let bundle = Bundle(for: BTConfiguration.self) + let url = bundle.url(forResource: "BTNavigationDropdownMenu", withExtension: "bundle") + let imageBundle = Bundle(url: url!) + let checkMarkImagePath = imageBundle?.path(forResource: "checkmark_icon", ofType: "png") + let arrowImagePath = imageBundle?.path(forResource: "arrow_down_icon", ofType: "png") + // Default values - self.menuTitleColor = UIColor.darkGrayColor() + self.menuTitleColor = UIColor.darkGray self.cellHeight = 50 - self.cellBackgroundColor = UIColor.whiteColor() - self.arrowTintColor = UIColor.whiteColor() - self.cellSeparatorColor = UIColor.darkGrayColor() - self.cellTextLabelColor = UIColor.darkGrayColor() - self.selectedCellTextLabelColor = UIColor.darkGrayColor() + self.cellBackgroundColor = UIColor.white + self.arrowTintColor = UIColor.white + self.cellSeparatorColor = UIColor.darkGray + self.cellTextLabelColor = UIColor.darkGray + self.selectedCellTextLabelColor = UIColor.darkGray self.cellTextLabelFont = UIFont(name: "HelveticaNeue-Bold", size: 17) self.navigationBarTitleFont = UIFont(name: "HelveticaNeue-Bold", size: 17) - self.cellTextLabelAlignment = NSTextAlignment.Left - self.cellSelectionColor = UIColor.lightGrayColor() + self.cellTextLabelAlignment = NSTextAlignment.left + self.cellTextLabelHorizontalMargin = 50 + self.cellImageSize = 35 + self.cellLabelImageDistance = 5.0 + self.cellSelectionColor = UIColor.lightGray self.checkMarkImage = UIImage(contentsOfFile: checkMarkImagePath!) self.shouldKeepSelectedCellColor = false self.animationDuration = 0.5 self.arrowImage = UIImage(contentsOfFile: arrowImagePath!) self.arrowPadding = 15 - self.maskBackgroundColor = UIColor.blackColor() - self.maskBackgroundOpacity = 0.3 + self.dimBackgroundColor = UIColor.black + self.dimBackgroundOpacity = 0.3 + self.blurStyle = .dark self.shouldChangeTitleText = true } } @@ -531,78 +698,136 @@ class BTTableView: UITableView, UITableViewDelegate, UITableViewDataSource { // Public properties var configuration: BTConfiguration! - var selectRowAtIndexPathHandler: ((indexPath: Int) -> ())? + var selectRowAtIndexPathHandler: ((_ indexPath: Int) -> ())? // Private properties - private var items: [AnyObject]! - private var selectedIndexPath: Int? + fileprivate var items:[BTNavigationDropdownMenu.MenuItem]! + fileprivate var selectedIndexPath: Int? required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - init(frame: CGRect, items: [AnyObject], title: String, configuration: BTConfiguration) { - super.init(frame: frame, style: UITableViewStyle.Plain) + init(frame: CGRect, items: [BTNavigationDropdownMenu.MenuItem], title: String, configuration: BTConfiguration) { + super.init(frame: frame, style: UITableViewStyle.plain) self.items = items - self.selectedIndexPath = (items as! [String]).indexOf(title) + + print("BT table view init, title is \(title)") + var index = 0 + for item in self.items { + if item.title == title { + self.selectedIndexPath = index + print("selected index path title is \(item.title)") + break + } + + index += 1 + } + + self.configuration = configuration // Setup table view self.delegate = self self.dataSource = self - self.backgroundColor = UIColor.clearColor() - self.separatorStyle = UITableViewCellSeparatorStyle.None + self.backgroundColor = UIColor.clear + self.separatorStyle = UITableViewCellSeparatorStyle.none // self.separatorEffect = UIBlurEffect(style: .Light) - self.autoresizingMask = UIViewAutoresizing.FlexibleWidth - self.tableFooterView = UIView(frame: CGRectZero) + self.autoresizingMask = UIViewAutoresizing.flexibleWidth + self.tableFooterView = UIView(frame: CGRect.zero) } - override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { - if let hitView = super.hitTest(point, withEvent: event) where hitView.isKindOfClass(BTTableCellContentView.self) { + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + if let hitView = super.hitTest(point, with: event), hitView.isKind(of: BTTableCellContentView.self) { return hitView } return nil; } // Table view data source - func numberOfSectionsInTableView(tableView: UITableView) -> Int { + func numberOfSections(in tableView: UITableView) -> Int { return 1 } - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.items.count } - func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return self.configuration.cellHeight } - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = BTTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell", configuration: self.configuration) - cell.textLabel?.text = self.items[indexPath.row] as? String - cell.checkmarkIcon.hidden = (indexPath.row == selectedIndexPath) ? false : true + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let cell = BTTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell", configuration: self.configuration) + cell.textLabel?.text = self.items[indexPath.row].title + + // cell.isSelected = indexPath.row == self.selectedIndexPath! ? true : false + + cell.checkmarkIcon.isHidden = (indexPath.row == selectedIndexPath) ? false : true + + // images not supported for text alignment center + if (self.items[indexPath.row].image != nil) && self.configuration.cellTextLabelAlignment != .center { + + let imageOriginX:CGFloat + + if self.configuration.cellTextLabelAlignment == .left { + imageOriginX = cell.textLabel!.frame.origin.x - self.configuration.cellLabelImageDistance - self.configuration.cellImageSize + } else { + imageOriginX = cell.textLabel!.frame.origin.x + cell.textLabel!.frame.size.width + self.configuration.cellLabelImageDistance + } + + + cell.imageView?.frame = CGRect(x: imageOriginX, y: (self.configuration.cellHeight - self.configuration.cellImageSize) / 2, width: self.configuration.cellImageSize, height: self.configuration.cellImageSize) + cell.imageView?.clipsToBounds = true + cell.imageView?.contentMode = .center + cell.contentView.addSubview(cell.imageView!) + + if let _ = self.configuration.cellTintColor { + cell.imageView!.image = self.items[indexPath.row].image!.withRenderingMode(.alwaysTemplate) + } else { + cell.imageView!.image = self.items[indexPath.row].image! + } + + + // badge + + let badgeFrame = CGRect(x: imageOriginX + cell.imageView!.frame.size.width - 7.0, y: cell.imageView!.frame.origin.y + 3.0, width: 8.0, height: 8.0) + cell.badge = DYBadge(frame: badgeFrame) + cell.badge.font = UIFont(name: "HelveticaNeue-Bold", size: 10.0)! + cell.badge.textColor = UIColor.white + cell.badge.backgroundColor = UIColor.red + + cell.contentView.addSubview(cell.badge) + + cell.badge.badgeString = self.items[indexPath.row].badgeString + + + } + + return cell } // Table view delegate - func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectedIndexPath = indexPath.row - self.selectRowAtIndexPathHandler!(indexPath: indexPath.row) + self.selectRowAtIndexPathHandler!(indexPath.row) self.reloadData() - let cell = tableView.cellForRowAtIndexPath(indexPath) as? BTTableViewCell + let cell = tableView.cellForRow(at: indexPath) as? BTTableViewCell cell?.contentView.backgroundColor = self.configuration.cellSelectionColor cell?.textLabel?.textColor = self.configuration.selectedCellTextLabelColor } - func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { - let cell = tableView.cellForRowAtIndexPath(indexPath) as? BTTableViewCell - cell?.checkmarkIcon.hidden = true + func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { + let cell = tableView.cellForRow(at: indexPath) as? BTTableViewCell + cell?.checkmarkIcon.isHidden = true cell?.contentView.backgroundColor = self.configuration.cellBackgroundColor cell?.textLabel?.textColor = self.configuration.cellTextLabelColor } - - func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { + + func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if self.configuration.shouldKeepSelectedCellColor == true { cell.backgroundColor = self.configuration.cellBackgroundColor cell.contentView.backgroundColor = (indexPath.row == selectedIndexPath) ? self.configuration.cellSelectionColor : self.configuration.cellBackgroundColor @@ -613,11 +838,12 @@ class BTTableView: UITableView, UITableViewDelegate, UITableViewDataSource { // MARK: Table view cell class BTTableViewCell: UITableViewCell { let checkmarkIconWidth: CGFloat = 50 - let horizontalMargin: CGFloat = 20 + var checkmarkIcon: UIImageView! var cellContentFrame: CGRect! var configuration: BTConfiguration! + var badge: DYBadge! init(style: UITableViewCellStyle, reuseIdentifier: String?, configuration: BTConfiguration) { super.init(style: style, reuseIdentifier: reuseIdentifier) @@ -625,33 +851,44 @@ class BTTableViewCell: UITableViewCell { self.configuration = configuration // Setup cell - cellContentFrame = CGRectMake(0, 0, (UIApplication.sharedApplication().keyWindow?.frame.width)!, self.configuration.cellHeight) + cellContentFrame = CGRect(x: 0, y: 0, width: (UIApplication.shared.keyWindow?.frame.width)!, height: self.configuration.cellHeight) self.contentView.backgroundColor = self.configuration.cellBackgroundColor - self.selectionStyle = UITableViewCellSelectionStyle.None + self.selectionStyle = UITableViewCellSelectionStyle.none self.textLabel!.textColor = self.configuration.cellTextLabelColor self.textLabel!.font = self.configuration.cellTextLabelFont self.textLabel!.textAlignment = self.configuration.cellTextLabelAlignment - if self.textLabel!.textAlignment == .Center { - self.textLabel!.frame = CGRectMake(0, 0, cellContentFrame.width, cellContentFrame.height) - } else if self.textLabel!.textAlignment == .Left { - self.textLabel!.frame = CGRectMake(horizontalMargin, 0, cellContentFrame.width, cellContentFrame.height) + if self.textLabel!.textAlignment == .center { + self.textLabel!.frame = CGRect(x: 0, y: 0, width: cellContentFrame.width, height: cellContentFrame.height) + } else if self.textLabel!.textAlignment == .left { + self.textLabel!.frame = CGRect(x: self.configuration.cellTextLabelHorizontalMargin, y: 0, width: cellContentFrame.width, height: cellContentFrame.height) } else { - self.textLabel!.frame = CGRectMake(-horizontalMargin, 0, cellContentFrame.width, cellContentFrame.height) + self.textLabel!.frame = CGRect(x: -self.configuration.cellTextLabelHorizontalMargin, y: 0, width: cellContentFrame.width, height: cellContentFrame.height) } + + self.tintColor = self.configuration.cellTintColor + // Checkmark icon - if self.textLabel!.textAlignment == .Center { - self.checkmarkIcon = UIImageView(frame: CGRectMake(cellContentFrame.width - checkmarkIconWidth, (cellContentFrame.height - 30)/2, 30, 30)) - } else if self.textLabel!.textAlignment == .Left { - self.checkmarkIcon = UIImageView(frame: CGRectMake(cellContentFrame.width - checkmarkIconWidth, (cellContentFrame.height - 30)/2, 30, 30)) + if self.textLabel!.textAlignment == .center { + self.checkmarkIcon = UIImageView(frame: CGRect(x: cellContentFrame.width - checkmarkIconWidth, y: (cellContentFrame.height - 30)/2, width: 30, height: 30)) + } else if self.textLabel!.textAlignment == .left { + self.checkmarkIcon = UIImageView(frame: CGRect(x: cellContentFrame.width - checkmarkIconWidth, y: (cellContentFrame.height - 30)/2, width: 30, height: 30)) + } else {// right + self.checkmarkIcon = UIImageView(frame: CGRect(x: self.configuration.cellLabelImageDistance + checkmarkIconWidth, y: (cellContentFrame.height - 30)/2, width: 30, height: 30)) + } + self.checkmarkIcon.isHidden = true + + + if let _ = self.configuration.cellTintColor { + self.checkmarkIcon.image = self.configuration.checkMarkImage.withRenderingMode(.alwaysTemplate) } else { - self.checkmarkIcon = UIImageView(frame: CGRectMake(horizontalMargin, (cellContentFrame.height - 30)/2, 30, 30)) + self.checkmarkIcon.image = self.configuration.checkMarkImage } - self.checkmarkIcon.hidden = true - self.checkmarkIcon.image = self.configuration.checkMarkImage - self.checkmarkIcon.contentMode = UIViewContentMode.ScaleAspectFill + + self.checkmarkIcon.contentMode = UIViewContentMode.scaleAspectFill self.contentView.addSubview(self.checkmarkIcon) + // Separator for cell let separator = BTTableCellContentView(frame: cellContentFrame) if let cellSeparatorColor = self.configuration.cellSeparatorColor { @@ -672,7 +909,7 @@ class BTTableViewCell: UITableViewCell { // Content view of table view cell class BTTableCellContentView: UIView { - var separatorColor: UIColor = UIColor.blackColor() + var separatorColor: UIColor = UIColor.black override init(frame: CGRect) { super.init(frame: frame) @@ -687,19 +924,19 @@ class BTTableCellContentView: UIView { } func initialize() { - self.backgroundColor = UIColor.clearColor() + self.backgroundColor = UIColor.clear } - override func drawRect(rect: CGRect) { - super.drawRect(rect) + override func draw(_ rect: CGRect) { + super.draw(rect) let context = UIGraphicsGetCurrentContext() // Set separator color of dropdown menu based on barStyle - CGContextSetStrokeColorWithColor(context, self.separatorColor.CGColor) - CGContextSetLineWidth(context, 1) - CGContextMoveToPoint(context, 0, self.bounds.size.height) - CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height) - CGContextStrokePath(context) + context?.setStrokeColor(self.separatorColor.cgColor) + context?.setLineWidth(1) + context?.move(to: CGPoint(x: 0, y: self.bounds.size.height)) + context?.addLine(to: CGPoint(x: self.bounds.size.width, y: self.bounds.size.height)) + context?.strokePath() } }