├── ZMJTipView ├── Assets │ └── .gitkeep └── Classes │ └── .gitkeep ├── _Pods.xcodeproj ├── Example ├── Tests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── Tests-Info.plist ├── ZMJTipView │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── ZMJViewController.h │ ├── ZMJAppDelegate.h │ ├── ZMJTipView-Prefix.pch │ ├── main.m │ ├── ZMJTaskView.h │ ├── ZMJTipView-Info.plist │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ZMJAppDelegate.m │ ├── UIView+Frame.h │ ├── UIView+Frame.m │ └── ZMJTaskView.m ├── Pods │ ├── Target Support Files │ │ ├── ZMJTipView │ │ │ ├── ZMJTipView.modulemap │ │ │ ├── ZMJTipView-dummy.m │ │ │ ├── ZMJTipView-prefix.pch │ │ │ ├── ZMJTipView-umbrella.h │ │ │ ├── ZMJTipView.xcconfig │ │ │ └── Info.plist │ │ ├── YYCategories │ │ │ ├── YYCategories.modulemap │ │ │ ├── YYCategories-dummy.m │ │ │ ├── YYCategories-prefix.pch │ │ │ ├── YYCategories.xcconfig │ │ │ ├── Info.plist │ │ │ └── YYCategories-umbrella.h │ │ ├── FBSnapshotTestCase │ │ │ ├── FBSnapshotTestCase.modulemap │ │ │ ├── FBSnapshotTestCase-dummy.m │ │ │ ├── FBSnapshotTestCase-prefix.pch │ │ │ ├── FBSnapshotTestCase-umbrella.h │ │ │ ├── FBSnapshotTestCase.xcconfig │ │ │ └── Info.plist │ │ ├── Pods-ZMJTipView_Tests │ │ │ ├── Pods-ZMJTipView_Tests.modulemap │ │ │ ├── Pods-ZMJTipView_Tests-dummy.m │ │ │ ├── Pods-ZMJTipView_Tests-umbrella.h │ │ │ ├── Info.plist │ │ │ ├── Pods-ZMJTipView_Tests.debug.xcconfig │ │ │ ├── Pods-ZMJTipView_Tests.release.xcconfig │ │ │ ├── Pods-ZMJTipView_Tests-acknowledgements.markdown │ │ │ ├── Pods-ZMJTipView_Tests-acknowledgements.plist │ │ │ └── Pods-ZMJTipView_Tests-resources.sh │ │ └── Pods-ZMJTipView_Example │ │ │ ├── Pods-ZMJTipView_Example.modulemap │ │ │ ├── Pods-ZMJTipView_Example-dummy.m │ │ │ ├── Pods-ZMJTipView_Example-umbrella.h │ │ │ ├── Pods-ZMJTipView_Example.debug.xcconfig │ │ │ ├── Pods-ZMJTipView_Example.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-ZMJTipView_Example-acknowledgements.markdown │ │ │ ├── Pods-ZMJTipView_Example-acknowledgements.plist │ │ │ └── Pods-ZMJTipView_Example-resources.sh │ ├── FBSnapshotTestCase │ │ ├── FBSnapshotTestCase │ │ │ ├── Categories │ │ │ │ ├── UIApplication+StrictKeyWindow.h │ │ │ │ ├── UIImage+Snapshot.h │ │ │ │ ├── UIApplication+StrictKeyWindow.m │ │ │ │ ├── UIImage+Diff.h │ │ │ │ ├── UIImage+Compare.h │ │ │ │ ├── UIImage+Snapshot.m │ │ │ │ ├── UIImage+Diff.m │ │ │ │ └── UIImage+Compare.m │ │ │ ├── FBSnapshotTestCasePlatform.h │ │ │ └── FBSnapshotTestCasePlatform.m │ │ ├── LICENSE │ │ └── README.md │ ├── Local Podspecs │ │ └── ZMJTipView.podspec.json │ ├── Manifest.lock │ └── YYCategories │ │ ├── YYCategories │ │ ├── Foundation │ │ │ ├── NSObject+YYAddForARC.h │ │ │ ├── NSThread+YYAdd.h │ │ │ ├── NSNumber+YYAdd.h │ │ │ ├── NSObject+YYAddForARC.m │ │ │ ├── NSTimer+YYAdd.m │ │ │ ├── NSKeyedUnarchiver+YYAdd.m │ │ │ ├── NSKeyedUnarchiver+YYAdd.h │ │ │ ├── NSObject+YYAddForKVO.h │ │ │ ├── NSNumber+YYAdd.m │ │ │ ├── NSTimer+YYAdd.h │ │ │ ├── NSNotificationCenter+YYAdd.m │ │ │ ├── NSBundle+YYAdd.m │ │ │ ├── NSNotificationCenter+YYAdd.h │ │ │ ├── NSObject+YYAddForKVO.m │ │ │ ├── NSBundle+YYAdd.h │ │ │ ├── NSThread+YYAdd.m │ │ │ ├── NSArray+YYAdd.m │ │ │ └── NSArray+YYAdd.h │ │ ├── UIKit │ │ │ ├── UITextField+YYAdd.h │ │ │ ├── UIBarButtonItem+YYAdd.h │ │ │ ├── UIBezierPath+YYAdd.h │ │ │ ├── UITextField+YYAdd.m │ │ │ ├── UIGestureRecognizer+YYAdd.h │ │ │ ├── UIScrollView+YYAdd.h │ │ │ ├── UIBarButtonItem+YYAdd.m │ │ │ ├── UIScrollView+YYAdd.m │ │ │ ├── UIScreen+YYAdd.h │ │ │ ├── UIGestureRecognizer+YYAdd.m │ │ │ ├── UIBezierPath+YYAdd.m │ │ │ ├── UIApplication+YYAdd.h │ │ │ ├── UIControl+YYAdd.h │ │ │ ├── UITableView+YYAdd.m │ │ │ ├── UIControl+YYAdd.m │ │ │ ├── UIView+YYAdd.h │ │ │ └── UIFont+YYAdd.h │ │ ├── YYCategories.h │ │ └── Quartz │ │ │ └── CALayer+YYAdd.h │ │ ├── LICENSE │ │ └── README.md ├── ZMJTipView.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── ZMJTipView-Example.xcscheme ├── Podfile ├── ZMJTipView.xcworkspace │ └── contents.xcworkspacedata └── Podfile.lock ├── Resources ├── static.png ├── animation.gif ├── easytipview.gif └── static-iphonex.png ├── .travis.yml ├── .gitignore ├── LICENSE ├── ZMJTipView.podspec └── README.md /ZMJTipView/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ZMJTipView/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/ZMJTipView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Resources/static.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keshiim/ZMJTipView/HEAD/Resources/static.png -------------------------------------------------------------------------------- /Resources/animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keshiim/ZMJTipView/HEAD/Resources/animation.gif -------------------------------------------------------------------------------- /Resources/easytipview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keshiim/ZMJTipView/HEAD/Resources/easytipview.gif -------------------------------------------------------------------------------- /Resources/static-iphonex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keshiim/ZMJTipView/HEAD/Resources/static-iphonex.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/ZMJTipView.modulemap: -------------------------------------------------------------------------------- 1 | framework module ZMJTipView { 2 | umbrella header "ZMJTipView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/YYCategories.modulemap: -------------------------------------------------------------------------------- 1 | framework module YYCategories { 2 | umbrella header "YYCategories-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/ZMJTipView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ZMJTipView : NSObject 3 | @end 4 | @implementation PodsDummy_ZMJTipView 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/YYCategories-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_YYCategories : NSObject 3 | @end 4 | @implementation PodsDummy_YYCategories 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | @import FBSnapshotTestCase; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap: -------------------------------------------------------------------------------- 1 | framework module FBSnapshotTestCase { 2 | umbrella header "FBSnapshotTestCase-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FBSnapshotTestCase : NSObject 3 | @end 4 | @implementation PodsDummy_FBSnapshotTestCase 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ZMJTipView_Tests { 2 | umbrella header "Pods-ZMJTipView_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_ZMJTipView_Example { 2 | umbrella header "Pods-ZMJTipView_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ZMJTipView_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ZMJTipView_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/ZMJTipView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_ZMJTipView_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_ZMJTipView_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'ZMJTipView_Example' do 4 | pod 'ZMJTipView', :path => '../' 5 | pod 'YYCategories', '~> 1.0.4' 6 | 7 | target 'ZMJTipView_Tests' do 8 | inherit! :search_paths 9 | 10 | pod 'FBSnapshotTestCase' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJViewController.h 3 | // ZMJTipView 4 | // 5 | // Created by keshiim on 02/08/2018. 6 | // Copyright (c) 2018 keshiim. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface ZMJViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/ZMJTipView-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/YYCategories-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/ZMJTipView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJAppDelegate.h 3 | // ZMJTipView 4 | // 5 | // Created by keshiim on 02/08/2018. 6 | // Copyright (c) 2018 keshiim. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface ZMJAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJTipView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/ZMJTipView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZMJTipView 4 | // 5 | // Created by keshiim on 02/08/2018. 6 | // Copyright (c) 2018 keshiim. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "ZMJAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ZMJAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJTaskView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJTaskView.h 3 | // ZMJTipView_Example 4 | // 5 | // Created by Jason on 2018/2/11. 6 | // Copyright © 2018年 keshiim. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZMJTaskView : UIView 12 | @property (nonatomic, strong) NSString *taskTitle; 13 | @property (nonatomic, strong) NSString *startTime; 14 | @property (nonatomic, strong) NSString *endTime; 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/ZMJTipView-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "ZMJTipView.h" 14 | 15 | FOUNDATION_EXPORT double ZMJTipViewVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char ZMJTipViewVersionString[]; 17 | 18 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_ZMJTipView_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ZMJTipView_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_ZMJTipView_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ZMJTipView_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "FBSnapshotTestCase.h" 14 | #import "FBSnapshotTestCasePlatform.h" 15 | #import "FBSnapshotTestController.h" 16 | 17 | FOUNDATION_EXPORT double FBSnapshotTestCaseVersionNumber; 18 | FOUNDATION_EXPORT const unsigned char FBSnapshotTestCaseVersionString[]; 19 | 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/ZMJTipView.xcworkspace -scheme ZMJTipView-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/ZMJTipView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "UIKit" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIApplication+StrictKeyWindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @interface UIApplication (StrictKeyWindow) 14 | 15 | /** 16 | @return The receiver's @c keyWindow. Raises an assertion if @c nil. 17 | */ 18 | - (UIWindow *)fb_strictKeyWindow; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/ZMJTipView.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZMJTipView", 3 | "version": "0.1.0", 4 | "summary": "Fully customisable tooltip view in Objective-C for iOS.", 5 | "description": "Fully customisable tooltip view in Objective-C for iOS.", 6 | "homepage": "https://github.com/keshiim/ZMJTipView", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "keshiim": "keshiim@163.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/keshiim/ZMJTipView.git", 16 | "tag": "0.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0" 20 | }, 21 | "source_files": "ZMJTipView/Classes/**/*", 22 | "frameworks": "UIKit" 23 | } 24 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJTipViewTests.m 3 | // ZMJTipViewTests 4 | // 5 | // Created by keshiim on 02/08/2018. 6 | // Copyright (c) 2018 keshiim. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/YYCategories.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YYCategories 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -l"z" -framework "Accelerate" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreText" -framework "ImageIO" -framework "QuartzCore" -framework "UIKit" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/YYCategories 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FBSnapshotTestCase (2.1.4): 3 | - FBSnapshotTestCase/SwiftSupport (= 2.1.4) 4 | - FBSnapshotTestCase/Core (2.1.4) 5 | - FBSnapshotTestCase/SwiftSupport (2.1.4): 6 | - FBSnapshotTestCase/Core 7 | - YYCategories (1.0.4): 8 | - YYCategories/no-arc (= 1.0.4) 9 | - YYCategories/no-arc (1.0.4) 10 | - ZMJTipView (0.1.0) 11 | 12 | DEPENDENCIES: 13 | - FBSnapshotTestCase 14 | - YYCategories (~> 1.0.4) 15 | - ZMJTipView (from `../`) 16 | 17 | EXTERNAL SOURCES: 18 | ZMJTipView: 19 | :path: ../ 20 | 21 | SPEC CHECKSUMS: 22 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 23 | YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd 24 | ZMJTipView: 15f549581fcc1c7af51606e8f866e58d7d348ea3 25 | 26 | PODFILE CHECKSUM: fc17da7d952453bf1e25621591603c7442c6b9d4 27 | 28 | COCOAPODS: 1.4.0 29 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView/ZMJTipView.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "YYCategories" -framework "ZMJTipView" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView/ZMJTipView.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "YYCategories" -framework "ZMJTipView" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FBSnapshotTestCase (2.1.4): 3 | - FBSnapshotTestCase/SwiftSupport (= 2.1.4) 4 | - FBSnapshotTestCase/Core (2.1.4) 5 | - FBSnapshotTestCase/SwiftSupport (2.1.4): 6 | - FBSnapshotTestCase/Core 7 | - YYCategories (1.0.4): 8 | - YYCategories/no-arc (= 1.0.4) 9 | - YYCategories/no-arc (1.0.4) 10 | - ZMJTipView (0.1.0) 11 | 12 | DEPENDENCIES: 13 | - FBSnapshotTestCase 14 | - YYCategories (~> 1.0.4) 15 | - ZMJTipView (from `../`) 16 | 17 | EXTERNAL SOURCES: 18 | ZMJTipView: 19 | :path: ../ 20 | 21 | SPEC CHECKSUMS: 22 | FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a 23 | YYCategories: 6bcd4314c6661a561410dce4a793379ebd306abd 24 | ZMJTipView: 15f549581fcc1c7af51606e8f866e58d7d348ea3 25 | 26 | PODFILE CHECKSUM: fc17da7d952453bf1e25621591603c7442c6b9d4 27 | 28 | COCOAPODS: 1.4.0 29 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAddForARC.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+YYAddForARC.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/12/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | /** 15 | Debug method for NSObject when using ARC. 16 | */ 17 | @interface NSObject (YYAddForARC) 18 | 19 | /// Same as `retain` 20 | - (instancetype)arcDebugRetain; 21 | 22 | /// Same as `release` 23 | - (oneway void)arcDebugRelease; 24 | 25 | /// Same as `autorelease` 26 | - (instancetype)arcDebugAutorelease; 27 | 28 | /// Same as `retainCount` 29 | - (NSUInteger)arcDebugRetainCount; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UITextField+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/5/12. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UITextField`. 18 | */ 19 | @interface UITextField (YYAdd) 20 | 21 | /** 22 | Set all text selected. 23 | */ 24 | - (void)selectAllText; 25 | 26 | /** 27 | Set text in range selected. 28 | 29 | @param range The range of selected text in a document. 30 | */ 31 | - (void)setSelectedRange:(NSRange)range; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSThread+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSThread+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 15/7/3. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | @interface NSThread (YYAdd) 15 | 16 | /** 17 | Add an autorelease pool to current runloop for current thread. 18 | 19 | @discussion If you create your own thread (NSThread/pthread), and you use 20 | runloop to manage your task, you may use this method to add an autorelease pool 21 | to the runloop. Its behavior is the same as the main thread's autorelease pool. 22 | */ 23 | + (void)addAutoreleasePoolToCurrentRunloop; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase 2 | ENABLE_BITCODE = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 6 | OTHER_LDFLAGS = -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FBSnapshotTestCase 12 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 13 | SKIP_INSTALL = YES 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @interface UIImage (Snapshot) 14 | 15 | /// Uses renderInContext: to get a snapshot of the layer. 16 | + (UIImage *)fb_imageForLayer:(CALayer *)layer; 17 | 18 | /// Uses renderInContext: to get a snapshot of the view layer. 19 | + (UIImage *)fb_imageForViewLayer:(UIView *)view; 20 | 21 | /// Uses drawViewHierarchyInRect: to get a snapshot of the view and adds the view into a window if needed. 22 | + (UIImage *)fb_imageForView:(UIView *)view; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSNumber+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/24. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provide a method to parse `NSString` for `NSNumber`. 18 | */ 19 | @interface NSNumber (YYAdd) 20 | 21 | /** 22 | Creates and returns an NSNumber object from a string. 23 | Valid format: @"12", @"12.345", @" -0xFF", @" .23e99 "... 24 | 25 | @param string The string described an number. 26 | 27 | @return an NSNumber when parse succeed, or nil if an error occurs. 28 | */ 29 | + (nullable NSNumber *)numberWithString:(NSString *)string; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.4 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/ZMJTipView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FBSnapshotTestCase/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.1.4 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIBarButtonItem+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/10/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIBarButtonItem`. 18 | */ 19 | @interface UIBarButtonItem (YYAdd) 20 | 21 | /** 22 | The block that invoked when the item is selected. The objects captured by block 23 | will retained by the ButtonItem. 24 | 25 | @discussion This param is conflict with `target` and `action` property. 26 | Set this will set `target` and `action` property to some internal objects. 27 | */ 28 | @property (nullable, nonatomic, copy) void (^actionBlock)(id); 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAddForARC.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+YYAddForARC.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/12/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSObject+YYAddForARC.h" 13 | 14 | @interface NSObject_YYAddForARC : NSObject @end 15 | @implementation NSObject_YYAddForARC @end 16 | 17 | #if __has_feature(objc_arc) 18 | #error This file must be compiled without ARC. Specify the -fno-objc-arc flag to this file. 19 | #endif 20 | 21 | 22 | @implementation NSObject (YYAddForARC) 23 | 24 | - (instancetype)arcDebugRetain { 25 | return [self retain]; 26 | } 27 | 28 | - (oneway void)arcDebugRelease { 29 | [self release]; 30 | } 31 | 32 | - (instancetype)arcDebugAutorelease { 33 | return [self autorelease]; 34 | } 35 | 36 | - (NSUInteger)arcDebugRetainCount { 37 | return [self retainCount]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView/ZMJTipView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories" "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYCategories/YYCategories.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/ZMJTipView/ZMJTipView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 keshiim 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIApplication+StrictKeyWindow.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | @implementation UIApplication (StrictKeyWindow) 14 | 15 | - (UIWindow *)fb_strictKeyWindow 16 | { 17 | UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; 18 | if (!keyWindow) { 19 | [NSException raise:@"FBSnapshotTestCaseNilKeyWindowException" 20 | format:@"Snapshot tests must be hosted by an application with a key window. Please ensure your test" 21 | " host sets up a key window at launch (either via storyboards or programmatically) and doesn't" 22 | " do anything to remove it while snapshot tests are running."]; 23 | } 24 | return keyWindow; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIBezierPath+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBezierPath+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/30. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIBezierPath`. 18 | */ 19 | @interface UIBezierPath (YYAdd) 20 | 21 | /** 22 | Creates and returns a new UIBezierPath object initialized with the text glyphs 23 | generated from the specified font. 24 | 25 | @discussion It doesnot support apple emoji. If you want get emoji image, try 26 | [UIImage imageWithEmoji:size:] in `UIImage(YYAdd)`. 27 | 28 | @param text The text to generate glyph path. 29 | @param font The font to generate glyph path. 30 | 31 | @return A new path object with the text and font, or nil if an error occurs. 32 | */ 33 | + (nullable UIBezierPath *)bezierPathWithText:(NSString *)text font:(UIFont *)font; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ibireme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UITextField+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/5/12. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UITextField+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | 15 | YYSYNTH_DUMMY_CLASS(UITextField_YYAdd) 16 | 17 | 18 | @implementation UITextField (YYAdd) 19 | 20 | - (void)selectAllText { 21 | UITextRange *range = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument]; 22 | [self setSelectedTextRange:range]; 23 | } 24 | 25 | - (void)setSelectedRange:(NSRange)range { 26 | UITextPosition *beginning = self.beginningOfDocument; 27 | UITextPosition *startPosition = [self positionFromPosition:beginning offset:range.location]; 28 | UITextPosition *endPosition = [self positionFromPosition:beginning offset:NSMaxRange(range)]; 29 | UITextRange *selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition]; 30 | [self setSelectedTextRange:selectionRange]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSTimer+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimer+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/15/11. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSTimer+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | 15 | YYSYNTH_DUMMY_CLASS(NSTimer_YYAdd) 16 | 17 | 18 | @implementation NSTimer (YYAdd) 19 | 20 | + (void)_yy_ExecBlock:(NSTimer *)timer { 21 | if ([timer userInfo]) { 22 | void (^block)(NSTimer *timer) = (void (^)(NSTimer *timer))[timer userInfo]; 23 | block(timer); 24 | } 25 | } 26 | 27 | + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds block:(void (^)(NSTimer *timer))block repeats:(BOOL)repeats { 28 | return [NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(_yy_ExecBlock:) userInfo:[block copy] repeats:repeats]; 29 | } 30 | 31 | + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)seconds block:(void (^)(NSTimer *timer))block repeats:(BOOL)repeats { 32 | return [NSTimer timerWithTimeInterval:seconds target:self selector:@selector(_yy_ExecBlock:) userInfo:[block copy] repeats:repeats]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSKeyedUnarchiver+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSKeyedUnarchiver+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/4. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSKeyedUnarchiver+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | 15 | YYSYNTH_DUMMY_CLASS(NSKeyedUnarchiver_YYAdd) 16 | 17 | 18 | @implementation NSKeyedUnarchiver (YYAdd) 19 | 20 | + (id)unarchiveObjectWithData:(NSData *)data exception:(__autoreleasing NSException **)exception { 21 | id object = nil; 22 | @try { 23 | object = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 24 | } 25 | @catch (NSException *e) 26 | { 27 | if (exception) *exception = e; 28 | } 29 | @finally 30 | { 31 | } 32 | return object; 33 | } 34 | 35 | + (id)unarchiveObjectWithFile:(NSString *)path exception:(__autoreleasing NSException **)exception { 36 | id object = nil; 37 | 38 | @try { 39 | object = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 40 | } 41 | @catch (NSException *e) 42 | { 43 | if (exception) *exception = e; 44 | } 45 | @finally 46 | { 47 | } 48 | return object; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIGestureRecognizer+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIGestureRecognizer+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/10/13. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIGestureRecognizer`. 18 | */ 19 | @interface UIGestureRecognizer (YYAdd) 20 | 21 | /** 22 | Initializes an allocated gesture-recognizer object with a action block. 23 | 24 | @param block An action block that to handle the gesture recognized by the 25 | receiver. nil is invalid. It is retained by the gesture. 26 | 27 | @return An initialized instance of a concrete UIGestureRecognizer subclass or 28 | nil if an error occurred in the attempt to initialize the object. 29 | */ 30 | - (instancetype)initWithActionBlock:(void (^)(id sender))block; 31 | 32 | /** 33 | Adds an action block to a gesture-recognizer object. It is retained by the 34 | gesture. 35 | 36 | @param block A block invoked by the action message. nil is not a valid value. 37 | */ 38 | - (void)addActionBlock:(void (^)(id sender))block; 39 | 40 | /** 41 | Remove all action blocks. 42 | */ 43 | - (void)removeAllActionBlocks; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/YYCategories/YYCategories-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "NSArray+YYAdd.h" 14 | #import "NSBundle+YYAdd.h" 15 | #import "NSData+YYAdd.h" 16 | #import "NSDate+YYAdd.h" 17 | #import "NSDictionary+YYAdd.h" 18 | #import "NSKeyedUnarchiver+YYAdd.h" 19 | #import "NSNotificationCenter+YYAdd.h" 20 | #import "NSNumber+YYAdd.h" 21 | #import "NSObject+YYAdd.h" 22 | #import "NSObject+YYAddForKVO.h" 23 | #import "NSString+YYAdd.h" 24 | #import "NSTimer+YYAdd.h" 25 | #import "CALayer+YYAdd.h" 26 | #import "YYCGUtilities.h" 27 | #import "UIApplication+YYAdd.h" 28 | #import "UIBarButtonItem+YYAdd.h" 29 | #import "UIBezierPath+YYAdd.h" 30 | #import "UIColor+YYAdd.h" 31 | #import "UIControl+YYAdd.h" 32 | #import "UIDevice+YYAdd.h" 33 | #import "UIFont+YYAdd.h" 34 | #import "UIGestureRecognizer+YYAdd.h" 35 | #import "UIImage+YYAdd.h" 36 | #import "UIScreen+YYAdd.h" 37 | #import "UIScrollView+YYAdd.h" 38 | #import "UITableView+YYAdd.h" 39 | #import "UITextField+YYAdd.h" 40 | #import "UIView+YYAdd.h" 41 | #import "YYCategories.h" 42 | #import "YYCategoriesMacro.h" 43 | #import "NSObject+YYAddForARC.h" 44 | #import "NSThread+YYAdd.h" 45 | 46 | FOUNDATION_EXPORT double YYCategoriesVersionNumber; 47 | FOUNDATION_EXPORT const unsigned char YYCategoriesVersionString[]; 48 | 49 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSKeyedUnarchiver+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSKeyedUnarchiver+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/4. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `NSKeyedUnarchiver`. 18 | */ 19 | @interface NSKeyedUnarchiver (YYAdd) 20 | 21 | /** 22 | Same as unarchiveObjectWithData:, except it returns the exception by reference. 23 | 24 | @param data The data need unarchived. 25 | 26 | @param exception Pointer which will, upon return, if an exception occurred and 27 | said pointer is not NULL, point to said NSException. 28 | */ 29 | + (nullable id)unarchiveObjectWithData:(NSData *)data 30 | exception:(NSException *_Nullable *_Nullable)exception; 31 | 32 | /** 33 | Same as unarchiveObjectWithFile:, except it returns the exception by reference. 34 | 35 | @param path The path of archived object file. 36 | 37 | @param exception Pointer which will, upon return, if an exception occurred and 38 | said pointer is not NULL, point to said NSException. 39 | */ 40 | + (nullable id)unarchiveObjectWithFile:(NSString *)path 41 | exception:(NSException *_Nullable *_Nullable)exception; 42 | 43 | @end 44 | 45 | NS_ASSUME_NONNULL_END 46 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIScrollView+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/5. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIScrollView`. 18 | */ 19 | @interface UIScrollView (YYAdd) 20 | 21 | /** 22 | Scroll content to top with animation. 23 | */ 24 | - (void)scrollToTop; 25 | 26 | /** 27 | Scroll content to bottom with animation. 28 | */ 29 | - (void)scrollToBottom; 30 | 31 | /** 32 | Scroll content to left with animation. 33 | */ 34 | - (void)scrollToLeft; 35 | 36 | /** 37 | Scroll content to right with animation. 38 | */ 39 | - (void)scrollToRight; 40 | 41 | /** 42 | Scroll content to top. 43 | 44 | @param animated Use animation. 45 | */ 46 | - (void)scrollToTopAnimated:(BOOL)animated; 47 | 48 | /** 49 | Scroll content to bottom. 50 | 51 | @param animated Use animation. 52 | */ 53 | - (void)scrollToBottomAnimated:(BOOL)animated; 54 | 55 | /** 56 | Scroll content to left. 57 | 58 | @param animated Use animation. 59 | */ 60 | - (void)scrollToLeftAnimated:(BOOL)animated; 61 | 62 | /** 63 | Scroll content to right. 64 | 65 | @param animated Use animation. 66 | */ 67 | - (void)scrollToRightAnimated:(BOOL)animated; 68 | 69 | @end 70 | 71 | NS_ASSUME_NONNULL_END 72 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For the FBSnapshotTestCase software 4 | 5 | Copyright (c) 2013, Facebook, Inc. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | * Neither the name Facebook nor the names of its contributors may be used to 17 | endorse or promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @interface UIImage (Diff) 34 | 35 | - (UIImage *)fb_diffWithImage:(UIImage *)image; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @interface UIImage (Compare) 34 | 35 | - (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | /** 18 | Returns a Boolean value that indicates whether the snapshot test is running in 64Bit. 19 | This method is a convenience for creating the suffixes set based on the architecture 20 | that the test is running. 21 | 22 | @returns @c YES if the test is running in 64bit, otherwise @c NO. 23 | */ 24 | BOOL FBSnapshotTestCaseIs64Bit(void); 25 | 26 | /** 27 | Returns a default set of strings that is used to append a suffix based on the architectures. 28 | @warning Do not modify this function, you can create your own and use it with @c FBSnapshotVerifyViewWithOptions() 29 | 30 | @returns An @c NSOrderedSet object containing strings that are appended to the reference images directory. 31 | */ 32 | NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void); 33 | 34 | /** 35 | Returns a fully «normalized» file name. 36 | Strips punctuation and spaces and replaces them with @c _. Also appends the device model, running OS and screen size to the file name. 37 | 38 | @returns An @c NSString object containing the passed @c fileName with the device model, OS and screen size appended at the end. 39 | */ 40 | NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIBarButtonItem+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/10/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UIBarButtonItem+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | #import 15 | 16 | YYSYNTH_DUMMY_CLASS(UIBarButtonItem_YYAdd) 17 | 18 | 19 | static const int block_key; 20 | 21 | @interface _YYUIBarButtonItemBlockTarget : NSObject 22 | 23 | @property (nonatomic, copy) void (^block)(id sender); 24 | 25 | - (id)initWithBlock:(void (^)(id sender))block; 26 | - (void)invoke:(id)sender; 27 | 28 | @end 29 | 30 | @implementation _YYUIBarButtonItemBlockTarget 31 | 32 | - (id)initWithBlock:(void (^)(id sender))block{ 33 | self = [super init]; 34 | if (self) { 35 | _block = [block copy]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void)invoke:(id)sender { 41 | if (self.block) self.block(sender); 42 | } 43 | 44 | @end 45 | 46 | 47 | @implementation UIBarButtonItem (YYAdd) 48 | 49 | - (void)setActionBlock:(void (^)(id sender))block { 50 | _YYUIBarButtonItemBlockTarget *target = [[_YYUIBarButtonItemBlockTarget alloc] initWithBlock:block]; 51 | objc_setAssociatedObject(self, &block_key, target, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 52 | 53 | [self setTarget:target]; 54 | [self setAction:@selector(invoke:)]; 55 | } 56 | 57 | - (void (^)(id)) actionBlock { 58 | _YYUIBarButtonItemBlockTarget *target = objc_getAssociatedObject(self, &block_key); 59 | return target.block; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJTipView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIScrollView+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/5. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UIScrollView+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | 15 | YYSYNTH_DUMMY_CLASS(UIScrollView_YYAdd) 16 | 17 | 18 | @implementation UIScrollView (YYAdd) 19 | 20 | - (void)scrollToTop { 21 | [self scrollToTopAnimated:YES]; 22 | } 23 | 24 | - (void)scrollToBottom { 25 | [self scrollToBottomAnimated:YES]; 26 | } 27 | 28 | - (void)scrollToLeft { 29 | [self scrollToLeftAnimated:YES]; 30 | } 31 | 32 | - (void)scrollToRight { 33 | [self scrollToRightAnimated:YES]; 34 | } 35 | 36 | - (void)scrollToTopAnimated:(BOOL)animated { 37 | CGPoint off = self.contentOffset; 38 | off.y = 0 - self.contentInset.top; 39 | [self setContentOffset:off animated:animated]; 40 | } 41 | 42 | - (void)scrollToBottomAnimated:(BOOL)animated { 43 | CGPoint off = self.contentOffset; 44 | off.y = self.contentSize.height - self.bounds.size.height + self.contentInset.bottom; 45 | [self setContentOffset:off animated:animated]; 46 | } 47 | 48 | - (void)scrollToLeftAnimated:(BOOL)animated { 49 | CGPoint off = self.contentOffset; 50 | off.x = 0 - self.contentInset.left; 51 | [self setContentOffset:off animated:animated]; 52 | } 53 | 54 | - (void)scrollToRightAnimated:(BOOL)animated { 55 | CGPoint off = self.contentOffset; 56 | off.x = self.contentSize.width - self.bounds.size.width + self.contentInset.right; 57 | [self setContentOffset:off animated:animated]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIScreen+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScreen+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/5. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIScreen`. 18 | */ 19 | @interface UIScreen (YYAdd) 20 | 21 | /** 22 | Main screen's scale 23 | 24 | @return screen's scale 25 | */ 26 | + (CGFloat)screenScale; 27 | 28 | /** 29 | Returns the bounds of the screen for the current device orientation. 30 | 31 | @return A rect indicating the bounds of the screen. 32 | @see boundsForOrientation: 33 | */ 34 | - (CGRect)currentBounds NS_EXTENSION_UNAVAILABLE_IOS(""); 35 | 36 | /** 37 | Returns the bounds of the screen for a given device orientation. 38 | `UIScreen`'s `bounds` method always returns the bounds of the 39 | screen of it in the portrait orientation. 40 | 41 | @param orientation The orientation to get the screen's bounds. 42 | @return A rect indicating the bounds of the screen. 43 | @see currentBounds 44 | */ 45 | - (CGRect)boundsForOrientation:(UIInterfaceOrientation)orientation; 46 | 47 | /** 48 | The screen's real size in pixel (width is always smaller than height). 49 | This value may not be very accurate in an unknown device, or simulator. 50 | e.g. (768,1024) 51 | */ 52 | @property (nonatomic, readonly) CGSize sizeInPixel; 53 | 54 | /** 55 | The screen's PPI. 56 | This value may not be very accurate in an unknown device, or simulator. 57 | Default value is 96. 58 | */ 59 | @property (nonatomic, readonly) CGFloat pixelsPerInch; 60 | 61 | @end 62 | 63 | NS_ASSUME_NONNULL_END 64 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAddForKVO.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+YYAddForKVO.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Observer with block (KVO). 18 | */ 19 | @interface NSObject (YYAddForKVO) 20 | 21 | /** 22 | Registers a block to receive KVO notifications for the specified key-path 23 | relative to the receiver. 24 | 25 | @discussion The block and block captured objects are retained. Call 26 | `removeObserverBlocksForKeyPath:` or `removeObserverBlocks` to release. 27 | 28 | @param keyPath The key path, relative to the receiver, of the property to 29 | observe. This value must not be nil. 30 | 31 | @param block The block to register for KVO notifications. 32 | */ 33 | - (void)addObserverBlockForKeyPath:(NSString*)keyPath 34 | block:(void (^)(id _Nonnull obj, id _Nonnull oldVal, id _Nonnull newVal))block; 35 | 36 | /** 37 | Stops all blocks (associated by `addObserverBlockForKeyPath:block:`) from 38 | receiving change notifications for the property specified by a given key-path 39 | relative to the receiver, and release these blocks. 40 | 41 | @param keyPath A key-path, relative to the receiver, for which blocks is 42 | registered to receive KVO change notifications. 43 | */ 44 | - (void)removeObserverBlocksForKeyPath:(NSString*)keyPath; 45 | 46 | /** 47 | Stops all blocks (associated by `addObserverBlockForKeyPath:block:`) from 48 | receiving change notifications, and release these blocks. 49 | */ 50 | - (void)removeObserverBlocks; 51 | 52 | @end 53 | 54 | NS_ASSUME_NONNULL_END 55 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FBSnapshotTestCase 5 | 6 | BSD License 7 | 8 | For the FBSnapshotTestCase software 9 | 10 | Copyright (c) 2013, Facebook, Inc. 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright notice, 19 | this list of conditions and the following disclaimer in the documentation 20 | and/or other materials provided with the distribution. 21 | * Neither the name Facebook nor the names of its contributors may be used to 22 | endorse or promote products derived from this software without specific 23 | prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | Generated by CocoaPods - https://cocoapods.org 37 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | BOOL FBSnapshotTestCaseIs64Bit(void) 16 | { 17 | #if __LP64__ 18 | return YES; 19 | #else 20 | return NO; 21 | #endif 22 | } 23 | 24 | NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void) 25 | { 26 | NSMutableOrderedSet *suffixesSet = [[NSMutableOrderedSet alloc] init]; 27 | [suffixesSet addObject:@"_32"]; 28 | [suffixesSet addObject:@"_64"]; 29 | if (FBSnapshotTestCaseIs64Bit()) { 30 | return [suffixesSet reversedOrderedSet]; 31 | } 32 | return [suffixesSet copy]; 33 | } 34 | 35 | NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName) 36 | { 37 | UIDevice *device = [UIDevice currentDevice]; 38 | UIWindow *keyWindow = [[UIApplication sharedApplication] fb_strictKeyWindow]; 39 | CGSize screenSize = keyWindow.bounds.size; 40 | NSString *os = device.systemVersion; 41 | 42 | fileName = [NSString stringWithFormat:@"%@_%@%@_%.0fx%.0f", fileName, device.model, os, screenSize.width, screenSize.height]; 43 | 44 | NSMutableCharacterSet *invalidCharacters = [NSMutableCharacterSet new]; 45 | [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]]; 46 | [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; 47 | NSArray *validComponents = [fileName componentsSeparatedByCharactersInSet:invalidCharacters]; 48 | fileName = [validComponents componentsJoinedByString:@"_"]; 49 | 50 | return fileName; 51 | } -------------------------------------------------------------------------------- /Example/ZMJTipView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSNumber+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/24. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSNumber+YYAdd.h" 13 | #import "NSString+YYAdd.h" 14 | #import "YYCategoriesMacro.h" 15 | 16 | YYSYNTH_DUMMY_CLASS(NSNumber_YYAdd) 17 | 18 | 19 | @implementation NSNumber (YYAdd) 20 | 21 | + (NSNumber *)numberWithString:(NSString *)string { 22 | NSString *str = [[string stringByTrim] lowercaseString]; 23 | if (!str || !str.length) { 24 | return nil; 25 | } 26 | 27 | static NSDictionary *dic; 28 | static dispatch_once_t onceToken; 29 | dispatch_once(&onceToken, ^{ 30 | dic = @{@"true" : @(YES), 31 | @"yes" : @(YES), 32 | @"false" : @(NO), 33 | @"no" : @(NO), 34 | @"nil" : [NSNull null], 35 | @"null" : [NSNull null], 36 | @"" : [NSNull null]}; 37 | }); 38 | NSNumber *num = dic[str]; 39 | if (num) { 40 | if (num == (id)[NSNull null]) return nil; 41 | return num; 42 | } 43 | 44 | // hex number 45 | int sign = 0; 46 | if ([str hasPrefix:@"0x"]) sign = 1; 47 | else if ([str hasPrefix:@"-0x"]) sign = -1; 48 | if (sign != 0) { 49 | NSScanner *scan = [NSScanner scannerWithString:str]; 50 | unsigned num = -1; 51 | BOOL suc = [scan scanHexInt:&num]; 52 | if (suc) 53 | return [NSNumber numberWithLong:((long)num * sign)]; 54 | else 55 | return nil; 56 | } 57 | // normal number 58 | NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 59 | [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; 60 | return [formatter numberFromString:string]; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Example/ZMJTipView/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /ZMJTipView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint ZMJTipView.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'ZMJTipView' 11 | s.version = '0.1.7' 12 | s.summary = 'Fully customisable tooltip view in Objective-C for iOS.' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | Fully customisable tooltip view in Objective-C for iOS. 22 | Features 23 | Can be shown pointing to any UIBarItem or UIView subclass. 24 | support for any arrow direction ←, →, ↑, ↓ 25 | Automatic orientation change adjustments. 26 | Fully customisable appearance. 27 | Fully customisable presentation and dismissal animations. 28 | Support contain custom view. 29 | DESC 30 | 31 | s.homepage = 'https://github.com/keshiim/ZMJTipView' 32 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 33 | s.license = { :type => 'MIT', :file => 'LICENSE' } 34 | s.author = { 'keshiim' => 'keshiim@163.com' } 35 | s.source = { :git => 'https://github.com/keshiim/ZMJTipView.git', :tag => s.version.to_s } 36 | # s.social_media_url = 'https://twitter.com/' 37 | 38 | s.ios.deployment_target = '8.0' 39 | 40 | s.source_files = 'ZMJTipView/Classes/**/*' 41 | 42 | # s.resource_bundles = { 43 | # 'ZMJTipView' => ['ZMJTipView/Assets/*.png'] 44 | # } 45 | 46 | # s.public_header_files = 'Pod/Classes/**/*.h' 47 | s.frameworks = 'UIKit' 48 | # s.dependency 'AFNetworking', '~> 2.3' 49 | end 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZMJTipView 2 | 3 | [![CI Status](http://img.shields.io/travis/keshiim/ZMJTipView.svg?style=flat)](https://travis-ci.org/keshiim/ZMJTipView) 4 | [![Version](https://img.shields.io/cocoapods/v/ZMJTipView.svg?style=flat)](http://cocoapods.org/pods/ZMJTipView) 5 | [![License](https://img.shields.io/cocoapods/l/ZMJTipView.svg?style=flat)](http://cocoapods.org/pods/ZMJTipView) 6 | [![Platform](https://img.shields.io/cocoapods/p/ZMJTipView.svg?style=flat)](http://cocoapods.org/pods/ZMJTipView) 7 | 8 | Description 9 | --------------- 10 | ```ZMJTipView``` is a fully customisable tooltip view written in Swift that can be used as a call to action or informative tip. 11 | 12 | ||| 13 | |----------|-------------| 14 | || 15 | 16 | 17 | ## Contents 18 | [Features](#features) 19 | 20 | ## Features 21 | - [x] Can be shown pointing to any ``UIBarItem`` or ``UIView`` subclass. 22 | - [x] support for any arrow direction `←, →, ↑, ↓` 23 | - [x] Automatic orientation change adjustments. 24 | - [x] Fully customisable appearance. 25 | - [x] Fully customisable presentation and dismissal animations. 26 | - [x] Support contain custom view. 27 | 28 | ## Example 29 | 30 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 31 | 32 | ## Requirements 33 | 34 | ## Installation 35 | 36 | ZMJTipView is available through [CocoaPods](http://cocoapods.org). To install 37 | it, simply add the following line to your Podfile: 38 | 39 | ```ruby 40 | pod 'ZMJTipView' 41 | ``` 42 | 43 | ## Author 44 | 45 | keshiim, keshiim@163.com 46 | 47 | ## License 48 | 49 | ZMJTipView is available under the MIT license. See the LICENSE file for more info. 50 | 51 | 52 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJAppDelegate.m 3 | // ZMJTipView 4 | // 5 | // Created by keshiim on 02/08/2018. 6 | // Copyright (c) 2018 keshiim. All rights reserved. 7 | // 8 | 9 | #import "ZMJAppDelegate.h" 10 | 11 | @implementation ZMJAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIGestureRecognizer+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIGestureRecognizer+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/10/13. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UIGestureRecognizer+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | #import 15 | 16 | static const int block_key; 17 | 18 | @interface _YYUIGestureRecognizerBlockTarget : NSObject 19 | 20 | @property (nonatomic, copy) void (^block)(id sender); 21 | 22 | - (id)initWithBlock:(void (^)(id sender))block; 23 | - (void)invoke:(id)sender; 24 | 25 | @end 26 | 27 | @implementation _YYUIGestureRecognizerBlockTarget 28 | 29 | - (id)initWithBlock:(void (^)(id sender))block{ 30 | self = [super init]; 31 | if (self) { 32 | _block = [block copy]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)invoke:(id)sender { 38 | if (_block) _block(sender); 39 | } 40 | 41 | @end 42 | 43 | 44 | 45 | 46 | @implementation UIGestureRecognizer (YYAdd) 47 | 48 | - (instancetype)initWithActionBlock:(void (^)(id sender))block { 49 | self = [self init]; 50 | [self addActionBlock:block]; 51 | return self; 52 | } 53 | 54 | - (void)addActionBlock:(void (^)(id sender))block { 55 | _YYUIGestureRecognizerBlockTarget *target = [[_YYUIGestureRecognizerBlockTarget alloc] initWithBlock:block]; 56 | [self addTarget:target action:@selector(invoke:)]; 57 | NSMutableArray *targets = [self _yy_allUIGestureRecognizerBlockTargets]; 58 | [targets addObject:target]; 59 | } 60 | 61 | - (void)removeAllActionBlocks{ 62 | NSMutableArray *targets = [self _yy_allUIGestureRecognizerBlockTargets]; 63 | [targets enumerateObjectsUsingBlock:^(id target, NSUInteger idx, BOOL *stop) { 64 | [self removeTarget:target action:@selector(invoke:)]; 65 | }]; 66 | [targets removeAllObjects]; 67 | } 68 | 69 | - (NSMutableArray *)_yy_allUIGestureRecognizerBlockTargets { 70 | NSMutableArray *targets = objc_getAssociatedObject(self, &block_key); 71 | if (!targets) { 72 | targets = [NSMutableArray array]; 73 | objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 74 | } 75 | return targets; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | @implementation UIImage (Snapshot) 15 | 16 | + (UIImage *)fb_imageForLayer:(CALayer *)layer 17 | { 18 | CGRect bounds = layer.bounds; 19 | NSAssert1(CGRectGetWidth(bounds), @"Zero width for layer %@", layer); 20 | NSAssert1(CGRectGetHeight(bounds), @"Zero height for layer %@", layer); 21 | 22 | UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); 23 | CGContextRef context = UIGraphicsGetCurrentContext(); 24 | NSAssert1(context, @"Could not generate context for layer %@", layer); 25 | CGContextSaveGState(context); 26 | [layer layoutIfNeeded]; 27 | [layer renderInContext:context]; 28 | CGContextRestoreGState(context); 29 | 30 | UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); 31 | UIGraphicsEndImageContext(); 32 | return snapshot; 33 | } 34 | 35 | + (UIImage *)fb_imageForViewLayer:(UIView *)view 36 | { 37 | [view layoutIfNeeded]; 38 | return [self fb_imageForLayer:view.layer]; 39 | } 40 | 41 | + (UIImage *)fb_imageForView:(UIView *)view 42 | { 43 | CGRect bounds = view.bounds; 44 | NSAssert1(CGRectGetWidth(bounds), @"Zero width for view %@", view); 45 | NSAssert1(CGRectGetHeight(bounds), @"Zero height for view %@", view); 46 | 47 | // If the input view is already a UIWindow, then just use that. Otherwise wrap in a window. 48 | UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *)view : view.window; 49 | BOOL removeFromSuperview = NO; 50 | if (!window) { 51 | window = [[UIApplication sharedApplication] fb_strictKeyWindow]; 52 | } 53 | 54 | if (!view.window && view != window) { 55 | [window addSubview:view]; 56 | removeFromSuperview = YES; 57 | } 58 | 59 | UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); 60 | [view layoutIfNeeded]; 61 | [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; 62 | 63 | UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); 64 | UIGraphicsEndImageContext(); 65 | 66 | if (removeFromSuperview) { 67 | [view removeFromSuperview]; 68 | } 69 | 70 | return snapshot; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## YYCategories 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 ibireme 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | 30 | ## ZMJTipView 31 | 32 | Copyright (c) 2018 keshiim 33 | 34 | Permission is hereby granted, free of charge, to any person obtaining a copy 35 | of this software and associated documentation files (the "Software"), to deal 36 | in the Software without restriction, including without limitation the rights 37 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 | copies of the Software, and to permit persons to whom the Software is 39 | furnished to do so, subject to the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included in 42 | all copies or substantial portions of the Software. 43 | 44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 50 | THE SOFTWARE. 51 | 52 | Generated by CocoaPods - https://cocoapods.org 53 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | @implementation UIImage (Diff) 34 | 35 | - (UIImage *)fb_diffWithImage:(UIImage *)image 36 | { 37 | if (!image) { 38 | return nil; 39 | } 40 | CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); 41 | UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); 42 | CGContextRef context = UIGraphicsGetCurrentContext(); 43 | [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; 44 | CGContextSetAlpha(context, 0.5); 45 | CGContextBeginTransparencyLayer(context, NULL); 46 | [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; 47 | CGContextSetBlendMode(context, kCGBlendModeDifference); 48 | CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor); 49 | CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); 50 | CGContextEndTransparencyLayer(context); 51 | UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); 52 | UIGraphicsEndImageContext(); 53 | return returnImage; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIBezierPath+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBezierPath+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/30. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UIBezierPath+YYAdd.h" 13 | #import "UIFont+YYAdd.h" 14 | #import 15 | #import "YYCategoriesMacro.h" 16 | 17 | YYSYNTH_DUMMY_CLASS(UIBezierPath_YYAdd) 18 | 19 | 20 | @implementation UIBezierPath (YYAdd) 21 | 22 | + (UIBezierPath *)bezierPathWithText:(NSString *)text font:(UIFont *)font { 23 | CTFontRef ctFont = font.CTFontRef; 24 | if (!ctFont) return nil; 25 | NSDictionary *attrs = @{ (__bridge id)kCTFontAttributeName:(__bridge id)ctFont }; 26 | NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:text attributes:attrs]; 27 | CFRelease(ctFont); 28 | 29 | CTLineRef line = CTLineCreateWithAttributedString((__bridge CFTypeRef)attrString); 30 | if (!line) return nil; 31 | 32 | CGMutablePathRef cgPath = CGPathCreateMutable(); 33 | CFArrayRef runs = CTLineGetGlyphRuns(line); 34 | for (CFIndex iRun = 0, iRunMax = CFArrayGetCount(runs); iRun < iRunMax; iRun++) { 35 | CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, iRun); 36 | CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName); 37 | 38 | for (CFIndex iGlyph = 0, iGlyphMax = CTRunGetGlyphCount(run); iGlyph < iGlyphMax; iGlyph++) { 39 | CFRange glyphRange = CFRangeMake(iGlyph, 1); 40 | CGGlyph glyph; 41 | CGPoint position; 42 | CTRunGetGlyphs(run, glyphRange, &glyph); 43 | CTRunGetPositions(run, glyphRange, &position); 44 | 45 | CGPathRef glyphPath = CTFontCreatePathForGlyph(runFont, glyph, NULL); 46 | if (glyphPath) { 47 | CGAffineTransform transform = CGAffineTransformMakeTranslation(position.x, position.y); 48 | CGPathAddPath(cgPath, &transform, glyphPath); 49 | CGPathRelease(glyphPath); 50 | } 51 | } 52 | } 53 | UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:cgPath]; 54 | CGRect boundingBox = CGPathGetPathBoundingBox(cgPath); 55 | CFRelease(cgPath); 56 | CFRelease(line); 57 | 58 | [path applyTransform:CGAffineTransformMakeScale(1.0, -1.0)]; 59 | [path applyTransform:CGAffineTransformMakeTranslation(0.0, boundingBox.size.height)]; 60 | 61 | return path; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSTimer+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimer+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/15/11. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `NSTimer`. 18 | */ 19 | @interface NSTimer (YYAdd) 20 | 21 | /** 22 | Creates and returns a new NSTimer object and schedules it on the current run 23 | loop in the default mode. 24 | 25 | @discussion After seconds seconds have elapsed, the timer fires, 26 | sending the message aSelector to target. 27 | 28 | @param seconds The number of seconds between firings of the timer. If seconds 29 | is less than or equal to 0.0, this method chooses the 30 | nonnegative value of 0.1 milliseconds instead. 31 | 32 | @param block The block to invoke when the timer fires. The timer maintains 33 | a strong reference to the block until it (the timer) is invalidated. 34 | 35 | @param repeats If YES, the timer will repeatedly reschedule itself until 36 | invalidated. If NO, the timer will be invalidated after it fires. 37 | 38 | @return A new NSTimer object, configured according to the specified parameters. 39 | */ 40 | + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds block:(void (^)(NSTimer *timer))block repeats:(BOOL)repeats; 41 | 42 | /** 43 | Creates and returns a new NSTimer object initialized with the specified block. 44 | 45 | @discussion You must add the new timer to a run loop, using addTimer:forMode:. 46 | Then, after seconds have elapsed, the timer fires, invoking 47 | block. (If the timer is configured to repeat, there is no need 48 | to subsequently re-add the timer to the run loop.) 49 | 50 | @param seconds The number of seconds between firings of the timer. If seconds 51 | is less than or equal to 0.0, this method chooses the 52 | nonnegative value of 0.1 milliseconds instead. 53 | 54 | @param block The block to invoke when the timer fires. The timer instructs 55 | the block to maintain a strong reference to its arguments. 56 | 57 | @param repeats If YES, the timer will repeatedly reschedule itself until 58 | invalidated. If NO, the timer will be invalidated after it fires. 59 | 60 | @return A new NSTimer object, configured according to the specified parameters. 61 | */ 62 | + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)seconds block:(void (^)(NSTimer *timer))block repeats:(BOOL)repeats; 63 | 64 | @end 65 | 66 | NS_ASSUME_NONNULL_END 67 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | BSD License 18 | 19 | For the FBSnapshotTestCase software 20 | 21 | Copyright (c) 2013, Facebook, Inc. 22 | All rights reserved. 23 | 24 | Redistribution and use in source and binary forms, with or without 25 | modification, are permitted provided that the following conditions are met: 26 | 27 | * Redistributions of source code must retain the above copyright notice, 28 | this list of conditions and the following disclaimer. 29 | * Redistributions in binary form must reproduce the above copyright notice, 30 | this list of conditions and the following disclaimer in the documentation 31 | and/or other materials provided with the distribution. 32 | * Neither the name Facebook nor the names of its contributors may be used to 33 | endorse or promote products derived from this software without specific 34 | prior written permission. 35 | 36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 37 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 40 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 42 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 43 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | 47 | License 48 | BSD 49 | Title 50 | FBSnapshotTestCase 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | FooterText 56 | Generated by CocoaPods - https://cocoapods.org 57 | Title 58 | 59 | Type 60 | PSGroupSpecifier 61 | 62 | 63 | StringsTable 64 | Acknowledgements 65 | Title 66 | Acknowledgements 67 | 68 | 69 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIApplication+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/4. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIApplication`. 18 | */ 19 | @interface UIApplication (YYAdd) 20 | 21 | /// "Documents" folder in this app's sandbox. 22 | @property (nonatomic, readonly) NSURL *documentsURL; 23 | @property (nonatomic, readonly) NSString *documentsPath; 24 | 25 | /// "Caches" folder in this app's sandbox. 26 | @property (nonatomic, readonly) NSURL *cachesURL; 27 | @property (nonatomic, readonly) NSString *cachesPath; 28 | 29 | /// "Library" folder in this app's sandbox. 30 | @property (nonatomic, readonly) NSURL *libraryURL; 31 | @property (nonatomic, readonly) NSString *libraryPath; 32 | 33 | /// Application's Bundle Name (show in SpringBoard). 34 | @property (nullable, nonatomic, readonly) NSString *appBundleName; 35 | 36 | /// Application's Bundle ID. e.g. "com.ibireme.MyApp" 37 | @property (nullable, nonatomic, readonly) NSString *appBundleID; 38 | 39 | /// Application's Version. e.g. "1.2.0" 40 | @property (nullable, nonatomic, readonly) NSString *appVersion; 41 | 42 | /// Application's Build number. e.g. "123" 43 | @property (nullable, nonatomic, readonly) NSString *appBuildVersion; 44 | 45 | /// Whether this app is priated (not install from appstore). 46 | @property (nonatomic, readonly) BOOL isPirated; 47 | 48 | /// Whether this app is being debugged (debugger attached). 49 | @property (nonatomic, readonly) BOOL isBeingDebugged; 50 | 51 | /// Current thread real memory used in byte. (-1 when error occurs) 52 | @property (nonatomic, readonly) int64_t memoryUsage; 53 | 54 | /// Current thread CPU usage, 1.0 means 100%. (-1 when error occurs) 55 | @property (nonatomic, readonly) float cpuUsage; 56 | 57 | 58 | /** 59 | Increments the number of active network requests. 60 | If this number was zero before incrementing, this will start animating the 61 | status bar network activity indicator. 62 | 63 | This method is thread safe. 64 | */ 65 | - (void)incrementNetworkActivityCount; 66 | 67 | /** 68 | Decrements the number of active network requests. 69 | If this number becomes zero after decrementing, this will stop animating the 70 | status bar network activity indicator. 71 | 72 | This method is thread safe. 73 | */ 74 | - (void)decrementNetworkActivityCount; 75 | 76 | 77 | /// Returns YES in App Extension. 78 | + (BOOL)isAppExtension; 79 | 80 | /// Same as sharedApplication, but returns nil in App Extension. 81 | + (nullable UIApplication *)sharedExtensionApplication; 82 | 83 | @end 84 | 85 | NS_ASSUME_NONNULL_END 86 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIControl+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/5. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIControl`. 18 | */ 19 | @interface UIControl (YYAdd) 20 | 21 | /** 22 | Removes all targets and actions for a particular event (or events) 23 | from an internal dispatch table. 24 | */ 25 | - (void)removeAllTargets; 26 | 27 | /** 28 | Adds or replaces a target and action for a particular event (or events) 29 | to an internal dispatch table. 30 | 31 | @param target The target object—that is, the object to which the 32 | action message is sent. If this is nil, the responder 33 | chain is searched for an object willing to respond to the 34 | action message. 35 | 36 | @param action A selector identifying an action message. It cannot be NULL. 37 | 38 | @param controlEvents A bitmask specifying the control events for which the 39 | action message is sent. 40 | */ 41 | - (void)setTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; 42 | 43 | /** 44 | Adds a block for a particular event (or events) to an internal dispatch table. 45 | It will cause a strong reference to @a block. 46 | 47 | @param block The block which is invoked then the action message is 48 | sent (cannot be nil). The block is retained. 49 | 50 | @param controlEvents A bitmask specifying the control events for which the 51 | action message is sent. 52 | */ 53 | - (void)addBlockForControlEvents:(UIControlEvents)controlEvents block:(void (^)(id sender))block; 54 | 55 | /** 56 | Adds or replaces a block for a particular event (or events) to an internal 57 | dispatch table. It will cause a strong reference to @a block. 58 | 59 | @param block The block which is invoked then the action message is 60 | sent (cannot be nil). The block is retained. 61 | 62 | @param controlEvents A bitmask specifying the control events for which the 63 | action message is sent. 64 | */ 65 | - (void)setBlockForControlEvents:(UIControlEvents)controlEvents block:(void (^)(id sender))block; 66 | 67 | /** 68 | Removes all blocks for a particular event (or events) from an internal 69 | dispatch table. 70 | 71 | @param controlEvents A bitmask specifying the control events for which the 72 | action message is sent. 73 | */ 74 | - (void)removeAllBlocksForControlEvents:(UIControlEvents)controlEvents; 75 | 76 | @end 77 | 78 | NS_ASSUME_NONNULL_END 79 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSNotificationCenter+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNotificationCenter+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/24. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSNotificationCenter+YYAdd.h" 13 | #include 14 | #import "YYCategoriesMacro.h" 15 | 16 | YYSYNTH_DUMMY_CLASS(NSNotificationCenter_YYAdd) 17 | 18 | 19 | @implementation NSNotificationCenter (YYAdd) 20 | 21 | - (void)postNotificationOnMainThread:(NSNotification *)notification { 22 | if (pthread_main_np()) return [self postNotification:notification]; 23 | [self postNotificationOnMainThread:notification waitUntilDone:NO]; 24 | } 25 | 26 | - (void)postNotificationOnMainThread:(NSNotification *)notification waitUntilDone:(BOOL)wait { 27 | if (pthread_main_np()) return [self postNotification:notification]; 28 | [[self class] performSelectorOnMainThread:@selector(_yy_postNotification:) withObject:notification waitUntilDone:wait]; 29 | } 30 | 31 | - (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object { 32 | if (pthread_main_np()) return [self postNotificationName:name object:object userInfo:nil]; 33 | [self postNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO]; 34 | } 35 | 36 | - (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo { 37 | if (pthread_main_np()) return [self postNotificationName:name object:object userInfo:userInfo]; 38 | [self postNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO]; 39 | } 40 | 41 | - (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo waitUntilDone:(BOOL)wait { 42 | if (pthread_main_np()) return [self postNotificationName:name object:object userInfo:userInfo]; 43 | NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:3]; 44 | if (name) [info setObject:name forKey:@"name"]; 45 | if (object) [info setObject:object forKey:@"object"]; 46 | if (userInfo) [info setObject:userInfo forKey:@"userInfo"]; 47 | [[self class] performSelectorOnMainThread:@selector(_yy_postNotificationName:) withObject:info waitUntilDone:wait]; 48 | } 49 | 50 | + (void)_yy_postNotification:(NSNotification *)notification { 51 | [[self defaultCenter] postNotification:notification]; 52 | } 53 | 54 | + (void)_yy_postNotificationName:(NSDictionary *)info { 55 | NSString *name = [info objectForKey:@"name"]; 56 | id object = [info objectForKey:@"object"]; 57 | NSDictionary *userInfo = [info objectForKey:@"userInfo"]; 58 | 59 | [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo]; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Example/ZMJTipView/UIView+Frame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.h 3 | // Trader 4 | // 5 | // Created by Mingfei Huang on 9/17/15. 6 | // 7 | // 8 | 9 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 10 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 11 | 12 | #import 13 | 14 | @interface UIView (WBGFrame) 15 | 16 | @property (nonatomic) CGFloat x; 17 | @property (nonatomic) CGFloat y; 18 | 19 | @property (nonatomic, readonly) CGFloat maxX; 20 | @property (nonatomic, readonly) CGFloat maxY; 21 | 22 | @property (nonatomic, readonly) CGPoint boundCenter; 23 | 24 | /// [平移]这个view, 让view.maxX = maxX 25 | - (void)setMaxXByShift:(CGFloat)maxX; 26 | 27 | /// [拉伸]这个view, 让view.maxX = maxX 28 | - (void)setMaxXByStretch:(CGFloat)maxX; 29 | 30 | /// [平移]这个view, 让view.maxY = maxY 31 | - (void)setMaxYByShift:(CGFloat)maxY; 32 | 33 | /// [拉伸]这个view, 让view.maxY = maxY 34 | - (void)setMaxYByStretch:(CGFloat)maxY; 35 | 36 | @property (nonatomic, /* setonly */ setter=setMaxXByShift:, getter=maxX) CGFloat maxXByShift; 37 | @property (nonatomic, /* setonly */ setter=setMaxYByShift:, getter=maxY) CGFloat maxYByShift; 38 | @property (nonatomic, /* setonly */ setter=setMaxXByStretch:, getter=maxX) CGFloat maxXByStretch; 39 | @property (nonatomic, /* setonly */ setter=setMaxYByStretch:, getter=maxY) CGFloat maxYByStretch; 40 | 41 | @end 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | // ======================================================================== 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | @interface CALayer (WBGFrame) 61 | 62 | @property (nonatomic) CGFloat x; 63 | @property (nonatomic) CGFloat y; 64 | 65 | @property (nonatomic, readonly) CGFloat maxX; 66 | @property (nonatomic, readonly) CGFloat maxY; 67 | 68 | @property (nonatomic, readonly) CGPoint boundCenter; 69 | 70 | - (void)setMaxXByShift:(CGFloat)maxX; 71 | - (void)setMaxXByStretch:(CGFloat)maxX; 72 | 73 | - (void)setMaxYByShift:(CGFloat)maxY; 74 | - (void)setMaxYByStretch:(CGFloat)maxY; 75 | 76 | @end 77 | 78 | 79 | 80 | 81 | 82 | // ======================================================================== 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | @interface UICollectionViewLayoutAttributes (WBGFrame) 93 | 94 | @property (nonatomic) CGFloat x; 95 | @property (nonatomic) CGFloat y; 96 | @property (nonatomic) CGFloat width; 97 | @property (nonatomic) CGFloat height; 98 | 99 | 100 | @property (nonatomic, readonly) CGFloat maxX; 101 | @property (nonatomic, readonly) CGFloat maxY; 102 | 103 | @property (nonatomic, readonly) CGPoint boundCenter; 104 | 105 | - (void)setMaxXByShift:(CGFloat)maxX; 106 | - (void)setMaxXByStretch:(CGFloat)maxX; 107 | 108 | - (void)setMaxYByShift:(CGFloat)maxY; 109 | - (void)setMaxYByStretch:(CGFloat)maxY; 110 | 111 | @property (nonatomic) CGFloat centerX; 112 | @property (nonatomic) CGFloat centerY; 113 | 114 | @end 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/YYCategories.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYCategories.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/3/29. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | #if __has_include() 15 | FOUNDATION_EXPORT double YYCategoriesVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char YYCategoriesVersionString[]; 17 | #import 18 | #import 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #import 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | #import 37 | #import 38 | #import 39 | #import 40 | #import 41 | #import 42 | #import 43 | #import 44 | #import 45 | #import 46 | #import 47 | #import 48 | #else 49 | #import "YYCategoriesMacro.h" 50 | #import "NSObject+YYAdd.h" 51 | #import "NSObject+YYAddForKVO.h" 52 | #import "NSObject+YYAddForARC.h" 53 | #import "NSData+YYAdd.h" 54 | #import "NSString+YYAdd.h" 55 | #import "NSArray+YYAdd.h" 56 | #import "NSDictionary+YYAdd.h" 57 | #import "NSDate+YYAdd.h" 58 | #import "NSNumber+YYAdd.h" 59 | #import "NSNotificationCenter+YYAdd.h" 60 | #import "NSKeyedUnarchiver+YYAdd.h" 61 | #import "NSTimer+YYAdd.h" 62 | #import "NSBundle+YYAdd.h" 63 | #import "NSThread+YYAdd.h" 64 | #import "UIColor+YYAdd.h" 65 | #import "UIImage+YYAdd.h" 66 | #import "UIControl+YYAdd.h" 67 | #import "UIBarButtonItem+YYAdd.h" 68 | #import "UIGestureRecognizer+YYAdd.h" 69 | #import "UIView+YYAdd.h" 70 | #import "UIScrollView+YYAdd.h" 71 | #import "UITableView+YYAdd.h" 72 | #import "UITextField+YYAdd.h" 73 | #import "UIScreen+YYAdd.h" 74 | #import "UIDevice+YYAdd.h" 75 | #import "UIApplication+YYAdd.h" 76 | #import "UIFont+YYAdd.h" 77 | #import "UIBezierPath+YYAdd.h" 78 | #import "CALayer+YYAdd.h" 79 | #import "YYCGUtilities.h" 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSBundle+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/20. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSBundle+YYAdd.h" 13 | #import "NSString+YYAdd.h" 14 | #import "YYCategoriesMacro.h" 15 | 16 | YYSYNTH_DUMMY_CLASS(NSBundle_YYAdd) 17 | 18 | @implementation NSBundle (YYAdd) 19 | 20 | + (NSArray *)preferredScales { 21 | static NSArray *scales; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | CGFloat screenScale = [UIScreen mainScreen].scale; 25 | if (screenScale <= 1) { 26 | scales = @[@1,@2,@3]; 27 | } else if (screenScale <= 2) { 28 | scales = @[@2,@3,@1]; 29 | } else { 30 | scales = @[@3,@2,@1]; 31 | } 32 | }); 33 | return scales; 34 | } 35 | 36 | + (NSString *)pathForScaledResource:(NSString *)name ofType:(NSString *)ext inDirectory:(NSString *)bundlePath { 37 | if (name.length == 0) return nil; 38 | if ([name hasSuffix:@"/"]) return [self pathForResource:name ofType:ext inDirectory:bundlePath]; 39 | 40 | NSString *path = nil; 41 | NSArray *scales = [self preferredScales]; 42 | for (int s = 0; s < scales.count; s++) { 43 | CGFloat scale = ((NSNumber *)scales[s]).floatValue; 44 | NSString *scaledName = ext.length ? [name stringByAppendingNameScale:scale] 45 | : [name stringByAppendingPathScale:scale]; 46 | path = [self pathForResource:scaledName ofType:ext inDirectory:bundlePath]; 47 | if (path) break; 48 | } 49 | 50 | return path; 51 | } 52 | 53 | - (NSString *)pathForScaledResource:(NSString *)name ofType:(NSString *)ext { 54 | if (name.length == 0) return nil; 55 | if ([name hasSuffix:@"/"]) return [self pathForResource:name ofType:ext]; 56 | 57 | NSString *path = nil; 58 | NSArray *scales = [NSBundle preferredScales]; 59 | for (int s = 0; s < scales.count; s++) { 60 | CGFloat scale = ((NSNumber *)scales[s]).floatValue; 61 | NSString *scaledName = ext.length ? [name stringByAppendingNameScale:scale] 62 | : [name stringByAppendingPathScale:scale]; 63 | path = [self pathForResource:scaledName ofType:ext]; 64 | if (path) break; 65 | } 66 | 67 | return path; 68 | } 69 | 70 | - (NSString *)pathForScaledResource:(NSString *)name ofType:(NSString *)ext inDirectory:(NSString *)subpath { 71 | if (name.length == 0) return nil; 72 | if ([name hasSuffix:@"/"]) return [self pathForResource:name ofType:ext]; 73 | 74 | NSString *path = nil; 75 | NSArray *scales = [NSBundle preferredScales]; 76 | for (int s = 0; s < scales.count; s++) { 77 | CGFloat scale = ((NSNumber *)scales[s]).floatValue; 78 | NSString *scaledName = ext.length ? [name stringByAppendingNameScale:scale] 79 | : [name stringByAppendingPathScale:scale]; 80 | path = [self pathForResource:scaledName ofType:ext inDirectory:subpath]; 81 | if (path) break; 82 | } 83 | 84 | return path; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UITableView+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/5/12. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UITableView+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | 15 | YYSYNTH_DUMMY_CLASS(UITableView_YYAdd) 16 | 17 | 18 | @implementation UITableView (YYAdd) 19 | 20 | - (void)updateWithBlock:(void (^)(UITableView *tableView))block { 21 | [self beginUpdates]; 22 | block(self); 23 | [self endUpdates]; 24 | } 25 | 26 | - (void)scrollToRow:(NSUInteger)row inSection:(NSUInteger)section atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated { 27 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; 28 | [self scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated]; 29 | } 30 | 31 | - (void)insertRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation { 32 | [self insertRowsAtIndexPaths:@[indexPath] withRowAnimation:animation]; 33 | } 34 | 35 | - (void)insertRow:(NSUInteger)row inSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 36 | NSIndexPath *toInsert = [NSIndexPath indexPathForRow:row inSection:section]; 37 | [self insertRowAtIndexPath:toInsert withRowAnimation:animation]; 38 | } 39 | 40 | - (void)reloadRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation { 41 | [self reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:animation]; 42 | } 43 | 44 | - (void)reloadRow:(NSUInteger)row inSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 45 | NSIndexPath *toReload = [NSIndexPath indexPathForRow:row inSection:section]; 46 | [self reloadRowAtIndexPath:toReload withRowAnimation:animation]; 47 | } 48 | 49 | - (void)deleteRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation { 50 | [self deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:animation]; 51 | } 52 | 53 | - (void)deleteRow:(NSUInteger)row inSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 54 | NSIndexPath *toDelete = [NSIndexPath indexPathForRow:row inSection:section]; 55 | [self deleteRowAtIndexPath:toDelete withRowAnimation:animation]; 56 | } 57 | 58 | - (void)insertSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 59 | NSIndexSet *sections = [NSIndexSet indexSetWithIndex:section]; 60 | [self insertSections:sections withRowAnimation:animation]; 61 | } 62 | 63 | - (void)deleteSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 64 | NSIndexSet *sections = [NSIndexSet indexSetWithIndex:section]; 65 | [self deleteSections:sections withRowAnimation:animation]; 66 | } 67 | 68 | - (void)reloadSection:(NSUInteger)section withRowAnimation:(UITableViewRowAnimation)animation { 69 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section]; 70 | [self reloadSections:indexSet withRowAnimation:animation]; 71 | } 72 | 73 | - (void)clearSelectedRowsAnimated:(BOOL)animated { 74 | NSArray *indexs = [self indexPathsForSelectedRows]; 75 | [indexs enumerateObjectsUsingBlock:^(NSIndexPath* path, NSUInteger idx, BOOL *stop) { 76 | [self deselectRowAtIndexPath:path animated:animated]; 77 | }]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 ibireme <ibireme@gmail.com> 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | 40 | License 41 | MIT 42 | Title 43 | YYCategories 44 | Type 45 | PSGroupSpecifier 46 | 47 | 48 | FooterText 49 | Copyright (c) 2018 keshiim <keshiim@163.com> 50 | 51 | Permission is hereby granted, free of charge, to any person obtaining a copy 52 | of this software and associated documentation files (the "Software"), to deal 53 | in the Software without restriction, including without limitation the rights 54 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55 | copies of the Software, and to permit persons to whom the Software is 56 | furnished to do so, subject to the following conditions: 57 | 58 | The above copyright notice and this permission notice shall be included in 59 | all copies or substantial portions of the Software. 60 | 61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 67 | THE SOFTWARE. 68 | 69 | License 70 | MIT 71 | Title 72 | ZMJTipView 73 | Type 74 | PSGroupSpecifier 75 | 76 | 77 | FooterText 78 | Generated by CocoaPods - https://cocoapods.org 79 | Title 80 | 81 | Type 82 | PSGroupSpecifier 83 | 84 | 85 | StringsTable 86 | Acknowledgements 87 | Title 88 | Acknowledgements 89 | 90 | 91 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Quartz/CALayer+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/5/10. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | #import 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | /** 18 | Provides extensions for `CALayer`. 19 | */ 20 | @interface CALayer (YYAdd) 21 | 22 | /** 23 | Take snapshot without transform, image's size equals to bounds. 24 | */ 25 | - (nullable UIImage *)snapshotImage; 26 | 27 | /** 28 | Take snapshot without transform, PDF's page size equals to bounds. 29 | */ 30 | - (nullable NSData *)snapshotPDF; 31 | 32 | /** 33 | Shortcut to set the layer's shadow 34 | 35 | @param color Shadow Color 36 | @param offset Shadow offset 37 | @param radius Shadow radius 38 | */ 39 | - (void)setLayerShadow:(UIColor*)color offset:(CGSize)offset radius:(CGFloat)radius; 40 | 41 | /** 42 | Remove all sublayers. 43 | */ 44 | - (void)removeAllSublayers; 45 | 46 | @property (nonatomic) CGFloat left; ///< Shortcut for frame.origin.x. 47 | @property (nonatomic) CGFloat top; ///< Shortcut for frame.origin.y 48 | @property (nonatomic) CGFloat right; ///< Shortcut for frame.origin.x + frame.size.width 49 | @property (nonatomic) CGFloat bottom; ///< Shortcut for frame.origin.y + frame.size.height 50 | @property (nonatomic) CGFloat width; ///< Shortcut for frame.size.width. 51 | @property (nonatomic) CGFloat height; ///< Shortcut for frame.size.height. 52 | @property (nonatomic) CGPoint center; ///< Shortcut for center. 53 | @property (nonatomic) CGFloat centerX; ///< Shortcut for center.x 54 | @property (nonatomic) CGFloat centerY; ///< Shortcut for center.y 55 | @property (nonatomic) CGPoint origin; ///< Shortcut for frame.origin. 56 | @property (nonatomic, getter=frameSize, setter=setFrameSize:) CGSize size; ///< Shortcut for frame.size. 57 | 58 | 59 | @property (nonatomic) CGFloat transformRotation; ///< key path "tranform.rotation" 60 | @property (nonatomic) CGFloat transformRotationX; ///< key path "tranform.rotation.x" 61 | @property (nonatomic) CGFloat transformRotationY; ///< key path "tranform.rotation.y" 62 | @property (nonatomic) CGFloat transformRotationZ; ///< key path "tranform.rotation.z" 63 | @property (nonatomic) CGFloat transformScale; ///< key path "tranform.scale" 64 | @property (nonatomic) CGFloat transformScaleX; ///< key path "tranform.scale.x" 65 | @property (nonatomic) CGFloat transformScaleY; ///< key path "tranform.scale.y" 66 | @property (nonatomic) CGFloat transformScaleZ; ///< key path "tranform.scale.z" 67 | @property (nonatomic) CGFloat transformTranslationX; ///< key path "tranform.translation.x" 68 | @property (nonatomic) CGFloat transformTranslationY; ///< key path "tranform.translation.y" 69 | @property (nonatomic) CGFloat transformTranslationZ; ///< key path "tranform.translation.z" 70 | 71 | /** 72 | Shortcut for transform.m34, -1/1000 is a good value. 73 | It should be set before other transform shortcut. 74 | */ 75 | @property (nonatomic) CGFloat transformDepth; 76 | 77 | /** 78 | Wrapper for `contentsGravity` property. 79 | */ 80 | @property (nonatomic) UIViewContentMode contentMode; 81 | 82 | /** 83 | Add a fade animation to layer's contents when the contents is changed. 84 | 85 | @param duration Animation duration 86 | @param curve Animation curve. 87 | */ 88 | - (void)addFadeAnimationWithDuration:(NSTimeInterval)duration curve:(UIViewAnimationCurve)curve; 89 | 90 | /** 91 | Cancel fade animation which is added with "-addFadeAnimationWithDuration:curve:". 92 | */ 93 | - (void)removePreviousFadeAnimation; 94 | 95 | @end 96 | 97 | NS_ASSUME_NONNULL_END 98 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSNotificationCenter+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNotificationCenter+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/8/24. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provide some method for `NSNotificationCenter` 18 | to post notification in different thread. 19 | */ 20 | @interface NSNotificationCenter (YYAdd) 21 | 22 | /** 23 | Posts a given notification to the receiver on main thread. 24 | If current thread is main thread, the notification is posted synchronized; 25 | otherwise, is posted asynchronized. 26 | 27 | @param notification The notification to post. 28 | An exception is raised if notification is nil. 29 | */ 30 | - (void)postNotificationOnMainThread:(NSNotification *)notification; 31 | 32 | /** 33 | Posts a given notification to the receiver on main thread. 34 | 35 | @param notification The notification to post. 36 | An exception is raised if notification is nil. 37 | 38 | @param wait A Boolean that specifies whether the current thread blocks 39 | until after the specified notification is posted on the 40 | receiver on the main thread. Specify YES to block this 41 | thread; otherwise, specify NO to have this method return 42 | immediately. 43 | */ 44 | - (void)postNotificationOnMainThread:(NSNotification *)notification 45 | waitUntilDone:(BOOL)wait; 46 | 47 | /** 48 | Creates a notification with a given name and sender and posts it to the 49 | receiver on main thread. If current thread is main thread, the notification 50 | is posted synchronized; otherwise, is posted asynchronized. 51 | 52 | @param name The name of the notification. 53 | 54 | @param object The object posting the notification. 55 | */ 56 | - (void)postNotificationOnMainThreadWithName:(NSString *)name 57 | object:(nullable id)object; 58 | 59 | /** 60 | Creates a notification with a given name and sender and posts it to the 61 | receiver on main thread. If current thread is main thread, the notification 62 | is posted synchronized; otherwise, is posted asynchronized. 63 | 64 | @param name The name of the notification. 65 | 66 | @param object The object posting the notification. 67 | 68 | @param userInfo Information about the the notification. May be nil. 69 | */ 70 | - (void)postNotificationOnMainThreadWithName:(NSString *)name 71 | object:(nullable id)object 72 | userInfo:(nullable NSDictionary *)userInfo; 73 | 74 | /** 75 | Creates a notification with a given name and sender and posts it to the 76 | receiver on main thread. 77 | 78 | @param name The name of the notification. 79 | 80 | @param object The object posting the notification. 81 | 82 | @param userInfo Information about the the notification. May be nil. 83 | 84 | @param wait A Boolean that specifies whether the current thread blocks 85 | until after the specified notification is posted on the 86 | receiver on the main thread. Specify YES to block this 87 | thread; otherwise, specify NO to have this method return 88 | immediately. 89 | */ 90 | - (void)postNotificationOnMainThreadWithName:(NSString *)name 91 | object:(nullable id)object 92 | userInfo:(nullable NSDictionary *)userInfo 93 | waitUntilDone:(BOOL)wait; 94 | 95 | @end 96 | 97 | NS_ASSUME_NONNULL_END 98 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAddForKVO.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+YYAddForKVO.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/15. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSObject+YYAddForKVO.h" 13 | #import "YYCategoriesMacro.h" 14 | #import 15 | #import 16 | 17 | YYSYNTH_DUMMY_CLASS(NSObject_YYAddForKVO) 18 | 19 | 20 | 21 | 22 | static const int block_key; 23 | 24 | @interface _YYNSObjectKVOBlockTarget : NSObject 25 | 26 | @property (nonatomic, copy) void (^block)(__weak id obj, id oldVal, id newVal); 27 | 28 | - (id)initWithBlock:(void (^)(__weak id obj, id oldVal, id newVal))block; 29 | 30 | @end 31 | 32 | @implementation _YYNSObjectKVOBlockTarget 33 | 34 | - (id)initWithBlock:(void (^)(__weak id obj, id oldVal, id newVal))block { 35 | self = [super init]; 36 | if (self) { 37 | self.block = block; 38 | } 39 | return self; 40 | } 41 | 42 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 43 | if (!self.block) return; 44 | 45 | BOOL isPrior = [[change objectForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue]; 46 | if (isPrior) return; 47 | 48 | NSKeyValueChange changeKind = [[change objectForKey:NSKeyValueChangeKindKey] integerValue]; 49 | if (changeKind != NSKeyValueChangeSetting) return; 50 | 51 | id oldVal = [change objectForKey:NSKeyValueChangeOldKey]; 52 | if (oldVal == [NSNull null]) oldVal = nil; 53 | 54 | id newVal = [change objectForKey:NSKeyValueChangeNewKey]; 55 | if (newVal == [NSNull null]) newVal = nil; 56 | 57 | self.block(object, oldVal, newVal); 58 | } 59 | 60 | @end 61 | 62 | 63 | 64 | @implementation NSObject (YYAddForKVO) 65 | 66 | - (void)addObserverBlockForKeyPath:(NSString *)keyPath block:(void (^)(__weak id obj, id oldVal, id newVal))block { 67 | if (!keyPath || !block) return; 68 | _YYNSObjectKVOBlockTarget *target = [[_YYNSObjectKVOBlockTarget alloc] initWithBlock:block]; 69 | NSMutableDictionary *dic = [self _yy_allNSObjectObserverBlocks]; 70 | NSMutableArray *arr = dic[keyPath]; 71 | if (!arr) { 72 | arr = [NSMutableArray new]; 73 | dic[keyPath] = arr; 74 | } 75 | [arr addObject:target]; 76 | [self addObserver:target forKeyPath:keyPath options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL]; 77 | } 78 | 79 | - (void)removeObserverBlocksForKeyPath:(NSString *)keyPath { 80 | if (!keyPath) return; 81 | NSMutableDictionary *dic = [self _yy_allNSObjectObserverBlocks]; 82 | NSMutableArray *arr = dic[keyPath]; 83 | [arr enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { 84 | [self removeObserver:obj forKeyPath:keyPath]; 85 | }]; 86 | 87 | [dic removeObjectForKey:keyPath]; 88 | } 89 | 90 | - (void)removeObserverBlocks { 91 | NSMutableDictionary *dic = [self _yy_allNSObjectObserverBlocks]; 92 | [dic enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSArray *arr, BOOL *stop) { 93 | [arr enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { 94 | [self removeObserver:obj forKeyPath:key]; 95 | }]; 96 | }]; 97 | 98 | [dic removeAllObjects]; 99 | } 100 | 101 | - (NSMutableDictionary *)_yy_allNSObjectObserverBlocks { 102 | NSMutableDictionary *targets = objc_getAssociatedObject(self, &block_key); 103 | if (!targets) { 104 | targets = [NSMutableDictionary new]; 105 | objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 106 | } 107 | return targets; 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSBundle+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/10/20. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `NSBundle` to get resource by @2x or @3x... 18 | 19 | Example: ico.png, ico@2x.png, ico@3x.png. Call scaledResource:@"ico" ofType:@"png" 20 | on iPhone6 will return "ico@2x.png"'s path. 21 | */ 22 | @interface NSBundle (YYAdd) 23 | 24 | /** 25 | An array of NSNumber objects, shows the best order for path scale search. 26 | e.g. iPhone3GS:@[@1,@2,@3] iPhone5:@[@2,@3,@1] iPhone6 Plus:@[@3,@2,@1] 27 | */ 28 | + (NSArray *)preferredScales; 29 | 30 | /** 31 | Returns the full pathname for the resource file identified by the specified 32 | name and extension and residing in a given bundle directory. It first search 33 | the file with current screen's scale (such as @2x), then search from higher 34 | scale to lower scale. 35 | 36 | @param name The name of a resource file contained in the directory 37 | specified by bundlePath. 38 | 39 | @param ext If extension is an empty string or nil, the extension is 40 | assumed not to exist and the file is the first file encountered that exactly matches name. 41 | 42 | @param bundlePath The path of a top-level bundle directory. This must be a 43 | valid path. For example, to specify the bundle directory for a Mac app, you 44 | might specify the path /Applications/MyApp.app. 45 | 46 | @return The full pathname for the resource file or nil if the file could not be 47 | located. This method also returns nil if the bundle specified by the bundlePath 48 | parameter does not exist or is not a readable directory. 49 | */ 50 | + (nullable NSString *)pathForScaledResource:(NSString *)name 51 | ofType:(nullable nullable NSString *)ext 52 | inDirectory:(NSString *)bundlePath; 53 | 54 | /** 55 | Returns the full pathname for the resource identified by the specified name and 56 | file extension. It first search the file with current screen's scale (such as @2x), 57 | then search from higher scale to lower scale. 58 | 59 | @param name The name of the resource file. If name is an empty string or 60 | nil, returns the first file encountered of the supplied type. 61 | 62 | @param ext If extension is an empty string or nil, the extension is 63 | assumed not to exist and the file is the first file encountered that exactly matches name. 64 | 65 | 66 | @return The full pathname for the resource file or nil if the file could not be located. 67 | */ 68 | - (nullable NSString *)pathForScaledResource:(NSString *)name ofType:(nullable NSString *)ext; 69 | 70 | /** 71 | Returns the full pathname for the resource identified by the specified name and 72 | file extension and located in the specified bundle subdirectory. It first search 73 | the file with current screen's scale (such as @2x), then search from higher 74 | scale to lower scale. 75 | 76 | @param name The name of the resource file. 77 | 78 | @param ext If extension is an empty string or nil, all the files in 79 | subpath and its subdirectories are returned. If an extension is provided the 80 | subdirectories are not searched. 81 | 82 | @param subpath The name of the bundle subdirectory. Can be nil. 83 | 84 | @return The full pathname for the resource file or nil if the file could not be located. 85 | */ 86 | - (nullable NSString *)pathForScaledResource:(NSString *)name 87 | ofType:(nullable NSString *)ext 88 | inDirectory:(nullable NSString *)subpath; 89 | 90 | @end 91 | 92 | NS_ASSUME_NONNULL_END 93 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/README.md: -------------------------------------------------------------------------------- 1 | FBSnapshotTestCase 2 | ====================== 3 | 4 | [![Build Status](https://travis-ci.org/facebook/ios-snapshot-test-case.svg)](https://travis-ci.org/facebook/ios-snapshot-test-case) [![Cocoa Pod Version](https://cocoapod-badges.herokuapp.com/v/FBSnapshotTestCase/badge.svg)](http://cocoadocs.org/docsets/FBSnapshotTestCase/) 5 | 6 | What it does 7 | ------------ 8 | 9 | A "snapshot test case" takes a configured `UIView` or `CALayer` and uses the 10 | `renderInContext:` method to get an image snapshot of its contents. It 11 | compares this snapshot to a "reference image" stored in your source code 12 | repository and fails the test if the two images don't match. 13 | 14 | Why? 15 | ---- 16 | 17 | At Facebook we write a lot of UI code. As you might imagine, each type of 18 | feed story is rendered using a subclass of `UIView`. There are a lot of edge 19 | cases that we want to handle correctly: 20 | 21 | - What if there is more text than can fit in the space available? 22 | - What if an image doesn't match the size of an image view? 23 | - What should the highlighted state look like? 24 | 25 | It's straightforward to test logic code, but less obvious how you should test 26 | views. You can do a lot of rectangle asserts, but these are hard to understand 27 | or visualize. Looking at an image diff shows you exactly what changed and how 28 | it will look to users. 29 | 30 | We developed `FBSnapshotTestCase` to make snapshot tests easy. 31 | 32 | Installation with CocoaPods 33 | --------------------------- 34 | 35 | 1. Add the following lines to your Podfile: 36 | 37 | ``` 38 | target "Tests" do 39 | pod 'FBSnapshotTestCase' 40 | end 41 | ``` 42 | 43 | If you support iOS 7 use `FBSnapshotTestCase/Core` instead, which doesn't contain Swift support. 44 | 45 | Replace "Tests" with the name of your test project. 46 | 47 | 2. There are [three ways](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCase/FBSnapshotTestCase.h#L19-L29) of setting reference image directories, the recommended one is to define `FB_REFERENCE_IMAGE_DIR` in your scheme. This should point to the directory where you want reference images to be stored. At Facebook, we normally use this: 48 | 49 | |Name|Value| 50 | |:---|:----| 51 | |`FB_REFERENCE_IMAGE_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages`| 52 | 53 | 54 | ![](FBSnapshotTestCaseDemo/Scheme_FB_REFERENCE_IMAGE_DIR.png) 55 | 56 | Creating a snapshot test 57 | ------------------------ 58 | 59 | 1. Subclass `FBSnapshotTestCase` instead of `XCTestCase`. 60 | 2. From within your test, use `FBSnapshotVerifyView`. 61 | 3. Run the test once with `self.recordMode = YES;` in the test's `-setUp` 62 | method. (This creates the reference images on disk.) 63 | 4. Remove the line enabling record mode and run the test. 64 | 65 | Features 66 | -------- 67 | 68 | - Automatically names reference images on disk according to test class and 69 | selector. 70 | - Prints a descriptive error message to the console on failure. (Bonus: 71 | failure message includes a one-line command to see an image diff if 72 | you have [Kaleidoscope](http://www.kaleidoscopeapp.com) installed.) 73 | - Supply an optional "identifier" if you want to perform multiple snapshots 74 | in a single test method. 75 | - Support for `CALayer` via `FBSnapshotVerifyLayer`. 76 | - `usesDrawViewHierarchyInRect` to handle cases like `UIVisualEffect`, `UIAppearance` and Size Classes. 77 | - `isDeviceAgnostic` to allow appending the device model (`iPhone`, `iPad`, `iPod Touch`, etc), OS version and screen size to the images (allowing to have multiple tests for the same «snapshot» for different `OS`s and devices). 78 | 79 | Notes 80 | ----- 81 | 82 | Your unit test must be an "application test", not a "logic test." (That is, it 83 | must be run within the Simulator so that it has access to UIKit.) In Xcode 5 84 | and later new projects only offer application tests, but older projects will 85 | have separate targets for the two types. 86 | 87 | Authors 88 | ------- 89 | 90 | `FBSnapshotTestCase` was written at Facebook by 91 | [Jonathan Dann](https://facebook.com/j.p.dann) with significant contributions by 92 | [Todd Krabach](https://facebook.com/toddkrabach). 93 | 94 | License 95 | ------- 96 | 97 | `FBSnapshotTestCase` is BSD-licensed. See `LICENSE`. 98 | -------------------------------------------------------------------------------- /Example/ZMJTipView.xcodeproj/xcshareddata/xcschemes/ZMJTipView-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 68 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 87 | 93 | 94 | 95 | 96 | 98 | 99 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIControl+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/5. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "UIControl+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | #import 15 | 16 | YYSYNTH_DUMMY_CLASS(UIControl_YYAdd) 17 | 18 | 19 | static const int block_key; 20 | 21 | @interface _YYUIControlBlockTarget : NSObject 22 | 23 | @property (nonatomic, copy) void (^block)(id sender); 24 | @property (nonatomic, assign) UIControlEvents events; 25 | 26 | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events; 27 | - (void)invoke:(id)sender; 28 | 29 | @end 30 | 31 | @implementation _YYUIControlBlockTarget 32 | 33 | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events { 34 | self = [super init]; 35 | if (self) { 36 | _block = [block copy]; 37 | _events = events; 38 | } 39 | return self; 40 | } 41 | 42 | - (void)invoke:(id)sender { 43 | if (_block) _block(sender); 44 | } 45 | 46 | @end 47 | 48 | 49 | 50 | @implementation UIControl (YYAdd) 51 | 52 | - (void)removeAllTargets { 53 | [[self allTargets] enumerateObjectsUsingBlock: ^(id object, BOOL *stop) { 54 | [self removeTarget:object action:NULL forControlEvents:UIControlEventAllEvents]; 55 | }]; 56 | [[self _yy_allUIControlBlockTargets] removeAllObjects]; 57 | } 58 | 59 | - (void)setTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents { 60 | if (!target || !action || !controlEvents) return; 61 | NSSet *targets = [self allTargets]; 62 | for (id currentTarget in targets) { 63 | NSArray *actions = [self actionsForTarget:currentTarget forControlEvent:controlEvents]; 64 | for (NSString *currentAction in actions) { 65 | [self removeTarget:currentTarget action:NSSelectorFromString(currentAction) 66 | forControlEvents:controlEvents]; 67 | } 68 | } 69 | [self addTarget:target action:action forControlEvents:controlEvents]; 70 | } 71 | 72 | - (void)addBlockForControlEvents:(UIControlEvents)controlEvents 73 | block:(void (^)(id sender))block { 74 | if (!controlEvents) return; 75 | _YYUIControlBlockTarget *target = [[_YYUIControlBlockTarget alloc] 76 | initWithBlock:block events:controlEvents]; 77 | [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents]; 78 | NSMutableArray *targets = [self _yy_allUIControlBlockTargets]; 79 | [targets addObject:target]; 80 | } 81 | 82 | - (void)setBlockForControlEvents:(UIControlEvents)controlEvents 83 | block:(void (^)(id sender))block { 84 | [self removeAllBlocksForControlEvents:UIControlEventAllEvents]; 85 | [self addBlockForControlEvents:controlEvents block:block]; 86 | } 87 | 88 | - (void)removeAllBlocksForControlEvents:(UIControlEvents)controlEvents { 89 | if (!controlEvents) return; 90 | 91 | NSMutableArray *targets = [self _yy_allUIControlBlockTargets]; 92 | NSMutableArray *removes = [NSMutableArray array]; 93 | for (_YYUIControlBlockTarget *target in targets) { 94 | if (target.events & controlEvents) { 95 | UIControlEvents newEvent = target.events & (~controlEvents); 96 | if (newEvent) { 97 | [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events]; 98 | target.events = newEvent; 99 | [self addTarget:target action:@selector(invoke:) forControlEvents:target.events]; 100 | } else { 101 | [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events]; 102 | [removes addObject:target]; 103 | } 104 | } 105 | } 106 | [targets removeObjectsInArray:removes]; 107 | } 108 | 109 | - (NSMutableArray *)_yy_allUIControlBlockTargets { 110 | NSMutableArray *targets = objc_getAssociatedObject(self, &block_key); 111 | if (!targets) { 112 | targets = [NSMutableArray array]; 113 | objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 114 | } 115 | return targets; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSThread+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSThread+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 15/7/3. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSThread+YYAdd.h" 13 | #import 14 | 15 | @interface NSThread_YYAdd : NSObject @end 16 | @implementation NSThread_YYAdd @end 17 | 18 | #if __has_feature(objc_arc) 19 | #error This file must be compiled without ARC. Specify the -fno-objc-arc flag to this file. 20 | #endif 21 | 22 | static NSString *const YYNSThreadAutoleasePoolKey = @"YYNSThreadAutoleasePoolKey"; 23 | static NSString *const YYNSThreadAutoleasePoolStackKey = @"YYNSThreadAutoleasePoolStackKey"; 24 | 25 | static const void *PoolStackRetainCallBack(CFAllocatorRef allocator, const void *value) { 26 | return value; 27 | } 28 | 29 | static void PoolStackReleaseCallBack(CFAllocatorRef allocator, const void *value) { 30 | CFRelease((CFTypeRef)value); 31 | } 32 | 33 | 34 | static inline void YYAutoreleasePoolPush() { 35 | NSMutableDictionary *dic = [NSThread currentThread].threadDictionary; 36 | NSMutableArray *poolStack = dic[YYNSThreadAutoleasePoolStackKey]; 37 | 38 | if (!poolStack) { 39 | /* 40 | do not retain pool on push, 41 | but release on pop to avoid memory analyze warning 42 | */ 43 | CFArrayCallBacks callbacks = {0}; 44 | callbacks.retain = PoolStackRetainCallBack; 45 | callbacks.release = PoolStackReleaseCallBack; 46 | poolStack = (id)CFArrayCreateMutable(CFAllocatorGetDefault(), 0, &callbacks); 47 | dic[YYNSThreadAutoleasePoolStackKey] = poolStack; 48 | CFRelease(poolStack); 49 | } 50 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //< create 51 | [poolStack addObject:pool]; // push 52 | } 53 | 54 | static inline void YYAutoreleasePoolPop() { 55 | NSMutableDictionary *dic = [NSThread currentThread].threadDictionary; 56 | NSMutableArray *poolStack = dic[YYNSThreadAutoleasePoolStackKey]; 57 | [poolStack removeLastObject]; // pop 58 | } 59 | 60 | static void YYRunLoopAutoreleasePoolObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { 61 | switch (activity) { 62 | case kCFRunLoopEntry: { 63 | YYAutoreleasePoolPush(); 64 | } break; 65 | case kCFRunLoopBeforeWaiting: { 66 | YYAutoreleasePoolPop(); 67 | YYAutoreleasePoolPush(); 68 | } break; 69 | case kCFRunLoopExit: { 70 | YYAutoreleasePoolPop(); 71 | } break; 72 | default: break; 73 | } 74 | } 75 | 76 | static void YYRunloopAutoreleasePoolSetup() { 77 | CFRunLoopRef runloop = CFRunLoopGetCurrent(); 78 | 79 | CFRunLoopObserverRef pushObserver; 80 | pushObserver = CFRunLoopObserverCreate(CFAllocatorGetDefault(), kCFRunLoopEntry, 81 | true, // repeat 82 | -0x7FFFFFFF, // before other observers 83 | YYRunLoopAutoreleasePoolObserverCallBack, NULL); 84 | CFRunLoopAddObserver(runloop, pushObserver, kCFRunLoopCommonModes); 85 | CFRelease(pushObserver); 86 | 87 | CFRunLoopObserverRef popObserver; 88 | popObserver = CFRunLoopObserverCreate(CFAllocatorGetDefault(), kCFRunLoopBeforeWaiting | kCFRunLoopExit, 89 | true, // repeat 90 | 0x7FFFFFFF, // after other observers 91 | YYRunLoopAutoreleasePoolObserverCallBack, NULL); 92 | CFRunLoopAddObserver(runloop, popObserver, kCFRunLoopCommonModes); 93 | CFRelease(popObserver); 94 | } 95 | 96 | @implementation NSThread (YYAdd) 97 | 98 | + (void)addAutoreleasePoolToCurrentRunloop { 99 | if ([NSThread isMainThread]) return; // The main thread already has autorelease pool. 100 | NSThread *thread = [self currentThread]; 101 | if (!thread) return; 102 | if (thread.threadDictionary[YYNSThreadAutoleasePoolKey]) return; // already added 103 | YYRunloopAutoreleasePoolSetup(); 104 | thread.threadDictionary[YYNSThreadAutoleasePoolKey] = YYNSThreadAutoleasePoolKey; // mark the state 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/README.md: -------------------------------------------------------------------------------- 1 | YYCategories 2 | ============== 3 | 4 | [![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/ibireme/YYCategories/master/LICENSE)  5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)  6 | [![CocoaPods](http://img.shields.io/cocoapods/v/YYCategories.svg?style=flat)](http://cocoapods.org/?q=YYCategories)  7 | [![CocoaPods](http://img.shields.io/cocoapods/p/YYCategories.svg?style=flat)](http://cocoapods.org/?q=YYCategories)  8 | [![Support](https://img.shields.io/badge/support-iOS%206%2B%20-blue.svg?style=flat)](https://www.apple.com/nl/ios/)  9 | [![Build Status](https://travis-ci.org/ibireme/YYCategories.svg?branch=master)](https://travis-ci.org/ibireme/YYCategories) 10 | 11 | A set of useful categories for Foundation and UIKit.
12 | (It's a component of [YYKit](https://github.com/ibireme/YYKit)) 13 | 14 | Documentation 15 | ============== 16 | 17 | You can build and install docset use `Docset` scheme in Xcode, `appledoc` need to be pre-installed. 18 | Or your can read the [Documentation](http://github.ibireme.com/doc/YYCategories/index.html) online. 19 | 20 | 21 | Installation 22 | ============== 23 | 24 | ### CocoaPods 25 | 26 | 1. Add `pod 'YYCategories'` to your Podfile. 27 | 2. Run `pod install` or `pod update`. 28 | 3. Import \. 29 | 30 | 31 | ### Carthage 32 | 33 | 1. Add `github "ibireme/YYCategories"` to your Cartfile. 34 | 2. Run `carthage update --platform ios` and add the framework to your project. 35 | 3. Import \. 36 | 37 | 38 | ### Manually 39 | 40 | 1. Download all the files in the YYCategories subdirectory. 41 | 2. Add the source files to your Xcode project. 42 | 3. Add `-fno-objc-arc` compiler flag to `NSObject+YYAddForARC.m` and `NSThread+YYAdd.m`. 43 | 4. Link with required frameworks: 44 | * UIKit 45 | * CoreGraphics 46 | * QuartzCore 47 | * Accelerate 48 | * ImageIO 49 | * CoreText 50 | * CoreFoundation 51 | * libz 52 | 5. Import `YYCategories.h`. 53 | 54 | 55 | Documentation 56 | ============== 57 | Full API documentation is available on [CocoaDocs](http://cocoadocs.org/docsets/YYCategories/).
58 | You can also install documentation locally using [appledoc](https://github.com/tomaz/appledoc). 59 | 60 | 61 | Requirements 62 | ============== 63 | This library requires `iOS 6.0+` and `Xcode 7.0+`. 64 | 65 | 66 | Notice 67 | ============== 68 | I want to use the APIs as if it was provided by system, so I don't add prefix in 69 | these categories. This may cause some potential problems(such as conflict with other libraries), so if you just need some pieces of code 70 | in this project, pick them out and don't import the whole library. 71 | 72 | 73 | License 74 | ============== 75 | YYCategories is provided under the MIT license. See LICENSE file for details. 76 | 77 | 78 | 79 | 80 |

81 | --- 82 | 中文介绍 83 | ============== 84 | 功能丰富的 Category 类型工具库。
85 | (该项目是 [YYKit](https://github.com/ibireme/YYKit) 组件之一) 86 | 87 | 文档 88 | ============== 89 | 90 | 你可以用 `Docset` scheme 来生成文档 (需要预先安装 appledoc),或者[在线查看](http://github.ibireme.com/doc/YYCategories/index.html)。 91 | 92 | 93 | 安装 94 | ============== 95 | 96 | ### CocoaPods 97 | 98 | 1. 在 Podfile 中添加 `pod 'YYCategories'`。 99 | 2. 执行 `pod install` 或 `pod update`。 100 | 3. 导入 \。 101 | 102 | 103 | ### Carthage 104 | 105 | 1. 在 Cartfile 中添加 `github "ibireme/YYCategories"`。 106 | 2. 执行 `carthage update --platform ios` 并将生成的 framework 添加到你的工程。 107 | 3. 导入 \。 108 | 109 | 110 | ### 手动安装 111 | 112 | 1. 下载 YYCategories 文件夹内的所有内容。 113 | 2. 将 YYCategories 内的源文件添加(拖放)到你的工程。 114 | 3. 为 `NSObject+YYAddForARC.m` 和 `NSThread+YYAdd.m` 添加编译参数 `-fno-objc-arc`。 115 | 4. 链接以下 frameworks: 116 | * UIKit 117 | * CoreGraphics 118 | * QuartzCore 119 | * Accelerate 120 | * ImageIO 121 | * CoreText 122 | * CoreFoundation 123 | * libz 124 | 5. 导入 `YYCategories.h`。 125 | 126 | 127 | 文档 128 | ============== 129 | 你可以在 [CocoaDocs](http://cocoadocs.org/docsets/YYCategories/) 查看在线 API 文档,也可以用 [appledoc](https://github.com/tomaz/appledoc) 本地生成文档。 130 | 131 | 系统要求 132 | ============== 133 | 该项目最低支持 `iOS 6.0` 和 `Xcode 7.0`。 134 | 135 | 136 | 注意 137 | ============== 138 | 我希望调用 API 时,有着和调用系统自带 API 一样的体验,所以我并没有为 Category 方法添加前缀。我已经用工具扫描过这个项目中的 API,确保没有对系统 API 产生影响。我知道没有前缀的 Category 可能会带来麻烦(比如可能和其他某些类库产生冲突),所以如果你只需要其中少量代码,那最好将那段代码取出来,而不是导入整个库。 139 | 140 | 141 | 许可证 142 | ============== 143 | YYCategories 使用 MIT 许可证,详情见 LICENSE 文件。 144 | 145 | 146 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIView+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/3. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provides extensions for `UIView`. 18 | */ 19 | @interface UIView (YYAdd) 20 | 21 | /** 22 | Create a snapshot image of the complete view hierarchy. 23 | */ 24 | - (nullable UIImage *)snapshotImage; 25 | 26 | /** 27 | Create a snapshot image of the complete view hierarchy. 28 | @discussion It's faster than "snapshotImage", but may cause screen updates. 29 | See -[UIView drawViewHierarchyInRect:afterScreenUpdates:] for more information. 30 | */ 31 | - (nullable UIImage *)snapshotImageAfterScreenUpdates:(BOOL)afterUpdates; 32 | 33 | /** 34 | Create a snapshot PDF of the complete view hierarchy. 35 | */ 36 | - (nullable NSData *)snapshotPDF; 37 | 38 | /** 39 | Shortcut to set the view.layer's shadow 40 | 41 | @param color Shadow Color 42 | @param offset Shadow offset 43 | @param radius Shadow radius 44 | */ 45 | - (void)setLayerShadow:(nullable UIColor*)color offset:(CGSize)offset radius:(CGFloat)radius; 46 | 47 | /** 48 | Remove all subviews. 49 | 50 | @warning Never call this method inside your view's drawRect: method. 51 | */ 52 | - (void)removeAllSubviews; 53 | 54 | /** 55 | Returns the view's view controller (may be nil). 56 | */ 57 | @property (nullable, nonatomic, readonly) UIViewController *viewController; 58 | 59 | /** 60 | Returns the visible alpha on screen, taking into account superview and window. 61 | */ 62 | @property (nonatomic, readonly) CGFloat visibleAlpha; 63 | 64 | /** 65 | Converts a point from the receiver's coordinate system to that of the specified view or window. 66 | 67 | @param point A point specified in the local coordinate system (bounds) of the receiver. 68 | @param view The view or window into whose coordinate system point is to be converted. 69 | If view is nil, this method instead converts to window base coordinates. 70 | @return The point converted to the coordinate system of view. 71 | */ 72 | - (CGPoint)convertPoint:(CGPoint)point toViewOrWindow:(nullable UIView *)view; 73 | 74 | /** 75 | Converts a point from the coordinate system of a given view or window to that of the receiver. 76 | 77 | @param point A point specified in the local coordinate system (bounds) of view. 78 | @param view The view or window with point in its coordinate system. 79 | If view is nil, this method instead converts from window base coordinates. 80 | @return The point converted to the local coordinate system (bounds) of the receiver. 81 | */ 82 | - (CGPoint)convertPoint:(CGPoint)point fromViewOrWindow:(nullable UIView *)view; 83 | 84 | /** 85 | Converts a rectangle from the receiver's coordinate system to that of another view or window. 86 | 87 | @param rect A rectangle specified in the local coordinate system (bounds) of the receiver. 88 | @param view The view or window that is the target of the conversion operation. If view is nil, this method instead converts to window base coordinates. 89 | @return The converted rectangle. 90 | */ 91 | - (CGRect)convertRect:(CGRect)rect toViewOrWindow:(nullable UIView *)view; 92 | 93 | /** 94 | Converts a rectangle from the coordinate system of another view or window to that of the receiver. 95 | 96 | @param rect A rectangle specified in the local coordinate system (bounds) of view. 97 | @param view The view or window with rect in its coordinate system. 98 | If view is nil, this method instead converts from window base coordinates. 99 | @return The converted rectangle. 100 | */ 101 | - (CGRect)convertRect:(CGRect)rect fromViewOrWindow:(nullable UIView *)view; 102 | 103 | 104 | @property (nonatomic) CGFloat left; ///< Shortcut for frame.origin.x. 105 | @property (nonatomic) CGFloat top; ///< Shortcut for frame.origin.y 106 | @property (nonatomic) CGFloat right; ///< Shortcut for frame.origin.x + frame.size.width 107 | @property (nonatomic) CGFloat bottom; ///< Shortcut for frame.origin.y + frame.size.height 108 | @property (nonatomic) CGFloat width; ///< Shortcut for frame.size.width. 109 | @property (nonatomic) CGFloat height; ///< Shortcut for frame.size.height. 110 | @property (nonatomic) CGFloat centerX; ///< Shortcut for center.x 111 | @property (nonatomic) CGFloat centerY; ///< Shortcut for center.y 112 | @property (nonatomic) CGPoint origin; ///< Shortcut for frame.origin. 113 | @property (nonatomic) CGSize size; ///< Shortcut for frame.size. 114 | 115 | @end 116 | 117 | NS_ASSUME_NONNULL_END 118 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/UIKit/UIFont+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 14/5/11. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | #import 14 | #import 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | /** 19 | Provides extensions for `UIFont`. 20 | */ 21 | @interface UIFont (YYAdd) 22 | 23 | #pragma mark - Font Traits 24 | ///============================================================================= 25 | /// @name Font Traits 26 | ///============================================================================= 27 | 28 | @property (nonatomic, readonly) BOOL isBold NS_AVAILABLE_IOS(7_0); ///< Whether the font is bold. 29 | @property (nonatomic, readonly) BOOL isItalic NS_AVAILABLE_IOS(7_0); ///< Whether the font is italic. 30 | @property (nonatomic, readonly) BOOL isMonoSpace NS_AVAILABLE_IOS(7_0); ///< Whether the font is mono space. 31 | @property (nonatomic, readonly) BOOL isColorGlyphs NS_AVAILABLE_IOS(7_0); ///< Whether the font is color glyphs (such as Emoji). 32 | @property (nonatomic, readonly) CGFloat fontWeight NS_AVAILABLE_IOS(7_0); ///< Font weight from -1.0 to 1.0. Regular weight is 0.0. 33 | 34 | /** 35 | Create a bold font from receiver. 36 | @return A bold font, or nil if failed. 37 | */ 38 | - (nullable UIFont *)fontWithBold NS_AVAILABLE_IOS(7_0); 39 | 40 | /** 41 | Create a italic font from receiver. 42 | @return A italic font, or nil if failed. 43 | */ 44 | - (nullable UIFont *)fontWithItalic NS_AVAILABLE_IOS(7_0); 45 | 46 | /** 47 | Create a bold and italic font from receiver. 48 | @return A bold and italic font, or nil if failed. 49 | */ 50 | - (nullable UIFont *)fontWithBoldItalic NS_AVAILABLE_IOS(7_0); 51 | 52 | /** 53 | Create a normal (no bold/italic/...) font from receiver. 54 | @return A normal font, or nil if failed. 55 | */ 56 | - (nullable UIFont *)fontWithNormal NS_AVAILABLE_IOS(7_0); 57 | 58 | #pragma mark - Create font 59 | ///============================================================================= 60 | /// @name Create font 61 | ///============================================================================= 62 | 63 | /** 64 | Creates and returns a font object for the specified CTFontRef. 65 | 66 | @param CTFont CoreText font. 67 | */ 68 | + (nullable UIFont *)fontWithCTFont:(CTFontRef)CTFont; 69 | 70 | /** 71 | Creates and returns a font object for the specified CGFontRef and size. 72 | 73 | @param CGFont CoreGraphic font. 74 | @param size Font size. 75 | */ 76 | + (nullable UIFont *)fontWithCGFont:(CGFontRef)CGFont size:(CGFloat)size; 77 | 78 | /** 79 | Creates and returns the CTFontRef object. (need call CFRelease() after used) 80 | */ 81 | - (nullable CTFontRef)CTFontRef CF_RETURNS_RETAINED; 82 | 83 | /** 84 | Creates and returns the CGFontRef object. (need call CFRelease() after used) 85 | */ 86 | - (nullable CGFontRef)CGFontRef CF_RETURNS_RETAINED; 87 | 88 | 89 | #pragma mark - Load and unload font 90 | ///============================================================================= 91 | /// @name Load and unload font 92 | ///============================================================================= 93 | 94 | /** 95 | Load the font from file path. Support format:TTF,OTF. 96 | If return YES, font can be load use it PostScript Name: [UIFont fontWithName:...] 97 | 98 | @param path font file's full path 99 | */ 100 | + (BOOL)loadFontFromPath:(NSString *)path; 101 | 102 | /** 103 | Unload font from file path. 104 | 105 | @param path font file's full path 106 | */ 107 | + (void)unloadFontFromPath:(NSString *)path; 108 | 109 | /** 110 | Load the font from data. Support format:TTF,OTF. 111 | 112 | @param data Font data. 113 | 114 | @return UIFont object if load succeed, otherwise nil. 115 | */ 116 | + (nullable UIFont *)loadFontFromData:(NSData *)data; 117 | 118 | /** 119 | Unload font which is loaded by loadFontFromData: function. 120 | 121 | @param font the font loaded by loadFontFromData: function 122 | 123 | @return YES if succeed, otherwise NO. 124 | */ 125 | + (BOOL)unloadFontFromData:(UIFont *)font; 126 | 127 | 128 | #pragma mark - Dump font data 129 | ///============================================================================= 130 | /// @name Dump font data 131 | ///============================================================================= 132 | 133 | /** 134 | Serialize and return the font data. 135 | 136 | @param font The font. 137 | 138 | @return data in TTF, or nil if an error occurs. 139 | */ 140 | + (nullable NSData *)dataFromFont:(UIFont *)font; 141 | 142 | /** 143 | Serialize and return the font data. 144 | 145 | @param cgFont The font. 146 | 147 | @return data in TTF, or nil if an error occurs. 148 | */ 149 | + (nullable NSData *)dataFromCGFont:(CGFontRef)cgFont; 150 | 151 | @end 152 | 153 | NS_ASSUME_NONNULL_END 154 | -------------------------------------------------------------------------------- /Example/ZMJTipView/UIView+Frame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.m 3 | // Trader 4 | // 5 | // Created by Mingfei Huang on 9/17/15. 6 | // 7 | // 8 | 9 | #import "UIView+Frame.h" 10 | @import YYCategories.UIView_YYAdd; 11 | @import YYCategories.CALayer_YYAdd; 12 | 13 | @implementation UIView (WBGFrame) 14 | 15 | # pragma mark Normal Frame 16 | - (void)setX: (CGFloat)x { 17 | CGRect frame = self.frame; 18 | frame.origin.x = x; 19 | self.frame = frame; 20 | } 21 | 22 | - (void)setY: (CGFloat)y { 23 | CGRect frame = self.frame; 24 | frame.origin.y = y; 25 | self.frame = frame; 26 | } 27 | 28 | - (CGFloat)x { return self.frame.origin.x; } 29 | 30 | - (CGFloat)y { return self.frame.origin.y; } 31 | 32 | # pragma mark max x/y 33 | 34 | - (CGFloat)maxX { 35 | return self.x + self.width; 36 | } 37 | 38 | - (CGFloat)maxY { 39 | return self.y + self.height; 40 | } 41 | 42 | - (void)setMaxXByShift:(CGFloat)maxX { 43 | self.x = maxX - self.width; 44 | } 45 | 46 | - (void)setMaxYByShift:(CGFloat)maxY { 47 | self.y = maxY - self.height; 48 | } 49 | 50 | - (void)setMaxXByStretch:(CGFloat)maxX { 51 | self.width = maxX - self.x; 52 | } 53 | 54 | - (void)setMaxYByStretch:(CGFloat)maxY { 55 | self.height = maxY - self.y; 56 | } 57 | 58 | - (CGPoint)boundCenter { 59 | return CGPointMake(self.bounds.size.width / 2, 60 | self.bounds.size.height / 2); 61 | } 62 | 63 | @end 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | // ======================================================================== 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | @implementation CALayer (WBGFrame) 89 | 90 | # pragma mark Normal Frame 91 | - (void)setX: (CGFloat)x { 92 | CGRect frame = self.frame; 93 | frame.origin.x = x; 94 | self.frame = frame; 95 | } 96 | 97 | - (void)setY: (CGFloat)y { 98 | CGRect frame = self.frame; 99 | frame.origin.y = y; 100 | self.frame = frame; 101 | } 102 | 103 | - (CGFloat)x { return self.frame.origin.x; } 104 | 105 | - (CGFloat)y { return self.frame.origin.y; } 106 | 107 | # pragma mark max x/y 108 | 109 | - (CGFloat)maxX { 110 | return self.x + self.width; 111 | } 112 | 113 | - (CGFloat)maxY { 114 | return self.y + self.height; 115 | } 116 | 117 | - (void)setMaxXByShift:(CGFloat)maxX { 118 | self.x = maxX - self.width; 119 | } 120 | 121 | - (void)setMaxYByShift:(CGFloat)maxY { 122 | self.y = maxY - self.height; 123 | } 124 | 125 | - (void)setMaxXByStretch:(CGFloat)maxX { 126 | self.width = maxX - self.x; 127 | } 128 | 129 | - (void)setMaxYByStretch:(CGFloat)maxY { 130 | self.height = maxY - self.y; 131 | } 132 | 133 | - (CGPoint)boundCenter { 134 | return CGPointMake(self.bounds.size.width / 2, 135 | self.bounds.size.height / 2); 136 | } 137 | 138 | @end 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | // ================================================== 148 | 149 | 150 | 151 | 152 | 153 | @implementation UICollectionViewLayoutAttributes (WBGFrame) 154 | 155 | # pragma mark Normal Frame 156 | - (void)setX: (CGFloat)x { 157 | CGRect frame = self.frame; 158 | frame.origin.x = x; 159 | self.frame = frame; 160 | } 161 | 162 | - (void)setY: (CGFloat)y { 163 | CGRect frame = self.frame; 164 | frame.origin.y = y; 165 | self.frame = frame; 166 | } 167 | 168 | - (void)setWidth: (CGFloat)width { 169 | CGRect frame = self.frame; 170 | frame.size.width = width; 171 | self.frame = frame; 172 | } 173 | 174 | - (void)setHeight: (CGFloat)height { 175 | CGRect frame = self.frame; 176 | frame.size.height = height; 177 | self.frame = frame; 178 | } 179 | 180 | - (CGFloat)x { return self.frame.origin.x; } 181 | 182 | - (CGFloat)y { return self.frame.origin.y; } 183 | 184 | - (CGFloat)width { return self.frame.size.width; } 185 | 186 | - (CGFloat)height { return self.frame.size.height; } 187 | 188 | # pragma mark max x/y 189 | 190 | - (CGFloat)maxX { 191 | return self.x + self.width; 192 | } 193 | 194 | - (CGFloat)maxY { 195 | return self.y + self.height; 196 | } 197 | 198 | - (void)setMaxXByShift:(CGFloat)maxX { 199 | self.x = maxX - self.width; 200 | } 201 | 202 | - (void)setMaxYByShift:(CGFloat)maxY { 203 | self.y = maxY - self.height; 204 | } 205 | 206 | - (void)setMaxXByStretch:(CGFloat)maxX { 207 | self.width = maxX - self.x; 208 | } 209 | 210 | - (void)setMaxYByStretch:(CGFloat)maxY { 211 | self.height = maxY - self.y; 212 | } 213 | 214 | 215 | # pragma mark Center 216 | - (void)setCenterX:(CGFloat)centerX { 217 | CGPoint center = self.center; 218 | center.x = centerX; 219 | self.center = center; 220 | } 221 | 222 | - (void)setCenterY:(CGFloat)centerY { 223 | CGPoint center = self.center; 224 | center.y = centerY; 225 | self.center = center; 226 | } 227 | 228 | - (CGFloat)centerX { 229 | return self.center.x; 230 | } 231 | 232 | - (CGFloat)centerY { 233 | return self.center.y; 234 | } 235 | 236 | - (CGPoint)boundCenter { 237 | return CGPointMake(self.bounds.size.width / 2, 238 | self.bounds.size.height / 2); 239 | } 240 | 241 | @end 242 | 243 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSArray+YYAdd.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+YYAdd.m 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/4. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import "NSArray+YYAdd.h" 13 | #import "YYCategoriesMacro.h" 14 | #import "NSData+YYAdd.h" 15 | 16 | YYSYNTH_DUMMY_CLASS(NSArray_YYAdd) 17 | 18 | 19 | @implementation NSArray (YYAdd) 20 | 21 | + (NSArray *)arrayWithPlistData:(NSData *)plist { 22 | if (!plist) return nil; 23 | NSArray *array = [NSPropertyListSerialization propertyListWithData:plist options:NSPropertyListImmutable format:NULL error:NULL]; 24 | if ([array isKindOfClass:[NSArray class]]) return array; 25 | return nil; 26 | } 27 | 28 | + (NSArray *)arrayWithPlistString:(NSString *)plist { 29 | if (!plist) return nil; 30 | NSData* data = [plist dataUsingEncoding:NSUTF8StringEncoding]; 31 | return [self arrayWithPlistData:data]; 32 | } 33 | 34 | - (NSData *)plistData { 35 | return [NSPropertyListSerialization dataWithPropertyList:self format:NSPropertyListBinaryFormat_v1_0 options:kNilOptions error:NULL]; 36 | } 37 | 38 | - (NSString *)plistString { 39 | NSData *xmlData = [NSPropertyListSerialization dataWithPropertyList:self format:NSPropertyListXMLFormat_v1_0 options:kNilOptions error:NULL]; 40 | if (xmlData) return xmlData.utf8String; 41 | return nil; 42 | } 43 | 44 | - (id)randomObject { 45 | if (self.count) { 46 | return self[arc4random_uniform((u_int32_t)self.count)]; 47 | } 48 | return nil; 49 | } 50 | 51 | - (id)objectOrNilAtIndex:(NSUInteger)index { 52 | return index < self.count ? self[index] : nil; 53 | } 54 | 55 | - (NSString *)jsonStringEncoded { 56 | if ([NSJSONSerialization isValidJSONObject:self]) { 57 | NSError *error; 58 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:0 error:&error]; 59 | NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 60 | return json; 61 | } 62 | return nil; 63 | } 64 | 65 | - (NSString *)jsonPrettyStringEncoded { 66 | if ([NSJSONSerialization isValidJSONObject:self]) { 67 | NSError *error; 68 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error]; 69 | NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 70 | return json; 71 | } 72 | return nil; 73 | } 74 | 75 | @end 76 | 77 | 78 | 79 | @implementation NSMutableArray (YYAdd) 80 | 81 | + (NSMutableArray *)arrayWithPlistData:(NSData *)plist { 82 | if (!plist) return nil; 83 | NSMutableArray *array = [NSPropertyListSerialization propertyListWithData:plist options:NSPropertyListMutableContainersAndLeaves format:NULL error:NULL]; 84 | if ([array isKindOfClass:[NSMutableArray class]]) return array; 85 | return nil; 86 | } 87 | 88 | + (NSMutableArray *)arrayWithPlistString:(NSString *)plist { 89 | if (!plist) return nil; 90 | NSData* data = [plist dataUsingEncoding:NSUTF8StringEncoding]; 91 | return [self arrayWithPlistData:data]; 92 | } 93 | 94 | - (void)removeFirstObject { 95 | if (self.count) { 96 | [self removeObjectAtIndex:0]; 97 | } 98 | } 99 | 100 | #pragma clang diagnostic push 101 | #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" 102 | - (void)removeLastObject { 103 | if (self.count) { 104 | [self removeObjectAtIndex:self.count - 1]; 105 | } 106 | } 107 | 108 | #pragma clang diagnostic pop 109 | 110 | 111 | - (id)popFirstObject { 112 | id obj = nil; 113 | if (self.count) { 114 | obj = self.firstObject; 115 | [self removeFirstObject]; 116 | } 117 | return obj; 118 | } 119 | 120 | - (id)popLastObject { 121 | id obj = nil; 122 | if (self.count) { 123 | obj = self.lastObject; 124 | [self removeLastObject]; 125 | } 126 | return obj; 127 | } 128 | 129 | - (void)appendObject:(id)anObject { 130 | [self addObject:anObject]; 131 | } 132 | 133 | - (void)prependObject:(id)anObject { 134 | [self insertObject:anObject atIndex:0]; 135 | } 136 | 137 | - (void)appendObjects:(NSArray *)objects { 138 | if (!objects) return; 139 | [self addObjectsFromArray:objects]; 140 | } 141 | 142 | - (void)prependObjects:(NSArray *)objects { 143 | if (!objects) return; 144 | NSUInteger i = 0; 145 | for (id obj in objects) { 146 | [self insertObject:obj atIndex:i++]; 147 | } 148 | } 149 | 150 | - (void)insertObjects:(NSArray *)objects atIndex:(NSUInteger)index { 151 | NSUInteger i = index; 152 | for (id obj in objects) { 153 | [self insertObject:obj atIndex:i++]; 154 | } 155 | } 156 | 157 | - (void)reverse { 158 | NSUInteger count = self.count; 159 | int mid = floor(count / 2.0); 160 | for (NSUInteger i = 0; i < mid; i++) { 161 | [self exchangeObjectAtIndex:i withObjectAtIndex:(count - (i + 1))]; 162 | } 163 | } 164 | 165 | - (void)shuffle { 166 | for (NSUInteger i = self.count; i > 1; i--) { 167 | [self exchangeObjectAtIndex:(i - 1) 168 | withObjectAtIndex:arc4random_uniform((u_int32_t)i)]; 169 | } 170 | } 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Tests/Pods-ZMJTipView_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.xib) 55 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 56 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 106 | fi 107 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-ZMJTipView_Example/Pods-ZMJTipView_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.xib) 55 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 56 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 106 | fi 107 | -------------------------------------------------------------------------------- /Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Gabriel Handford on 3/1/09. 3 | // Copyright 2009-2013. All rights reserved. 4 | // Created by John Boiles on 10/20/11. 5 | // Copyright (c) 2011. All rights reserved 6 | // Modified by Felix Schulze on 2/11/13. 7 | // Copyright 2013. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person 10 | // obtaining a copy of this software and associated documentation 11 | // files (the "Software"), to deal in the Software without 12 | // restriction, including without limitation the rights to use, 13 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the 15 | // Software is furnished to do so, subject to the following 16 | // conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | // OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | #import 32 | 33 | // This makes debugging much more fun 34 | typedef union { 35 | uint32_t raw; 36 | unsigned char bytes[4]; 37 | struct { 38 | char red; 39 | char green; 40 | char blue; 41 | char alpha; 42 | } __attribute__ ((packed)) pixels; 43 | } FBComparePixel; 44 | 45 | @implementation UIImage (Compare) 46 | 47 | - (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance 48 | { 49 | NSAssert(CGSizeEqualToSize(self.size, image.size), @"Images must be same size."); 50 | 51 | CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); 52 | CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); 53 | 54 | // The images have the equal size, so we could use the smallest amount of bytes because of byte padding 55 | size_t minBytesPerRow = MIN(CGImageGetBytesPerRow(self.CGImage), CGImageGetBytesPerRow(image.CGImage)); 56 | size_t referenceImageSizeBytes = referenceImageSize.height * minBytesPerRow; 57 | void *referenceImagePixels = calloc(1, referenceImageSizeBytes); 58 | void *imagePixels = calloc(1, referenceImageSizeBytes); 59 | 60 | if (!referenceImagePixels || !imagePixels) { 61 | free(referenceImagePixels); 62 | free(imagePixels); 63 | return NO; 64 | } 65 | 66 | CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels, 67 | referenceImageSize.width, 68 | referenceImageSize.height, 69 | CGImageGetBitsPerComponent(self.CGImage), 70 | minBytesPerRow, 71 | CGImageGetColorSpace(self.CGImage), 72 | (CGBitmapInfo)kCGImageAlphaPremultipliedLast 73 | ); 74 | CGContextRef imageContext = CGBitmapContextCreate(imagePixels, 75 | imageSize.width, 76 | imageSize.height, 77 | CGImageGetBitsPerComponent(image.CGImage), 78 | minBytesPerRow, 79 | CGImageGetColorSpace(image.CGImage), 80 | (CGBitmapInfo)kCGImageAlphaPremultipliedLast 81 | ); 82 | 83 | if (!referenceImageContext || !imageContext) { 84 | CGContextRelease(referenceImageContext); 85 | CGContextRelease(imageContext); 86 | free(referenceImagePixels); 87 | free(imagePixels); 88 | return NO; 89 | } 90 | 91 | CGContextDrawImage(referenceImageContext, CGRectMake(0, 0, referenceImageSize.width, referenceImageSize.height), self.CGImage); 92 | CGContextDrawImage(imageContext, CGRectMake(0, 0, imageSize.width, imageSize.height), image.CGImage); 93 | 94 | CGContextRelease(referenceImageContext); 95 | CGContextRelease(imageContext); 96 | 97 | BOOL imageEqual = YES; 98 | 99 | // Do a fast compare if we can 100 | if (tolerance == 0) { 101 | imageEqual = (memcmp(referenceImagePixels, imagePixels, referenceImageSizeBytes) == 0); 102 | } else { 103 | // Go through each pixel in turn and see if it is different 104 | const NSInteger pixelCount = referenceImageSize.width * referenceImageSize.height; 105 | 106 | FBComparePixel *p1 = referenceImagePixels; 107 | FBComparePixel *p2 = imagePixels; 108 | 109 | NSInteger numDiffPixels = 0; 110 | for (int n = 0; n < pixelCount; ++n) { 111 | // If this pixel is different, increment the pixel diff count and see 112 | // if we have hit our limit. 113 | if (p1->raw != p2->raw) { 114 | numDiffPixels ++; 115 | 116 | CGFloat percent = (CGFloat)numDiffPixels / pixelCount; 117 | if (percent > tolerance) { 118 | imageEqual = NO; 119 | break; 120 | } 121 | } 122 | 123 | p1++; 124 | p2++; 125 | } 126 | } 127 | 128 | free(referenceImagePixels); 129 | free(imagePixels); 130 | 131 | return imageEqual; 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Example/ZMJTipView/ZMJTaskView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZMJTaskView.m 3 | // ZMJTipView_Example 4 | // 5 | // Created by Jason on 2018/2/11. 6 | // Copyright © 2018年 keshiim. All rights reserved. 7 | // 8 | 9 | #import "ZMJTaskView.h" 10 | #import "UIView+Frame.h" 11 | @import YYCategories; 12 | @import ZMJTipView; 13 | 14 | #define TaskTitleColor [UIColor whiteColor]//eg.[UIColor colorWithHexString:@"333333"] 15 | #define TimeTitleColor [UIColor whiteColor]//eg.[UIColor colorWithHexString:@"999999"] 16 | #define ValueColor [UIColor whiteColor]//eg.[UIColor colorWithHexString:@"666666"] 17 | #define LineColor [UIColor whiteColor]//eg.[UIColor colorWithHexString:@"DBDBDB"] 18 | 19 | #define DateTitleWidth 45.f 20 | 21 | @interface ZMJTaskView () 22 | @property (nonatomic, strong) UILabel *taskTitleLabel; 23 | @property (nonatomic, strong) UILabel *startTimeTitleLabel; 24 | @property (nonatomic, strong) UILabel *startTimeLabel; 25 | @property (nonatomic, strong) UILabel *endTimeTitleLabel; 26 | @property (nonatomic, strong) UILabel *endTimeLabel; 27 | @property (nonatomic, strong) UIView *separatorLine; 28 | @property (nonatomic, strong) UILabel *viewDetailLabel; 29 | @end 30 | 31 | @implementation ZMJTaskView 32 | 33 | - (instancetype)initWithCoder:(NSCoder *)coder 34 | { 35 | self = [super initWithCoder:coder]; 36 | if (self) { 37 | [self setupViews]; 38 | } 39 | return self; 40 | } 41 | 42 | - (instancetype)initWithFrame:(CGRect)frame 43 | { 44 | self = [super initWithFrame:frame]; 45 | if (self) { 46 | [self setupViews]; 47 | } 48 | return self; 49 | } 50 | 51 | - (void)setupViews { 52 | 53 | self.taskTitleLabel = ({ 54 | UILabel *label = [UILabel new]; 55 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14]; 56 | label.lineBreakMode = NSLineBreakByWordWrapping; 57 | label.textColor = TaskTitleColor; 58 | [self addSubview:label]; 59 | label; 60 | }); 61 | 62 | self.startTimeTitleLabel = ({ 63 | UILabel *label = [UILabel new]; 64 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10]; 65 | label.text = @"Start time:"; 66 | label.textColor = TimeTitleColor; 67 | [self addSubview:label]; 68 | label; 69 | }); 70 | 71 | self.startTimeLabel = ({ 72 | UILabel *label = [UILabel new]; 73 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10]; 74 | label.lineBreakMode = NSLineBreakByWordWrapping; 75 | label.textColor = ValueColor; 76 | [self addSubview:label]; 77 | label; 78 | }); 79 | 80 | self.endTimeTitleLabel = ({ 81 | UILabel *label = [UILabel new]; 82 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10]; 83 | label.text = @"End time:"; 84 | label.textColor = TimeTitleColor; 85 | [self addSubview:label]; 86 | label; 87 | }); 88 | 89 | self.endTimeLabel = ({ 90 | UILabel *label = [UILabel new]; 91 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:10]; 92 | label.lineBreakMode = NSLineBreakByWordWrapping; 93 | label.textColor = ValueColor; 94 | [self addSubview:label]; 95 | label; 96 | }); 97 | 98 | self.separatorLine = ({ 99 | UIView *line = [UIView new]; 100 | line.backgroundColor = LineColor; 101 | [self addSubview:line]; 102 | line; 103 | }); 104 | 105 | self.viewDetailLabel = ({ 106 | UILabel *label = [UILabel new]; 107 | label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:12]; 108 | label.lineBreakMode = NSLineBreakByWordWrapping; 109 | label.text = @"View the detail"; 110 | label.textColor = ValueColor; 111 | [self addSubview:label]; 112 | label; 113 | }); 114 | } 115 | 116 | - (void)layoutSubviews { 117 | [super layoutSubviews]; 118 | 119 | [self.taskTitleLabel sizeToFit]; 120 | self.taskTitleLabel.x = self.taskTitleLabel.y = 12.f; 121 | self.taskTitleLabel.maxXByStretch = self.width - 12.f; 122 | 123 | [self.startTimeTitleLabel sizeToFit]; 124 | self.startTimeTitleLabel.x = 12.f; 125 | self.startTimeTitleLabel.y = self.taskTitleLabel.maxY + 6.f; 126 | self.startTimeTitleLabel.width = DateTitleWidth; 127 | 128 | [self.startTimeLabel sizeToFit]; 129 | self.startTimeLabel.x = self.startTimeTitleLabel.maxX + 3; 130 | self.startTimeLabel.y = self.startTimeTitleLabel.y; 131 | self.startTimeLabel.maxXByStretch = self.width - 12.f; 132 | 133 | [self.endTimeTitleLabel sizeToFit]; 134 | self.endTimeTitleLabel.x = 12.f; 135 | self.endTimeTitleLabel.y = self.startTimeLabel.maxY + 2.f; 136 | self.endTimeTitleLabel.width = DateTitleWidth; 137 | 138 | [self.endTimeLabel sizeToFit]; 139 | self.endTimeLabel.x = self.endTimeTitleLabel.maxX + 3; 140 | self.endTimeLabel.y = self.endTimeTitleLabel.y; 141 | self.endTimeLabel.maxXByStretch = self.width - 12.f; 142 | 143 | self.separatorLine.x = 0; 144 | self.separatorLine.y = self.endTimeTitleLabel.maxY + 10.f; 145 | self.separatorLine.maxXByStretch = self.width; 146 | self.separatorLine.height = 1 / [UIScreen mainScreen].scale; 147 | 148 | [self.viewDetailLabel sizeToFit]; 149 | self.viewDetailLabel.x = 12.f; 150 | self.viewDetailLabel.y = self.separatorLine.maxY + 10.f; 151 | self.viewDetailLabel.maxXByStretch = self.width - 12.f; 152 | } 153 | 154 | - (CGSize)intrinsicContentSize { 155 | CGFloat height = 0.f; 156 | [self layoutIfNeeded]; 157 | height = self.viewDetailLabel.maxY + 12.f; 158 | return CGSizeMake(self.width, height); 159 | } 160 | 161 | // MARK: getter 162 | - (void)setTaskTitle:(NSString *)taskTitle { 163 | _taskTitle = taskTitle; 164 | self.taskTitleLabel.text = taskTitle; 165 | } 166 | 167 | - (void)setStartTime:(NSString *)startTime { 168 | _startTime = startTime; 169 | self.startTimeLabel.text = startTime; 170 | } 171 | 172 | - (void)setEndTime:(NSString *)endTime { 173 | _endTime = endTime; 174 | self.endTimeLabel.text = endTime; 175 | } 176 | @end 177 | -------------------------------------------------------------------------------- /Example/Pods/YYCategories/YYCategories/Foundation/NSArray+YYAdd.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+YYAdd.h 3 | // YYCategories 4 | // 5 | // Created by ibireme on 13/4/4. 6 | // Copyright (c) 2015 ibireme. 7 | // 8 | // This source code is licensed under the MIT-style license found in the 9 | // LICENSE file in the root directory of this source tree. 10 | // 11 | 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | Provide some some common method for `NSArray`. 18 | */ 19 | @interface NSArray (YYAdd) 20 | 21 | /** 22 | Creates and returns an array from a specified property list data. 23 | 24 | @param plist A property list data whose root object is an array. 25 | @return A new array created from the plist data, or nil if an error occurs. 26 | */ 27 | + (nullable NSArray *)arrayWithPlistData:(NSData *)plist; 28 | 29 | /** 30 | Creates and returns an array from a specified property list xml string. 31 | 32 | @param plist A property list xml string whose root object is an array. 33 | @return A new array created from the plist string, or nil if an error occurs. 34 | */ 35 | + (nullable NSArray *)arrayWithPlistString:(NSString *)plist; 36 | 37 | /** 38 | Serialize the array to a binary property list data. 39 | 40 | @return A bplist data, or nil if an error occurs. 41 | */ 42 | - (nullable NSData *)plistData; 43 | 44 | /** 45 | Serialize the array to a xml property list string. 46 | 47 | @return A plist xml string, or nil if an error occurs. 48 | */ 49 | - (nullable NSString *)plistString; 50 | 51 | /** 52 | Returns the object located at a random index. 53 | 54 | @return The object in the array with a random index value. 55 | If the array is empty, returns nil. 56 | */ 57 | - (nullable id)randomObject; 58 | 59 | /** 60 | Returns the object located at index, or return nil when out of bounds. 61 | It's similar to `objectAtIndex:`, but it never throw exception. 62 | 63 | @param index The object located at index. 64 | */ 65 | - (nullable id)objectOrNilAtIndex:(NSUInteger)index; 66 | 67 | /** 68 | Convert object to json string. return nil if an error occurs. 69 | NSString/NSNumber/NSDictionary/NSArray 70 | */ 71 | - (nullable NSString *)jsonStringEncoded; 72 | 73 | /** 74 | Convert object to json string formatted. return nil if an error occurs. 75 | */ 76 | - (nullable NSString *)jsonPrettyStringEncoded; 77 | 78 | @end 79 | 80 | 81 | /** 82 | Provide some some common method for `NSMutableArray`. 83 | */ 84 | @interface NSMutableArray (YYAdd) 85 | 86 | /** 87 | Creates and returns an array from a specified property list data. 88 | 89 | @param plist A property list data whose root object is an array. 90 | @return A new array created from the plist data, or nil if an error occurs. 91 | */ 92 | + (nullable NSMutableArray *)arrayWithPlistData:(NSData *)plist; 93 | 94 | /** 95 | Creates and returns an array from a specified property list xml string. 96 | 97 | @param plist A property list xml string whose root object is an array. 98 | @return A new array created from the plist string, or nil if an error occurs. 99 | */ 100 | + (nullable NSMutableArray *)arrayWithPlistString:(NSString *)plist; 101 | 102 | /** 103 | Removes the object with the lowest-valued index in the array. 104 | If the array is empty, this method has no effect. 105 | 106 | @discussion Apple has implemented this method, but did not make it public. 107 | Override for safe. 108 | */ 109 | - (void)removeFirstObject; 110 | 111 | /** 112 | Removes the object with the highest-valued index in the array. 113 | If the array is empty, this method has no effect. 114 | 115 | @discussion Apple's implementation said it raises an NSRangeException if the 116 | array is empty, but in fact nothing will happen. Override for safe. 117 | */ 118 | - (void)removeLastObject; 119 | 120 | /** 121 | Removes and returns the object with the lowest-valued index in the array. 122 | If the array is empty, it just returns nil. 123 | 124 | @return The first object, or nil. 125 | */ 126 | - (nullable id)popFirstObject; 127 | 128 | /** 129 | Removes and returns the object with the highest-valued index in the array. 130 | If the array is empty, it just returns nil. 131 | 132 | @return The first object, or nil. 133 | */ 134 | - (nullable id)popLastObject; 135 | 136 | /** 137 | Inserts a given object at the end of the array. 138 | 139 | @param anObject The object to add to the end of the array's content. 140 | This value must not be nil. Raises an NSInvalidArgumentException if anObject is nil. 141 | */ 142 | - (void)appendObject:(id)anObject; 143 | 144 | /** 145 | Inserts a given object at the beginning of the array. 146 | 147 | @param anObject The object to add to the end of the array's content. 148 | This value must not be nil. Raises an NSInvalidArgumentException if anObject is nil. 149 | */ 150 | - (void)prependObject:(id)anObject; 151 | 152 | /** 153 | Adds the objects contained in another given array to the end of the receiving 154 | array's content. 155 | 156 | @param objects An array of objects to add to the end of the receiving array's 157 | content. If the objects is empty or nil, this method has no effect. 158 | */ 159 | - (void)appendObjects:(NSArray *)objects; 160 | 161 | /** 162 | Adds the objects contained in another given array to the beginnin of the receiving 163 | array's content. 164 | 165 | @param objects An array of objects to add to the beginning of the receiving array's 166 | content. If the objects is empty or nil, this method has no effect. 167 | */ 168 | - (void)prependObjects:(NSArray *)objects; 169 | 170 | /** 171 | Adds the objects contained in another given array at the index of the receiving 172 | array's content. 173 | 174 | @param objects An array of objects to add to the receiving array's 175 | content. If the objects is empty or nil, this method has no effect. 176 | 177 | @param index The index in the array at which to insert objects. This value must 178 | not be greater than the count of elements in the array. Raises an 179 | NSRangeException if index is greater than the number of elements in the array. 180 | */ 181 | - (void)insertObjects:(NSArray *)objects atIndex:(NSUInteger)index; 182 | 183 | /** 184 | Reverse the index of object in this array. 185 | Example: Before @[ @1, @2, @3 ], After @[ @3, @2, @1 ]. 186 | */ 187 | - (void)reverse; 188 | 189 | /** 190 | Sort the object in this array randomly. 191 | */ 192 | - (void)shuffle; 193 | 194 | @end 195 | 196 | NS_ASSUME_NONNULL_END 197 | --------------------------------------------------------------------------------