Repository: Boris-Em/NightView Branch: master Commit: aea628d84e31 Files: 22 Total size: 121.5 KB Directory structure: gitextract_hhkka7jk/ ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── NightView/ │ └── NightView.swift ├── NightViewSampleProject/ │ ├── NightViewSampleProject/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Moto.imageset/ │ │ │ │ └── Contents.json │ │ │ └── NightView.imageset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── CustomizationTableViewController.swift │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── NightViewSampleProject.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── NightViewSampleProject.xcscheme │ │ └── NightViewSampleProjectTests.xcscheme │ └── NightViewSampleProjectTests/ │ ├── Info.plist │ └── NightViewTests.swift └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore ## Build generated build/ DerivedData/ ## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ ## Other *.moved-aside *.xcuserstate ## Obj-C/Swift specific *.hmap *.ipa *.dSYM.zip *.dSYM ## Playgrounds timeline.xctimeline playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ .build/ # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output ================================================ FILE: .travis.yml ================================================ language: objective-c osx_image: xcode8.0 script: - xcodebuild clean build test -project "NightViewSampleProject/NightViewSampleProject.xcodeproj" -scheme NightViewSampleProject -sdk iphonesimulator10.0 -destination "OS=10.0,name=iPhone 5S" ONLY_ACTIVE_ARCH=NO ================================================ FILE: CHANGELOG.md ================================================ # Change Log ## [v1.1.0](https://github.com/Boris-Em/NightView/releases/tag/1.0.1) (2016-07-11) [Full Changelog](https://github.com/Boris-Em/BEMCheckBox/compare/1.0.0...1.0.1) - Fix starType enum. - Fix bug where NightView wasn't available in different modules. - Add title to Customization view controller. ## [v1.0.0](https://github.com/Boris-Em/NightView/releases/tag/1.0.0) (2016-07-10) First stable release of **NightView** ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016 Boris Emorine 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. ================================================ FILE: NightView/NightView.swift ================================================ // // NightView.swift // Go // // Created by Bobo on 7/8/16. // Copyright © 2016 Boris Emorine. All rights reserved. // import UIKit /** Dazzling Nights on iOS. */ @IBDesignable public class NightView: UIView { /** The number of points for each star. For example, setting this property to 1, means that there will be 1 star for every point in the view. A greater number means less stars within the view. Defaults to 10000.0. */ @IBInspectable public var numberOfPointsForStar: CGFloat = 10000.0 { didSet { reload() } } /** The size of the stars in points. Defaults to 5.0. */ @IBInspectable public var starSize: CGFloat = 5.0 { didSet { reload() } } /** The color of the stars. Defaults to white. */ @IBInspectable public var starColor = UIColor.white /** The minimum percent by which the stars' size could be changed. For example, a value of 50.0 means that the minimum size of a star will be 50% of the `starSize` property. Defaults to 50.0. - SeeAlso: `starSize` */ @IBInspectable public var starSizeMinRandomizer = 50.0 { didSet { let max = starSizeMaxRandomizer < starSizeMinRandomizer ? starSizeMinRandomizer + 1 : starSizeMaxRandomizer starSizeProductRandomizerRange = UInt32(starSizeMinRandomizer)...UInt32(max) } } /** The maximum percent by which the stars' size could be changed. For example, a value of 150.0 means that the maximum size of a star will be 150% of the `starSize` property. Defaults to 150.0. - SeeAlso: `starSize` */ @IBInspectable public var starSizeMaxRandomizer = 150.0 { didSet { let min = starSizeMinRandomizer > starSizeMaxRandomizer ? starSizeMaxRandomizer - 1 : starSizeMinRandomizer starSizeProductRandomizerRange = UInt32(min)...UInt32(starSizeMaxRandomizer) } } private var starSizeProductRandomizerRange = UInt32(50)...UInt32(150) { didSet { reload() } } /** The stars are drawn with a smaller opacity at the bottom of the view than at the top. This property sets the minimum opacity for the lower stars. Note that the stars at the top of the view will always have an opacity of 1.0. Defaults to 0.5. */ @IBInspectable public var minStarOpacity: Float = 0.5 { didSet { reload() } } /** The intensity of the glowing of the stars, from 0 to 1. If set to 0, the stars will not glow. Defaults to 0.5. */ @IBInspectable public var glowingIntensity: Float = 0.5 { didSet { reload() } } /** The duration in seconds at which the stars glow. Defaults to 2.0. */ @IBInspectable public var glowingDuration = 2.0 { didSet { reload() } } /** Type of stars. */ public enum starTypes { /** Round stars. */ case Round /** Smooth star with 5 branches. */ case FiveBranchStar } /** The type of stars to be drawn. Defaults to `.Round`. */ @IBInspectable public var starType: starTypes = .Round { didSet { reload() } } private let starLayer = CAShapeLayer() // MARK: Initializers override public init(frame: CGRect) { super.init(frame: frame) commonInit() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } private func commonInit() { layer.addSublayer(starLayer) } // MARK: Public Functions /** Reloads the NightView instance, redrawing all of the stars. */ public func reload() { setNeedsDisplay() layer.displayIfNeeded() } // MARK: Drawings override public func layoutSubviews() { super.layoutSubviews() reload() } override public func draw(_ rect: CGRect) { starLayer.frame = bounds drawStars() } private func drawStars() { removeSublayersFromLayer(layer: starLayer) let numberOfStars = numberOfStarsForSize(size: bounds.size) for _ in 0.. 0.0 { addGlowingAnimationToStar(layer: layer) } } } private func drawStarWithFrame(frame: CGRect, boundingFrame: CGRect?) -> CAShapeLayer { let layer = CAShapeLayer() layer.frame = frame layer.fillColor = starColor.cgColor layer.path = pathForStarWithType(starType: starType, frame: frame).cgPath layer.backgroundColor = UIColor.clear.cgColor if let boundingFrame = boundingFrame { layer.opacity = max((Float(boundingFrame.height - frame.origin.y) / 100.0) / (Float(boundingFrame.height) / 100.0), minStarOpacity) } starLayer.addSublayer(layer) return layer } // MARK: Paths private func pathForStarWithType(starType: starTypes, frame: CGRect) -> UIBezierPath { let width = frame.width switch starType { case .FiveBranchStar: let starPath = UIBezierPath() starPath.move(to: CGPoint(x: width / (1000 / 500), y: width / (1000 / 50))) starPath.addLine(to: CGPoint(x: width / (1000 / 676.34), y: width / (1000 / 307.29))) starPath.addLine(to: CGPoint(x: width / (1000 / 975.53), y: width / (1000 / 395.49))) starPath.addLine(to: CGPoint(x: width / (1000 / 785.32), y: width / (1000 / 642.71))) starPath.addLine(to: CGPoint(x: width / (1000 / 793.89), y: width / (1000 / 954.51))) starPath.addLine(to: CGPoint(x: width / (1000 / 500), y: width / (1000 / 850))) starPath.addLine(to: CGPoint(x: width / (1000 / 206.11), y: width / (1000 / 954.51))) starPath.addLine(to: CGPoint(x: width / (1000 / 214.68), y: width / (1000 / 642.71))) starPath.addLine(to: CGPoint(x: width / (1000 / 24.47), y: width / (1000 / 395.49))) starPath.addLine(to: CGPoint(x: width / (1000 / 323.66), y: width / (1000 / 307.29))) starPath.close() return starPath default: return UIBezierPath(ovalIn: CGRect(x: 0.0, y: 0.0, width: frame.width, height: frame.height)) } } // MARK: Animations private func addGlowingAnimationToStar(layer: CAShapeLayer) { let animation = CABasicAnimation(keyPath: "opacity") animation.duration = glowingDuration animation.fromValue = layer.opacity animation.beginTime = CACurrentMediaTime() + Double(arc4random_uniform(UInt32(glowingDuration) * 1000)) / 1000 animation.toValue = NSNumber(value: layer.opacity - layer.opacity * glowingIntensity) animation.autoreverses = true animation.repeatCount = .infinity layer.add(animation, forKey: "opacity") } // MARK: Generators private func randomStarFrameInFrame(frame: CGRect) -> CGRect { let size = randomStarSizeForSize(starSize: starSize) let minX = frame.origin.x let maxX = frame.origin.x + frame.size.width let minY = frame.origin.y let maxY = frame.origin.y + frame.size.height let randomX = CGFloat(arc4random_uniform(UInt32(maxX - minX))) + minX let randomY = CGFloat(arc4random_uniform(UInt32(maxY - minY))) + minY let starFrame = CGRect(x: randomX, y: randomY, width: size.width, height: size.height) return starFrame } private func randomStarSizeForSize(starSize: CGFloat) -> CGSize { let randomStarSizeProduct = CGFloat(arc4random_uniform(starSizeProductRandomizerRange.last! - starSizeProductRandomizerRange.first!) + starSizeProductRandomizerRange.first!) / 100.0; let randomSize = starSize * randomStarSizeProduct return CGSize(width: randomSize, height: randomSize) } private func numberOfStarsForSize(size: CGSize) -> Int { let area = size.width * size.height return Int(area / numberOfPointsForStar) } private func removeSublayersFromLayer(layer: CAShapeLayer) { if let sublayers = layer.sublayers { for sublayer in sublayers { sublayer.removeFromSuperlayer() } } } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/AppDelegate.swift ================================================ // // AppDelegate.swift // NightViewSampleProject // // Created by Bobo on 7/10/16. // Copyright © 2016 Boris Emorine. All rights reserved. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Assets.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Assets.xcassets/Moto.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Moto.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "Moto@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "Moto@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Assets.xcassets/NightView.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "NightView.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "NightView@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "NightView@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Base.lproj/Main.storyboard ================================================ ================================================ FILE: NightViewSampleProject/NightViewSampleProject/CustomizationTableViewController.swift ================================================ // // CustomizationTableViewController.swift // NightViewSampleProject // // Created by Bobo on 7/11/16. // Copyright © 2016 Boris Emorine. All rights reserved. // import UIKit class CustomizationTableViewController: UITableViewController { @IBOutlet weak var numberOfPointsForStarLabel: UILabel! @IBOutlet weak var starSizeLabel: UILabel! @IBOutlet weak var starSizeMinRandomizerLabel: UILabel! @IBOutlet weak var starSizeMaxRandomizerLabel: UILabel! @IBOutlet weak var minStarOpacityLabel: UILabel! @IBOutlet weak var glowingIntensityLabel: UILabel! @IBOutlet weak var glowingDurationLabel: UILabel! @IBOutlet weak var starTypeLabel: UILabel! @IBOutlet weak var numberOfPointsForStarSlider: UISlider! @IBOutlet weak var starSizeSlider: UISlider! @IBOutlet weak var starSizeMinRandomizerSlider: UISlider! @IBOutlet weak var starSizeMaxRandomizerSlider: UISlider! @IBOutlet weak var minStarOpacitySlider: UISlider! @IBOutlet weak var glowingIntensitySlider: UISlider! @IBOutlet weak var glowingDurationSlider: UISlider! @IBOutlet weak var starTypeSegmentedControl: UISegmentedControl! var nightView: NightView? override func viewDidLoad() { super.viewDidLoad() title = "Customization" if let numberOfPointsForStar = nightView?.numberOfPointsForStar { numberOfPointsForStarLabel.text = String(format: "%.1f", numberOfPointsForStar) numberOfPointsForStarSlider.value = Float(numberOfPointsForStar) } if let starSize = nightView?.starSize { starSizeLabel.text = String(format: "%.1f", starSize) starSizeSlider.value = Float(starSize) } if let starSizeMinRandomizer = nightView?.starSizeMinRandomizer { starSizeMinRandomizerLabel.text = String(format: "%.1f", starSizeMinRandomizer) starSizeMinRandomizerSlider.value = Float(starSizeMinRandomizer) } if let starSizeMaxRandomizer = nightView?.starSizeMaxRandomizer { starSizeMaxRandomizerLabel.text = String(format: "%.1f", starSizeMaxRandomizer) starSizeMaxRandomizerSlider.value = Float(starSizeMaxRandomizer) } if let minStarOpacity = nightView?.minStarOpacity { minStarOpacityLabel.text = String(format: "%.1f", minStarOpacity) minStarOpacitySlider.value = Float(minStarOpacity) } if let glowingIntensity = nightView?.glowingIntensity { glowingIntensityLabel.text = String(format: "%.1f", glowingIntensity) glowingIntensitySlider.value = Float(glowingIntensity) } if let glowingDuration = nightView?.glowingDuration { glowingDurationLabel.text = String(format: "%.1f", glowingDuration) glowingDurationSlider.value = Float(glowingDuration) } if let starType = nightView?.starType { switch starType { case .Round: starTypeSegmentedControl.selectedSegmentIndex = 0 break case .FiveBranchStar: starTypeSegmentedControl.selectedSegmentIndex = 1 break } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } @IBAction func handleSlideNumberOfPointsForStarSlider(_ sender: UISlider) { nightView?.numberOfPointsForStar = CGFloat(sender.value) numberOfPointsForStarLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleStarSizeSlider(_ sender: UISlider) { nightView?.starSize = CGFloat(sender.value) starSizeLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleStarSizeMinRandomizerSlider(_ sender: UISlider) { nightView?.starSizeMinRandomizer = Double(sender.value) starSizeMinRandomizerLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleStarSizeMaxRandomizerSlider(_ sender: UISlider) { nightView?.starSizeMaxRandomizer = Double(sender.value) starSizeMaxRandomizerLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleMinStarOpacitySlider(_ sender: UISlider) { nightView?.minStarOpacity = sender.value minStarOpacityLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleGlowingIntensitySlider(_ sender: UISlider) { nightView?.glowingIntensity = sender.value glowingIntensityLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleGlowingDurationSlider(_ sender: UISlider) { nightView?.glowingDuration = Double(sender.value) glowingDurationLabel.text = String(format: "%.1f", sender.value) } @IBAction func handleTapDoneButton(_ sender: AnyObject) { dismiss(animated: true, completion: nil) } @IBAction func handleStarTypeSegmentedControl(_ sender: UISegmentedControl) { switch sender.selectedSegmentIndex { case 0: nightView?.starType = .Round break default: nightView?.starType = .FiveBranchStar break } } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: NightViewSampleProject/NightViewSampleProject/ViewController.swift ================================================ // // ViewController.swift // NightViewSampleProject // // Created by Bobo on 7/10/16. // Copyright © 2016 Boris Emorine. All rights reserved. // import UIKit class ViewController: UIViewController { @IBOutlet weak var nightView: NightView! override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "toCustomization" { if let navVC = segue.destination as? UINavigationController, let customizationVC = navVC.topViewController as? CustomizationTableViewController { customizationVC.nightView = nightView } } } } ================================================ FILE: NightViewSampleProject/NightViewSampleProject.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ C31E42071D333B5C00A4A7A4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31E42061D333B5C00A4A7A4 /* AppDelegate.swift */; }; C31E42091D333B5C00A4A7A4 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31E42081D333B5C00A4A7A4 /* ViewController.swift */; }; C31E420C1D333B5C00A4A7A4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C31E420A1D333B5C00A4A7A4 /* Main.storyboard */; }; C31E420E1D333B5C00A4A7A4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C31E420D1D333B5C00A4A7A4 /* Assets.xcassets */; }; C31E42111D333B5C00A4A7A4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C31E420F1D333B5C00A4A7A4 /* LaunchScreen.storyboard */; }; C31E42281D333BBB00A4A7A4 /* NightView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31E42271D333BBB00A4A7A4 /* NightView.swift */; }; C3B4E3891D34020A0089FC02 /* NightViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B4E3881D34020A0089FC02 /* NightViewTests.swift */; }; C3B4E38B1D34CC240089FC02 /* CustomizationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B4E38A1D34CC240089FC02 /* CustomizationTableViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ C31E42181D333B5C00A4A7A4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C31E41FB1D333B5C00A4A7A4 /* Project object */; proxyType = 1; remoteGlobalIDString = C31E42021D333B5C00A4A7A4; remoteInfo = NightViewSampleProject; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ C31E42031D333B5C00A4A7A4 /* NightViewSampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NightViewSampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; C31E42061D333B5C00A4A7A4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C31E42081D333B5C00A4A7A4 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; C31E420B1D333B5C00A4A7A4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; C31E420D1D333B5C00A4A7A4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C31E42101D333B5C00A4A7A4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; C31E42121D333B5C00A4A7A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C31E42171D333B5C00A4A7A4 /* NightViewSampleProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NightViewSampleProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C31E421D1D333B5C00A4A7A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C31E42271D333BBB00A4A7A4 /* NightView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightView.swift; sourceTree = ""; }; C3B4E3881D34020A0089FC02 /* NightViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightViewTests.swift; sourceTree = ""; }; C3B4E38A1D34CC240089FC02 /* CustomizationTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomizationTableViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ C31E42001D333B5C00A4A7A4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; C31E42141D333B5C00A4A7A4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ C31E41FA1D333B5C00A4A7A4 = { isa = PBXGroup; children = ( C31E42261D333BBB00A4A7A4 /* NightView */, C31E42051D333B5C00A4A7A4 /* NightViewSampleProject */, C31E421A1D333B5C00A4A7A4 /* NightViewSampleProjectTests */, C31E42041D333B5C00A4A7A4 /* Products */, ); sourceTree = ""; }; C31E42041D333B5C00A4A7A4 /* Products */ = { isa = PBXGroup; children = ( C31E42031D333B5C00A4A7A4 /* NightViewSampleProject.app */, C31E42171D333B5C00A4A7A4 /* NightViewSampleProjectTests.xctest */, ); name = Products; sourceTree = ""; }; C31E42051D333B5C00A4A7A4 /* NightViewSampleProject */ = { isa = PBXGroup; children = ( C31E42061D333B5C00A4A7A4 /* AppDelegate.swift */, C31E42081D333B5C00A4A7A4 /* ViewController.swift */, C3B4E38A1D34CC240089FC02 /* CustomizationTableViewController.swift */, C31E420A1D333B5C00A4A7A4 /* Main.storyboard */, C31E420D1D333B5C00A4A7A4 /* Assets.xcassets */, C31E420F1D333B5C00A4A7A4 /* LaunchScreen.storyboard */, C31E42121D333B5C00A4A7A4 /* Info.plist */, ); path = NightViewSampleProject; sourceTree = ""; }; C31E421A1D333B5C00A4A7A4 /* NightViewSampleProjectTests */ = { isa = PBXGroup; children = ( C31E421D1D333B5C00A4A7A4 /* Info.plist */, C3B4E3881D34020A0089FC02 /* NightViewTests.swift */, ); path = NightViewSampleProjectTests; sourceTree = ""; }; C31E42261D333BBB00A4A7A4 /* NightView */ = { isa = PBXGroup; children = ( C31E42271D333BBB00A4A7A4 /* NightView.swift */, ); name = NightView; path = ../NightView; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ C31E42021D333B5C00A4A7A4 /* NightViewSampleProject */ = { isa = PBXNativeTarget; buildConfigurationList = C31E42201D333B5C00A4A7A4 /* Build configuration list for PBXNativeTarget "NightViewSampleProject" */; buildPhases = ( C31E41FF1D333B5C00A4A7A4 /* Sources */, C31E42001D333B5C00A4A7A4 /* Frameworks */, C31E42011D333B5C00A4A7A4 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = NightViewSampleProject; productName = NightViewSampleProject; productReference = C31E42031D333B5C00A4A7A4 /* NightViewSampleProject.app */; productType = "com.apple.product-type.application"; }; C31E42161D333B5C00A4A7A4 /* NightViewSampleProjectTests */ = { isa = PBXNativeTarget; buildConfigurationList = C31E42231D333B5C00A4A7A4 /* Build configuration list for PBXNativeTarget "NightViewSampleProjectTests" */; buildPhases = ( C31E42131D333B5C00A4A7A4 /* Sources */, C31E42141D333B5C00A4A7A4 /* Frameworks */, C31E42151D333B5C00A4A7A4 /* Resources */, ); buildRules = ( ); dependencies = ( C31E42191D333B5C00A4A7A4 /* PBXTargetDependency */, ); name = NightViewSampleProjectTests; productName = NightViewSampleProjectTests; productReference = C31E42171D333B5C00A4A7A4 /* NightViewSampleProjectTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ C31E41FB1D333B5C00A4A7A4 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0800; ORGANIZATIONNAME = "Boris Emorine"; TargetAttributes = { C31E42021D333B5C00A4A7A4 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0800; }; C31E42161D333B5C00A4A7A4 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0800; TestTargetID = C31E42021D333B5C00A4A7A4; }; }; }; buildConfigurationList = C31E41FE1D333B5C00A4A7A4 /* Build configuration list for PBXProject "NightViewSampleProject" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = C31E41FA1D333B5C00A4A7A4; productRefGroup = C31E42041D333B5C00A4A7A4 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( C31E42021D333B5C00A4A7A4 /* NightViewSampleProject */, C31E42161D333B5C00A4A7A4 /* NightViewSampleProjectTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ C31E42011D333B5C00A4A7A4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( C31E42111D333B5C00A4A7A4 /* LaunchScreen.storyboard in Resources */, C31E420E1D333B5C00A4A7A4 /* Assets.xcassets in Resources */, C31E420C1D333B5C00A4A7A4 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; C31E42151D333B5C00A4A7A4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ C31E41FF1D333B5C00A4A7A4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C31E42091D333B5C00A4A7A4 /* ViewController.swift in Sources */, C3B4E38B1D34CC240089FC02 /* CustomizationTableViewController.swift in Sources */, C31E42281D333BBB00A4A7A4 /* NightView.swift in Sources */, C31E42071D333B5C00A4A7A4 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; C31E42131D333B5C00A4A7A4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C3B4E3891D34020A0089FC02 /* NightViewTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ C31E42191D333B5C00A4A7A4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C31E42021D333B5C00A4A7A4 /* NightViewSampleProject */; targetProxy = C31E42181D333B5C00A4A7A4 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ C31E420A1D333B5C00A4A7A4 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( C31E420B1D333B5C00A4A7A4 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; C31E420F1D333B5C00A4A7A4 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( C31E42101D333B5C00A4A7A4 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ C31E421E1D333B5C00A4A7A4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; 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 = 9.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; C31E421F1D333B5C00A4A7A4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "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 = gnu99; 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 = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; C31E42211D333B5C00A4A7A4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = NightViewSampleProject/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = BEM.NightViewSampleProject; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_VERSION = 3.0; }; name = Debug; }; C31E42221D333B5C00A4A7A4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = NightViewSampleProject/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = BEM.NightViewSampleProject; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_INSTALL_OBJC_HEADER = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 3.0; }; name = Release; }; C31E42241D333B5C00A4A7A4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ENABLE_MODULES = YES; INFOPLIST_FILE = NightViewSampleProjectTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = BEM.NightViewSampleProjectTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NightViewSampleProject.app/NightViewSampleProject"; }; name = Debug; }; C31E42251D333B5C00A4A7A4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ENABLE_MODULES = YES; INFOPLIST_FILE = NightViewSampleProjectTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = BEM.NightViewSampleProjectTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NightViewSampleProject.app/NightViewSampleProject"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C31E41FE1D333B5C00A4A7A4 /* Build configuration list for PBXProject "NightViewSampleProject" */ = { isa = XCConfigurationList; buildConfigurations = ( C31E421E1D333B5C00A4A7A4 /* Debug */, C31E421F1D333B5C00A4A7A4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C31E42201D333B5C00A4A7A4 /* Build configuration list for PBXNativeTarget "NightViewSampleProject" */ = { isa = XCConfigurationList; buildConfigurations = ( C31E42211D333B5C00A4A7A4 /* Debug */, C31E42221D333B5C00A4A7A4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C31E42231D333B5C00A4A7A4 /* Build configuration list for PBXNativeTarget "NightViewSampleProjectTests" */ = { isa = XCConfigurationList; buildConfigurations = ( C31E42241D333B5C00A4A7A4 /* Debug */, C31E42251D333B5C00A4A7A4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = C31E41FB1D333B5C00A4A7A4 /* Project object */; } ================================================ FILE: NightViewSampleProject/NightViewSampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: NightViewSampleProject/NightViewSampleProject.xcodeproj/xcshareddata/xcschemes/NightViewSampleProject.xcscheme ================================================ ================================================ FILE: NightViewSampleProject/NightViewSampleProject.xcodeproj/xcshareddata/xcschemes/NightViewSampleProjectTests.xcscheme ================================================ ================================================ FILE: NightViewSampleProject/NightViewSampleProjectTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: NightViewSampleProject/NightViewSampleProjectTests/NightViewTests.swift ================================================ // // NightViewTests.swift // NightViewSampleProject // // Created by Bobo on 7/11/16. // Copyright © 2016 Boris Emorine. All rights reserved. // import XCTest @testable import NightViewSampleProject class NightViewTests: XCTestCase { override func setUp() { super.setUp() } override func tearDown() { super.tearDown() } func testInitWithFrame() { let nightView = NightView(frame: CGRect(x: 0.0, y: 0.0, width: 500.0, height: 500.0)) XCTAssertNotNil(nightView, "A fully initialized NightView instance should be instanciated.") } func testReload() { let nightView = NightView(frame: CGRect(x: 0.0, y: 0.0, width: 500.0, height: 500.0)) nightView.reload() let stars = nightView.layer.sublayers?.first?.sublayers XCTAssert(stars?.count > 0, "Multiple stars should have been drawn") nightView.reload() let newStars = nightView.layer.sublayers?.first?.sublayers XCTAssertEqual(stars?.count, newStars?.count, "After reloading, the same amount of stars should have been re-drawn") XCTAssertNotEqual(stars!, newStars!) } func testNumberOfPointsForStar() { let nightView = NightView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)) nightView.reload() var stars = nightView.layer.sublayers?.first?.sublayers XCTAssert(stars?.count > 0) nightView.numberOfPointsForStar = 1 stars = nightView.layer.sublayers?.first?.sublayers XCTAssertEqual(CGFloat(stars!.count), nightView.frame.size.width * nightView.frame.size.height) } func testStarSize() { let starSize: CGFloat = 100.0 let nightView = NightView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0)) nightView.numberOfPointsForStar = 1 nightView.starSize = starSize nightView.reload() var stars = nightView.layer.sublayers?.first?.sublayers var didFindBigStar = false var didFindSmallStar = false for star in stars! { if star.frame.size.height > starSize { didFindBigStar = true } else if star.frame.size.height < starSize { didFindSmallStar = true } } XCTAssertTrue(didFindSmallStar) XCTAssertTrue(didFindBigStar) nightView.starSizeMinRandomizer = 120.0 nightView.starSizeMaxRandomizer = 150.0 stars = nightView.layer.sublayers?.first?.sublayers didFindBigStar = false didFindSmallStar = false for star in stars! { if star.frame.size.height > starSize { didFindBigStar = true } else if star.frame.size.height < starSize { didFindSmallStar = true } } XCTAssertFalse(didFindSmallStar) XCTAssertTrue(didFindBigStar) nightView.starSizeMinRandomizer = 20.0 nightView.starSizeMaxRandomizer = 80.0 stars = nightView.layer.sublayers?.first?.sublayers didFindBigStar = false didFindSmallStar = false for star in stars! { if star.frame.size.height > starSize { didFindBigStar = true } else if star.frame.size.height < starSize { didFindSmallStar = true } } XCTAssertTrue(didFindSmallStar) XCTAssertFalse(didFindBigStar) nightView.starSizeMinRandomizer = 100.0 nightView.starSizeMaxRandomizer = 100.0 stars = nightView.layer.sublayers?.first?.sublayers didFindBigStar = false didFindSmallStar = false for star in stars! { if star.frame.size.height > starSize { didFindBigStar = true } else if star.frame.size.height < starSize { didFindSmallStar = true } XCTAssertEqual(star.frame.size.height, starSize) } XCTAssertFalse(didFindSmallStar) XCTAssertFalse(didFindBigStar) } func testMinStarOpacity() { let nightView = NightView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0)) nightView.numberOfPointsForStar = 1 nightView.reload() var stars = nightView.layer.sublayers?.first?.sublayers var didFindLowOpacityStar = false for star in stars! { if star.opacity < 1.0 { didFindLowOpacityStar = true break } } XCTAssertTrue(didFindLowOpacityStar, "By default the stars at the bottom of the view should have a lower opacity") nightView.minStarOpacity = 1.0 stars = nightView.layer.sublayers?.first?.sublayers didFindLowOpacityStar = false for star in stars! { if star.opacity < 1.0 { didFindLowOpacityStar = true break } } XCTAssertFalse(didFindLowOpacityStar, "All of the stars should have an opacity of 1") } } ================================================ FILE: README.md ================================================ # NightView [![Build Status](https://travis-ci.org/Boris-Em/NightView.svg?branch=master)](https://travis-ci.org/Boris-Em/NightView) [![Version](https://img.shields.io/cocoapods/v/NightView.svg?style=flat)](http://cocoadocs.org/docsets/NightView) [![License](https://img.shields.io/cocoapods/l/NightView.svg?style=flat)](http://cocoadocs.org/docsets/NightView) [![Platform](https://img.shields.io/cocoapods/p/NightView.svg?style=flat)](http://cocoadocs.org/docsets/NightView)

