diff --git a/Example/NotchToolkit-Example.xcodeproj/project.pbxproj b/Example/NotchToolkit-Example.xcodeproj/project.pbxproj index bee9d07..ae021c2 100644 --- a/Example/NotchToolkit-Example.xcodeproj/project.pbxproj +++ b/Example/NotchToolkit-Example.xcodeproj/project.pbxproj @@ -10,6 +10,9 @@ 8B46D7347C51E13D6A8F5752 /* Pods_NotchToolkit_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB89330EB9E75950CC5DD1E5 /* Pods_NotchToolkit_Example.framework */; }; 9F0D407B72BC9454BFAE5029 /* Pods_NotchToolkit_ExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F265AEF721C276AAF9FEFDF8 /* Pods_NotchToolkit_ExampleTests.framework */; }; FB211D911F7AE647008D87CE /* CornerOvalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB211D901F7AE647008D87CE /* CornerOvalViewController.swift */; }; + FB5F45721FB3DFA0004C542D /* NotchImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5F45711FB3DFA0004C542D /* NotchImageView.swift */; }; + FB5F45741FB3E029004C542D /* NotchImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5F45731FB3E029004C542D /* NotchImageViewController.swift */; }; + FB5F45771FB3E178004C542D /* tst_img.JPG in Resources */ = {isa = PBXBuildFile; fileRef = FB5F45761FB3E178004C542D /* tst_img.JPG */; }; FBB4BF521F79ED69001992BA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB4BF511F79ED69001992BA /* AppDelegate.swift */; }; FBB4BF541F79ED69001992BA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB4BF531F79ED69001992BA /* ViewController.swift */; }; FBB4BF571F79ED69001992BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FBB4BF551F79ED69001992BA /* Main.storyboard */; }; @@ -75,6 +78,9 @@ F02A2878BAA2A5AB05FCF077 /* Pods-NotchToolkit-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotchToolkit-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NotchToolkit-Example/Pods-NotchToolkit-Example.debug.xcconfig"; sourceTree = ""; }; F265AEF721C276AAF9FEFDF8 /* Pods_NotchToolkit_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NotchToolkit_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FB211D901F7AE647008D87CE /* CornerOvalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerOvalViewController.swift; sourceTree = ""; }; + FB5F45711FB3DFA0004C542D /* NotchImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotchImageView.swift; sourceTree = ""; }; + FB5F45731FB3E029004C542D /* NotchImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotchImageViewController.swift; sourceTree = ""; }; + FB5F45761FB3E178004C542D /* tst_img.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = tst_img.JPG; sourceTree = ""; }; FBB4BF4E1F79ED69001992BA /* NotchToolkit-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NotchToolkit-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FBB4BF511F79ED69001992BA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; FBB4BF531F79ED69001992BA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -153,6 +159,15 @@ name = Pods; sourceTree = ""; }; + FB5F45751FB3E164004C542D /* Assets */ = { + isa = PBXGroup; + children = ( + FB5F45761FB3E178004C542D /* tst_img.JPG */, + FBB4BF581F79ED69001992BA /* Assets.xcassets */, + ); + path = Assets; + sourceTree = ""; + }; FBB4BF451F79ED69001992BA = { isa = PBXGroup; children = ( @@ -181,11 +196,12 @@ children = ( FBB4BF511F79ED69001992BA /* AppDelegate.swift */, FBB4BF531F79ED69001992BA /* ViewController.swift */, + FB5F45731FB3E029004C542D /* NotchImageViewController.swift */, FB211D901F7AE647008D87CE /* CornerOvalViewController.swift */, FBB4BF551F79ED69001992BA /* Main.storyboard */, - FBB4BF581F79ED69001992BA /* Assets.xcassets */, FBB4BF5A1F79ED69001992BA /* LaunchScreen.storyboard */, FBB4BF5D1F79ED69001992BA /* Info.plist */, + FB5F45751FB3E164004C542D /* Assets */, ); path = "NotchToolkit-Example"; sourceTree = ""; @@ -226,6 +242,7 @@ isa = PBXGroup; children = ( FBED19241FB0253400D810BF /* NotchBar.swift */, + FB5F45711FB3DFA0004C542D /* NotchImageView.swift */, FBED19231FB0253400D810BF /* NotchToolbar.swift */, ); path = Classes; @@ -387,6 +404,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + FB5F45771FB3E178004C542D /* tst_img.JPG in Resources */, FBB4BF5C1F79ED69001992BA /* LaunchScreen.storyboard in Resources */, FBB4BF591F79ED69001992BA /* Assets.xcassets in Resources */, FBB4BF571F79ED69001992BA /* Main.storyboard in Resources */, @@ -520,6 +538,7 @@ FB211D911F7AE647008D87CE /* CornerOvalViewController.swift in Sources */, FBB4BF541F79ED69001992BA /* ViewController.swift in Sources */, FBB4BF521F79ED69001992BA /* AppDelegate.swift in Sources */, + FB5F45741FB3E029004C542D /* NotchImageViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -539,6 +558,7 @@ FBED193E1FB0257D00D810BF /* NotchToolNameIconCell.swift in Sources */, FBED19361FB0256900D810BF /* DeviceOrientation.swift in Sources */, FBED19371FB0256900D810BF /* NotchMode.swift in Sources */, + FB5F45721FB3DFA0004C542D /* NotchImageView.swift in Sources */, FBED19381FB0256900D810BF /* NotchScroll.swift in Sources */, FBED19391FB0256900D810BF /* ToolIconTypes.swift in Sources */, FBED193A1FB0256900D810BF /* CurveSettings.swift in Sources */, diff --git a/Example/NotchToolkit-Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/NotchToolkit-Example/Assets/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Example/NotchToolkit-Example/Assets.xcassets/Contents.json b/Example/NotchToolkit-Example/Assets/Assets.xcassets/Contents.json similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/Contents.json rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/Contents.json diff --git a/Example/NotchToolkit-Example/Assets.xcassets/pikachusquare.imageset/Contents.json b/Example/NotchToolkit-Example/Assets/Assets.xcassets/pikachusquare.imageset/Contents.json similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/pikachusquare.imageset/Contents.json rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/pikachusquare.imageset/Contents.json diff --git a/Example/NotchToolkit-Example/Assets.xcassets/pikachusquare.imageset/pikachusquare.png b/Example/NotchToolkit-Example/Assets/Assets.xcassets/pikachusquare.imageset/pikachusquare.png similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/pikachusquare.imageset/pikachusquare.png rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/pikachusquare.imageset/pikachusquare.png diff --git a/Example/NotchToolkit-Example/Assets.xcassets/spongebob.imageset/Contents.json b/Example/NotchToolkit-Example/Assets/Assets.xcassets/spongebob.imageset/Contents.json similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/spongebob.imageset/Contents.json rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/spongebob.imageset/Contents.json diff --git a/Example/NotchToolkit-Example/Assets.xcassets/spongebob.imageset/spongebob.png b/Example/NotchToolkit-Example/Assets/Assets.xcassets/spongebob.imageset/spongebob.png similarity index 100% rename from Example/NotchToolkit-Example/Assets.xcassets/spongebob.imageset/spongebob.png rename to Example/NotchToolkit-Example/Assets/Assets.xcassets/spongebob.imageset/spongebob.png diff --git a/Example/NotchToolkit-Example/Assets/tst_img.JPG b/Example/NotchToolkit-Example/Assets/tst_img.JPG new file mode 100755 index 0000000..d680367 Binary files /dev/null and b/Example/NotchToolkit-Example/Assets/tst_img.JPG differ diff --git a/Example/NotchToolkit-Example/Base.lproj/Main.storyboard b/Example/NotchToolkit-Example/Base.lproj/Main.storyboard index 26d0ae5..0de1dd8 100644 --- a/Example/NotchToolkit-Example/Base.lproj/Main.storyboard +++ b/Example/NotchToolkit-Example/Base.lproj/Main.storyboard @@ -17,7 +17,7 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -133,7 +176,7 @@ - + diff --git a/Example/NotchToolkit-Example/NotchImageViewController.swift b/Example/NotchToolkit-Example/NotchImageViewController.swift new file mode 100644 index 0000000..f300200 --- /dev/null +++ b/Example/NotchToolkit-Example/NotchImageViewController.swift @@ -0,0 +1,66 @@ +// +// NotchImageViewController.swift +// NotchToolkit-Example +// +// Created by Ahmed Bekhit on 11/8/17. +// Copyright © 2017 Ahmed Fathi Bekhit. All rights reserved. +// + +import UIKit +import NotchToolkit + +// MARK: - Implement NotchToolkit + +//Step 1. add `NotchToolbarDelegate` +//Step 2. implement delegate functions, check NotchToolkit Delegates + +class NotchImageViewController: UIViewController { + //Step 3. initialize `NotchImageView` + var imageView: NotchImageView? + + override func viewDidLoad() { + super.viewDidLoad() + imageView = NotchImageView(image: UIImage(named:"tst_img.JPG")) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + +} + +// MARK: - NotchToolkit Delegate Methods +extension NotchImageViewController: NotchToolbarDelegate { + func deviceDidRotate() { + //Step 5. call `autoResize` in the `deviceDidRotate` function + imageView?.autoResize() + } + + // This delegate function allows you to detect which toolbar icon was selected. + func didTapToolIcon(_ tools: UICollectionView, toolIndex: IndexPath, section: Int, row: Int) { + } +} + +// MARK: - ViewController Buttons IBAction +extension NotchImageViewController { + @IBAction func loadNotchImage(_ sender: UIButton) { + if !(imageView?.isVisible)! { + sender.setTitle("Delete Image Object", for: .normal) + imageView?.durationIntervals = 2.8 + imageView?.printBarColor = .red + imageView?.printBarHeight = 5 + imageView?.delegate = self + imageView?.prepare(in: self) + imageView?.load() + self.view.insertSubview(sender, aboveSubview: imageView!) + }else{ + sender.setTitle("Load Image from Notch", for: .normal) + imageView?.remove() + imageView = NotchImageView(image: UIImage(named:"tst_img.JPG")) + } + } + + @IBAction func goBack(_ sender: UIButton) { + self.dismiss(animated: true, completion: nil) + } +} diff --git a/Example/NotchToolkit-Example/ViewController.swift b/Example/NotchToolkit-Example/ViewController.swift index 91e8185..a550ffc 100644 --- a/Example/NotchToolkit-Example/ViewController.swift +++ b/Example/NotchToolkit-Example/ViewController.swift @@ -39,15 +39,12 @@ extension ViewController { //Step 2. implement delegate functions, check NotchToolkit Delegates class ViewController: UIViewController { - @IBOutlet var notchImage: UIImageView! //Step 3. initialize `NotchToolbar` let toolbar = NotchToolbar() - var imgView:UIImageView! override func viewDidLoad() { super.viewDidLoad() - //Step 4. setup `NotchToolbar` options //Set to true to make the toolbar visible initially--default is false. diff --git a/Example/NotchToolkit/Classes/NotchImageView.swift b/Example/NotchToolkit/Classes/NotchImageView.swift new file mode 100644 index 0000000..18363ce --- /dev/null +++ b/Example/NotchToolkit/Classes/NotchImageView.swift @@ -0,0 +1,179 @@ +// +// NotchImageView.swift +// NotchToolkit +// +// Created by Ahmed Bekhit on 11/1/17. +// Copyright © 2017 Ahmed Fathi Bekhit. All rights reserved. +// + +import UIKit + +/** + *NotchToolkit* is a framework for iOS that allow developers use the iPhones X notch space in creative ways. + + - Author: Ahmed Fathi Bekhit + * [Github](http://github.com/AFathi) + * [Website](http://ahmedbekhit.com) + * [Twitter](http://twitter.com/iAFapps) + * [Email](mailto:me@ahmedbekhit.com) + */ +public class NotchImageView: NotchBar { + // MARK: - Public objects + + /// This delegate is required to detect toolbar actions & automatically resize the NotchBar when device orientation is changed. + public var delegate:NotchToolbarDelegate? + + /// This allows you to enable NotchToolbar only for iPhone X. Default is false. + public var onlyFor10:Bool = false + /// Configure printing bar height + public var printBarHeight:CGFloat = 3 + /// Configure printing color + public var printBarColor:UIColor = .cyan + /// Configure image loading duration intervals + public var durationIntervals:TimeInterval = 0.8 + + // MARK: - Private Objects + private var recentOrientation: deviceOrientation! + private var imageView:UIImageView = UIImageView() + private var notchImage:UIImage? + private var printerBar:UIView = UIView() + private var isShown:Bool = false + private var isLoaded:Bool = false + + /// Initialize + public init() { + super.init(frame: CGRect.zero) + } + /// Initialize with a UIImage + public init(image: UIImage?) { + super.init(frame: CGRect.zero) + notchImage = image + self.bgColor = .clear + self.animationInterval = 0.1 + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +//MARK:- Methods +extension NotchImageView { + /// This method is required to prepare the NotchImageView in your view controller. + public func prepare(in vc:UIViewController) { + NotificationCenter.default.addObserver(vc, selector: #selector(delegate?.deviceDidRotate), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + if onlyFor10 && !UIScreen.main.isiPhone10 { + print("NotchToolbar: If you want to enable NotchToolBar on this device please add this line to your code\nNotchToolBar().onlyFor10 = false") + }else{ + recentOrientation = .portrait + imageView = UIImageView(frame: CGRect(x:0, y:0, width:self.bounds.width, height:self.bounds.height)) + imageView.center = CGPoint(x:(self.bounds.width)*0.5, y:-(self.bounds.height*0.5)) + imageView.backgroundColor = .clear + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + imageView.draw(.corner, position: .bottom, curve: self.curve) + if let img = notchImage { + imageView.image = img + } + self.addSubview(imageView) + + printerBar = UIView(frame: CGRect(x:0, y:0, width:self.bounds.width, height:printBarHeight)) + printerBar.center = CGPoint(x:self.bounds.width*0.5, y:-(self.bounds.height*0.5)) + printerBar.backgroundColor = printBarColor.withAlphaComponent(0.4) + printerBar.layer.shadowColor = printBarColor.cgColor + printerBar.layer.shadowOffset = CGSize(width: 0.0, height: 2.5) + printerBar.layer.shadowOpacity = 1.0 + self.addSubview(printerBar) + + vc.view.addSubview(self) + } + } + /// Loads image view from notch with animation + public func load() { + self.isVisible = true + + UIView.animate(withDuration: 0.3, delay: 0.1, usingSpringWithDamping: 1.2, initialSpringVelocity: 0.4, options: [.autoreverse, .repeat], animations: { + self.printerBar.center = CGPoint(x:self.self.bounds.width*0.5, y:(self.self.bounds.height)) + }) + + autoResize() + isShown = true + updateBounds(orientation: recentOrientation) + } + /// Removes image view from superview + public func remove() { + self.self.removeFromSuperview() + self.removeFromSuperview() + } + /// This function is required to be called from the `deviceDidRotate` delegate function. + public func autoResize() { + switch UIDevice.current.orientation { + case .portrait: + recentOrientation = .portrait + self.refresh(orientation: .portrait) + self.updateBounds(orientation: .portrait) + case .portraitUpsideDown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .landscapeLeft: + if UIScreen.main.bounds.size.width > UIScreen.main.bounds.height { + recentOrientation = .landscapeLeft + self.refresh(orientation: .landscapeLeft) + self.updateBounds(orientation: .landscapeLeft) + } + case .landscapeRight: + if UIScreen.main.bounds.size.width > UIScreen.main.bounds.height { + recentOrientation = .landscapeRight + self.refresh(orientation: .landscapeRight) + self.updateBounds(orientation: .landscapeRight) + } + case .faceDown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .faceUp: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .unknown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + } + } + + private func updateBounds(orientation: deviceOrientation) { + var xPos = (self.bounds.width*0.5) + var yPos = (self.bounds.height*0.5) + switch orientation { + case .landscapeLeft : + xPos = (!isShown) ? -(self.bounds.width*0.5) : (self.bounds.width*0.5) + case .landscapeRight: + xPos = (!isShown) ? (self.bounds.width*1.5) : (self.bounds.width*0.5) + case .portrait: + yPos = (!isShown) ? -(self.bounds.height*0.5) : (self.bounds.height*0.5) + } + + imageView.bounds = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height) + if self.isLoaded{ + self.self.frame = UIScreen.main.bounds + self.imageView.frame = self.self.frame + self.self.draw(.corner, position: .bottom, curve: 0) + self.imageView.draw(.corner, position: .bottom, curve: 0) + return + } + + UIView.animate(withDuration: self.durationIntervals, animations: { + self.imageView.center = CGPoint(x:xPos, y:yPos) + }) + if self.isShown { + UIView.animate(withDuration: 0.4, delay: self.durationIntervals, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.4, options: .curveLinear, animations: { + self.self.frame = UIScreen.main.bounds + self.imageView.frame = self.self.frame + self.draw(.corner, position: .bottom, curve: 0) + self.imageView.draw(.corner, position: .bottom, curve: 0) + self.printerBar.alpha = 0 + }){ done in + self.isLoaded = true + self.printerBar.layer.removeAllAnimations() + } + } + } +} diff --git a/Example/NotchToolkit/Info.plist b/Example/NotchToolkit/Info.plist index 1007fd9..85b6d3d 100644 --- a/Example/NotchToolkit/Info.plist +++ b/Example/NotchToolkit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 1.4 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/NotchToolkit.podspec b/NotchToolkit.podspec index 0d249c5..a180a5e 100644 --- a/NotchToolkit.podspec +++ b/NotchToolkit.podspec @@ -1,13 +1,13 @@ Pod::Spec.new do |s| s.name = "NotchToolkit" - s.version = "1.21" + s.version = "1.3" s.summary = "An iOS framework for iPhone X notch." s.description = "A framework for iOS that allow developers use the iPhone X notch space in creative ways." s.homepage = "https://github.com/AFathi/NotchToolkit" - s.screenshots = "http://whochatme1.ipage.com/preview.gif" + s.screenshots = "http://ahmedbekhit.com/toolbar_preview.gif" s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "Ahmed Bekhit" => "me@ahmedbekhit.com" } @@ -15,7 +15,7 @@ Pod::Spec.new do |s| s.platform = :ios, "11.0" - s.source = { :git => "https://github.com/AFathi/NotchToolkit.git", :tag => "1.21" } + s.source = { :git => "https://github.com/AFathi/NotchToolkit.git", :tag => "1.3" } s.source_files = "NotchToolkit", "NotchToolkit/**/*.{swift}" diff --git a/NotchToolkit.xcodeproj/project.pbxproj b/NotchToolkit.xcodeproj/project.pbxproj index e5a67dc..4c168d9 100644 --- a/NotchToolkit.xcodeproj/project.pbxproj +++ b/NotchToolkit.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ FB59EC771F7DC12700BD6B01 /* NotchToolNameIconCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB59EC761F7DC12700BD6B01 /* NotchToolNameIconCell.swift */; }; FB59EC791F7DC1B400BD6B01 /* ToolIconTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB59EC781F7DC1B400BD6B01 /* ToolIconTypes.swift */; }; + FB5F456D1FB3DF3D004C542D /* NotchImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB5F456C1FB3DF3D004C542D /* NotchImageView.swift */; }; FBB4BF1D1F79EC77001992BA /* NotchToolkit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBB4BF131F79EC77001992BA /* NotchToolkit.framework */; }; FBB4BF221F79EC77001992BA /* NotchToolkitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB4BF211F79EC77001992BA /* NotchToolkitTests.swift */; }; FBB4BF241F79EC77001992BA /* NotchToolkit.h in Headers */ = {isa = PBXBuildFile; fileRef = FBB4BF161F79EC77001992BA /* NotchToolkit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -40,6 +41,7 @@ /* Begin PBXFileReference section */ FB59EC761F7DC12700BD6B01 /* NotchToolNameIconCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotchToolNameIconCell.swift; sourceTree = ""; }; FB59EC781F7DC1B400BD6B01 /* ToolIconTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolIconTypes.swift; sourceTree = ""; }; + FB5F456C1FB3DF3D004C542D /* NotchImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NotchImageView.swift; path = NotchToolkit/Classes/NotchImageView.swift; sourceTree = SOURCE_ROOT; }; FBB4BF131F79EC77001992BA /* NotchToolkit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NotchToolkit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FBB4BF161F79EC77001992BA /* NotchToolkit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotchToolkit.h; sourceTree = ""; }; FBB4BF171F79EC77001992BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -80,6 +82,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + FB5F456E1FB3DF45004C542D /* Classes */ = { + isa = PBXGroup; + children = ( + FBB4BF381F79ECBC001992BA /* NotchBar.swift */, + FB5F456C1FB3DF3D004C542D /* NotchImageView.swift */, + FBB4BF321F79ECBC001992BA /* NotchToolbar.swift */, + ); + path = Classes; + sourceTree = ""; + }; FBB4BF091F79EC77001992BA = { isa = PBXGroup; children = ( @@ -102,8 +114,7 @@ FBB4BF151F79EC77001992BA /* NotchToolkit */ = { isa = PBXGroup; children = ( - FBB4BF321F79ECBC001992BA /* NotchToolbar.swift */, - FBB4BF381F79ECBC001992BA /* NotchBar.swift */, + FB5F456E1FB3DF45004C542D /* Classes */, FBB4BF731F79EDA4001992BA /* Cells */, FBB4BF711F79ED8F001992BA /* Enumerations */, FBB4BF741F79EDB2001992BA /* Extensions */, @@ -279,6 +290,7 @@ FBB4BF3C1F79ECBC001992BA /* UIScreen+NotchFrame.swift in Sources */, FBB4BF431F79ECBC001992BA /* NotchMode.swift in Sources */, FBB4BF3F1F79ECBC001992BA /* NotchScroll.swift in Sources */, + FB5F456D1FB3DF3D004C542D /* NotchImageView.swift in Sources */, FBB4BF421F79ECBC001992BA /* UIView+DrawNotch.swift in Sources */, FBB4BF3A1F79ECBC001992BA /* DeviceOrientation.swift in Sources */, FBB4BF3E1F79ECBC001992BA /* NotchToolbar.swift in Sources */, diff --git a/NotchToolkit/NotchBar.swift b/NotchToolkit/Classes/NotchBar.swift similarity index 100% rename from NotchToolkit/NotchBar.swift rename to NotchToolkit/Classes/NotchBar.swift diff --git a/NotchToolkit/Classes/NotchImageView.swift b/NotchToolkit/Classes/NotchImageView.swift new file mode 100644 index 0000000..18363ce --- /dev/null +++ b/NotchToolkit/Classes/NotchImageView.swift @@ -0,0 +1,179 @@ +// +// NotchImageView.swift +// NotchToolkit +// +// Created by Ahmed Bekhit on 11/1/17. +// Copyright © 2017 Ahmed Fathi Bekhit. All rights reserved. +// + +import UIKit + +/** + *NotchToolkit* is a framework for iOS that allow developers use the iPhones X notch space in creative ways. + + - Author: Ahmed Fathi Bekhit + * [Github](http://github.com/AFathi) + * [Website](http://ahmedbekhit.com) + * [Twitter](http://twitter.com/iAFapps) + * [Email](mailto:me@ahmedbekhit.com) + */ +public class NotchImageView: NotchBar { + // MARK: - Public objects + + /// This delegate is required to detect toolbar actions & automatically resize the NotchBar when device orientation is changed. + public var delegate:NotchToolbarDelegate? + + /// This allows you to enable NotchToolbar only for iPhone X. Default is false. + public var onlyFor10:Bool = false + /// Configure printing bar height + public var printBarHeight:CGFloat = 3 + /// Configure printing color + public var printBarColor:UIColor = .cyan + /// Configure image loading duration intervals + public var durationIntervals:TimeInterval = 0.8 + + // MARK: - Private Objects + private var recentOrientation: deviceOrientation! + private var imageView:UIImageView = UIImageView() + private var notchImage:UIImage? + private var printerBar:UIView = UIView() + private var isShown:Bool = false + private var isLoaded:Bool = false + + /// Initialize + public init() { + super.init(frame: CGRect.zero) + } + /// Initialize with a UIImage + public init(image: UIImage?) { + super.init(frame: CGRect.zero) + notchImage = image + self.bgColor = .clear + self.animationInterval = 0.1 + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +//MARK:- Methods +extension NotchImageView { + /// This method is required to prepare the NotchImageView in your view controller. + public func prepare(in vc:UIViewController) { + NotificationCenter.default.addObserver(vc, selector: #selector(delegate?.deviceDidRotate), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) + if onlyFor10 && !UIScreen.main.isiPhone10 { + print("NotchToolbar: If you want to enable NotchToolBar on this device please add this line to your code\nNotchToolBar().onlyFor10 = false") + }else{ + recentOrientation = .portrait + imageView = UIImageView(frame: CGRect(x:0, y:0, width:self.bounds.width, height:self.bounds.height)) + imageView.center = CGPoint(x:(self.bounds.width)*0.5, y:-(self.bounds.height*0.5)) + imageView.backgroundColor = .clear + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + imageView.draw(.corner, position: .bottom, curve: self.curve) + if let img = notchImage { + imageView.image = img + } + self.addSubview(imageView) + + printerBar = UIView(frame: CGRect(x:0, y:0, width:self.bounds.width, height:printBarHeight)) + printerBar.center = CGPoint(x:self.bounds.width*0.5, y:-(self.bounds.height*0.5)) + printerBar.backgroundColor = printBarColor.withAlphaComponent(0.4) + printerBar.layer.shadowColor = printBarColor.cgColor + printerBar.layer.shadowOffset = CGSize(width: 0.0, height: 2.5) + printerBar.layer.shadowOpacity = 1.0 + self.addSubview(printerBar) + + vc.view.addSubview(self) + } + } + /// Loads image view from notch with animation + public func load() { + self.isVisible = true + + UIView.animate(withDuration: 0.3, delay: 0.1, usingSpringWithDamping: 1.2, initialSpringVelocity: 0.4, options: [.autoreverse, .repeat], animations: { + self.printerBar.center = CGPoint(x:self.self.bounds.width*0.5, y:(self.self.bounds.height)) + }) + + autoResize() + isShown = true + updateBounds(orientation: recentOrientation) + } + /// Removes image view from superview + public func remove() { + self.self.removeFromSuperview() + self.removeFromSuperview() + } + /// This function is required to be called from the `deviceDidRotate` delegate function. + public func autoResize() { + switch UIDevice.current.orientation { + case .portrait: + recentOrientation = .portrait + self.refresh(orientation: .portrait) + self.updateBounds(orientation: .portrait) + case .portraitUpsideDown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .landscapeLeft: + if UIScreen.main.bounds.size.width > UIScreen.main.bounds.height { + recentOrientation = .landscapeLeft + self.refresh(orientation: .landscapeLeft) + self.updateBounds(orientation: .landscapeLeft) + } + case .landscapeRight: + if UIScreen.main.bounds.size.width > UIScreen.main.bounds.height { + recentOrientation = .landscapeRight + self.refresh(orientation: .landscapeRight) + self.updateBounds(orientation: .landscapeRight) + } + case .faceDown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .faceUp: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + case .unknown: + self.refresh(orientation: recentOrientation) + self.updateBounds(orientation: recentOrientation) + } + } + + private func updateBounds(orientation: deviceOrientation) { + var xPos = (self.bounds.width*0.5) + var yPos = (self.bounds.height*0.5) + switch orientation { + case .landscapeLeft : + xPos = (!isShown) ? -(self.bounds.width*0.5) : (self.bounds.width*0.5) + case .landscapeRight: + xPos = (!isShown) ? (self.bounds.width*1.5) : (self.bounds.width*0.5) + case .portrait: + yPos = (!isShown) ? -(self.bounds.height*0.5) : (self.bounds.height*0.5) + } + + imageView.bounds = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height) + if self.isLoaded{ + self.self.frame = UIScreen.main.bounds + self.imageView.frame = self.self.frame + self.self.draw(.corner, position: .bottom, curve: 0) + self.imageView.draw(.corner, position: .bottom, curve: 0) + return + } + + UIView.animate(withDuration: self.durationIntervals, animations: { + self.imageView.center = CGPoint(x:xPos, y:yPos) + }) + if self.isShown { + UIView.animate(withDuration: 0.4, delay: self.durationIntervals, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.4, options: .curveLinear, animations: { + self.self.frame = UIScreen.main.bounds + self.imageView.frame = self.self.frame + self.draw(.corner, position: .bottom, curve: 0) + self.imageView.draw(.corner, position: .bottom, curve: 0) + self.printerBar.alpha = 0 + }){ done in + self.isLoaded = true + self.printerBar.layer.removeAllAnimations() + } + } + } +} diff --git a/NotchToolkit/NotchToolbar.swift b/NotchToolkit/Classes/NotchToolbar.swift similarity index 100% rename from NotchToolkit/NotchToolbar.swift rename to NotchToolkit/Classes/NotchToolbar.swift diff --git a/NotchToolkit/Info.plist b/NotchToolkit/Info.plist index ceddb89..036bfa4 100644 --- a/NotchToolkit/Info.plist +++ b/NotchToolkit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.21 + 1.3 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/README.md b/README.md index 299a602..2b82d17 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,15 @@ Inspired by