diff --git a/Example/MobilliumToolTips.xcodeproj/project.pbxproj b/Example/MobilliumToolTips.xcodeproj/project.pbxproj index 328da03..ac0ef35 100644 --- a/Example/MobilliumToolTips.xcodeproj/project.pbxproj +++ b/Example/MobilliumToolTips.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 7EFD825F2A6D46FD00C17EB6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7EFD825E2A6D46FC00C17EB6 /* QuartzCore.framework */; }; F430C4A6EA16D430CF9B05E1 /* Pods_MobilliumToolTips_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F523F57AA3B4228071946E65 /* Pods_MobilliumToolTips_Example.framework */; }; /* End PBXBuildFile section */ @@ -30,7 +31,7 @@ /* Begin PBXFileReference section */ 0FD561E777EF2B975C7C848E /* Pods-MobilliumToolTips_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobilliumToolTips_Example.debug.xcconfig"; path = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example.debug.xcconfig"; sourceTree = ""; }; 1C0C55226749EFCA563EFEBA /* Pods-MobilliumToolTips_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobilliumToolTips_Tests.debug.xcconfig"; path = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests.debug.xcconfig"; sourceTree = ""; }; - 468D42805411B4AE81F5A464 /* MobilliumToolTips.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = MobilliumToolTips.podspec; path = ../MobilliumToolTips.podspec; sourceTree = ""; }; + 468D42805411B4AE81F5A464 /* MobilliumToolTips.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = MobilliumToolTips.podspec; path = ../MobilliumToolTips.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 607FACD01AFB9204008FA782 /* MobilliumToolTips_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MobilliumToolTips_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -42,8 +43,9 @@ 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 67C14D2AAA8FB3A3E1ABC0FF /* Pods-MobilliumToolTips_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobilliumToolTips_Example.release.xcconfig"; path = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example.release.xcconfig"; sourceTree = ""; }; - 98EB8C6FBE4DEE5828ABEF5A /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = ""; }; - D29FA3FF6CB9F359AF65623B /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 7EFD825E2A6D46FC00C17EB6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 98EB8C6FBE4DEE5828ABEF5A /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + D29FA3FF6CB9F359AF65623B /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; DA9047A335FCEE6D49935F78 /* Pods-MobilliumToolTips_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MobilliumToolTips_Tests.release.xcconfig"; path = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests.release.xcconfig"; sourceTree = ""; }; E7AE46168A3E7A9025CFBAC3 /* Pods_MobilliumToolTips_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MobilliumToolTips_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F523F57AA3B4228071946E65 /* Pods_MobilliumToolTips_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MobilliumToolTips_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -54,6 +56,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 7EFD825F2A6D46FD00C17EB6 /* QuartzCore.framework in Frameworks */, F430C4A6EA16D430CF9B05E1 /* Pods_MobilliumToolTips_Example.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -72,6 +75,7 @@ 566C0BE3FD777F22A4CECDD9 /* Frameworks */ = { isa = PBXGroup; children = ( + 7EFD825E2A6D46FC00C17EB6 /* QuartzCore.framework */, F523F57AA3B4228071946E65 /* Pods_MobilliumToolTips_Example.framework */, E7AE46168A3E7A9025CFBAC3 /* Pods_MobilliumToolTips_Tests.framework */, ); @@ -156,7 +160,6 @@ 1C0C55226749EFCA563EFEBA /* Pods-MobilliumToolTips_Tests.debug.xcconfig */, DA9047A335FCEE6D49935F78 /* Pods-MobilliumToolTips_Tests.release.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -227,6 +230,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -419,11 +423,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -465,10 +470,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; VALIDATE_PRODUCT = YES; }; name = Release; @@ -479,12 +485,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = MobilliumToolTips/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -494,12 +501,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = MobilliumToolTips/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -520,7 +528,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MobilliumToolTips_Example.app/MobilliumToolTips_Example"; }; name = Debug; @@ -538,7 +546,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MobilliumToolTips_Example.app/MobilliumToolTips_Example"; }; name = Release; diff --git a/Example/MobilliumToolTips.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/MobilliumToolTips.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Example/MobilliumToolTips.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Example/MobilliumToolTips/AppDelegate.swift b/Example/MobilliumToolTips/AppDelegate.swift index f599bff..fac387a 100644 --- a/Example/MobilliumToolTips/AppDelegate.swift +++ b/Example/MobilliumToolTips/AppDelegate.swift @@ -2,8 +2,8 @@ // AppDelegate.swift // MobilliumToolTips // -// Created by evam-mobile-customer on 07/21/2023. -// Copyright (c) 2023 evam-mobile-customer. All rights reserved. +// Created by mobillium on 07/21/2023. +// Copyright (c) 2023 mobillium. All rights reserved. // import UIKit @@ -13,34 +13,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - } diff --git a/Example/MobilliumToolTips/Info.plist b/Example/MobilliumToolTips/Info.plist index eb18faa..da9d7be 100644 --- a/Example/MobilliumToolTips/Info.plist +++ b/Example/MobilliumToolTips/Info.plist @@ -33,7 +33,10 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait diff --git a/Example/MobilliumToolTips/ViewController.swift b/Example/MobilliumToolTips/ViewController.swift index 9cd9368..e17cb01 100644 --- a/Example/MobilliumToolTips/ViewController.swift +++ b/Example/MobilliumToolTips/ViewController.swift @@ -2,23 +2,91 @@ // ViewController.swift // MobilliumToolTips // -// Created by evam-mobile-customer on 07/21/2023. -// Copyright (c) 2023 evam-mobile-customer. All rights reserved. +// Created by mobillium on 07/21/2023. +// Copyright (c) 2023 mobillium. All rights reserved. // import UIKit +import MobilliumToolTips class ViewController: UIViewController { + let button1 = UIButton(type: .system) + let button2 = UIButton(type: .system) + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. + configureContents() } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + configureTooltips() } +} + +// MARK: - Private Functions - +extension ViewController { + + private func configureContents() { + button1.setTitle("button", for: .normal) + button1.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(button1) + + button2.setTitle("button", for: .normal) + button2.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(button2) + NSLayoutConstraint.activate([ + button1.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 32), + button1.centerYAnchor.constraint(equalTo: view.centerYAnchor), + button2.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -32), + button2.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) + } + + private func configureTooltips() { + let gkTooltip = GKTooltip() + gkTooltip.startIntro(from: self, withNodes: self.getGKTooltipNodes(), isHighlightedWithOneNode: true) + + } } +// MARK: - Tooltip Walkthrough - +extension ViewController { + + fileprivate func getGKTooltipNodes() -> [GKTooltipNode] { + var nodes: [GKTooltipNode] = [] + + let testNodeButton1 = GKTooltipNode(text: "Lorem ipsum dolor sit amet", + target: .view(button1), + roundedCorners: false, + isLeftButtonHidden: true, + isRightButtonHidden: true, + isIconViewHidden: false, + leftButtonText: "txt_again", + leftButtonType: .again, + leftButtonTintColor: .orange03, + rightButtonText: "txt_next", + rightButtonType: .next, + rightButtonTintColor: .primary) + nodes.append(testNodeButton1) + + let testNodeButton2 = GKTooltipNode(text: "Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet\nLorem ipsum dolor sit amet,\n\nLorem ipsum dolor sit amet,", + target: .view(button2), + roundedCorners: false, + isLeftButtonHidden: false, + isRightButtonHidden: false, + isIconViewHidden: true, + leftButtonText: "txt_close", + leftButtonType: .close, + leftButtonTintColor: .elevation03, + rightButtonText: "txt_again", + rightButtonType: .again, + rightButtonTintColor: .pureBlack) + + nodes.append(testNodeButton2) + + return nodes + } +} diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 278dc70..4e451cb 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,13 +7,36 @@ objects = { /* Begin PBXBuildFile section */ - 2606A0C6A7E557EA635F22B9EB1BC697 /* ReplaceMe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D6C0E6BC377D65A89C62C0DA7E7855F /* ReplaceMe.swift */; }; 28156A5A7B099CE90249BE1D65223BCA /* MobilliumToolTips-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DE3EFA650A5C28FDC1F58371D8E4AD9 /* MobilliumToolTips-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28170827337ADC52F6E21D442BCF7EF1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 31CE27362799EFB44671703A0EEC7F2F /* Pods-MobilliumToolTips_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 99F96B3DD11B004EEC50D13C63F4F225 /* Pods-MobilliumToolTips_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 42D439484EFCE40C2825A8CBFC04C155 /* MobilliumToolTips-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9CD41B6F973010875E8A58B05E436B /* MobilliumToolTips-dummy.m */; }; 446B44C528E3167FB5674F7A01955291 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 6F18618C8015E0B52AA0E8C865CB1CF6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 7E8D3DBC2A6CA2D000707BC3 /* GKTooltipPopupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DB72A6CA2CF00707BC3 /* GKTooltipPopupModel.swift */; }; + 7E8D3DBD2A6CA2D000707BC3 /* EasytipView+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DB82A6CA2CF00707BC3 /* EasytipView+Helper.swift */; }; + 7E8D3DBE2A6CA2D000707BC3 /* GKTooltipPopupViewConstant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DB92A6CA2CF00707BC3 /* GKTooltipPopupViewConstant.swift */; }; + 7E8D3DBF2A6CA2D000707BC3 /* GKTooltipPopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DBA2A6CA2CF00707BC3 /* GKTooltipPopupView.swift */; }; + 7E8D3DC02A6CA2D000707BC3 /* EasytipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DBB2A6CA2D000707BC3 /* EasytipView.swift */; }; + 7E8D3DC92A6CA2D600707BC3 /* GKTooltipViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC12A6CA2D600707BC3 /* GKTooltipViewController.swift */; }; + 7E8D3DCA2A6CA2D600707BC3 /* GKTooltipTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC22A6CA2D600707BC3 /* GKTooltipTarget.swift */; }; + 7E8D3DCB2A6CA2D600707BC3 /* GKTooltipViewController+UISetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC32A6CA2D600707BC3 /* GKTooltipViewController+UISetup.swift */; }; + 7E8D3DCC2A6CA2D600707BC3 /* GKTooltipDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC42A6CA2D600707BC3 /* GKTooltipDataSource.swift */; }; + 7E8D3DCD2A6CA2D600707BC3 /* GKTooltipNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC52A6CA2D600707BC3 /* GKTooltipNode.swift */; }; + 7E8D3DCE2A6CA2D600707BC3 /* GKTooltip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC62A6CA2D600707BC3 /* GKTooltip.swift */; }; + 7E8D3DCF2A6CA2D600707BC3 /* UIScrollView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC72A6CA2D600707BC3 /* UIScrollView+Extensions.swift */; }; + 7E8D3DD02A6CA2D600707BC3 /* GKTooltipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DC82A6CA2D600707BC3 /* GKTooltipView.swift */; }; + 7E8D3DDB2A6CA3EF00707BC3 /* UIImage+Icons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DDA2A6CA3EF00707BC3 /* UIImage+Icons.swift */; }; + 7E8D3DDD2A6CA3F400707BC3 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DDC2A6CA3F400707BC3 /* UIColor+Extensions.swift */; }; + 7E8D3DE12A6CA40800707BC3 /* Inter-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7E8D3DDE2A6CA40800707BC3 /* Inter-Medium.otf */; }; + 7E8D3DE22A6CA40800707BC3 /* Inter-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7E8D3DDF2A6CA40800707BC3 /* Inter-Regular.otf */; }; + 7E8D3DE32A6CA40800707BC3 /* Inter-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7E8D3DE02A6CA40800707BC3 /* Inter-SemiBold.otf */; }; + 7E8D3DE72A6CA46200707BC3 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DE42A6CA46200707BC3 /* Fonts.swift */; }; + 7E8D3DE92A6CA46200707BC3 /* UIFont+Contants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DE62A6CA46200707BC3 /* UIFont+Contants.swift */; }; + 7E8D3DEC2A6CA52D00707BC3 /* BundleToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DEB2A6CA52D00707BC3 /* BundleToken.swift */; }; + 7E8D3DEE2A6CA5CF00707BC3 /* UIApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8D3DED2A6CA5CF00707BC3 /* UIApplication+Extension.swift */; }; + 7EE6F6B92A6CACCC009ED251 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7EE6F6B72A6CACCC009ED251 /* Colors.xcassets */; }; + 7EE6F6BA2A6CACCC009ED251 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7EE6F6B82A6CACCC009ED251 /* Icons.xcassets */; }; A4101F5B445E4ACE1CCC14BC21A0AF5E /* Pods-MobilliumToolTips_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DEB4B31CEFE48996AD32E38DCF1A571 /* Pods-MobilliumToolTips_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; DBD261BEE50DA729CBDE355B63E8E369 /* Pods-MobilliumToolTips_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3970F72CEB8DD77C413173AA1FB04EDA /* Pods-MobilliumToolTips_Example-dummy.m */; }; EA9B37B0D914E8B9742A3421CEA9AF79 /* Pods-MobilliumToolTips_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 627D5AF2C96C16009B01B17961923D1A /* Pods-MobilliumToolTips_Tests-dummy.m */; }; @@ -38,19 +61,42 @@ /* Begin PBXFileReference section */ 0DEB4B31CEFE48996AD32E38DCF1A571 /* Pods-MobilliumToolTips_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-MobilliumToolTips_Example-umbrella.h"; sourceTree = ""; }; - 1353E41A753B8556943B8C89EFA1C87F /* MobilliumToolTips.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = MobilliumToolTips.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 1353E41A753B8556943B8C89EFA1C87F /* MobilliumToolTips.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = MobilliumToolTips.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 197369B49B67E831295A745A92C8124B /* Pods-MobilliumToolTips_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MobilliumToolTips_Tests.debug.xcconfig"; sourceTree = ""; }; 2313240EBDB69721DE79202ABD41EEE4 /* MobilliumToolTips.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MobilliumToolTips.modulemap; sourceTree = ""; }; 24CB0FCD4D7642E9935BEED21001108E /* Pods-MobilliumToolTips_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-MobilliumToolTips_Tests.modulemap"; sourceTree = ""; }; - 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods-MobilliumToolTips_Tests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-MobilliumToolTips_Tests"; path = Pods_MobilliumToolTips_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MobilliumToolTips; path = MobilliumToolTips.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 306C7BA313A81AF42F03F9CB2BB4E250 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods_MobilliumToolTips_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MobilliumToolTips_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MobilliumToolTips.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 306C7BA313A81AF42F03F9CB2BB4E250 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 3970F72CEB8DD77C413173AA1FB04EDA /* Pods-MobilliumToolTips_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MobilliumToolTips_Example-dummy.m"; sourceTree = ""; }; 627D5AF2C96C16009B01B17961923D1A /* Pods-MobilliumToolTips_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MobilliumToolTips_Tests-dummy.m"; sourceTree = ""; }; 64348D61F02EC1C331D37374E5CE8A18 /* Pods-MobilliumToolTips_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MobilliumToolTips_Example.release.xcconfig"; sourceTree = ""; }; 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 749A5A6CF037D4269174FF199B0E18AB /* MobilliumToolTips.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MobilliumToolTips.debug.xcconfig; sourceTree = ""; }; - 7D6C0E6BC377D65A89C62C0DA7E7855F /* ReplaceMe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplaceMe.swift; path = MobilliumToolTips/Classes/ReplaceMe.swift; sourceTree = ""; }; + 7E8D3DB72A6CA2CF00707BC3 /* GKTooltipPopupModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipPopupModel.swift; path = MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupModel.swift; sourceTree = ""; }; + 7E8D3DB82A6CA2CF00707BC3 /* EasytipView+Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "EasytipView+Helper.swift"; path = "MobilliumToolTips/Classes/GKTooltipPopup/EasytipView+Helper.swift"; sourceTree = ""; }; + 7E8D3DB92A6CA2CF00707BC3 /* GKTooltipPopupViewConstant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipPopupViewConstant.swift; path = MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupViewConstant.swift; sourceTree = ""; }; + 7E8D3DBA2A6CA2CF00707BC3 /* GKTooltipPopupView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipPopupView.swift; path = MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupView.swift; sourceTree = ""; }; + 7E8D3DBB2A6CA2D000707BC3 /* EasytipView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EasytipView.swift; path = MobilliumToolTips/Classes/GKTooltipPopup/EasytipView.swift; sourceTree = ""; }; + 7E8D3DC12A6CA2D600707BC3 /* GKTooltipViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipViewController.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController.swift; sourceTree = ""; }; + 7E8D3DC22A6CA2D600707BC3 /* GKTooltipTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipTarget.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltipTarget.swift; sourceTree = ""; }; + 7E8D3DC32A6CA2D600707BC3 /* GKTooltipViewController+UISetup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "GKTooltipViewController+UISetup.swift"; path = "MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController+UISetup.swift"; sourceTree = ""; }; + 7E8D3DC42A6CA2D600707BC3 /* GKTooltipDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipDataSource.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltipDataSource.swift; sourceTree = ""; }; + 7E8D3DC52A6CA2D600707BC3 /* GKTooltipNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipNode.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltipNode.swift; sourceTree = ""; }; + 7E8D3DC62A6CA2D600707BC3 /* GKTooltip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltip.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltip.swift; sourceTree = ""; }; + 7E8D3DC72A6CA2D600707BC3 /* UIScrollView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIScrollView+Extensions.swift"; path = "MobilliumToolTips/Classes/GKTooltipView/UIScrollView+Extensions.swift"; sourceTree = ""; }; + 7E8D3DC82A6CA2D600707BC3 /* GKTooltipView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GKTooltipView.swift; path = MobilliumToolTips/Classes/GKTooltipView/GKTooltipView.swift; sourceTree = ""; }; + 7E8D3DDA2A6CA3EF00707BC3 /* UIImage+Icons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Icons.swift"; sourceTree = ""; }; + 7E8D3DDC2A6CA3F400707BC3 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = ""; }; + 7E8D3DDE2A6CA40800707BC3 /* Inter-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-Medium.otf"; sourceTree = ""; }; + 7E8D3DDF2A6CA40800707BC3 /* Inter-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-Regular.otf"; sourceTree = ""; }; + 7E8D3DE02A6CA40800707BC3 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inter-SemiBold.otf"; sourceTree = ""; }; + 7E8D3DE42A6CA46200707BC3 /* Fonts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; + 7E8D3DE62A6CA46200707BC3 /* UIFont+Contants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+Contants.swift"; sourceTree = ""; }; + 7E8D3DEB2A6CA52D00707BC3 /* BundleToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BundleToken.swift; path = MobilliumToolTips/Classes/BundleToken.swift; sourceTree = ""; }; + 7E8D3DED2A6CA5CF00707BC3 /* UIApplication+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIApplication+Extension.swift"; path = "MobilliumToolTips/Classes/UIApplication+Extension.swift"; sourceTree = ""; }; + 7EE6F6B72A6CACCC009ED251 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Colors.xcassets; path = MobilliumToolTips/Assets/Colors.xcassets; sourceTree = ""; }; + 7EE6F6B82A6CACCC009ED251 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Icons.xcassets; path = MobilliumToolTips/Assets/Icons.xcassets; sourceTree = ""; }; 7EFDB2946D56914CF3B470CCDF63644A /* Pods-MobilliumToolTips_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-MobilliumToolTips_Example-frameworks.sh"; sourceTree = ""; }; 8B9CD41B6F973010875E8A58B05E436B /* MobilliumToolTips-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MobilliumToolTips-dummy.m"; sourceTree = ""; }; 8E5A9B423770AEF5BA0CB2741C4EDDF3 /* Pods-MobilliumToolTips_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-MobilliumToolTips_Example-acknowledgements.markdown"; sourceTree = ""; }; @@ -59,12 +105,12 @@ 99E61A790B0A95EBD986C949CC4A92E6 /* Pods-MobilliumToolTips_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MobilliumToolTips_Tests-acknowledgements.plist"; sourceTree = ""; }; 99F96B3DD11B004EEC50D13C63F4F225 /* Pods-MobilliumToolTips_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-MobilliumToolTips_Tests-umbrella.h"; sourceTree = ""; }; 9ACA5FA4A1DC1FBE52300CB733573560 /* Pods-MobilliumToolTips_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MobilliumToolTips_Example.debug.xcconfig"; sourceTree = ""; }; - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 9DE3EFA650A5C28FDC1F58371D8E4AD9 /* MobilliumToolTips-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MobilliumToolTips-umbrella.h"; sourceTree = ""; }; A218DAC5A4797F25E2C5FA40BD629CEE /* MobilliumToolTips.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MobilliumToolTips.release.xcconfig; sourceTree = ""; }; B22F1E589E3D0EA32A2CB00AD33BA0B1 /* MobilliumToolTips-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MobilliumToolTips-Info.plist"; sourceTree = ""; }; - BD72E0954C0A15E201420817217A5766 /* Pods-MobilliumToolTips_Example */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-MobilliumToolTips_Example"; path = Pods_MobilliumToolTips_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C38BDEA9F4646229FC7FC22BAA3BBCE2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; + BD72E0954C0A15E201420817217A5766 /* Pods_MobilliumToolTips_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MobilliumToolTips_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C38BDEA9F4646229FC7FC22BAA3BBCE2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; CFCDB0BCD9CC146AD1E4BFB822072288 /* Pods-MobilliumToolTips_Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MobilliumToolTips_Tests-Info.plist"; sourceTree = ""; }; E2EA7632E42D221F8B0CDA2DB04204C2 /* Pods-MobilliumToolTips_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MobilliumToolTips_Example-acknowledgements.plist"; sourceTree = ""; }; EA5E9F22E93637D7C82515BE572E566E /* Pods-MobilliumToolTips_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-MobilliumToolTips_Example.modulemap"; sourceTree = ""; }; @@ -103,7 +149,24 @@ 4A21ECDCD6364A7791C53B2EFA680DF2 /* MobilliumToolTips */ = { isa = PBXGroup; children = ( - 7D6C0E6BC377D65A89C62C0DA7E7855F /* ReplaceMe.swift */, + 7E8D3DBB2A6CA2D000707BC3 /* EasytipView.swift */, + 7E8D3DB82A6CA2CF00707BC3 /* EasytipView+Helper.swift */, + 7E8D3DB72A6CA2CF00707BC3 /* GKTooltipPopupModel.swift */, + 7E8D3DBA2A6CA2CF00707BC3 /* GKTooltipPopupView.swift */, + 7E8D3DB92A6CA2CF00707BC3 /* GKTooltipPopupViewConstant.swift */, + 7E8D3DC62A6CA2D600707BC3 /* GKTooltip.swift */, + 7E8D3DC42A6CA2D600707BC3 /* GKTooltipDataSource.swift */, + 7E8D3DC52A6CA2D600707BC3 /* GKTooltipNode.swift */, + 7E8D3DC22A6CA2D600707BC3 /* GKTooltipTarget.swift */, + 7E8D3DC82A6CA2D600707BC3 /* GKTooltipView.swift */, + 7E8D3DC12A6CA2D600707BC3 /* GKTooltipViewController.swift */, + 7E8D3DC32A6CA2D600707BC3 /* GKTooltipViewController+UISetup.swift */, + 7E8D3DC72A6CA2D600707BC3 /* UIScrollView+Extensions.swift */, + 7E8D3DEB2A6CA52D00707BC3 /* BundleToken.swift */, + 7E8D3DED2A6CA5CF00707BC3 /* UIApplication+Extension.swift */, + 7EE6F6B72A6CACCC009ED251 /* Colors.xcassets */, + 7EE6F6B82A6CACCC009ED251 /* Icons.xcassets */, + 7E8D3DAB2A6CA01700707BC3 /* Resources */, 69B4A86B944D6068B5169BBE3B72CB60 /* Pod */, 73C8FA93C65B9C8D73E49BA965C4CACB /* Support Files */, ); @@ -161,6 +224,44 @@ path = "Target Support Files/Pods-MobilliumToolTips_Example"; sourceTree = ""; }; + 7E8D3DAB2A6CA01700707BC3 /* Resources */ = { + isa = PBXGroup; + children = ( + 7E8D3DD82A6CA3DF00707BC3 /* Assets */, + 7E8D3DD92A6CA3E400707BC3 /* Colors */, + 7E8D3DD72A6CA3A500707BC3 /* Fonts */, + ); + path = Resources; + sourceTree = ""; + }; + 7E8D3DD72A6CA3A500707BC3 /* Fonts */ = { + isa = PBXGroup; + children = ( + 7E8D3DE42A6CA46200707BC3 /* Fonts.swift */, + 7E8D3DE62A6CA46200707BC3 /* UIFont+Contants.swift */, + 7E8D3DDE2A6CA40800707BC3 /* Inter-Medium.otf */, + 7E8D3DDF2A6CA40800707BC3 /* Inter-Regular.otf */, + 7E8D3DE02A6CA40800707BC3 /* Inter-SemiBold.otf */, + ); + path = Fonts; + sourceTree = ""; + }; + 7E8D3DD82A6CA3DF00707BC3 /* Assets */ = { + isa = PBXGroup; + children = ( + 7E8D3DDA2A6CA3EF00707BC3 /* UIImage+Icons.swift */, + ); + path = Assets; + sourceTree = ""; + }; + 7E8D3DD92A6CA3E400707BC3 /* Colors */ = { + isa = PBXGroup; + children = ( + 7E8D3DDC2A6CA3F400707BC3 /* UIColor+Extensions.swift */, + ); + path = Colors; + sourceTree = ""; + }; 848E0F098AD1945F9D75889B4D26F62E /* Pods-MobilliumToolTips_Tests */ = { isa = PBXGroup; children = ( @@ -216,9 +317,9 @@ FC01C4DFA2257E6A8765E78D102831EF /* Products */ = { isa = PBXGroup; children = ( - 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips */, - BD72E0954C0A15E201420817217A5766 /* Pods-MobilliumToolTips_Example */, - 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods-MobilliumToolTips_Tests */, + 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips.framework */, + BD72E0954C0A15E201420817217A5766 /* Pods_MobilliumToolTips_Example.framework */, + 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods_MobilliumToolTips_Tests.framework */, ); name = Products; sourceTree = ""; @@ -268,7 +369,7 @@ ); name = MobilliumToolTips; productName = MobilliumToolTips; - productReference = 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips */; + productReference = 2F6905F0157F86216F2FCCBC5E658122 /* MobilliumToolTips.framework */; productType = "com.apple.product-type.framework"; }; A66FD4E90EB08660D9167303D59E2046 /* Pods-MobilliumToolTips_Tests */ = { @@ -287,7 +388,7 @@ ); name = "Pods-MobilliumToolTips_Tests"; productName = Pods_MobilliumToolTips_Tests; - productReference = 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods-MobilliumToolTips_Tests */; + productReference = 2B1E27686BB23AA9D9C4F8B2B706E026 /* Pods_MobilliumToolTips_Tests.framework */; productType = "com.apple.product-type.framework"; }; E522305E5D2E78E3928200A760F96563 /* Pods-MobilliumToolTips_Example */ = { @@ -306,7 +407,7 @@ ); name = "Pods-MobilliumToolTips_Example"; productName = Pods_MobilliumToolTips_Example; - productReference = BD72E0954C0A15E201420817217A5766 /* Pods-MobilliumToolTips_Example */; + productReference = BD72E0954C0A15E201420817217A5766 /* Pods_MobilliumToolTips_Example.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -317,6 +418,11 @@ attributes = { LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 1300; + TargetAttributes = { + A18D9C8BF46AC645C7C2749BB9AD7B95 = { + LastSwiftMigration = 1430; + }; + }; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -357,6 +463,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7E8D3DE22A6CA40800707BC3 /* Inter-Regular.otf in Resources */, + 7EE6F6B92A6CACCC009ED251 /* Colors.xcassets in Resources */, + 7E8D3DE12A6CA40800707BC3 /* Inter-Medium.otf in Resources */, + 7E8D3DE32A6CA40800707BC3 /* Inter-SemiBold.otf in Resources */, + 7EE6F6BA2A6CACCC009ED251 /* Icons.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -367,8 +478,26 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7E8D3DBD2A6CA2D000707BC3 /* EasytipView+Helper.swift in Sources */, + 7E8D3DBC2A6CA2D000707BC3 /* GKTooltipPopupModel.swift in Sources */, + 7E8D3DCC2A6CA2D600707BC3 /* GKTooltipDataSource.swift in Sources */, + 7E8D3DCE2A6CA2D600707BC3 /* GKTooltip.swift in Sources */, + 7E8D3DD02A6CA2D600707BC3 /* GKTooltipView.swift in Sources */, + 7E8D3DC92A6CA2D600707BC3 /* GKTooltipViewController.swift in Sources */, + 7E8D3DBE2A6CA2D000707BC3 /* GKTooltipPopupViewConstant.swift in Sources */, + 7E8D3DE92A6CA46200707BC3 /* UIFont+Contants.swift in Sources */, + 7E8D3DE72A6CA46200707BC3 /* Fonts.swift in Sources */, + 7E8D3DCA2A6CA2D600707BC3 /* GKTooltipTarget.swift in Sources */, + 7E8D3DDB2A6CA3EF00707BC3 /* UIImage+Icons.swift in Sources */, + 7E8D3DCF2A6CA2D600707BC3 /* UIScrollView+Extensions.swift in Sources */, + 7E8D3DEC2A6CA52D00707BC3 /* BundleToken.swift in Sources */, 42D439484EFCE40C2825A8CBFC04C155 /* MobilliumToolTips-dummy.m in Sources */, - 2606A0C6A7E557EA635F22B9EB1BC697 /* ReplaceMe.swift in Sources */, + 7E8D3DDD2A6CA3F400707BC3 /* UIColor+Extensions.swift in Sources */, + 7E8D3DC02A6CA2D000707BC3 /* EasytipView.swift in Sources */, + 7E8D3DCD2A6CA2D600707BC3 /* GKTooltipNode.swift in Sources */, + 7E8D3DCB2A6CA2D600707BC3 /* GKTooltipViewController+UISetup.swift in Sources */, + 7E8D3DEE2A6CA5CF00707BC3 /* UIApplication+Extension.swift in Sources */, + 7E8D3DBF2A6CA2D000707BC3 /* GKTooltipPopupView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -422,7 +551,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example.modulemap"; @@ -455,7 +584,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example.modulemap"; @@ -489,7 +618,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests.modulemap"; @@ -562,8 +691,7 @@ MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; @@ -573,6 +701,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = A218DAC5A4797F25E2C5FA40BD629CEE /* MobilliumToolTips.release.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -585,7 +714,7 @@ GCC_PREFIX_HEADER = "Target Support Files/MobilliumToolTips/MobilliumToolTips-prefix.pch"; INFOPLIST_FILE = "Target Support Files/MobilliumToolTips/MobilliumToolTips-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/MobilliumToolTips/MobilliumToolTips.modulemap"; PRODUCT_MODULE_NAME = MobilliumToolTips; @@ -593,7 +722,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -605,6 +734,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 749A5A6CF037D4269174FF199B0E18AB /* MobilliumToolTips.debug.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -617,7 +747,7 @@ GCC_PREFIX_HEADER = "Target Support Files/MobilliumToolTips/MobilliumToolTips-prefix.pch"; INFOPLIST_FILE = "Target Support Files/MobilliumToolTips/MobilliumToolTips-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/MobilliumToolTips/MobilliumToolTips.modulemap"; PRODUCT_MODULE_NAME = MobilliumToolTips; @@ -625,7 +755,8 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -648,7 +779,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-MobilliumToolTips_Tests/Pods-MobilliumToolTips_Tests.modulemap"; diff --git a/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.markdown index 144bb00..52cb018 100644 --- a/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.markdown +++ b/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.markdown @@ -3,7 +3,7 @@ This application makes use of the following third party libraries: ## MobilliumToolTips -Copyright (c) 2023 evam-mobile-customer +Copyright (c) 2023 mobillium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.plist index c2cf962..96f1e1c 100644 --- a/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.plist +++ b/Example/Pods/Target Support Files/Pods-MobilliumToolTips_Example/Pods-MobilliumToolTips_Example-acknowledgements.plist @@ -14,10 +14,10 @@ FooterText - Copyright (c) 2023 evam-mobile-customer <aslanmsalih@gmail.com> + Copyright (c) 2023 mobillium <info@mobillium.com> Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal +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 @@ -26,7 +26,7 @@ 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 +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 diff --git a/LICENSE b/LICENSE index 0d9d8ca..6eb86c8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2023 evam-mobile-customer +Copyright (c) 2023 mobillium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MobilliumToolTips.podspec b/MobilliumToolTips.podspec index c90ad25..509f7e2 100644 --- a/MobilliumToolTips.podspec +++ b/MobilliumToolTips.podspec @@ -1,42 +1,34 @@ -# -# Be sure to run `pod lib lint MobilliumToolTips.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 https://guides.cocoapods.org/syntax/podspec.html -# - Pod::Spec.new do |s| - s.name = 'MobilliumToolTips' - s.version = '0.1.0' - s.summary = 'A short description of MobilliumToolTips.' - -# 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 -TODO: Add long description of the pod here. - DESC - - s.homepage = 'https://github.com/evam-mobile-customer/MobilliumToolTips' - # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' - s.license = { :type => 'MIT', :file => 'LICENSE' } - s.author = { 'evam-mobile-customer' => 'aslanmsalih@gmail.com' } - s.source = { :git => 'https://github.com/evam-mobile-customer/MobilliumToolTips.git', :tag => s.version.to_s } - # s.social_media_url = 'https://twitter.com/' - - s.ios.deployment_target = '10.0' - - s.source_files = 'MobilliumToolTips/Classes/**/*' - - # s.resource_bundles = { - # 'MobilliumToolTips' => ['MobilliumToolTips/Assets/*.png'] - # } - - # s.public_header_files = 'Pod/Classes/**/*.h' - # s.frameworks = 'UIKit', 'MapKit' - # s.dependency 'AFNetworking', '~> 2.3' + s.name = 'MobilliumToolTips' + s.version = '0.1.0' + s.summary = 'Simplify the user journey with customizable step-by-step guides' + + s.description = <<-DESC + You can display brief informational notes to users in the targeted areas on the desired page. Additionally, you have the ability to show or hide the buttons in the lower section. + DESC + + s.homepage = 'https://github.com/mobillium/MobilliumToolTips' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'serkan' => 'srkanerkan@gmail.com' } + s.source = { :git => 'https://github.com/mobillium/MobilliumToolTips.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/serkandSYM' + s.ios.deployment_target = '13.0' + s.swift_version = "5.0" + + s.source_files = [ + 'MobilliumToolTips/Classes/**/*', + 'Resources/Fonts/**/*', + 'Resources/Colors/**/*', + 'Resources/Assets/**/*' + ] + s.resources = [ + 'MobilliumToolTips/Assets/*.xcassets', + 'Resources/Fonts/*.otf' + ] + s.frameworks = [ + 'Foundation', + 'UIKit' + ] + s.dependency 'MobilliumBuilders', '~> 1.5' + s.dependency 'TinyConstraints', '~> 4.0' end diff --git a/MobilliumToolTips/Assets/Colors.xcassets/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/background01.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/background01.colorset/Contents.json new file mode 100644 index 0000000..e54fa3d --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/background01.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFC", + "green" : "0xFA", + "red" : "0xF8" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x1D", + "green" : "0x1A", + "red" : "0x17" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/background02.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/background02.colorset/Contents.json new file mode 100644 index 0000000..cf8e4f6 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/background02.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x19", + "green" : "0x17", + "red" : "0x15" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/base.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/base.colorset/Contents.json new file mode 100644 index 0000000..2d8e16c --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/base.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2E", + "green" : "0x27", + "red" : "0x1F" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/elevation01.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/elevation01.colorset/Contents.json new file mode 100644 index 0000000..34bd7f5 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/elevation01.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF7", + "green" : "0xF3", + "red" : "0xEF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3D", + "green" : "0x34", + "red" : "0x29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/elevation02.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/elevation02.colorset/Contents.json new file mode 100644 index 0000000..88135b9 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/elevation02.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE9", + "green" : "0xDF", + "red" : "0xD4" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x44", + "green" : "0x3E", + "red" : "0x36" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/elevation03.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/elevation03.colorset/Contents.json new file mode 100644 index 0000000..42df2e8 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/elevation03.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xDB", + "green" : "0xCB", + "red" : "0xB8" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x5B", + "green" : "0x52", + "red" : "0x48" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/focus.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/focus.colorset/Contents.json new file mode 100644 index 0000000..9d09a76 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/focus.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x1D", + "green" : "0x1A", + "red" : "0x17" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0xF7", + "red" : "0xF7" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/green01.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/green01.colorset/Contents.json new file mode 100644 index 0000000..02a0ef6 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/green01.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xC8", + "green" : "0xEC", + "red" : "0xBB" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x39", + "green" : "0x56", + "red" : "0x24" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/green02.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/green02.colorset/Contents.json new file mode 100644 index 0000000..cc6118d --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/green02.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x90", + "green" : "0xDA", + "red" : "0x78" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x43", + "green" : "0x85", + "red" : "0x28" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/green03.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/green03.colorset/Contents.json new file mode 100644 index 0000000..4a59b9a --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/green03.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x59", + "green" : "0xC7", + "red" : "0x34" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x4E", + "green" : "0xB4", + "red" : "0x2D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/orange01.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/orange01.colorset/Contents.json new file mode 100644 index 0000000..c7718c2 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/orange01.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xAA", + "green" : "0xDC", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x22", + "green" : "0x4F", + "red" : "0x6A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/orange02.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/orange02.colorset/Contents.json new file mode 100644 index 0000000..f03669d --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/orange02.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x55", + "green" : "0xB8", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x16", + "green" : "0x77", + "red" : "0xB4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/orange03.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/orange03.colorset/Contents.json new file mode 100644 index 0000000..bd327ec --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/orange03.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x95", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x0A", + "green" : "0x9F", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/primary.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/primary.colorset/Contents.json new file mode 100644 index 0000000..1dff723 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/primary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE8", + "green" : "0x6B", + "red" : "0x01" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF5", + "green" : "0x86", + "red" : "0x29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/pureBlack.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/pureBlack.colorset/Contents.json new file mode 100644 index 0000000..be9d677 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/pureBlack.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/pureWhite.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/pureWhite.colorset/Contents.json new file mode 100644 index 0000000..2536dc2 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/pureWhite.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/red01.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/red01.colorset/Contents.json new file mode 100644 index 0000000..6603a98 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/red01.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE1", + "green" : "0xE3", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2E", + "green" : "0x2A", + "red" : "0x3F" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/red02.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/red02.colorset/Contents.json new file mode 100644 index 0000000..7081dc1 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/red02.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x89", + "green" : "0x8F", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2F", + "green" : "0x32", + "red" : "0x9F" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/red03.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/red03.colorset/Contents.json new file mode 100644 index 0000000..f79dfd1 --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/red03.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x30", + "green" : "0x3B", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3A", + "green" : "0x45", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Colors.xcassets/text.colorset/Contents.json b/MobilliumToolTips/Assets/Colors.xcassets/text.colorset/Contents.json new file mode 100644 index 0000000..0b1080c --- /dev/null +++ b/MobilliumToolTips/Assets/Colors.xcassets/text.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB9", + "green" : "0xA0", + "red" : "0x83" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB9", + "green" : "0xA0", + "red" : "0x83" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Icons.xcassets/Contents.json b/MobilliumToolTips/Assets/Icons.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/MobilliumToolTips/Assets/Icons.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/Contents.json b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/Contents.json new file mode 100644 index 0000000..0845221 --- /dev/null +++ b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "ic_info.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ic_info@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ic_info@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info.png b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info.png new file mode 100644 index 0000000..a2e2679 Binary files /dev/null and b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info.png differ diff --git a/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@2x.png b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@2x.png new file mode 100644 index 0000000..281ac5d Binary files /dev/null and b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@2x.png differ diff --git a/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@3x.png b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@3x.png new file mode 100644 index 0000000..94c5760 Binary files /dev/null and b/MobilliumToolTips/Assets/Icons.xcassets/ic_info.imageset/ic_info@3x.png differ diff --git a/MobilliumToolTips/Classes/BundleToken.swift b/MobilliumToolTips/Classes/BundleToken.swift new file mode 100644 index 0000000..6e0c52d --- /dev/null +++ b/MobilliumToolTips/Classes/BundleToken.swift @@ -0,0 +1,19 @@ +// +// BundleToken.swift +// MobilliumGenesisKit +// +// Created by Mehmet Salih Aslan on 10.03.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import Foundation + +final class BundleToken { + static let bundle: Bundle = { + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleToken.self) + #endif + }() +} diff --git a/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView+Helper.swift b/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView+Helper.swift new file mode 100644 index 0000000..d44b6b7 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView+Helper.swift @@ -0,0 +1,64 @@ +// +// EasytipView+Helper.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +// MARK: - UIBarItem Extension - +extension UIBarItem { + var view: UIView? { + if let item = self as? UIBarButtonItem, let customView = item.customView { + return customView + } + return self.value(forKey: "view") as? UIView + } +} + +// MARK: - UIView Extension - +extension UIView { + func hasSuperview(_ superview: UIView) -> Bool{ + return viewHasSuperview(self, superview: superview) + } + + fileprivate func viewHasSuperview(_ view: UIView, superview: UIView) -> Bool { + if let sview = view.superview { + if sview === superview { + return true + } else { + return viewHasSuperview(sview, superview: superview) + } + } else { + return false + } + } +} + +// MARK: - CGRect Extension - +extension CGRect { + var x: CGFloat { + get { + return self.origin.x + } + set { + self.origin.x = newValue + } + } + + var y: CGFloat { + get { + return self.origin.y + } + + set { + self.origin.y = newValue + } + } + + var center: CGPoint { + return CGPoint(x: self.x + self.width / 2, y: self.y + self.height / 2) + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView.swift b/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView.swift new file mode 100644 index 0000000..543e0f9 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipPopup/EasytipView.swift @@ -0,0 +1,666 @@ +// +// EasytipView.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public protocol EasyTipViewDelegate : AnyObject { + func easyTipViewDidDismiss(_ tipView : EasyTipView) +} + +// MARK: - Public methods - +public extension EasyTipView { + + // MARK: - Class methods - + /** + Presents an EasyTipView pointing to a particular UIBarItem instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter item: The UIBarButtonItem or UITabBarItem instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIBarButtonItem instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + - parameter text: The text to be displayed. + - parameter preferences: The preferences which will configure the EasyTipView. + - parameter delegate: The delegate. + */ + + class func show(animated: Bool = true, forItem item: UIBarItem, withinSuperview superview: UIView? = nil, text: String, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil){ + + if let view = item.view { + show(animated: animated, forView: view, withinSuperview: superview, text: text, preferences: preferences, delegate: delegate) + } + } + + /** + Presents an EasyTipView pointing to a particular UIView instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter view: The UIView instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIView instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + - parameter text: The text to be displayed. + - parameter preferences: The preferences which will configure the EasyTipView. + - parameter delegate: The delegate. + */ + + class func show(animated: Bool = true, forView view: UIView, withinSuperview superview: UIView? = nil, text: String, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil){ + + let ev = EasyTipView(text: text, preferences: preferences, delegate: delegate) + ev.show(animated: animated, forView: view, withinSuperview: superview) + } + + /** + Presents an EasyTipView pointing to a particular UIBarItem instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter item: The UIBarButtonItem or UITabBarItem instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIBarButtonItem instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + - parameter contentView: The view to be displayed. + - parameter preferences: The preferences which will configure the EasyTipView. + - parameter delegate: The delegate. + */ + + class func show(animated: Bool = true, forItem item: UIBarItem, withinSuperview superview: UIView? = nil, contentView: UIView, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil){ + + if let view = item.view { + show(animated: animated, forView: view, withinSuperview: superview, contentView: contentView, preferences: preferences, delegate: delegate) + } + } + + /** + Presents an EasyTipView pointing to a particular UIView instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter view: The UIView instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIView instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + - parameter contentView: The view to be displayed. + - parameter preferences: The preferences which will configure the EasyTipView. + - parameter delegate: The delegate. + */ + + class func show(animated: Bool = true, forView view: UIView, withinSuperview superview: UIView? = nil, contentView: UIView, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil){ + + let ev = EasyTipView(contentView: contentView, preferences: preferences, delegate: delegate) + ev.show(animated: animated, forView: view, withinSuperview: superview) + } + + // MARK:- Instance methods - + + /** + Presents an EasyTipView pointing to a particular UIBarItem instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter item: The UIBarButtonItem or UITabBarItem instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIBarButtonItem instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + */ + + func show(animated: Bool = true, forItem item: UIBarItem, withinSuperView superview: UIView? = nil) { + if let view = item.view { + show(animated: animated, forView: view, withinSuperview: superview) + } + } + + /** + Presents an EasyTipView pointing to a particular UIView instance within the specified superview + + - parameter animated: Pass true to animate the presentation. + - parameter view: The UIView instance which the EasyTipView will be pointing to. + - parameter superview: A view which is part of the UIView instances superview hierarchy. Ignore this parameter in order to display the EasyTipView within the main window. + */ + + func show(animated: Bool = true, forView view: UIView, withinSuperview superview: UIView? = nil) { + + precondition(superview == nil || view.hasSuperview(superview!), "The supplied superview <\(superview!)> is not a direct nor an indirect superview of the supplied reference view <\(view)>. The superview passed to this method should be a direct or an indirect superview of the reference view. To display the tooltip within the main window, ignore the superview parameter.") + + let superview = superview ?? UIApplication.shared.windows.first! + + let initialTransform = preferences.animating.showInitialTransform + let finalTransform = preferences.animating.showFinalTransform + let initialAlpha = preferences.animating.showInitialAlpha + let damping = preferences.animating.springDamping + let velocity = preferences.animating.springVelocity + + presentingView = view + arrange(withinSuperview: superview) + + transform = initialTransform + alpha = initialAlpha + + let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap)) + tap.delegate = self + addGestureRecognizer(tap) + + superview.addSubview(self) + + let animations : () -> () = { + self.transform = finalTransform + self.alpha = 1 + } + + if animated { + UIView.animate(withDuration: preferences.animating.showDuration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: velocity, options: [.curveEaseInOut], animations: animations, completion: nil) + }else{ + animations() + } + } + + /** + Dismisses the EasyTipView + + - parameter completion: Completion block to be executed after the EasyTipView is dismissed. + */ + + func dismiss(withCompletion completion: (() -> ())? = nil){ + + let damping = preferences.animating.springDamping + let velocity = preferences.animating.springVelocity + + UIView.animate(withDuration: preferences.animating.dismissDuration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: velocity, options: [.curveEaseInOut], animations: { + self.transform = self.preferences.animating.dismissTransform + self.alpha = self.preferences.animating.dismissFinalAlpha + }) { (finished) -> Void in + completion?() + self.delegate?.easyTipViewDidDismiss(self) + self.removeFromSuperview() + self.transform = CGAffineTransform.identity + } + } +} + +// MARK: - UIGestureRecognizerDelegate implementation +extension EasyTipView: UIGestureRecognizerDelegate { + + open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + return preferences.animating.dismissOnTap + } +} + +// MARK: - EasyTipView class implementation - +open class EasyTipView: UIView { + + // Nested types + public enum ArrowPosition { + case any + case top + case bottom + case right + case left + + static let allValues = [top, bottom, right, left] + } + + public struct Preferences { + + public struct Drawing { + public var cornerRadius = CGFloat(5) + public var arrowHeight = CGFloat(10) + public var arrowWidth = CGFloat(20) + public var foregroundColor = UIColor.clear + public var backgroundColor = UIColor.clear + public var arrowPosition = ArrowPosition.any + public var textAlignment = NSTextAlignment.center + public var borderWidth = CGFloat(0) + public var borderColor = UIColor.clear + public var font = UIFont.systemFont(ofSize: 15) + public var shadowColor = UIColor.clear + public var shadowOffset = CGSize(width: 0.0, height: 0.0) + public var shadowRadius = CGFloat(0) + public var shadowOpacity = CGFloat(0) + } + + public struct Positioning { + public var bubbleHInset = CGFloat(1) + public var bubbleVInset = CGFloat(1) + public var contentHInset = CGFloat(0) + public var contentVInset = CGFloat(0) + public var maxWidth = CGFloat(240) + } + + public struct Animating { + public var dismissTransform = CGAffineTransform(scaleX: 0.1, y: 0.1) + public var showInitialTransform = CGAffineTransform(scaleX: 0, y: 0) + public var showFinalTransform = CGAffineTransform.identity + public var springDamping = CGFloat(0.7) + public var springVelocity = CGFloat(0.7) + public var showInitialAlpha = CGFloat(0) + public var dismissFinalAlpha = CGFloat(0) + public var showDuration = 0.7 + public var dismissDuration = 0.7 + public var dismissOnTap = false + } + + public var drawing = Drawing() + public var positioning = Positioning() + public var animating = Animating() + public var hasBorder : Bool { + return drawing.borderWidth > 0 && drawing.borderColor != UIColor.clear + } + + public var hasShadow : Bool { + return drawing.shadowOpacity > 0 && drawing.shadowColor != UIColor.clear + } + + public init() {} + } + + private enum Content: CustomStringConvertible { + + case text(String) + case view(UIView) + + var description: String { + switch self { + case .text(let text): + return "text : '\(text)'" + case .view(let contentView): + return "view : \(contentView)" + } + } + } + +// MARK: - Variables - + override open var backgroundColor: UIColor? { + didSet { + guard let color = backgroundColor + , color != UIColor.clear else {return} + + preferences.drawing.backgroundColor = color + backgroundColor = UIColor.clear + } + } + + override open var description: String { + let type = "'\(String(reflecting: Swift.type(of: self)))'".components(separatedBy: ".").last! + + return "<< \(type) with \(content) >>" + } + + fileprivate weak var presentingView: UIView? + fileprivate weak var delegate: EasyTipViewDelegate? + fileprivate var arrowTip = CGPoint.zero + fileprivate(set) open var preferences: Preferences + private let content: Content + +// MARK: - Lazy variables - + fileprivate lazy var contentSize: CGSize = { + + [unowned self] in + + switch content { + case .text(let text): +#if swift(>=4.2) + var attributes = [NSAttributedString.Key.font : self.preferences.drawing.font] +#else + var attributes = [NSAttributedStringKey.font : self.preferences.drawing.font] +#endif + + var textSize = text.boundingRect(with: CGSize(width: self.preferences.positioning.maxWidth, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil).size + + textSize.width = ceil(textSize.width) + textSize.height = ceil(textSize.height) + + if textSize.width < self.preferences.drawing.arrowWidth { + textSize.width = self.preferences.drawing.arrowWidth + } + + return textSize + + case .view(let contentView): + return contentView.frame.size + } + }() + + fileprivate lazy var tipViewSize: CGSize = { + + [unowned self] in + + var tipViewSize = CGSize(width: self.contentSize.width + self.preferences.positioning.contentHInset * 2 + self.preferences.positioning.bubbleHInset * 2, height: self.contentSize.height + self.preferences.positioning.contentVInset * 2 + self.preferences.positioning.bubbleVInset * 2 + self.preferences.drawing.arrowHeight) + + return tipViewSize + }() + +// MARK: - Static Variables - + public static var globalPreferences = Preferences() + + // Initializer + public convenience init (text: String, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil) { + self.init(content: .text(text), preferences: preferences, delegate: delegate) + } + + public convenience init (contentView: UIView, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil) { + self.init(content: .view(contentView), preferences: preferences, delegate: delegate) + } + + private init (content: Content, preferences: Preferences = EasyTipView.globalPreferences, delegate: EasyTipViewDelegate? = nil) { + + self.content = content + self.preferences = preferences + self.delegate = delegate + + super.init(frame: CGRect.zero) + + self.backgroundColor = UIColor.clear + +#if swift(>=4.2) + let notificationName = UIDevice.orientationDidChangeNotification +#else + let notificationName = NSNotification.Name.UIDeviceOrientationDidChange +#endif + + NotificationCenter.default.addObserver(self, selector: #selector(handleRotation), name: notificationName, object: nil) + } + + deinit + { + NotificationCenter.default.removeObserver(self) + } + + /** + NSCoding not supported. Use init(text, preferences, delegate) instead! + */ + + required public init?(coder aDecoder: NSCoder) { + fatalError("NSCoding not supported. Use init(text, preferences, delegate) instead!") + } + +// MARK: - Rotation Support - + @objc func handleRotation() { + guard let _ = superview, presentingView != nil else { return } + + // TODO: open this if you want to change accoring to orientation + // UIView.animate(withDuration: 0.3) { + // self.arrange(withinSuperview: sview) + // self.setNeedsDisplay() + // } + } + +// MARK: - Private Methods - + fileprivate func computeFrame(arrowPosition position: ArrowPosition, refViewFrame: CGRect, superviewFrame: CGRect) -> CGRect { + var xOrigin: CGFloat = 0 + var yOrigin: CGFloat = 0 + + switch position { + case .top, .any: + xOrigin = refViewFrame.center.x - tipViewSize.width / 2 + yOrigin = refViewFrame.minY + refViewFrame.height + case .bottom: + xOrigin = refViewFrame.center.x - tipViewSize.width / 2 + yOrigin = refViewFrame.minY - tipViewSize.height + case .right: + xOrigin = refViewFrame.minX - tipViewSize.width + yOrigin = refViewFrame.center.y - tipViewSize.height / 2 + case .left: + xOrigin = refViewFrame.minX + refViewFrame.width + yOrigin = refViewFrame.minY - tipViewSize.height / 2 + } + + var frame = CGRect(x: xOrigin, y: yOrigin, width: tipViewSize.width, height: tipViewSize.height) + adjustFrame(&frame, forSuperviewFrame: superviewFrame) + return frame + } + + fileprivate func adjustFrame(_ frame: inout CGRect, forSuperviewFrame superviewFrame: CGRect) { + + // adjust horizontally + if frame.x < 0 { + frame.x = 0 + } else if frame.maxX > superviewFrame.width { + frame.x = superviewFrame.width - frame.width + } + + // adjust vertically + if frame.y < 0 { + frame.y = 0 + } else if frame.maxY > superviewFrame.maxY { + frame.y = superviewFrame.height - frame.height + } + } + + fileprivate func isFrameValid(_ frame: CGRect, forRefViewFrame: CGRect, withinSuperviewFrame: CGRect) -> Bool { + return !frame.intersects(forRefViewFrame) + } + + fileprivate func arrange(withinSuperview superview: UIView) { + + var position = preferences.drawing.arrowPosition + + let refViewFrame = presentingView!.convert(presentingView!.bounds, to: superview); + + let superviewFrame: CGRect + if let scrollview = superview as? UIScrollView { + superviewFrame = CGRect(origin: scrollview.frame.origin, size: scrollview.contentSize) + } else { + superviewFrame = superview.frame + } + + var frame = computeFrame(arrowPosition: position, refViewFrame: refViewFrame, superviewFrame: superviewFrame) + + if !isFrameValid(frame, forRefViewFrame: refViewFrame, withinSuperviewFrame: superviewFrame) { + for value in ArrowPosition.allValues where value != position { + let newFrame = computeFrame(arrowPosition: value, refViewFrame: refViewFrame, superviewFrame: superviewFrame) + if isFrameValid(newFrame, forRefViewFrame: refViewFrame, withinSuperviewFrame: superviewFrame) { + + if position != .any { + print("[EasyTipView - Info] The arrow position you chose <\(position)> could not be applied. Instead, position <\(value)> has been applied! Please specify position <\(ArrowPosition.any)> if you want EasyTipView to choose a position for you.") + } + + frame = newFrame + position = value + preferences.drawing.arrowPosition = value + break + } + } + } + + var arrowTipXOrigin: CGFloat + + switch position { + case .bottom, .top, .any: + if frame.width < refViewFrame.width { + arrowTipXOrigin = tipViewSize.width / 2 + } else { + arrowTipXOrigin = abs(frame.minX - refViewFrame.x) + refViewFrame.width / 2 + } + + arrowTip = CGPoint(x: arrowTipXOrigin, y: position == .bottom ? tipViewSize.height - preferences.positioning.bubbleVInset : preferences.positioning.bubbleVInset) + case .right, .left: + if frame.height < refViewFrame.height { + arrowTipXOrigin = tipViewSize.height / 2 + } else { + arrowTipXOrigin = abs(frame.minY - refViewFrame.y) + refViewFrame.height / 2 + } + + arrowTip = CGPoint(x: preferences.drawing.arrowPosition == .left ? preferences.positioning.bubbleVInset : tipViewSize.width - preferences.positioning.bubbleVInset, y: arrowTipXOrigin) + } + + if case .view(let contentView) = content { + contentView.translatesAutoresizingMaskIntoConstraints = false + contentView.frame = getContentRect(from: getBubbleFrame()) + } + + self.frame = frame + } + +// MARK: - Callbacks - + @objc func handleTap() { + dismiss() + } + +// MARK: - Drawing - + fileprivate func drawBubble(_ bubbleFrame: CGRect, arrowPosition: ArrowPosition, context: CGContext) { + + let arrowWidth = preferences.drawing.arrowWidth + let arrowHeight = preferences.drawing.arrowHeight + let cornerRadius = preferences.drawing.cornerRadius + + let contourPath = CGMutablePath() + + contourPath.move(to: CGPoint(x: arrowTip.x, y: arrowTip.y)) + + switch arrowPosition { + case .bottom, .top, .any: + + contourPath.addLine(to: CGPoint(x: arrowTip.x - arrowWidth / 2, y: arrowTip.y + (arrowPosition == .bottom ? -1 : 1) * arrowHeight)) + + if arrowPosition == .bottom { + drawBubbleBottomShape(bubbleFrame, cornerRadius: cornerRadius, path: contourPath) + } else { + drawBubbleTopShape(bubbleFrame, cornerRadius: cornerRadius, path: contourPath) + } + + contourPath.addLine(to: CGPoint(x: arrowTip.x + arrowWidth / 2, y: arrowTip.y + (arrowPosition == .bottom ? -1 : 1) * arrowHeight)) + + case .right, .left: + + contourPath.addLine(to: CGPoint(x: arrowTip.x + (arrowPosition == .right ? -1 : 1) * arrowHeight, y: arrowTip.y - arrowWidth / 2)) + + if arrowPosition == .right { + drawBubbleRightShape(bubbleFrame, cornerRadius: cornerRadius, path: contourPath) + } else { + drawBubbleLeftShape(bubbleFrame, cornerRadius: cornerRadius, path: contourPath) + } + + contourPath.addLine(to: CGPoint(x: arrowTip.x + (arrowPosition == .right ? -1 : 1) * arrowHeight, y: arrowTip.y + arrowWidth / 2)) + } + + contourPath.closeSubpath() + context.addPath(contourPath) + context.clip() + + paintBubble(context) + + if preferences.hasBorder { + drawBorder(contourPath, context: context) + } + } + + fileprivate func drawBubbleBottomShape(_ frame: CGRect, cornerRadius: CGFloat, path: CGMutablePath) { + + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x, y: frame.y), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x, y: frame.y + frame.height), radius: cornerRadius) + } + + fileprivate func drawBubbleTopShape(_ frame: CGRect, cornerRadius: CGFloat, path: CGMutablePath) { + + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY), tangent2End: CGPoint(x: frame.x, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY), tangent2End: CGPoint(x: frame.x, y: frame.y), radius: cornerRadius) + } + + fileprivate func drawBubbleRightShape(_ frame: CGRect, cornerRadius: CGFloat, path: CGMutablePath) { + + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY), tangent2End: CGPoint(x: frame.x, y: frame.y), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY), tangent2End: CGPoint(x: frame.x, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.height), radius: cornerRadius) + + } + + fileprivate func drawBubbleLeftShape(_ frame: CGRect, cornerRadius: CGFloat, path: CGMutablePath) { + + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY), tangent2End: CGPoint(x: frame.x + frame.width, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX + frame.width, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x, y: frame.y + frame.height), radius: cornerRadius) + path.addArc(tangent1End: CGPoint(x: frame.minX, y: frame.minY + frame.height), tangent2End: CGPoint(x: frame.x, y: frame.y), radius: cornerRadius) + } + + fileprivate func paintBubble(_ context: CGContext) { + context.setFillColor(preferences.drawing.backgroundColor.cgColor) + context.fill(bounds) + } + + fileprivate func drawBorder(_ borderPath: CGPath, context: CGContext) { + context.addPath(borderPath) + context.setStrokeColor(preferences.drawing.borderColor.cgColor) + context.setLineWidth(preferences.drawing.borderWidth) + context.strokePath() + } + + fileprivate func drawText(_ bubbleFrame: CGRect, context : CGContext) { + guard case .text(let text) = content else { return } + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.alignment = preferences.drawing.textAlignment + paragraphStyle.lineBreakMode = NSLineBreakMode.byWordWrapping + + let textRect = getContentRect(from: bubbleFrame) + +#if swift(>=4.2) + let attributes = [NSAttributedString.Key.font : preferences.drawing.font, NSAttributedString.Key.foregroundColor : preferences.drawing.foregroundColor, NSAttributedString.Key.paragraphStyle : paragraphStyle] +#else + let attributes = [NSAttributedStringKey.font : preferences.drawing.font, NSAttributedStringKey.foregroundColor : preferences.drawing.foregroundColor, NSAttributedStringKey.paragraphStyle : paragraphStyle] +#endif + + text.draw(in: textRect, withAttributes: attributes) + } + + fileprivate func drawShadow() { + if preferences.hasShadow { + self.layer.masksToBounds = false + self.layer.shadowColor = preferences.drawing.shadowColor.cgColor + self.layer.shadowOffset = preferences.drawing.shadowOffset + self.layer.shadowRadius = preferences.drawing.shadowRadius + self.layer.shadowOpacity = Float(preferences.drawing.shadowOpacity) + } + } + + override open func draw(_ rect: CGRect) { + + let bubbleFrame = getBubbleFrame() + + let context = UIGraphicsGetCurrentContext()! + context.saveGState () + + drawBubble(bubbleFrame, arrowPosition: preferences.drawing.arrowPosition, context: context) + + switch content { + case .text: + drawText(bubbleFrame, context: context) + case .view (let view): + addSubview(view) + view.translatesAutoresizingMaskIntoConstraints = false + view.topAnchor.constraint(equalTo: topAnchor).isActive = true + view.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + view.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + view.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + } + + drawShadow() + context.restoreGState() + } + + private func getBubbleFrame() -> CGRect { + let arrowPosition = preferences.drawing.arrowPosition + let bubbleWidth: CGFloat + let bubbleHeight: CGFloat + let bubbleXOrigin: CGFloat + let bubbleYOrigin: CGFloat + switch arrowPosition { + case .bottom, .top, .any: + + bubbleWidth = tipViewSize.width - 2 * preferences.positioning.bubbleHInset + bubbleHeight = tipViewSize.height - 2 * preferences.positioning.bubbleVInset - preferences.drawing.arrowHeight + + bubbleXOrigin = preferences.positioning.bubbleHInset + bubbleYOrigin = arrowPosition == .bottom ? preferences.positioning.bubbleVInset : preferences.positioning.bubbleVInset + preferences.drawing.arrowHeight + + case .left, .right: + + bubbleWidth = tipViewSize.width - 2 * preferences.positioning.bubbleHInset - preferences.drawing.arrowHeight + bubbleHeight = tipViewSize.height - 2 * preferences.positioning.bubbleVInset + + bubbleXOrigin = arrowPosition == .right ? preferences.positioning.bubbleHInset : preferences.positioning.bubbleHInset + preferences.drawing.arrowHeight + bubbleYOrigin = preferences.positioning.bubbleVInset + + } + return CGRect(x: bubbleXOrigin, y: bubbleYOrigin, width: bubbleWidth, height: bubbleHeight) + } + + private func getContentRect(from bubbleFrame: CGRect) -> CGRect { + return CGRect(x: bubbleFrame.origin.x + (bubbleFrame.size.width - contentSize.width) / 2, y: bubbleFrame.origin.y + (bubbleFrame.size.height - contentSize.height) / 2, width: contentSize.width, height: contentSize.height) + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupModel.swift b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupModel.swift new file mode 100644 index 0000000..2fb28f5 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupModel.swift @@ -0,0 +1,57 @@ +// +// GKTooltipPopupModel.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 20.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public struct GKTooltipPopupModel { + var currentPage: Int + var numberOfCount: Int + + // text+icon + var tooltipText: String + var isIconViewHidden: Bool = false + + // buttons + var leftButtonText: String + var leftButtonType: ButtonType + var leftButtonTintColor: UIColor + var isLeftButtonHidden: Bool = false + + var rightButtonText: String + var rightButtonType: ButtonType + var rightButtonTintColor: UIColor + var isRightButtonHidden: Bool = false + + init( + tooltipText: String, + currentPage: Int, + numberOfCount: Int, + leftButtonText: String, + rightButtonText: String, + leftButtonType: ButtonType, + rightButtonType: ButtonType, + leftButtonTintColor: UIColor, + rightButtonTintColor: UIColor) { + self.tooltipText = tooltipText + self.currentPage = currentPage + self.numberOfCount = numberOfCount + self.leftButtonText = leftButtonText + self.leftButtonType = leftButtonType + self.leftButtonTintColor = leftButtonTintColor + self.rightButtonText = rightButtonText + self.rightButtonType = rightButtonType + self.rightButtonTintColor = rightButtonTintColor + } + + public enum ButtonType { + case skip + case again + case next + case close + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupView.swift b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupView.swift new file mode 100644 index 0000000..a9671d5 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupView.swift @@ -0,0 +1,259 @@ +// +// GKTooltipPopupView.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +protocol GKTooltipPopupDelegate { + func buttonTapped(buttonType: GKTooltipPopupModel.ButtonType) + func closeTapped() + func didTapLink(index: Int) +} + +class GKTooltipPopupView: UIView { + private let containerView: UIView = UIView() + private let iconView = UIImageView() + private var labelTooltipText: UILabel = UILabel() + + private var buttonStackView = UIStackView() + private let leftButton: UIButton = UIButton() + private let rightButton: UIButton = UIButton() + + // setting popup-view height + var bottomConstant: CGFloat { + if buttonStackView.isHidden { + return 8 + bubleV + } else { + return 64 + bubleV + } + } + + private var topConstraint = NSLayoutConstraint() + private var bottomConstraint = NSLayoutConstraint() + private var bottomStackViewHeightConstraint = NSLayoutConstraint() + private var tooltipBottomLabelConstraint = NSLayoutConstraint() + private var tooltipLabelTrailingConstraint = NSLayoutConstraint() + private var tooltipLabelTopConstraint = NSLayoutConstraint() + private var tooltipLabelLeadingConstraint = NSLayoutConstraint() + + var delegate: GKTooltipPopupDelegate? + var dataSource: GKTooltipPopupModel? { + didSet { + if let dataSource = dataSource { + setupUI(with: dataSource) + } + } + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: frame) + draw() + configureUI() + configureButtons() + } +} + +// MARK: - Private Methods - +extension GKTooltipPopupView { + private func configureUI(){ + iconView.image = .icInfo + iconView.tintColor = .pureBlack + + labelTooltipText.font = .footnote01Medium + labelTooltipText.textColor = .pureBlack + labelTooltipText.textAlignment = .left + labelTooltipText.numberOfLines = 0 + + leftButton.titleLabel?.font = UIFont.systemFont(ofSize: 12.0, weight: .regular) + leftButton.setTitleColor(UIColor.blue, for: .normal) + leftButton.contentHorizontalAlignment = .left + leftButton.titleLabel?.adjustsFontSizeToFitWidth = true + leftButton.titleLabel?.minimumScaleFactor = 0.5 + + rightButton.titleLabel?.font = UIFont.systemFont(ofSize: 12.0, weight: .bold) + rightButton.setTitleColor(UIColor.blue, for: .normal) + rightButton.contentHorizontalAlignment = .right + rightButton.titleLabel?.adjustsFontSizeToFitWidth = true + rightButton.titleLabel?.minimumScaleFactor = 0.5 + } + + private func configureButtons() { + self.leftButton.addTarget(self, action: #selector(leftButtonAction(sender:)), for: .touchUpInside) + self.rightButton.addTarget(self, action: #selector(rightButtonAction(sender:)), for: .touchUpInside) + } + + private func setupUI(with dataSource: GKTooltipPopupModel) { + self.iconView.isHidden = dataSource.isIconViewHidden + self.labelTooltipText.text = dataSource.tooltipText + self.leftButton.setTitle(dataSource.leftButtonText, for: .normal) + self.rightButton.setTitle(dataSource.rightButtonText, for: .normal) + self.leftButton.isHidden = dataSource.isLeftButtonHidden + self.rightButton.isHidden = dataSource.isRightButtonHidden + + // hide-show left-right buttons + if dataSource.isLeftButtonHidden && dataSource.isRightButtonHidden { + buttonStackView.isHidden = true + bottomStackViewHeightConstraint.constant = 20 + + } else { + buttonStackView.isHidden = false + bottomStackViewHeightConstraint.constant = stackViewHeight + } + + // hide-show icon + if dataSource.isIconViewHidden { + NSLayoutConstraint.deactivate([tooltipLabelLeadingConstraint]) + tooltipLabelLeadingConstraint = labelTooltipText.leadingAnchor.constraint(equalTo: containerView.leadingAnchor) + tooltipLabelLeadingConstraint.isActive = true + } else { + NSLayoutConstraint.deactivate([tooltipLabelLeadingConstraint]) + tooltipLabelLeadingConstraint = labelTooltipText.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 16) + tooltipLabelLeadingConstraint.isActive = true + } + } + + private func updateConstraint(bottomPadding: CGFloat, topPadding: CGFloat) { + self.bottomConstraint.constant = bottomPadding + self.topConstraint.constant = topPadding + } +} + +// MARK: - Public Methods - +extension GKTooltipPopupView { + public func getRect() -> CGRect { + let tooltipLabelSize: CGSize = labelTooltipText.sizeThatFits(self.maximumSize) + let totalHeight = topConstant + (tooltipLabelSize.height) + bottomConstant + + return CGRect(x: 0, y: 0, width: self.maximumWidth, height: totalHeight) + } + + public func configure(with model: GKTooltipPopupModel) { + self.dataSource = model + + setButtonTintColors(leftButtonTintColor: model.leftButtonTintColor, + rightButtonTintColor: model.rightButtonTintColor) + } + + public func updatePadding(by arrowPosition: EasyTipView.ArrowPosition) { + var bottomPadding = self.bottomConstant + var topPadding = self.topConstant + switch arrowPosition { + case .bottom: + bottomPadding = self.bottomConstant + self.arrowHeight + topPadding = self.topConstant - self.arrowHeight + case .top, .any: + bottomPadding = self.bottomConstant + topPadding = self.topConstant + default: break + } + updateConstraint(bottomPadding: -bottomPadding, topPadding: topPadding) + } + + func showIconView() { + iconView.isHidden = false + } + + func hideIconView() { + iconView.isHidden = true + } + + func setButtonTintColors(leftButtonTintColor: UIColor, rightButtonTintColor: UIColor) { + leftButton.setTitleColor(leftButtonTintColor, for: .normal) + rightButton.setTitleColor(rightButtonTintColor, for: .normal) + } +} + +// MARK: - Drawing - +extension GKTooltipPopupView: GKTooltipPopupViewConstant { + func draw() { + topBottomConstraints() + buttonStack() + leftIcon() + tooltipText() + } + + func topBottomConstraints() { + addSubview(containerView) + containerView.translatesAutoresizingMaskIntoConstraints = false + topConstraint = containerView.topAnchor.constraint(equalTo: topAnchor, constant: self.topConstant) + topConstraint.isActive = true + + bottomConstraint = containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: self.bottomConstant) + bottomConstraint.isActive = true + containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: self.leadingConstant).isActive = true + containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -self.trailingConstant).isActive = true + } + + func buttonStack() { + addSubview(buttonStackView) + buttonStackView.translatesAutoresizingMaskIntoConstraints = false + buttonStackView.distribution = .fillProportionally + buttonStackView.axis = .horizontal + buttonStackView.topAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 8).isActive = true + buttonStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true + buttonStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true + + buttonStackView.addArrangedSubview(leftButton) + buttonStackView.addArrangedSubview(rightButton) + leftButton.setContentHuggingPriority(.required, for: .horizontal) + rightButton.setContentHuggingPriority(.required, for: .horizontal) + + bottomStackViewHeightConstraint = buttonStackView.heightAnchor.constraint(equalToConstant: stackViewHeight) + bottomStackViewHeightConstraint.isActive = true + } + + func leftIcon() { + containerView.addSubview(iconView) + iconView.translatesAutoresizingMaskIntoConstraints = false + iconView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16).isActive = true + iconView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true + iconView.widthAnchor.constraint(equalToConstant: 16).isActive = true + iconView.heightAnchor.constraint(equalToConstant: 16).isActive = true + } + + func tooltipText() { + containerView.addSubview(labelTooltipText) + labelTooltipText.translatesAutoresizingMaskIntoConstraints = false + tooltipLabelTopConstraint = labelTooltipText.topAnchor.constraint(equalTo: containerView.topAnchor) + tooltipLabelTopConstraint.isActive = true + + labelTooltipText.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 16).isActive = true + labelTooltipText.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true + tooltipLabelTrailingConstraint = labelTooltipText.trailingAnchor.constraint(equalTo: containerView.trailingAnchor) + tooltipLabelTrailingConstraint.isActive = true + + tooltipBottomLabelConstraint = labelTooltipText.bottomAnchor.constraint(equalTo: buttonStackView.topAnchor, constant: -buttonSpacing) + tooltipBottomLabelConstraint.isActive = true + + labelTooltipText.setContentHuggingPriority(.required, for: .vertical) + labelTooltipText.setContentCompressionResistancePriority(.required, for: .vertical) + } +} + +// MARK: - Actions - +extension GKTooltipPopupView { + + @objc func leftButtonAction(sender: UIButton) { + if let source = dataSource { + delegate?.buttonTapped(buttonType: source.leftButtonType) + } + } + + @objc func rightButtonAction(sender: UIButton) { + if let source = dataSource { + delegate?.buttonTapped(buttonType: source.rightButtonType) + } + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupViewConstant.swift b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupViewConstant.swift new file mode 100644 index 0000000..1efbd5d --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipPopup/GKTooltipPopupViewConstant.swift @@ -0,0 +1,65 @@ +// +// GKTooltipPopupViewConstant.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +protocol GKTooltipPopupViewConstant {} + +extension GKTooltipPopupViewConstant { + var topConstant: CGFloat { + 16 + bubleV + } + + var bottomConstant: CGFloat { + 8 + bubleV + } + + var leadingConstant: CGFloat { + 10 + bubleH + } + + var trailingConstant: CGFloat { + 10 + bubleH + } + + var bubleH: CGFloat { + 8 + } + + var bubleV: CGFloat { + 10 + } + + var arrowHeight: CGFloat { + 10 + } + + var labelWidth: CGFloat { + maximumWidth - (leadingConstant - bubleV) - (trailingConstant - bubleV) + } + + var maximumWidth: CGFloat { + return 310 + } + + var maximumHeight: CGFloat { + return 675 + } + + var maximumSize: CGSize { + CGSize(width: labelWidth, height: maximumHeight) + } + + var buttonSpacing: CGFloat { + 6 + } + + var stackViewHeight: CGFloat { + 30.0 + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltip.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltip.swift new file mode 100644 index 0000000..f47850c --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltip.swift @@ -0,0 +1,75 @@ +// +// GKTooltip.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import Foundation +import UIKit + +public protocol GKTooltipDelegate: AnyObject { + func didAdvance(to node: Int, of total: Int) + func didDismiss() + func skipButtonTapped(to node: Int) + func nextButtonTapped(to node: Int) + func closeButtonTapped(to node: Int) +} + +public protocol PopupDelegate: AnyObject { + func didTapLink(index: Int) +} + +public final class GKTooltip { + public static var delay: TimeInterval = 5.0 + public static var animationDuration: TimeInterval = 0.3 + public static var popupAnimationDuration: TimeInterval = 0.8 + public static var alpha: CGFloat = 0.7 + public static var backgroundColor: UIColor = .pureBlack + + public weak var delegate: GKTooltipDelegate? + public weak var popupDelegate: PopupDelegate? + + public init() {} + + public func startIntro(from controller: UIViewController, + with scrollView: UIScrollView? = nil, + withNodes nodes: [GKTooltipNode], + isHighlightedWithOneNode: Bool = false) { + guard !nodes.isEmpty else { return } + gkTooltipVC.dataSource = GKTooltipDataSource(nodes, isHighlightedWithOneNode: isHighlightedWithOneNode) + gkTooltipVC.delegate = delegate + gkTooltipVC.popupDelegate = popupDelegate + gkTooltipVC.scrollView = scrollView + if controller == UIApplication.topViewController() { + print("Presenting gkTooltipVC") + controller.present(gkTooltipVC, + animated: true, + completion: nil) + } else { + print("controller is not top view controller") + } + print("startIntro method called with nodes: \(nodes)") + } + + public func startIntro(childFrom childViewController: UIViewController, + with scrollView: UIScrollView? = nil, + withNodes nodes: [GKTooltipNode], + isHighlightedWithOneNode: Bool = false) { + guard !nodes.isEmpty else { return } + gkTooltipVC.dataSource = GKTooltipDataSource(nodes, isHighlightedWithOneNode: isHighlightedWithOneNode) + gkTooltipVC.delegate = delegate + gkTooltipVC.popupDelegate = popupDelegate + gkTooltipVC.scrollView = scrollView + childViewController.present(gkTooltipVC, + animated: true, + completion: nil) + } + + public func dismissGKTooltip() { + gkTooltipVC.dismissGKTooltip() + } + + private let gkTooltipVC = GKTooltipViewController() +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipDataSource.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipDataSource.swift new file mode 100644 index 0000000..046cfdb --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipDataSource.swift @@ -0,0 +1,39 @@ +// +// GKTooltipDataSource.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +struct GKTooltipDataSource { + var gkTooltipNodes: [GKTooltipNode] = [] + var gkTooltipPopupModels: [GKTooltipPopupModel] = [] + var isHighlightedWithOneNode: Bool = false + + init(_ nodes: [GKTooltipNode], isHighlightedWithOneNode: Bool = false) { + gkTooltipNodes = nodes + fillGKTooltipPopupModels() + self.isHighlightedWithOneNode = isHighlightedWithOneNode + } + + init() {} + + private mutating func fillGKTooltipPopupModels() { + for (index, node) in gkTooltipNodes.enumerated() { + var model = GKTooltipPopupModel(tooltipText: node.text, + currentPage: index, + numberOfCount: gkTooltipNodes.count, + leftButtonText: node.leftButtonText, + rightButtonText: node.rightButtonText, + leftButtonType: node.leftButtonType, + rightButtonType: node.rightButtonType, + leftButtonTintColor: node.leftButtonTintColor, + rightButtonTintColor: node.rightButtonTintColor) + model.isLeftButtonHidden = node.isLeftButtonHidden + model.isRightButtonHidden = node.isRightButtonHidden + model.isIconViewHidden = node.isIconViewHidden + gkTooltipPopupModels.append(model) + } + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipNode.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipNode.swift new file mode 100644 index 0000000..76a2e62 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipNode.swift @@ -0,0 +1,53 @@ +// +// GKTooltipNode.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 20.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public struct GKTooltipNode { + var text: String + var target: GKTooltipTarget + var roundedCorners: Bool + var isLeftButtonHidden: Bool = false + var isRightButtonHidden: Bool = false + var isIconViewHidden: Bool = false + + var leftButtonText: String + var leftButtonType: GKTooltipPopupModel.ButtonType + var leftButtonTintColor: UIColor + var rightButtonText: String + var rightButtonType: GKTooltipPopupModel.ButtonType + var rightButtonTintColor: UIColor + + public init( + text: String, + target: GKTooltipTarget, + roundedCorners: Bool = true, + isLeftButtonHidden: Bool = true, + isRightButtonHidden: Bool = true, + isIconViewHidden: Bool = true, + leftButtonText: String, + leftButtonType: GKTooltipPopupModel.ButtonType, + leftButtonTintColor: UIColor, + rightButtonText: String, + rightButtonType: GKTooltipPopupModel.ButtonType, + rightButtonTintColor: UIColor) + { + self.text = text + self.target = target + self.roundedCorners = roundedCorners + self.isLeftButtonHidden = isLeftButtonHidden + self.isRightButtonHidden = isRightButtonHidden + self.isIconViewHidden = isIconViewHidden + self.leftButtonText = leftButtonText + self.leftButtonType = leftButtonType + self.leftButtonTintColor = leftButtonTintColor + self.rightButtonText = rightButtonText + self.rightButtonType = rightButtonType + self.rightButtonTintColor = rightButtonTintColor + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipTarget.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipTarget.swift new file mode 100644 index 0000000..fa3132c --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipTarget.swift @@ -0,0 +1,67 @@ +// +// GKTooltipTarget.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import Foundation +import UIKit + +public enum GKTooltipTarget { + case view(UIView) + case barButton(UIBarButtonItem) + case tabBarItem(UITabBarController, Int) + case point(CGPoint, radius: CGFloat) + case rect(CGRect) + + var targetView: UIView { + let target: UIView + switch self { + case let .view(view): + target = view + case let .barButton(barButtonItem): + let view = (barButtonItem.value(forKey: "view") as? UIView) ?? UIView() + target = view.subviews.first ?? view + case let .tabBarItem(tabBarController, index): + let tabBarItems = tabBarController.tabBar.subviews.filter { $0.isUserInteractionEnabled } + guard index > -1, tabBarItems.count > index else { return UIView() } + let tabBarItemView = tabBarItems[index] + let frame = CGRect(x: tabBarItemView.frame.midX - 22, y: tabBarController.tabBar.frame.origin.y, width: 44, height: 44) + target = UIView(frame: frame) + case let .point(center, radius): + target = UIView(frame: CGRect(x: 0, y: 0, width: radius * 2, height: radius * 2)) + target.center = center + case let .rect(frame): + target = UIView(frame: frame) + } + return target + } + + func path(node: GKTooltipNode, translater: UIView) -> UIBezierPath { + let translatedFrame = targetView.convert(targetView.bounds, to: translater) + + // Add some breathing space for the tooltip + let gkTooltipFrame = translatedFrame.insetBy(dx: -6.0, dy: -6.0) + + if node.roundedCorners { + return UIBezierPath(roundedRect: gkTooltipFrame, + cornerRadius: gkTooltipFrame.height / 2.0) + } else { + return UIBezierPath(roundedRect: gkTooltipFrame, + cornerRadius: 2) + } + } + + func infinitesmalPath(node: GKTooltipNode, translater: UIView) -> UIBezierPath { + let gkTooltipFrame = targetView.convert(targetView.bounds, to: translater) + let gkTooltipCenter = CGPoint(x: gkTooltipFrame.midX, y: gkTooltipFrame.midY) + + if node.roundedCorners { + return UIBezierPath(roundedRect: CGRect(origin: gkTooltipCenter, size: CGSize.zero), cornerRadius: 0) + } else { + return UIBezierPath(rect: CGRect(origin: gkTooltipCenter, size: CGSize.zero)) + } + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipView.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipView.swift new file mode 100644 index 0000000..f79eed2 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipView.swift @@ -0,0 +1,151 @@ +// +// GKTooltipView.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +final class GKTooltipView: UIView { + public override init(frame: CGRect) { + super.init(frame: frame) + commonInit() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + commonInit() + } + + fileprivate func commonInit() { + layer.mask = maskLayer + layer.addSublayer(borderLayer) + } + + override func layoutSubviews() { + super.layoutSubviews() + maskLayer.frame = frame + } + + func appear(_ node: GKTooltipNode, duration: TimeInterval = GKTooltip.animationDuration) -> CGRect { + maskLayer.add(appearAnimation(duration, node: node, isMaskPath: true), forKey: nil) + borderLayer.add(appearAnimation(duration, node: node, isMaskPath: false), forKey: nil) + return node.target.targetView.frame + } + + func disappear(_ node: GKTooltipNode, duration: TimeInterval = GKTooltip.animationDuration) -> CGRect { + maskLayer.add(disappearAnimation(duration, node: node, isMaskPath: true), forKey: nil) + borderLayer.add(disappearAnimation(duration, node: node, isMaskPath: false), forKey: nil) + return node.target.targetView.frame + } + + func move(_ toNode: GKTooltipNode, duration: TimeInterval = GKTooltip.animationDuration, moveType: GKTooltipMoveType = .direct) -> CGRect { + switch moveType { + case .direct: + moveDirect(toNode, duration: duration) + case .disappear: + moveDisappear(toNode, duration: duration) + } + return toNode.target.targetView.frame + } + + fileprivate lazy var maskLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.fillRule = CAShapeLayerFillRule.evenOdd + layer.fillColor = UIColor.black.cgColor + return layer + }() + + fileprivate lazy var borderLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.fillRule = CAShapeLayerFillRule.nonZero + layer.fillColor = UIColor.clear.cgColor + layer.strokeColor = UIColor.lightGray.cgColor + layer.lineWidth = 3.0 + + return layer + }() +} + +private extension GKTooltipView { + func moveDirect(_ toNode: GKTooltipNode, duration: TimeInterval = GKTooltip.animationDuration) { + maskLayer.add(moveAnimation(duration, toNode: toNode, isMaskPath: true), forKey: nil) + borderLayer.add(moveAnimation(duration, toNode: toNode, isMaskPath: false), forKey: nil) + } + + func moveDisappear(_ toNode: GKTooltipNode, duration: TimeInterval = GKTooltip.animationDuration) { + CATransaction.begin() + CATransaction.setCompletionBlock { + _ = self.appear(toNode, duration: duration) + } + _ = disappear(toNode) + CATransaction.commit() + } + + func maskPath(_ path: UIBezierPath) -> UIBezierPath { + return [path].reduce(UIBezierPath(rect: frame)) { + $0.append($1) + return $0 + } + } + + func pathRect(_ path: UIBezierPath) -> CGRect { + return path.bounds + } + + func appearAnimation(_ duration: TimeInterval, node: GKTooltipNode, isMaskPath: Bool) -> CAAnimation { + if isMaskPath { + let beginPath = maskPath(node.target.infinitesmalPath(node: node, translater: self)) + let endPath = maskPath(node.target.path(node: node, translater: self)) + return pathAnimation(duration, beginPath: beginPath, endPath: endPath) + } + else { + let beginPath = node.target.infinitesmalPath(node: node, translater: self) + let endPath = node.target.path(node: node, translater: self) + return pathAnimation(duration, beginPath: beginPath, endPath: endPath) + } + } + + func disappearAnimation(_ duration: TimeInterval, node: GKTooltipNode, isMaskPath: Bool) -> CAAnimation { + if isMaskPath { + let endPath = maskPath(node.target.infinitesmalPath(node: node, translater: self)) + return pathAnimation(duration, beginPath: nil, endPath: endPath) + } + else { + let endPath = node.target.infinitesmalPath(node: node, translater: self) + return pathAnimation(duration, beginPath: nil, endPath: endPath) + } + } + + func moveAnimation(_ duration: TimeInterval, toNode: GKTooltipNode, isMaskPath: Bool) -> CAAnimation { + if isMaskPath { + let endPath = maskPath(toNode.target.path(node: toNode, translater: self)) + return pathAnimation(duration, beginPath: nil, endPath: endPath) + } + else { + let endPath = toNode.target.path(node: toNode, translater: self) + return pathAnimation(duration, beginPath: nil, endPath: endPath) + } + } + + func pathAnimation(_ duration: TimeInterval, beginPath: UIBezierPath?, endPath: UIBezierPath) -> CAAnimation { + let animation = CABasicAnimation(keyPath: "path") + animation.duration = duration + animation.timingFunction = CAMediaTimingFunction(controlPoints: 0.66, 0, 0.33, 1) + + if let path = beginPath { + animation.fromValue = path.cgPath + } + animation.toValue = endPath.cgPath + animation.isRemovedOnCompletion = false + animation.fillMode = .forwards + return animation + } +} + +enum GKTooltipMoveType { + case direct + case disappear +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController+UISetup.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController+UISetup.swift new file mode 100644 index 0000000..f1c18e3 --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController+UISetup.swift @@ -0,0 +1,94 @@ +// +// GKTooltipViewController+UISetup.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import Foundation +import UIKit + +// MARK: - Public Methods - +extension GKTooltipViewController { + func setup() { + modalPresentationStyle = .overFullScreen + } + + func setupGKTooltipView() { + gkTooltipView.frame = UIScreen.main.bounds + gkTooltipView.backgroundColor = GKTooltip.backgroundColor.withAlphaComponent(GKTooltip.alpha) + gkTooltipView.isUserInteractionEnabled = false + gkTooltipPopup.delegate = self + guard let view = view else { return } + view.insertSubview(gkTooltipView, at: 0) + view.addConstraints([NSLayoutConstraint.Attribute.top, .bottom, .left, .right].map { + NSLayoutConstraint(item: view, + attribute: $0, + relatedBy: .equal, + toItem: gkTooltipView, + attribute: $0, + multiplier: 1, + constant: 0) + }) + } + + func showTip(gkTooltipTarget: GKTooltipTarget) { + clearTip() + showTip(with: gkTooltipTarget.targetView) + } + + func clearTip() { + if let tipView = self.tipView { + tipView.dismiss(withCompletion: {}) + } + } + + func setupTapGestureRecognizer() { + let gesture = UITapGestureRecognizer(target: self, action: #selector(GKTooltipViewController.viewTapped(_:))) + view.addGestureRecognizer(gesture) + } + + // MARK: - Private Methods - + private func showTip(with view: UIView) { + gkTooltipPopup.configure(with: dataSource.gkTooltipPopupModels[currentNodeIndex]) + gkTooltipPopup.frame = gkTooltipPopup.getRect() + let preferences = getTipPrefences(bubbleHInset: gkTooltipPopup.bubleH, bubleVInset: gkTooltipPopup.bubleV) + let tipView = EasyTipView(contentView: gkTooltipPopup, preferences: preferences, delegate: nil) + tipView.show(forView: view) + self.tipView = tipView + + // change frame according to arrow + gkTooltipPopup.updatePadding(by: (self.tipView?.preferences.drawing.arrowPosition)!) + } + + private func showTip(with barItem: UIBarItem) { + gkTooltipPopup.configure(with: dataSource.gkTooltipPopupModels[currentNodeIndex]) + gkTooltipPopup.frame = gkTooltipPopup.getRect() + let preferences = getTipPrefences(bubbleHInset: gkTooltipPopup.bubleH, bubleVInset: gkTooltipPopup.bubleV) + let tipView = EasyTipView(contentView: gkTooltipPopup, preferences: preferences, delegate: nil) + tipView.show(forItem: barItem) + self.tipView = tipView + + // change padding according to arrow + gkTooltipPopup.updatePadding(by: (self.tipView?.preferences.drawing.arrowPosition)!) + } + + private func getTipPrefences(bubbleHInset: CGFloat, bubleVInset: CGFloat) -> EasyTipView.Preferences { + var preferences = EasyTipView.globalPreferences + preferences.drawing.backgroundColor = .pureWhite + preferences.drawing.cornerRadius = 10 + preferences.drawing.shadowColor = .pureBlack + preferences.drawing.shadowRadius = 14 + preferences.drawing.shadowOpacity = 0.65 + + preferences.animating.showInitialAlpha = 0 + preferences.animating.showDuration = GKTooltip.popupAnimationDuration + preferences.animating.dismissDuration = GKTooltip.popupAnimationDuration + + preferences.positioning.bubbleHInset = bubbleHInset + preferences.positioning.bubbleVInset = 32 + + return preferences + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController.swift b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController.swift new file mode 100644 index 0000000..88bdf3a --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/GKTooltipViewController.swift @@ -0,0 +1,175 @@ +// +// GKTooltipViewController.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import Foundation +import UIKit + +final class GKTooltipViewController: UIViewController { + var dataSource: GKTooltipDataSource = GKTooltipDataSource() + var scrollView: UIScrollView? + weak var delegate: GKTooltipDelegate? + weak var popupDelegate: PopupDelegate? + weak var tipView: EasyTipView? + var gkTooltipPopup = GKTooltipPopupView(frame: .zero) + let gkTooltipView = GKTooltipView() + var currentNodeIndex: Int = -1 + fileprivate var timer = Timer() + + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + override func viewDidLoad() { + super.viewDidLoad() + setupGKTooltipView() + setupTapGestureRecognizer() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + nextGKTooltip() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + gkTooltipView.isHidden = true + timer.invalidate() + } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + // Re-draw tooltip for the new dimension + gkTooltipView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) + showGKTooltip() + } +} + +// MARK: - Actions - +extension GKTooltipViewController: GKTooltipPopupDelegate { + func didTapLink(index: Int) { + popupDelegate?.didTapLink(index: index) + } + + func closeTapped() { + dismissGKTooltip() + } + + func buttonTapped(buttonType: GKTooltipPopupModel.ButtonType) { + timer.invalidate() + switch buttonType { + case .again: + currentNodeIndex = -1 + nextGKTooltip() + case .close: + delegate?.closeButtonTapped(to: currentNodeIndex) + dismissGKTooltip() + case .next: + delegate?.nextButtonTapped(to: currentNodeIndex) + nextGKTooltip() + case .skip: + delegate?.skipButtonTapped(to: currentNodeIndex) + dismissGKTooltip() + } + } + + @objc func viewTapped(_: UITapGestureRecognizer) { + timer.invalidate() + nextGKTooltip() + } + + @objc func nextGKTooltip() { + if currentNodeIndex == dataSource.gkTooltipNodes.count - 1 { + dismissGKTooltip() + return + } + currentNodeIndex += 1 + showGKTooltip() + } + + func previousGKTooltip() { + if currentNodeIndex == 0 { + dismissGKTooltip() + return + } + currentNodeIndex -= 1 + showGKTooltip() + } + + func showGKTooltip() { + let node = dataSource.gkTooltipNodes[currentNodeIndex] + let isEnableAutomaticScroll = ifNeedAutomaticScroll(with: node.target) + + if let targetView = isEnableAutomaticScroll.targetView, isEnableAutomaticScroll.ifNeed { + _ = self.gkTooltipView.disappear(node) + self.clearTip() + scrollView?.scrollTo(item: targetView, with: { + self.gkTooltipMoving(with: node, with: true, isHighlightedWithOneNode: self.dataSource.isHighlightedWithOneNode) + }) + } else { + gkTooltipMoving(with: node, with: false, isHighlightedWithOneNode: dataSource.isHighlightedWithOneNode) + } + + let newNodeIndex = currentNodeIndex + 1 + delegate?.didAdvance(to: newNodeIndex, of: dataSource.gkTooltipNodes.count) + } + + func gkTooltipMoving(with node: GKTooltipNode, with isScrolling: Bool, isHighlightedWithOneNode: Bool = false) { + if self.dataSource.gkTooltipNodes.count == 1 { + if !isHighlightedWithOneNode { + self.view.backgroundColor = GKTooltip.backgroundColor.withAlphaComponent(0.5) + } + switch self.currentNodeIndex { + case 0: + if isHighlightedWithOneNode { + _ = self.gkTooltipView.appear(node) + } + self.showTip(gkTooltipTarget: node.target) + case let index where index == self.dataSource.gkTooltipNodes.count: + self.clearTip() + default: + self.showTip(gkTooltipTarget: node.target) + } + } else { + switch self.currentNodeIndex { + case 0: + _ = self.gkTooltipView.appear(node) + self.showTip(gkTooltipTarget: node.target) + case let index where index == self.dataSource.gkTooltipNodes.count: + _ = self.gkTooltipView.disappear(node) + self.clearTip() + default: + if isScrolling { + _ = self.gkTooltipView.appear(node) + } else { + _ = self.gkTooltipView.move(node) + } + self.showTip(gkTooltipTarget: node.target) + } + } + } + + func ifNeedAutomaticScroll(with target: GKTooltipTarget) -> (ifNeed: Bool,targetView: UIView?) { + if let scrollView = self.scrollView { + return (!scrollView.isVisible(view: target.targetView), target.targetView) + } + return (false, nil) + } + + func dismissGKTooltip() { + self.view.backgroundColor = .clear + clearTip() + dismiss(animated: true, completion: nil) + delegate?.didDismiss() + } +} diff --git a/MobilliumToolTips/Classes/GKTooltipView/UIScrollView+Extensions.swift b/MobilliumToolTips/Classes/GKTooltipView/UIScrollView+Extensions.swift new file mode 100644 index 0000000..2fc685b --- /dev/null +++ b/MobilliumToolTips/Classes/GKTooltipView/UIScrollView+Extensions.swift @@ -0,0 +1,78 @@ +// +// UIScrollView+Extensions.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public enum ScrollDirection { + case Top + case Right + case Bottom + case Left + + func contentOffsetWith(_ scrollView: UIScrollView) -> CGPoint { + var contentOffset = CGPoint.zero + switch self { + case .Top: + contentOffset = CGPoint(x: 0, y: -scrollView.contentInset.top) + case .Right: + contentOffset = CGPoint(x: scrollView.contentSize.width - scrollView.bounds.size.width, y: 0) + case .Bottom: + contentOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height) + case .Left: + contentOffset = CGPoint(x: -scrollView.contentInset.left, y: 0) + } + return contentOffset + } +} + +extension UIScrollView { + func scrollTo(direction: ScrollDirection, animated: Bool = true) { + self.setContentOffset(direction.contentOffsetWith(self), animated: animated) + } + + func scrollTo(item: UIView, animated: Bool = true, with completion: @escaping (() -> ())) { + UIView.animate(withDuration: 0.3, animations: { + self.contentOffset = self.calculateScrolingContentSize(item: item) + }) { (success) in + completion() + } + } + + func isVisible(view: UIView) -> Bool { + let convertedFrame = view.convert(view.bounds, to: self) + if self.bounds.contains(convertedFrame){ + return true + } + return false + } + + func scrollToTop(animated: Bool) { + let topOffset = CGPoint(x: 0, y: -contentInset.top) + setContentOffset(topOffset, animated: animated) + } + + func scrollToBottom() { + let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom) + if(bottomOffset.y > 0) { + setContentOffset(bottomOffset, animated: true) + } + } + + private func calculateScrolingContentSize(item: UIView) -> CGPoint { + let rect = item.convert(item.bounds, to: self) + if rect.minY + rect.height < frame.height { + return CGPoint(x: 0, y: -contentInset.top) + } + else { + let maximumBottomPadding = 40 + let bottomPadding: Int = Int(contentSize.height - (rect.minY + rect.height)) + let padding = min(maximumBottomPadding, bottomPadding) + return CGPoint(x: 0, y: (rect.minY - self.frame.height) + rect.height + CGFloat(padding)) + } + } +} diff --git a/MobilliumToolTips/Classes/ReplaceMe.swift b/MobilliumToolTips/Classes/ReplaceMe.swift deleted file mode 100644 index e69de29..0000000 diff --git a/MobilliumToolTips/Classes/UIApplication+Extension.swift b/MobilliumToolTips/Classes/UIApplication+Extension.swift new file mode 100644 index 0000000..83c6bb9 --- /dev/null +++ b/MobilliumToolTips/Classes/UIApplication+Extension.swift @@ -0,0 +1,28 @@ +// +// UIApplication+Extension.swift +// MobilliumGenesisKitDemo +// +// Created by Serkan Erkan on 7.07.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +extension UIApplication { + + class func topViewController(controller: UIViewController? = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController) -> UIViewController? { + + if let navigationController = controller as? UINavigationController { + return topViewController(controller: navigationController.visibleViewController) + } + if let tabController = controller as? UITabBarController, let selected = tabController.selectedViewController { + return topViewController(controller: selected) + + } + if let presented = controller?.presentedViewController { + return topViewController(controller: presented) + } + return controller + } +} + diff --git a/README.md b/README.md index 84ffdea..45f417f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MobilliumToolTips -[![CI Status](https://img.shields.io/travis/evam-mobile-customer/MobilliumToolTips.svg?style=flat)](https://travis-ci.org/evam-mobile-customer/MobilliumToolTips) +[![CI Status](https://img.shields.io/travis/mobillium/MobilliumToolTips.svg?style=flat)](https://travis-ci.org/mobillium/MobilliumToolTips) [![Version](https://img.shields.io/cocoapods/v/MobilliumToolTips.svg?style=flat)](https://cocoapods.org/pods/MobilliumToolTips) [![License](https://img.shields.io/cocoapods/l/MobilliumToolTips.svg?style=flat)](https://cocoapods.org/pods/MobilliumToolTips) [![Platform](https://img.shields.io/cocoapods/p/MobilliumToolTips.svg?style=flat)](https://cocoapods.org/pods/MobilliumToolTips) @@ -22,7 +22,7 @@ pod 'MobilliumToolTips' ## Author -evam-mobile-customer, aslanmsalih@gmail.com +mobillium, info@mobillium.com ## License diff --git a/Resources/Assets/UIImage+Icons.swift b/Resources/Assets/UIImage+Icons.swift new file mode 100644 index 0000000..4767f04 --- /dev/null +++ b/Resources/Assets/UIImage+Icons.swift @@ -0,0 +1,16 @@ +// +// UIImage+Icons.swift +// MobilliumGenesisKit +// +// Created by Mehmet Salih Aslan on 11.05.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public extension UIImage { + + static var icInfo: UIImage { + return UIImage(named: "ic_info", in: BundleToken.bundle, compatibleWith: nil)! + } +} diff --git a/Resources/Colors/UIColor+Extensions.swift b/Resources/Colors/UIColor+Extensions.swift new file mode 100644 index 0000000..09d81a9 --- /dev/null +++ b/Resources/Colors/UIColor+Extensions.swift @@ -0,0 +1,132 @@ +// +// UIColor+Extensions.swift +// MobilliumGenesisKit +// +// Created by Mehmet Salih Aslan on 9.03.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit + +public extension UIColor { + + /// #any: #F8FAFC + /// #dark: #171A1D + static var background01: UIColor { + return UIColor(named: "background01", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFFFFF + /// #dark: #151719 + static var background02: UIColor { + return UIColor(named: "background02", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFFFFF + /// #dark: #1F272E + static var base: UIColor { + return UIColor(named: "base", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #EFF3F7 + /// #dark: #29343D + static var elevation01: UIColor { + return UIColor(named: "elevation01", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #D4DFE9 + /// #dark: #363E44 + static var elevation02: UIColor { + return UIColor(named: "elevation02", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #B8CBDB + /// #dark: #48525B + static var elevation03: UIColor { + return UIColor(named: "elevation03", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #171A1D + /// #dark: #F7F7F8 + static var focus: UIColor { + return UIColor(named: "focus", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #BBECC8 + /// #dark: #245639 + static var green01: UIColor { + return UIColor(named: "green01", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #78DA90 + /// #dark: #288543 + static var green02: UIColor { + return UIColor(named: "green02", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #34C759 + /// #dark: #2DB44E + static var green03: UIColor { + return UIColor(named: "green03", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFDCAA + /// #dark: #6A4F22 + static var orange01: UIColor { + return UIColor(named: "orange01", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFB855 + /// #dark: #B47716 + static var orange02: UIColor { + return UIColor(named: "orange02", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FF9500 + /// #dark: #FF9F0A + static var orange03: UIColor { + return UIColor(named: "orange03", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #016BE8 + /// #dark: #2986F5 + static var primary: UIColor { + return UIColor(named: "primary", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #000000 + /// #dark: #000000 + static var pureBlack: UIColor { + return UIColor(named: "pureBlack", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFFFFF + /// #dark: #FFFFFF + static var pureWhite: UIColor { + return UIColor(named: "pureWhite", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FFE3E1 + /// #dark: #3F2A2E + static var red01: UIColor { + return UIColor(named: "red01", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FF8F89 + /// #dark: #9F322F + static var red02: UIColor { + return UIColor(named: "red02", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #FF3B30 + /// #dark: #FF453A + static var red03: UIColor { + return UIColor(named: "red03", in: BundleToken.bundle, compatibleWith: nil)! + } + + /// #any: #83A0B9 + /// #dark: #83A0B9 + static var text: UIColor { + return UIColor(named: "text", in: BundleToken.bundle, compatibleWith: nil)! + } +} diff --git a/Resources/Fonts/Fonts.swift b/Resources/Fonts/Fonts.swift new file mode 100644 index 0000000..76f851b --- /dev/null +++ b/Resources/Fonts/Fonts.swift @@ -0,0 +1,79 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSFont +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIFont +#endif + +// Deprecated typealiases +public typealias Font = FontConvertible.Font + +// swiftlint:disable superfluous_disable_command +// swiftlint:disable file_length + +// MARK: - Fonts + +// swiftlint:disable identifier_name line_length type_body_length +public enum FontFamily { + public enum Inter { + public static let regular = FontConvertible(name: "Inter-Regular", family: "Inter", path: "Inter-Regular.otf") + public static let medium = FontConvertible(name: "Inter-Medium", family: "Inter", path: "Inter-Medium.otf") + public static let semibold = FontConvertible(name: "Inter-SemiBold", family: "Inter", path: "Inter-SemiBold.otf") + public static let all: [FontConvertible] = [medium, regular, semibold] + } + public static let allCustomFonts: [FontConvertible] = [Inter.all].flatMap { $0 } + public static func registerAllCustomFonts() { + allCustomFonts.forEach { $0.register() } + } +} +// swiftlint:enable identifier_name line_length type_body_length + +// MARK: - Implementation Details + +public struct FontConvertible { + public let name: String + public let family: String + public let path: String + + #if os(OSX) + public typealias Font = NSFont + #elseif os(iOS) || os(tvOS) || os(watchOS) + public typealias Font = UIFont + #endif + + public func font(size: CGFloat) -> Font { + guard let font = Font(font: self, size: size) else { + fatalError("Unable to initialize font '\(name)' (\(family))") + } + return font + } + + public func register() { + // swiftlint:disable:next conditional_returns_on_newline + guard let url = url else { return } + CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil) + } + + fileprivate var url: URL? { + // swiftlint:disable:next implicit_return + return BundleToken.bundle.url(forResource: path, withExtension: nil) + } +} + +public extension FontConvertible.Font { + convenience init?(font: FontConvertible, size: CGFloat) { + #if os(iOS) || os(tvOS) || os(watchOS) + if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) { + font.register() + } + #elseif os(OSX) + if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none { + font.register() + } + #endif + + self.init(name: font.name, size: size) + } +} diff --git a/Resources/Fonts/Inter-Medium.otf b/Resources/Fonts/Inter-Medium.otf new file mode 100644 index 0000000..ca7bfcd Binary files /dev/null and b/Resources/Fonts/Inter-Medium.otf differ diff --git a/Resources/Fonts/Inter-Regular.otf b/Resources/Fonts/Inter-Regular.otf new file mode 100644 index 0000000..84e6a61 Binary files /dev/null and b/Resources/Fonts/Inter-Regular.otf differ diff --git a/Resources/Fonts/Inter-SemiBold.otf b/Resources/Fonts/Inter-SemiBold.otf new file mode 100644 index 0000000..daf4c44 Binary files /dev/null and b/Resources/Fonts/Inter-SemiBold.otf differ diff --git a/Resources/Fonts/UIFont+Contants.swift b/Resources/Fonts/UIFont+Contants.swift new file mode 100644 index 0000000..4e42182 --- /dev/null +++ b/Resources/Fonts/UIFont+Contants.swift @@ -0,0 +1,155 @@ +// +// UIFont+Contants.swift +// MobilliumGenesisKit +// +// Created by Mehmet Salih Aslan on 2.03.2023. +// Copyright © 2023 Mobillium. All rights reserved. +// + +import UIKit +import Foundation + +public extension UIFont { + // MARK: - largeTitle + /// size: 32 + /// weight: book + static var largeTitleBook: UIFont = FontFamily.Inter.regular.font(size: 32) + /// size: 32 + /// weight: medium + static var largeTitleMedium: UIFont = FontFamily.Inter.medium.font(size: 32) + /// size: 32 + /// weight: semibold + static var largeTitleSemibold: UIFont = FontFamily.Inter.semibold.font(size: 32) + + + // MARK: - title04 + /// size: 28 + /// weight: book + static var title04Book: UIFont = FontFamily.Inter.regular.font(size: 28) + /// size: 28 + /// weight: medium + static var title04Medium: UIFont = FontFamily.Inter.medium.font(size: 28) + /// size: 28 + /// weight: semibold + static var title04Semibold: UIFont = FontFamily.Inter.semibold.font(size: 28) + + + // MARK: - title03 + /// size: 24 + /// weight: book + static var title03Book: UIFont = FontFamily.Inter.regular.font(size: 24) + /// size: 24 + /// weight: medium + static var title03Medium: UIFont = FontFamily.Inter.medium.font(size: 24) + /// size: 24 + /// weight: semibold + static var title03Semibold: UIFont = FontFamily.Inter.semibold.font(size: 24) + + + // MARK: - title02 + /// size: 22 + /// weight: book + static var title02Book: UIFont = FontFamily.Inter.regular.font(size: 22) + /// size: 22 + /// weight: medium + static var title02Medium: UIFont = FontFamily.Inter.medium.font(size: 22) + /// size: 22 + /// weight: semibold + static var title02Semibold: UIFont = FontFamily.Inter.semibold.font(size: 22) + + + // MARK: - title01 + /// size: 20 + /// weight: book + static var title01Book: UIFont = FontFamily.Inter.regular.font(size: 20) + /// size: 20 + /// weight: medium + static var title01Medium: UIFont = FontFamily.Inter.medium.font(size: 20) + /// size: 20 + /// weight: semibold + static var title01Semibold: UIFont = FontFamily.Inter.semibold.font(size: 20) + + + // MARK: - body + /// size: 16 + /// weight: regular + static var bodyRegular: UIFont = FontFamily.Inter.regular.font(size: 16) + /// size: 16 + /// weight: medium + static var bodyMedium: UIFont = FontFamily.Inter.medium.font(size: 16) + /// size: 16 + /// weight: semibold + static var bodySemibold: UIFont = FontFamily.Inter.semibold.font(size: 16) + + + // MARK: - smallBold + /// size: 14 + /// weight: regular + static var smallBodyRegular: UIFont = FontFamily.Inter.regular.font(size: 14) + /// size: 14 + /// weight: medium + static var smallBodyMedium: UIFont = FontFamily.Inter.medium.font(size: 14) + /// size: 14 + /// weight: semibold + static var smallBodySemibold: UIFont = FontFamily.Inter.semibold.font(size: 14) + + + // MARK: - caption + /// size: 13 + /// weight: regular + static var captionRegular: UIFont = FontFamily.Inter.regular.font(size: 13) + /// size: 13 + /// weight: medium + static var captionMedium: UIFont = FontFamily.Inter.medium.font(size: 13) + /// size: 13 + /// weight: semibold + static var captionSemibold: UIFont = FontFamily.Inter.semibold.font(size: 13) + + + // MARK: - footnote01 + /// size: 12 + /// weight: regular + static var footnote01Regular: UIFont = FontFamily.Inter.regular.font(size: 12) + /// size: 12 + /// weight: medium + static var footnote01Medium: UIFont = FontFamily.Inter.medium.font(size: 12) + /// size: 12 + /// weight: semibold + static var footnote01Semibold: UIFont = FontFamily.Inter.semibold.font(size: 12) + + + // MARK: - footnote02 + /// size: 11 + /// weight: regular + static var footnote02Regular: UIFont = FontFamily.Inter.regular.font(size: 11) + /// size: 11 + /// weight: medium + static var footnote02Medium: UIFont = FontFamily.Inter.medium.font(size: 11) + /// size: 11 + /// weight: semibold + static var footnote02Semibold: UIFont = FontFamily.Inter.semibold.font(size: 11) + + + // MARK: - microUI01 + /// size: 10 + /// weight: regular + static var microUI01Regular: UIFont = FontFamily.Inter.regular.font(size: 10) + /// size: 10 + /// weight: medium + static var microUI01Medium: UIFont = FontFamily.Inter.medium.font(size: 10) + /// size: 10 + /// weight: semibold + static var microUI01Semibold: UIFont = FontFamily.Inter.semibold.font(size: 10) + + + // MARK: - microUI01 + /// size: 9 + /// weight: regular + static var microUI02Regular: UIFont = FontFamily.Inter.regular.font(size: 9) + /// size: 9 + /// weight: medium + static var microUI02Medium: UIFont = FontFamily.Inter.medium.font(size: 9) + /// size: 9 + /// weight: semibold + static var microUI02Semibold: UIFont = FontFamily.Inter.semibold.font(size: 9) +}