**NightView** is an open source library that generates beautiful, random, starry skies on iOS. ## Table of Contents * [**Project Details**](#project-details) * [Requirements](#requirements) * [License](#license) * [Support](#support) * [Sample App](#sample-app) * [**Getting Started**](#getting-started) * [Installation](#installation) * [Setup](#setup) * [**Documentation**](#documentation) ## Project Details Learn more about the **NightView** project, licensing, support etc.

### Requirements - Requires iOS 7 or later. The sample project is optimized for iOS 9. - Requires Automatic Reference Counting (ARC). - Optimized for ARM64 Architecture. ### License See the [License](https://github.com/Boris-Em/NightView/blob/master/LICENSE). You are free to make changes and use this in either personal or commercial projects. Attribution is not required, but highly appreciated. A little "Thanks!" (or something to that affect) is always welcome. If you use **NightView** in your app, please let us know! ### Support [![https://gitter.im/Boris-Em/NightView](https://badges.gitter.im/Boris-Em/NightView.svg)](https://gitter.im/Boris-Em/NightView?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Join us on gitter if you have any question! ### Sample App The iOS Sample App included with this project demonstrates one way to correctly setup and use **NightView**. It also offers the possibility to customize the view within the app. ## Getting Started It only takes a few simple steps to install and setup **NightView** to your project. ###Installation The easiest way to install **NightView** is to use CocoaPods. To do so, simply add the following line to your `Podfile`:
pod 'NightView'
The other way to install **NightView**, is to drag and drop the *NightView* folder into your Xcode project. When you do so, make sure to check the "*Copy items into destination group's folder*" box. ### Setup **NightView** is a simple UIView subclass. It can be initialized with Interface Builder, or programatically. **Interface Builder Initialization** 1 - Drag a `UIView` to your `UIViewController`. 2 - Change the class of the new `UIView` to `NightView`. 3 - Select the `NightView` and open the Attributes Inspector. Most of the customizable properties can easily be set from the Attributes Inspector. The Sample App demonstrates this capability. **Programmatical Initialization** Here is an example illustrating how to initialize a NightView instance programmatically: ```swift let nightView = NightView(frame: CGRectMake(0.0, 0.0, 200.0, 200.0)) view.addSubview(nightView) ``` ## Documentation All of the methods and properties available for **NightView** are documented below. ##### `numberOfPointsForStar` The number of points for each star. For example, setting this property to 1, means that there will be 1 star for every point in the view. A greater number means less stars within the view. *Defaults to 10000.0.* ##### `starSize` The size of the stars in points. Note that setting `starSizeMinRandomizer` and `starSizeMaxRandomizer` will also influence the size of stars. *Defaults to 5.0.* ##### `starColor` The color of the stars. *Defaults to white.* ##### `starSizeMinRandomizer` The size of the stars is randomized within the `starSize` value. This property sets the minimum percent by which the stars' size could be changed. For example, a value of 50.0 means that the minimum size of a star will be 50% of the `starSize` property. *Defaults to 50.0.* ##### `starSizeMaxRandomizer` The size of the stars is randomized within the `starSize` value. This property sets the maximum percent by which the stars' size could be changed. For example, a value of 150.0 means that the maximum size of a star will be 150% of the `starSize` property. *Defaults to 150.0.* ##### `minStarOpacity` The stars are drawn with a smaller opacity at the bottom of the view than at the top. This property sets the minimum opacity for the lower stars. Note that the stars at the top of the view will always have an opacity of 1.0. *Defaults to 0.5.* ##### `glowingIntensity` The intensity of the glowing of the stars, from 0 to 1. If set to 0, the stars will not glow. *Defaults to 0.5.* ##### `glowingDuration` The duration in seconds at which the stars glow. *Defaults to 2.0.* ##### `starType` The type of stars to be drawn. *Defaults to `.Round`.*

##### `reload()` Reloads the **NightView** instance, redrawing all of the stars.