From 5c77f9b5b08e320b69a8a290bb283856bd52d9c0 Mon Sep 17 00:00:00 2001 From: "jialun.zeng" Date: Fri, 1 Jul 2022 19:11:53 +0800 Subject: [PATCH 1/5] Add scene management function; Simplify data set configuration and method invocation; Modify README.md file; New EmptyExt target; --- DZNEmptyDataSet/Applications copy-Info.plist | 45 ++ .../DZNEmptyDataSet.xcodeproj/project.pbxproj | 161 +++++ .../xcshareddata/xcschemes/EmptyExt.xcscheme | 78 +++ DZNEmptyDataSet/Ext/AppDelegate.h | 15 + DZNEmptyDataSet/Ext/AppDelegate.m | 21 + DZNEmptyDataSet/Ext/MainViewController.h | 15 + DZNEmptyDataSet/Ext/MainViewController.m | 113 ++++ .../Supporting Files/Applications-Prefix.pch | 16 + .../Base.lproj/LaunchScreen.storyboard | 27 + .../Ext/Supporting Files/Info.plist | 45 ++ .../Supporting Files/Storyboard.storyboard | 85 +++ .../en.lproj/InfoPlist.strings | 2 + DZNEmptyDataSet/Ext/Supporting Files/main.m | 16 + README.md | 124 ++++ Source/UIScrollView+DZNEmptyExt.h | 306 ++++++++++ Source/UIScrollView+DZNEmptyExt.m | 564 ++++++++++++++++++ 16 files changed, 1633 insertions(+) create mode 100644 DZNEmptyDataSet/Applications copy-Info.plist create mode 100644 DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme create mode 100644 DZNEmptyDataSet/Ext/AppDelegate.h create mode 100644 DZNEmptyDataSet/Ext/AppDelegate.m create mode 100644 DZNEmptyDataSet/Ext/MainViewController.h create mode 100644 DZNEmptyDataSet/Ext/MainViewController.m create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/Applications-Prefix.pch create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/Base.lproj/LaunchScreen.storyboard create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/Info.plist create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/Storyboard.storyboard create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/en.lproj/InfoPlist.strings create mode 100644 DZNEmptyDataSet/Ext/Supporting Files/main.m create mode 100644 Source/UIScrollView+DZNEmptyExt.h create mode 100644 Source/UIScrollView+DZNEmptyExt.m diff --git a/DZNEmptyDataSet/Applications copy-Info.plist b/DZNEmptyDataSet/Applications copy-Info.plist new file mode 100644 index 00000000..7b0138cd --- /dev/null +++ b/DZNEmptyDataSet/Applications copy-Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIAppFonts + + IdealSans-Book-Pro.otf + Lato-Regular.ttf + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Storyboard + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.pbxproj b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.pbxproj index c7e201b9..ead038fb 100644 --- a/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.pbxproj +++ b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/project.pbxproj @@ -8,6 +8,17 @@ /* Begin PBXBuildFile section */ 3AC13C2C04A330F6731CD271 /* Pods_DZNEmptyDataSetTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C5DC4B343BE997FFAA0048 /* Pods_DZNEmptyDataSetTests.framework */; }; + 7DA71C25286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DA71C23286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.m */; }; + 7DA71C26286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DA71C24286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7DA71C8B286EF48200C69885 /* DZNEmptyDataSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; }; + 7DA71CAF286EF68900C69885 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7DA71CA3286EF68900C69885 /* InfoPlist.strings */; }; + 7DA71CB0286EF68900C69885 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7DA71CA5286EF68900C69885 /* LaunchScreen.storyboard */; }; + 7DA71CB1286EF68900C69885 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DA71CA7286EF68900C69885 /* main.m */; }; + 7DA71CB2286EF68900C69885 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7DA71CA9286EF68900C69885 /* Storyboard.storyboard */; }; + 7DA71CB4286EF68900C69885 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DA71CAD286EF68900C69885 /* AppDelegate.m */; }; + 7DA71CB5286EF68900C69885 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DA71CAE286EF68900C69885 /* MainViewController.m */; }; + 7DA71CFA286EFBF600C69885 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */; }; + 7DA71D00286F010700C69885 /* UIColor+Hexadecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E921E66B62F0086E0EF /* UIColor+Hexadecimal.m */; }; F56CEC4B1E67430000E2FACA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F58A3E7F1E66B62F0086E0EF /* Assets.xcassets */; }; F58A3E3C1E66AEE90086E0EF /* DZNEmptyDataSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */; }; F58A3E411E66AEE90086E0EF /* ApplicationsSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F58A3E401E66AEE90086E0EF /* ApplicationsSnapshotTests.m */; }; @@ -70,6 +81,20 @@ 23BB766D928F8635A201F389 /* Pods_EmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EmptyDataSetTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3456B9A6D72D48F19A7F61 /* Pods-DZNEmptyDataSetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DZNEmptyDataSetTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.debug.xcconfig"; sourceTree = ""; }; 78C5DC4B343BE997FFAA0048 /* Pods_DZNEmptyDataSetTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DZNEmptyDataSetTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7DA71C23286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIScrollView+DZNEmptyExt.m"; path = "../../Source/UIScrollView+DZNEmptyExt.m"; sourceTree = ""; }; + 7DA71C24286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIScrollView+DZNEmptyExt.h"; path = "../../Source/UIScrollView+DZNEmptyExt.h"; sourceTree = ""; }; + 7DA71C96286EF48200C69885 /* EmptyExt.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EmptyExt.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7DA71C9C286EF48300C69885 /* Applications copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Applications copy-Info.plist"; path = "/Users/jialunzeng/Documents/DZNEmptyDataSet/DZNEmptyDataSet/Applications copy-Info.plist"; sourceTree = ""; }; + 7DA71CA4286EF68900C69885 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 7DA71CA6286EF68900C69885 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 7DA71CA7286EF68900C69885 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 7DA71CA8286EF68900C69885 /* Applications-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Applications-Prefix.pch"; sourceTree = ""; }; + 7DA71CA9286EF68900C69885 /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; + 7DA71CAA286EF68900C69885 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7DA71CAB286EF68900C69885 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MainViewController.h; path = Ext/MainViewController.h; sourceTree = ""; }; + 7DA71CAC286EF68900C69885 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Ext/AppDelegate.h; sourceTree = ""; }; + 7DA71CAD286EF68900C69885 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Ext/AppDelegate.m; sourceTree = ""; }; + 7DA71CAE286EF68900C69885 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MainViewController.m; path = Ext/MainViewController.m; sourceTree = ""; }; 84189CEC4210484C1F24D3A8 /* Pods-DZNEmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DZNEmptyDataSetTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DZNEmptyDataSetTests/Pods-DZNEmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; DC2B63699C936D9C9CDB1740 /* Pods-EmptyDataSetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EmptyDataSetTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-EmptyDataSetTests/Pods-EmptyDataSetTests.release.xcconfig"; sourceTree = ""; }; F58A3E321E66AEE90086E0EF /* DZNEmptyDataSet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DZNEmptyDataSet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -126,6 +151,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 7DA71C8A286EF48200C69885 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7DA71C8B286EF48200C69885 /* DZNEmptyDataSet.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F58A3E2E1E66AEE90086E0EF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -172,6 +205,32 @@ name = Pods; sourceTree = ""; }; + 7DA71C3E286EF19C00C69885 /* Sample - EmptyExt */ = { + isa = PBXGroup; + children = ( + 7DA71CAC286EF68900C69885 /* AppDelegate.h */, + 7DA71CAD286EF68900C69885 /* AppDelegate.m */, + 7DA71CAB286EF68900C69885 /* MainViewController.h */, + 7DA71CAE286EF68900C69885 /* MainViewController.m */, + 7DA71CA2286EF68900C69885 /* Supporting Files */, + ); + name = "Sample - EmptyExt"; + sourceTree = ""; + }; + 7DA71CA2286EF68900C69885 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 7DA71CA3286EF68900C69885 /* InfoPlist.strings */, + 7DA71CA5286EF68900C69885 /* LaunchScreen.storyboard */, + 7DA71CA7286EF68900C69885 /* main.m */, + 7DA71CA8286EF68900C69885 /* Applications-Prefix.pch */, + 7DA71CA9286EF68900C69885 /* Storyboard.storyboard */, + 7DA71CAA286EF68900C69885 /* Info.plist */, + ); + name = "Supporting Files"; + path = "Ext/Supporting Files"; + sourceTree = ""; + }; A7CC5E0B0809CA256BDA9067 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -188,9 +247,11 @@ F58A3E3F1E66AEE90086E0EF /* DZNEmptyDataSetTests */, F58A3E641E66B5410086E0EF /* Sample - Applications */, F5BE15261E713E2100F6FBEA /* Sample - Colors */, + 7DA71C3E286EF19C00C69885 /* Sample - EmptyExt */, F58A3E331E66AEE90086E0EF /* Products */, 242E9BB031D3264D62C731D6 /* Pods */, A7CC5E0B0809CA256BDA9067 /* Frameworks */, + 7DA71C9C286EF48300C69885 /* Applications copy-Info.plist */, ); sourceTree = ""; }; @@ -201,6 +262,7 @@ F58A3E3B1E66AEE90086E0EF /* DZNEmptyDataSetTests.xctest */, F58A3E631E66B5410086E0EF /* Applications.app */, F5BE15251E713E2100F6FBEA /* Colors.app */, + 7DA71C96286EF48200C69885 /* EmptyExt.app */, ); name = Products; sourceTree = ""; @@ -211,6 +273,8 @@ F58A3E351E66AEE90086E0EF /* DZNEmptyDataSet.h */, F58A3E4C1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h */, F58A3E4D1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m */, + 7DA71C24286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.h */, + 7DA71C23286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.m */, F58A3E361E66AEE90086E0EF /* Info.plist */, ); path = DZNEmptyDataSet; @@ -347,6 +411,7 @@ files = ( F58A3EA31E66B6C70086E0EF /* Applications-Prefix.pch in Headers */, F58A3E431E66AEE90086E0EF /* DZNEmptyDataSet.h in Headers */, + 7DA71C26286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.h in Headers */, F58A3E4E1E66AF400086E0EF /* UIScrollView+EmptyDataSet.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -354,6 +419,23 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 7DA71C82286EF48200C69885 /* EmptyExt */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7DA71C93286EF48200C69885 /* Build configuration list for PBXNativeTarget "EmptyExt" */; + buildPhases = ( + 7DA71C83286EF48200C69885 /* Sources */, + 7DA71C8A286EF48200C69885 /* Frameworks */, + 7DA71C8C286EF48200C69885 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = EmptyExt; + productName = Applications; + productReference = 7DA71C96286EF48200C69885 /* EmptyExt.app */; + productType = "com.apple.product-type.application"; + }; F58A3E311E66AEE90086E0EF /* DZNEmptyDataSet */ = { isa = PBXNativeTarget; buildConfigurationList = F58A3E461E66AEE90086E0EF /* Build configuration list for PBXNativeTarget "DZNEmptyDataSet" */; @@ -473,11 +555,23 @@ F58A3E3A1E66AEE90086E0EF /* DZNEmptyDataSetTests */, F58A3E621E66B5410086E0EF /* Applications */, F5BE15241E713E2100F6FBEA /* Colors */, + 7DA71C82286EF48200C69885 /* EmptyExt */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 7DA71C8C286EF48200C69885 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7DA71CFA286EFBF600C69885 /* Assets.xcassets in Resources */, + 7DA71CB0286EF68900C69885 /* LaunchScreen.storyboard in Resources */, + 7DA71CB2286EF68900C69885 /* Storyboard.storyboard in Resources */, + 7DA71CAF286EF68900C69885 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F58A3E301E66AEE90086E0EF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -565,10 +659,22 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 7DA71C83286EF48200C69885 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7DA71D00286F010700C69885 /* UIColor+Hexadecimal.m in Sources */, + 7DA71CB5286EF68900C69885 /* MainViewController.m in Sources */, + 7DA71CB4286EF68900C69885 /* AppDelegate.m in Sources */, + 7DA71CB1286EF68900C69885 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F58A3E2D1E66AEE90086E0EF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7DA71C25286E0CBE00C69885 /* UIScrollView+DZNEmptyExt.m in Sources */, F58A3E4F1E66AF400086E0EF /* UIScrollView+EmptyDataSet.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -628,6 +734,22 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 7DA71CA3286EF68900C69885 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7DA71CA4286EF68900C69885 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7DA71CA5286EF68900C69885 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7DA71CA6286EF68900C69885 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; F58A3E8B1E66B62F0086E0EF /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -655,6 +777,36 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 7DA71C94286EF48200C69885 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "LaunchImage-3"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "Applications copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRIVATE_HEADERS_FOLDER_PATH = EmptyExt.app/PrivateHeaders; + PRODUCT_BUNDLE_IDENTIFIER = com.dzn.EmptyExt; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 7DA71C95286EF48200C69885 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "LaunchImage-3"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "Applications copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRIVATE_HEADERS_FOLDER_PATH = EmptyExt.app/PrivateHeaders; + PRODUCT_BUNDLE_IDENTIFIER = com.dzn.EmptyExt; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; F58A3E441E66AEE90086E0EF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -893,6 +1045,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 7DA71C93286EF48200C69885 /* Build configuration list for PBXNativeTarget "EmptyExt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7DA71C94286EF48200C69885 /* Debug */, + 7DA71C95286EF48200C69885 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; F58A3E2C1E66AEE90086E0EF /* Build configuration list for PBXProject "DZNEmptyDataSet" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme new file mode 100644 index 00000000..de0220ab --- /dev/null +++ b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DZNEmptyDataSet/Ext/AppDelegate.h b/DZNEmptyDataSet/Ext/AppDelegate.h new file mode 100644 index 00000000..d28b0b26 --- /dev/null +++ b/DZNEmptyDataSet/Ext/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// Applications +// +// Created by Ignacio on 6/6/14. +// Copyright (c) 2014 DZN Labs. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/DZNEmptyDataSet/Ext/AppDelegate.m b/DZNEmptyDataSet/Ext/AppDelegate.m new file mode 100644 index 00000000..e61849d3 --- /dev/null +++ b/DZNEmptyDataSet/Ext/AppDelegate.m @@ -0,0 +1,21 @@ +// +// AppDelegate.m +// Applications +// +// Created by Ignacio on 6/6/14. +// Copyright (c) 2014 DZN Labs. All rights reserved. +// + +#import "AppDelegate.h" +#import "MainViewController.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window.backgroundColor = [UIColor whiteColor]; + + return YES; +} + +@end diff --git a/DZNEmptyDataSet/Ext/MainViewController.h b/DZNEmptyDataSet/Ext/MainViewController.h new file mode 100644 index 00000000..1f5b6d25 --- /dev/null +++ b/DZNEmptyDataSet/Ext/MainViewController.h @@ -0,0 +1,15 @@ +// +// MainViewController.h +// Applications +// +// Created by Ignacio on 6/6/14. +// Copyright (c) 2014 DZN Labs. All rights reserved. +// + +#import +#import "DetailViewController.h" +#import "Application.h" + +@interface MainViewController : UITableViewController + +@end diff --git a/DZNEmptyDataSet/Ext/MainViewController.m b/DZNEmptyDataSet/Ext/MainViewController.m new file mode 100644 index 00000000..d8ed7464 --- /dev/null +++ b/DZNEmptyDataSet/Ext/MainViewController.m @@ -0,0 +1,113 @@ +// +// MainViewController.m +// Applications +// +// Created by Ignacio on 6/6/14. +// Copyright (c) 2014 DZN Labs. All rights reserved. +// + +#import "MainViewController.h" +#import "UIScrollView+DZNEmptyExt.h" +#import "UIColor+Hexadecimal.h" + +@interface MainViewController () + +@end + +@implementation MainViewController + +#pragma mark - View lifecycle + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = @"EmptyExt"; + + self.tableView.tableFooterView = [UIView new]; + self.tableView.delegate = self; + self.tableView.dataSource = self; + + NSString * titleStr = @"Star Your Favorite Files"; + UIFont * titleFont = [UIFont systemFontOfSize:17.0]; + UIColor * titleColor = [UIColor colorWithHex:@"25282b"]; + + NSString * describeStr = @"Favorites are saved for offline access."; + UIFont * describeFont = [UIFont systemFontOfSize:14.5]; + UIColor * describeColor = [UIColor colorWithHex:@"7b8994"]; + + NSString * buttonStr = @"Learn more"; + UIFont * buttonFont = [UIFont systemFontOfSize:15.0]; + UIColor * buttonNormalColor = [UIColor colorWithHex:@"007ee5"]; + UIColor * buttonHighLightColor = [UIColor colorWithHex:@"48a1ea"]; + + UIImage * loadingImage = [UIImage imageNamed:@"loading_imgBlue_78x78" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil]; + + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; + animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; + animation.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0) ]; + animation.duration = 0.25; + animation.cumulative = YES; + animation.repeatCount = MAXFLOAT; + __weak typeof(self) weakSelf = self; + [[[[self.tableView makeEmptyPage:^(DZNEmptyMaker *make) { + + // Configuring the dropbox dataset + make.displayScene(@"dropbox") + .image([UIImage imageNamed:@"placeholder_dropbox"]) + .title(titleStr, titleFont, titleColor) + .describe(describeStr, describeFont, describeColor) + .buttonTitle(buttonStr, buttonFont, buttonNormalColor, UIControlStateNormal) + .buttonTitle(buttonStr, buttonFont, buttonHighLightColor, UIControlStateHighlighted) + .backgroundColor([UIColor colorWithHex:@"f0f3f5"]) + .allowScroll(YES) + .allowTouch(YES); + + // Configuring the loading dataset + make.displayScene(@"loading") + .image(loadingImage) + .title(titleStr, titleFont, titleColor) + .describe(describeStr, describeFont, describeColor) + .buttonTitle(buttonStr, buttonFont, buttonNormalColor, UIControlStateNormal) + .buttonTitle(buttonStr, buttonFont, buttonHighLightColor, UIControlStateHighlighted) + .backgroundColor([UIColor colorWithHex:@"f0f3f5"]) + .imageAnimation(animation) + .allowImageAnimate(YES) + .allowScroll(YES) + .allowTouch(YES); + + }] emptySceneChange:^(DZNDisplayScene type) { + // do something + }] emptyViewLifeCycle:^(DZNEmptyViewLifeCycle status) { + // do something + }] emptyDisplayClick:^(DZNTapType tapType, UIScrollView *scrollView, UIView *view) { + // Click to switch scenarios + [weakSelf.tableView reloadData: @"loading"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.tableView reloadData: @"dropbox"]; + }); + }]; + + // Show a view of the Dropbox scene + [self.tableView reloadData: @"dropbox"]; +} + +#pragma mark - UITableViewDataSource Methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return 0; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *cellIdentifier = @"app_cell_identifier"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; + + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; + } + + return cell; +} + +@end diff --git a/DZNEmptyDataSet/Ext/Supporting Files/Applications-Prefix.pch b/DZNEmptyDataSet/Ext/Supporting Files/Applications-Prefix.pch new file mode 100644 index 00000000..82a2bb45 --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/Applications-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_5_0 +#warning "This project uses features only available in iOS SDK 5.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/DZNEmptyDataSet/Ext/Supporting Files/Base.lproj/LaunchScreen.storyboard b/DZNEmptyDataSet/Ext/Supporting Files/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..fdf3f97d --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DZNEmptyDataSet/Ext/Supporting Files/Info.plist b/DZNEmptyDataSet/Ext/Supporting Files/Info.plist new file mode 100644 index 00000000..7b0138cd --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIAppFonts + + IdealSans-Book-Pro.otf + Lato-Regular.ttf + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Storyboard + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/DZNEmptyDataSet/Ext/Supporting Files/Storyboard.storyboard b/DZNEmptyDataSet/Ext/Supporting Files/Storyboard.storyboard new file mode 100644 index 00000000..f04d4f15 --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/Storyboard.storyboard @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DZNEmptyDataSet/Ext/Supporting Files/en.lproj/InfoPlist.strings b/DZNEmptyDataSet/Ext/Supporting Files/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..477b28ff --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/DZNEmptyDataSet/Ext/Supporting Files/main.m b/DZNEmptyDataSet/Ext/Supporting Files/main.m new file mode 100644 index 00000000..ff8a98d5 --- /dev/null +++ b/DZNEmptyDataSet/Ext/Supporting Files/main.m @@ -0,0 +1,16 @@ +// +// main.m +// Applications +// +// Created by Ignacio Romero on 2/28/17. +// Copyright © 2017 DZN. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/README.md b/README.md index 7494f96b..c1672819 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,130 @@ depending of which you are using. You can also call `[self.tableView reloadEmptyDataSet]` to invalidate the current empty state layout and trigger a layout update, bypassing `-reloadData`. This might be useful if you have a lot of logic on your data source that you want to avoid calling, when not needed. `[self.scrollView reloadEmptyDataSet]` is the only way to refresh content when using with UIScrollView. +## How to use DZNEmptyExt + +### Import +```objc +#import "UIScrollView+DZNEmptyExt.h" +``` +Unless you are importing as a framework, then do: +```objc +#import +``` + +This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset. + +1、Added display state management (the corresponding display content can be configured according to loading, loading failure, network failure or other customized scenarios. When displaying, use reloaddata: < # expected state # > to switch.) +2、Use functional programming and Chain programming to configure data(similar to masonry) + +### Configure display data + +``` +// Bind display to scence +[tableView makeEmptyPage:^(DZNEmptyMaker *make) { + + // Parameter display of default view + make.displayScene(@"dropbox") + // -------Corresponding to DZNEmptyDataSetSource------ + .image(/** image */) + // Equivalent to attrTitle(/** NSAttributedString */) + .title(/** string */, /** font */, /** color */) + // Equivalent to attrDescribe(/** NSAttributedString */) + .describe(/** string */, /** font */, /** color */) + // Equivalent to attrButtonTitle(/** NSAttributedString */) + .buttonTitle(/** string */, /** font */, /** color */, /** UIControlState */) + .buttonImage(/** image */), /** UIControlState */) + .buttonBackImage(/** image */), /** UIControlState */) + .imageAnimation(/** animation */) + .imageTintColor(/** color */) + .backgroundColor(/** color */) + .spaceHeight(/** float */) + .offset(/** offset */) + // -------Corresponding to DZNEmptyDataSetDelegate------ + .shouldBeForcedToDisplay(/** YES/NO */) + .allowImageAnimate(/** YES/NO */) + .shouldDisplay(/** YES/NO */) + .shouldFadeIn(/** YES/NO */) + .allowScroll(/** YES/NO */) + .allowTouch(/** YES/NO */); + + // Parameter display of customized view + make.displayScene(@"Loading") + .customView(/** view */) //Use custom view + .shouldBeForcedToDisplay(/** YES/NO */) + .allowImageAnimate(/** YES/NO */) + .shouldDisplay(/** YES/NO */) + .shouldFadeIn(/** YES/NO */) + .allowScroll(/** YES/NO */) + .allowTouch(/** YES/NO */); + + make.displayScene(@"LoadFailure") + .image(/** image */) + .title(/** string */, /** font */, /** color */) + ...; // Configure data as needed + + make.displayScene(@"NetworkFailure") + ...; // Configure data as needed + + ...... +}]; +``` + +#### Refresh layout + +Using [tableview reloaddata] will maintain the current display scene + +``` +// Do not display empty datasets +[tableView reloadData: hideEmptyDataSet]; + +// Refresh the contents of the display string binding +[tableView reloadData: @"dropbox"]; +[tableView reloadData: @"Loading"]; +[tableView reloadData: @"LoadFailure"]; +[tableView reloadData: @"NetworkFailure"]; +... +``` +#### Event monitoring(displaySceneChange、LifeCycle、Click/tap ) + +``` +// +DZNEmptyMaker * emptyMaker = [tableView makeEmptyPage:^(DZNEmptyMaker *make) { + // Bind display to scene + ...... +}]; + +[[[emptyMaker emptySceneChange:^(DZNDisplayScene type) { + // Callback when changing the current display scene + // do something +}] emptyViewLifeCycle:^(DZNEmptyViewLifeCycle status) { + // Callback when the empty page lifecycle method changes + // do something +}] emptyDisplayClick:^(DZNTapType tapType, UIScrollView *scrollView, UIView *view) { + // Callback when tap button or view + // do something +}]; +``` + +#### initialize/reset、update 、add + +``` +/** + Initialize or reset empty page content +*/ +-(DZNEmptyMaker *)makeEmptyPage:(DZNEmptyMakerBlock)block; + +/** + add Empty Page content(Existing ones will be overwritten) +*/ +-(DZNEmptyMaker *)addEmptyPage:(DZNEmptyMakerBlock)block; + +/** + update Empty Page content(Only configured states can be modified) +*/ +-(DZNEmptyMaker *)updateEmptyPage:(DZNEmptyMakerBlock)block; +``` + ## Sample projects #### Applications diff --git a/Source/UIScrollView+DZNEmptyExt.h b/Source/UIScrollView+DZNEmptyExt.h new file mode 100644 index 00000000..8d2cbdbd --- /dev/null +++ b/Source/UIScrollView+DZNEmptyExt.h @@ -0,0 +1,306 @@ +// +// UIScrollView+DZNEmptyExt.h +// JLEmptyExt +// +// Created by Jialun Zeng on 2017/4/21. +// Copyright © 2017年 com.jl.emptyext. All rights reserved. +// + +#import +#import +#import "UIScrollView+EmptyDataSet.h" +@class DZNEmptyMaker; +@class DZNEmpty; + +@protocol DZNEmptyCustomSource; +@protocol DZNEmptyDelegate; +@protocol DZNEmptyDataSource; + +typedef NSString * DZNDisplayScene; + +// Normal display page (no empty view) +static DZNDisplayScene hideEmptyDataSet = @"DZNDisplaySceneHideEmptyDataSet"; + +typedef NS_ENUM(NSInteger, DZNTapType) { + // Tells the delegate that the action button was tapped. + DZNTapOfButton, + // Tells the delegate that the empty dataset view was tapped. Use this method either to resignFirstResponder of a textfield or searchBar. + DZNTapOfView, +}; + +typedef NS_ENUM(NSInteger, DZNEmptyViewLifeCycle) { + DZNEmptyViewWillAppear, // Tells the delegate that the empty data set will appear. + DZNEmptyViewDidAppear, // Tells the delegate that the empty data set did appear. + DZNEmptyViewWillDisappear, // Tells the delegate that the empty data set will disappear. + DZNEmptyViewDidDisappear, // Tells the delegate that the empty data set did disappear. +}; + + +typedef void (^DZNEmptyMakerBlock)(DZNEmptyMaker * make); +typedef DZNEmpty * (^DZNDefaultStrBlock)(NSString * title, UIFont * font, UIColor * color); +typedef DZNEmpty * (^DZNButtonStrBlock)(NSString * title, UIFont * font, UIColor * color, UIControlState state); +typedef DZNEmpty * (^DZNAttrButtonStrBlock)(NSAttributedString * title, UIControlState state); +typedef DZNEmpty * (^DZNAttrStrBlock)(NSAttributedString * title); +typedef DZNEmpty * (^DZNButtonImageBlock)(UIImage * img, UIControlState state); +typedef DZNEmpty * (^DZNImageBlock)(UIImage * img); +typedef DZNEmpty * (^DZNShowAnimateBlock)(BOOL allow); +typedef DZNEmpty * (^DZNAnimationBlock)(CAAnimation * animation); +typedef DZNEmpty * (^DZNFloatBlock)(CGFloat spaceHeight); +typedef DZNEmpty * (^DZNColorBlock)(UIColor * color); +typedef DZNEmpty * (^DZNBoolBlock)(BOOL allow); +typedef DZNEmpty * (^DZNOffsetBlock)(CGFloat offset); +typedef DZNEmpty * (^DZNCustomBlock)(UIView * view); + + +//_____________________________________________________________________________ + +#pragma mark public Delegate +@protocol DZNEmptyDelegate + +/** + Asks the delegate for scroll permission. Default is NO. + */ +@property (nonatomic ,copy) DZNBoolBlock allowScroll; + +/** + Asks the delegate for touch permission. Default is YES. + */ +@property (nonatomic ,copy) DZNBoolBlock allowTouch; + +/** + Asks the delegate to know if the empty dataset should fade in when displayed. Default is YES. + */ +@property (nonatomic ,copy) DZNBoolBlock shouldFadeIn; + +/** + Asks the delegate to know if the empty dataset should still be displayed when the amount of items is more than 0. Default is NO + */ +@property (nonatomic ,copy) DZNBoolBlock shouldBeForcedToDisplay; + +/** + Asks the delegate to know if the empty dataset should be rendered and displayed. Default is YES. + */ +@property (nonatomic ,copy) DZNBoolBlock shouldDisplay; + +/** + Asks the delegate for image view animation permission. Default is NO. + */ +@property (nonatomic, copy) DZNShowAnimateBlock allowImageAnimate; + +@end + +//_____________________________________________________________________________ + +#pragma mark Custom layout Delegate + +@protocol DZNEmptyCustomSource + +/** + Asks the data source for a custom view to be displayed instead of the default views such as labels, imageview and button. Default is nil. + Use this method to show an activity view indicator for loading feedback, or for complete custom empty data set. + Returning a custom view will ignore -offsetForEmptyDataSet and -spaceHeightForEmptyDataSet configurations. + */ +@property (nonatomic ,copy) DZNCustomBlock customView; + +@end + +//_____________________________________________________________________________ + + +#pragma mark default layout Delegate + +@protocol DZNEmptyDataSource + +/** + Asks the data source for the title of the dataset. + The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. + */ +@property (nonatomic ,copy) DZNDefaultStrBlock title; + +/** + Asks the data source for the description of the dataset. + The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. + */ +@property (nonatomic ,copy) DZNDefaultStrBlock describe; + +/** + Asks the data source for the title to be used for the normal button state. + The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. + */ +@property (nonatomic ,copy) DZNButtonStrBlock buttonTitle; +@property (nonatomic, copy) DZNAttrButtonStrBlock attrButtonTitle; + +/** + Asks the data source for the image to be used for the specified button state. present the image only without any text + */ +@property (nonatomic, copy) DZNButtonImageBlock buttonImage; + +/** + Asks the data source for a background image to be used for the specified button status + There is no default style for this call. + */ +@property (nonatomic, copy) DZNButtonImageBlock buttonBackImage; + +/** + Asks the data source for the title of the dataset. + The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. + */ + +@property (nonatomic, copy) DZNAttrStrBlock attrTitle; + +/** + Asks the data source for the description of the dataset. + The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string. + */ +@property (nonatomic, copy) DZNAttrStrBlock attrDescribe; + +/** + Asks the data source for the image of the dataset. + */ +@property (nonatomic, copy) DZNImageBlock image; + +/** + Asks the data source for a vertical space between elements. Default is 11 pts. + */ +@property (nonatomic, copy) DZNFloatBlock spaceHeight; + +/** + Asks the data source for the image animation of the dataset. + */ +@property (nonatomic, copy) DZNAnimationBlock imageAnimation; + +/** + Asks the data source for a offset for vertical and horizontal alignment of the content. Default is CGPointZero. + */ +@property (nonatomic ,copy) DZNOffsetBlock offset; + +/** + Asks the data source for the background color of the dataset. Default is clear color. + */ +@property (nonatomic ,copy) DZNColorBlock backgroundColor; + +/** + Asks the data source for a tint color of the image dataset. Default is nil. + */ +@property (nonatomic ,copy) DZNColorBlock imageTintColor; + +@end + + +//_______________________________________________________________________________________________________________ + + +@interface UIScrollView (DZNEmptyExt) + +// get current display scene +- (DZNDisplayScene)displayScene; + +/** + reload and Toggle display scene + + @param scene Desired display scene + You can directly use strings to represent scene + eg: [scrollview reloadData: @"no order"]; + */ +- (void)reloadData:(DZNDisplayScene)scene; + +/** + Get "make" in the specified state + + @param displayScene input DZNdisplayScene(NSString) + */ +- (DZNEmpty *)getEmptyMake:(DZNDisplayScene)displayScene; + +/** + Initialize or reset empty page content + + @param block block + @return DZNEmptyMaker object + */ +-(DZNEmptyMaker *)makeEmptyPage:(DZNEmptyMakerBlock)block; + +/** + add Empty Page content(Existing ones will be overwritten) + +@param block block +@return DZNEmptyMaker object +*/ +-(DZNEmptyMaker *)addEmptyPage:(DZNEmptyMakerBlock)block; + +/** + update Empty Page content(Only configured states can be modified) + +@param block block +@return DZNEmptyMaker object +*/ +-(DZNEmptyMaker *)updateEmptyPage:(DZNEmptyMakerBlock)block; + +@end + + +//_______________________________________________________________________________________________________________ + +typedef NS_ENUM(NSInteger, DZNEmptyEditType) { + DZNEmptyEditTypeMake, + DZNEmptyEditTypeUpdate, + DZNEmptyEditTypeAdd, +}; + +typedef void (^DZNSceneChangeBlock)(DZNDisplayScene type); +typedef void (^DZNEmptyViewLifeCycleBlock)(DZNEmptyViewLifeCycle status); +typedef void (^DZNTapBlock)(DZNTapType tapType, UIScrollView * scrollView, UIView * view); +typedef DZNEmpty * (^DZNdisplaySceneBlock)(DZNDisplayScene type); + + +@interface DZNEmptyMaker : NSObject + +@property (nonatomic ,strong) NSMutableDictionary * dataSource; +@property (nonatomic ,copy) DZNTapBlock tapBlock; +@property (nonatomic ,copy) DZNEmptyViewLifeCycleBlock lifeCycleBlock; +@property (nonatomic ,copy) DZNSceneChangeBlock sceneBlock; +@property (nonatomic ,assign) DZNEmptyEditType editType; + +/** + You can directly use strings to represent states + eg: + // Bind display to scene + [tableView makeEmptyPage:^(DZNEmptyMaker *make) { + make.displayScene(@"no order") + ........; // The specific content corresponding to the scene, such as title, picture, button, etc + + make.displayScene(displaySceneNetworkFailure) + ........; // The specific content corresponding to the scene, such as title, picture, button, etc + }]; + // reloadData with scene + [tableView reloadData: @"no order"]; or [tableView reloadData: displaySceneNetworkFailure]; + */ +@property (nonatomic ,copy) DZNdisplaySceneBlock displayScene; + +/** + Callback when changing the current display state + */ +-(DZNEmptyMaker *)emptySceneChange:(DZNSceneChangeBlock)block; + + +/** + Callback when the empty page lifecycle method changes + */ +-(DZNEmptyMaker *)emptyViewLifeCycle:(DZNEmptyViewLifeCycleBlock)block; + + +/** + Callback when tap button or view + + @param block block + */ +-(DZNEmptyMaker *)emptyDisplayClick:(DZNTapBlock)block; + + +@end + + +//_______________________________________________________________________________________________________________ + +@interface DZNEmpty : NSObject + +@end diff --git a/Source/UIScrollView+DZNEmptyExt.m b/Source/UIScrollView+DZNEmptyExt.m new file mode 100644 index 00000000..b033475c --- /dev/null +++ b/Source/UIScrollView+DZNEmptyExt.m @@ -0,0 +1,564 @@ +// +// UIScrollView+DZNEmptyExt.m +// JLEmptyExt +// +// Created by Jialun Zeng on 2017/4/21. +// Copyright © 2017年 com.jl.emptyext. All rights reserved. +// + +#import "UIScrollView+DZNEmptyExt.h" +#import + +@implementation UIScrollView (DZNEmptyExt) + +static const char typeKey; +static const char emptyMakerKey; + + +#pragma mark - reload + +-(void)reloadData:(DZNDisplayScene)scene{ + + [self setScrollViewType: scene]; + + self.emptyDataSetSource = self; + self.emptyDataSetDelegate = self; + + if ([self isKindOfClass: [UITableView class]]) { + UITableView * tableView = (UITableView *)self; + [tableView reloadData]; + }else if ([self isKindOfClass: [UICollectionView class]]){ + UICollectionView * collectionView = (UICollectionView *)self; + [collectionView reloadData]; + }else{ + [self reloadEmptyDataSet]; + } + + DZNEmptyMaker * maker = [self getEmptyMaker]; + + if (maker.sceneBlock) { + maker.sceneBlock(scene); + } +} + +-(DZNEmptyMaker *)makeEmptyPage:(DZNEmptyMakerBlock)block{ + + DZNEmptyMaker * maker = [[DZNEmptyMaker alloc] init]; + + maker.editType = DZNEmptyEditTypeMake; + + [self setEmptyMaker: maker]; + + if (block) { + block(maker); + } + + return maker; +} + +-(DZNEmptyMaker *)addEmptyPage:(DZNEmptyMakerBlock)block{ + + DZNEmptyMaker * maker = [self getEmptyMaker]; + + maker.editType = DZNEmptyEditTypeAdd; + + if (block) { + block(maker); + } + + return maker; +} + +-(DZNEmptyMaker *)updateEmptyPage:(DZNEmptyMakerBlock)block{ + + DZNEmptyMaker * maker = [self getEmptyMaker]; + + maker.editType = DZNEmptyEditTypeUpdate; + + if (block) { + block(maker); + } + + return maker; +} + + +-(DZNDisplayScene)displayScene{ + return [self getScrollViewType]; +} + + +#pragma mark - save data + + +- (void)setEmptyMaker:(DZNEmptyMaker *)emptyMaker{ + objc_setAssociatedObject(self, &emptyMakerKey, emptyMaker, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (DZNEmptyMaker *) getEmptyMaker{ + return objc_getAssociatedObject(self, &emptyMakerKey); +} + +- (void)setScrollViewType:(DZNDisplayScene)scrollViewType{ + objc_setAssociatedObject(self, &typeKey, scrollViewType, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (DZNDisplayScene)getScrollViewType{ + return objc_getAssociatedObject(self, &typeKey); +} + +//Get the "DZNEmpty" object in the current state +- (DZNEmpty *)getEmpty{ + NSMutableDictionary * dataSource = [self getEmptyMaker].dataSource; + return [dataSource objectForKey: [NSString stringWithFormat: @"%ld", (long)[self getScrollViewType]]]; +} + +- (DZNEmpty *)getEmptyMake:(DZNDisplayScene)displayScene{ + NSMutableDictionary * dataSource = [self getEmptyMaker].dataSource; + return [dataSource objectForKey: [NSString stringWithFormat: @"%ld", (long)displayScene]]; +} + +#pragma mark - DZNEmptyDataSetSource + +- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"Image"]; +} + +- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"Title"]; +} + +- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"Describe"]; +} + +- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state +{ + DZNEmpty * empty = [self getEmpty]; + + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + return [[empty valueForKey:@"ButtonTitles"] valueForKey: key]; +} + +- (UIImage *)buttonImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state +{ + DZNEmpty * empty = [self getEmpty]; + + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + return [[empty valueForKey:@"ButtonImages"] valueForKey: key]; +} + +- (nullable UIImage *)buttonBackgroundImageForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state{ + DZNEmpty * empty = [self getEmpty]; + + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + return [[empty valueForKey:@"ButtonBackImages"] valueForKey: key]; +} + +- (CAAnimation *)imageAnimationForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"ImageAnimation"]; +} + +-(UIView *)customViewForEmptyDataSet:(UIScrollView *)scrollView{ + + return [[self getEmpty] valueForKey: @"CustomView"]; +} + +- (UIColor *)backgroundColorForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"BackgroundColor"]; +} + +-(CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView{ + + return [[[self getEmpty] valueForKey: @"Offset"] floatValue]; +} + +- (CGFloat)spaceHeightForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"SpaceHeight"] floatValue]; +} + +- (UIColor *)imageTintColorForEmptyDataSet:(UIScrollView *)scrollView +{ + return [[self getEmpty] valueForKey: @"ImageTintColor"]; +} + + +#pragma mark DZNEmptyDataSetDelegate + +- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView +{ + if ([[self getScrollViewType] isEqualToString: hideEmptyDataSet]) return NO; + return [[[self getEmpty] valueForKey: @"ShouldDisplay"] boolValue]; +} + +- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"AllowTouch"] boolValue]; +} + +- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"AllowScroll"] boolValue]; +} + +- (BOOL)emptyDataSetShouldAnimateImageView:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"AllowImageAnimate"] boolValue]; +} + +- (BOOL)emptyDataSetShouldFadeIn:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"ShouldFadeIn"] boolValue]; +} + +- (BOOL)emptyDataSetShouldBeForcedToDisplay:(UIScrollView *)scrollView +{ + return [[[self getEmpty] valueForKey: @"ShouldBeForcedToDisplay"] boolValue]; +} + + + +- (void)emptyDataSetWillAppear:(UIScrollView *)scrollView{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.lifeCycleBlock) { + maker.lifeCycleBlock(DZNEmptyViewWillAppear); + } +} + +- (void)emptyDataSetDidAppear:(UIScrollView *)scrollView{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.lifeCycleBlock) { + maker.lifeCycleBlock(DZNEmptyViewDidAppear); + } +} + +- (void)emptyDataSetWillDisappear:(UIScrollView *)scrollView{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.lifeCycleBlock) { + maker.lifeCycleBlock(DZNEmptyViewWillDisappear); + } +} + +- (void)emptyDataSetDidDisappear:(UIScrollView *)scrollView{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.lifeCycleBlock) { + maker.lifeCycleBlock(DZNEmptyViewDidDisappear); + } +} + +- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.tapBlock) { + maker.tapBlock(DZNTapOfView, self, view); + } +} + +- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button{ + DZNEmptyMaker * maker = [self getEmptyMaker]; + if (maker.tapBlock) { + maker.tapBlock(DZNTapOfButton, self, button); + } +} + + +@end + + +//_______________________________________________________________________________________________________________ + +@implementation DZNEmptyMaker + +-(NSMutableDictionary *)dataSource{ + if (!_dataSource) { + _dataSource = [[NSMutableDictionary alloc] init]; + } + return _dataSource; +} + + +-(DZNEmpty * (^)(DZNDisplayScene type))displayScene{ + + return ^DZNEmpty *(DZNDisplayScene type){ + + DZNEmpty * empty; + + if (self.editType == DZNEmptyEditTypeUpdate) { + empty = [self.dataSource objectForKey: [NSString stringWithFormat: @"%ld", (long)type]]; + }else{ + empty = [[DZNEmpty alloc] init]; + [self.dataSource setObject: empty forKey: [NSString stringWithFormat: @"%ld", (long)type]]; + } + + return empty; + }; +} + +-(DZNEmptyMaker *)emptySceneChange:(DZNSceneChangeBlock)block{ + self.sceneBlock = block; + return self; +} + +-(DZNEmptyMaker *)emptyViewLifeCycle:(DZNEmptyViewLifeCycleBlock)block{ + self.lifeCycleBlock = block; + return self; +} + + +-(DZNEmptyMaker *)emptyDisplayClick:(DZNTapBlock)block{ + self.tapBlock = block; + return self; +} + + +@end + +//_______________________________________________________________________________________________________________ + +@interface DZNEmpty () + +@property (nonatomic ,strong) UIImage * Image; +@property (nonatomic ,strong) NSMutableDictionary * ButtonImages; +@property (nonatomic ,strong) NSMutableDictionary * ButtonBackImages; +@property (nonatomic ,strong) NSNumber * AllowImageAnimate; +@property (nonatomic ,strong) NSNumber * SpaceHeight; +@property (nonatomic ,strong) CAAnimation * ImageAnimation; +@property (nonatomic ,strong) NSAttributedString * Title; +@property (nonatomic ,strong) NSAttributedString * Describe; +@property (nonatomic ,strong) NSMutableDictionary * ButtonTitles; +@property (nonatomic ,strong) NSAttributedString * ButtonTitle; +@property (nonatomic ,strong) NSAttributedString * ButtonTitleHighlighted; +@property (nonatomic ,strong) NSNumber * Offset; +@property (nonatomic ,strong) NSNumber * AllowScroll; +@property (nonatomic ,strong) NSNumber * AllowTouch; +@property (nonatomic ,strong) NSNumber * ShouldDisplay; +@property (nonatomic ,strong) NSNumber * ShouldFadeIn; +@property (nonatomic ,strong) NSNumber * ShouldBeForcedToDisplay; +@property (nonatomic ,strong) UIColor * BackgroundColor; +@property (nonatomic ,strong) UIColor * ImageTintColor; +@property (nonatomic ,strong) UIView * CustomView; + +@end + +@implementation DZNEmpty + +#pragma mark - init +- (instancetype)init +{ + self = [super init]; + if (self) { + self.Offset = [NSNumber numberWithFloat: 0.0]; + self.AllowTouch = [NSNumber numberWithBool: YES]; + self.AllowScroll = [NSNumber numberWithBool: NO]; + self.ShouldFadeIn = [NSNumber numberWithBool: YES]; + self.ShouldDisplay = [NSNumber numberWithBool: YES]; + self.AllowImageAnimate = [NSNumber numberWithBool: NO]; + self.ShouldBeForcedToDisplay = [NSNumber numberWithBool: NO]; + self.ButtonBackImages = [[NSMutableDictionary alloc]init]; + self.ButtonImages = [[NSMutableDictionary alloc]init]; + self.ButtonTitles = [[NSMutableDictionary alloc]init]; + } + return self; +} + + +#pragma mark - Custom Empty + +-(DZNEmpty * (^)(UIView * view))customView{ + return ^id(UIView * view){ + self.CustomView = view; + return self; + }; +} + + +#pragma mark - 默认的缺省页设置 + +-(DZNDefaultStrBlock)title{ + return ^(NSString * title, UIFont * font, UIColor * color){ + if (title) { + if (!font) font = [UIFont systemFontOfSize: 17]; + if (!color) color = [UIColor lightGrayColor]; + + NSDictionary *attributes = @{NSFontAttributeName: font, + NSForegroundColorAttributeName: color}; + + self.Title = [[NSAttributedString alloc] initWithString: title attributes: attributes]; + } + + return self; + }; +} + +-(DZNDefaultStrBlock)describe{ + return ^(NSString * title, UIFont * font, UIColor * color){ + if (title) { + if (!font) font = [UIFont systemFontOfSize: 17]; + if (!color) color = [UIColor lightGrayColor]; + + NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new]; + paragraph.lineBreakMode = NSLineBreakByWordWrapping; + paragraph.alignment = NSTextAlignmentCenter; + NSDictionary *attributes = @{NSFontAttributeName: font, + NSForegroundColorAttributeName: color, + NSParagraphStyleAttributeName: paragraph}; + + self.Describe = [[NSAttributedString alloc] initWithString: title attributes: attributes]; + } + + return self; + }; +} + +-(DZNButtonStrBlock)buttonTitle{ + return ^(NSString *title, UIFont * font, UIColor * color, UIControlState state){ + if (title) { + if (!font) font = [UIFont systemFontOfSize: 17]; + if (!color) color = [UIColor lightGrayColor]; + + NSDictionary *attributes = @{NSFontAttributeName: font, + NSForegroundColorAttributeName: color}; + + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + NSAttributedString * str = [[NSAttributedString alloc] initWithString: title attributes: attributes]; + + self.ButtonTitles[key] = str; + } + + return self; + }; +} + +-(DZNEmpty * (^)(NSAttributedString * title, UIControlState state))attrButtonTitle{ + return ^id (NSAttributedString * title, UIControlState state){ + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + self.ButtonTitles[key] = title; + return self; + }; +} + +-(DZNEmpty * (^)(NSAttributedString * title))attrTitle{ + return ^id (NSAttributedString * title){ + self.Title = title; + return self; + }; +} + +-(DZNEmpty * (^)(NSAttributedString * title))attrDescribe{ + return ^id (NSAttributedString * title){ + self.Describe = title; + return self; + }; +} + +-(DZNEmpty * (^)(UIImage * img))image{ + return ^id(UIImage * img){ + self.Image = img; + return self; + }; +} + +-(DZNEmpty * (^)(UIImage * img, UIControlState state))buttonImage{ + return ^id(UIImage * img, UIControlState state){ + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + self.ButtonImages[key] = img; + return self; + }; +} + +-(DZNEmpty * (^)(UIImage * img, UIControlState state))buttonBackImage{ + return ^id(UIImage * img, UIControlState state){ + NSString * key = [NSString stringWithFormat:@"%lu", (unsigned long)state]; + self.ButtonBackImages[key] = img; + return self; + }; +} + +-(DZNEmpty * (^)(CAAnimation * animation))imageAnimation{ + return ^id(CAAnimation * animation){ + self.ImageAnimation = animation; + return self; + }; +} + +-(DZNEmpty * (^)(CGFloat spaceHeight))spaceHeight{ + return ^id(CGFloat spaceHeight){ + self.SpaceHeight = [NSNumber numberWithFloat: spaceHeight]; + return self; + }; +} + +-(DZNEmpty * (^)(CGFloat offset))offset{ + return ^id(CGFloat offset){ + self.Offset = [NSNumber numberWithFloat: offset]; + return self; + }; +} + +-(DZNEmpty * (^)(UIColor * color))backgroundColor{ + return ^id (UIColor * color){ + self.BackgroundColor = color; + return self; + }; +} + +-(DZNEmpty * (^)(UIColor * color))imageTintColor{ + return ^id (UIColor * color){ + self.ImageTintColor = color; + return self; + }; +} + + +#pragma mark - delegate + +-(DZNEmpty * (^)(BOOL allow))allowScroll{ + return ^id(BOOL allow){ + self.AllowScroll = [NSNumber numberWithBool: allow]; + return self; + }; +} + +-(DZNEmpty * (^)(BOOL allow))allowTouch{ + return ^id(BOOL allow){ + self.AllowTouch = [NSNumber numberWithBool: allow]; + return self; + }; +} + +-(DZNEmpty * (^)(BOOL should))shouldDisplay{ + return ^id(BOOL should){ + self.ShouldDisplay = [NSNumber numberWithBool: should]; + return self; + }; +} + +-(DZNEmpty * (^)(BOOL should))shouldFadeIn{ + return ^id(BOOL should){ + self.ShouldFadeIn = [NSNumber numberWithBool: should]; + return self; + }; +} + +-(DZNEmpty * (^)(BOOL should))shouldBeForcedToDisplay{ + return ^id(BOOL should){ + self.ShouldBeForcedToDisplay = [NSNumber numberWithBool: should]; + return self; + }; +} + +-(DZNEmpty * (^)(BOOL allow))allowImageAnimate{ + return ^id(BOOL allow){ + self.AllowImageAnimate = [NSNumber numberWithBool: allow]; + return self; + }; +} + +@end + + From 6f0ef02b07242230302d0a74ea2f7ee935424120 Mon Sep 17 00:00:00 2001 From: "jialun.zeng" Date: Fri, 1 Jul 2022 22:10:30 +0800 Subject: [PATCH 2/5] update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c1672819..902894ad 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset. ### Configure display data -``` +```objc // Bind display to scence [tableView makeEmptyPage:^(DZNEmptyMaker *make) { @@ -352,7 +352,7 @@ This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset. Using [tableview reloaddata] will maintain the current display scene -``` +```objc // Do not display empty datasets [tableView reloadData: hideEmptyDataSet]; @@ -365,7 +365,7 @@ Using [tableview reloaddata] will maintain the current display scene ``` #### Event monitoring(displaySceneChange、LifeCycle、Click/tap ) -``` +```objc // DZNEmptyMaker * emptyMaker = [tableView makeEmptyPage:^(DZNEmptyMaker *make) { // Bind display to scene @@ -386,7 +386,7 @@ DZNEmptyMaker * emptyMaker = [tableView makeEmptyPage:^(DZNEmptyMaker *make) { #### initialize/reset、update 、add -``` +```objc /** Initialize or reset empty page content */ From 9391721393c261dc8298d67533462c2e505fa40e Mon Sep 17 00:00:00 2001 From: jlzeng1991 <137766015@qq.com> Date: Fri, 1 Jul 2022 22:26:16 +0800 Subject: [PATCH 3/5] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 902894ad..e9dd7b23 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,10 @@ You can also call `[self.tableView reloadEmptyDataSet]` to invalidate the curren ## How to use DZNEmptyExt +This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset.
+1、Added scene management functio
+2、Simplify data configuration and method call(similar to masonry) + ### Import ```objc #import "UIScrollView+DZNEmptyExt.h" @@ -288,12 +292,8 @@ You can also call `[self.tableView reloadEmptyDataSet]` to invalidate the curren Unless you are importing as a framework, then do: ```objc #import -``` - -This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset. +`` -1、Added display state management (the corresponding display content can be configured according to loading, loading failure, network failure or other customized scenarios. When displaying, use reloaddata: < # expected state # > to switch.) -2、Use functional programming and Chain programming to configure data(similar to masonry) ### Configure display data From 1f8049b7b7382e753b0b684fe4bdb614c0d1fb76 Mon Sep 17 00:00:00 2001 From: jlzeng1991 <137766015@qq.com> Date: Fri, 1 Jul 2022 22:27:44 +0800 Subject: [PATCH 4/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9dd7b23..a3b804aa 100644 --- a/README.md +++ b/README.md @@ -292,7 +292,7 @@ This DZNEmptyExt is an encapsulation of uiscrollview+emptydataset.
Unless you are importing as a framework, then do: ```objc #import -`` +``` ### Configure display data From a415fdb261dd3509506361fea1cdda6ce8f46a57 Mon Sep 17 00:00:00 2001 From: "jialun.zeng" Date: Wed, 6 Jul 2022 15:54:31 +0800 Subject: [PATCH 5/5] add NS_ASSUME_NONNULL_BEGIN --- .../xcshareddata/xcschemes/EmptyExt.xcscheme | 12 +++--- Source/UIScrollView+DZNEmptyExt.h | 37 ++++++++++++------- Source/UIScrollView+DZNEmptyExt.m | 2 + 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme index de0220ab..1e9168b4 100644 --- a/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme +++ b/DZNEmptyDataSet/DZNEmptyDataSet.xcodeproj/xcshareddata/xcschemes/EmptyExt.xcscheme @@ -15,8 +15,8 @@ @@ -45,8 +45,8 @@ @@ -62,8 +62,8 @@ diff --git a/Source/UIScrollView+DZNEmptyExt.h b/Source/UIScrollView+DZNEmptyExt.h index 8d2cbdbd..0a6bf31a 100644 --- a/Source/UIScrollView+DZNEmptyExt.h +++ b/Source/UIScrollView+DZNEmptyExt.h @@ -12,6 +12,8 @@ @class DZNEmptyMaker; @class DZNEmpty; +NS_ASSUME_NONNULL_BEGIN + @protocol DZNEmptyCustomSource; @protocol DZNEmptyDelegate; @protocol DZNEmptyDataSource; @@ -37,19 +39,19 @@ typedef NS_ENUM(NSInteger, DZNEmptyViewLifeCycle) { typedef void (^DZNEmptyMakerBlock)(DZNEmptyMaker * make); -typedef DZNEmpty * (^DZNDefaultStrBlock)(NSString * title, UIFont * font, UIColor * color); -typedef DZNEmpty * (^DZNButtonStrBlock)(NSString * title, UIFont * font, UIColor * color, UIControlState state); -typedef DZNEmpty * (^DZNAttrButtonStrBlock)(NSAttributedString * title, UIControlState state); -typedef DZNEmpty * (^DZNAttrStrBlock)(NSAttributedString * title); -typedef DZNEmpty * (^DZNButtonImageBlock)(UIImage * img, UIControlState state); -typedef DZNEmpty * (^DZNImageBlock)(UIImage * img); -typedef DZNEmpty * (^DZNShowAnimateBlock)(BOOL allow); -typedef DZNEmpty * (^DZNAnimationBlock)(CAAnimation * animation); -typedef DZNEmpty * (^DZNFloatBlock)(CGFloat spaceHeight); -typedef DZNEmpty * (^DZNColorBlock)(UIColor * color); -typedef DZNEmpty * (^DZNBoolBlock)(BOOL allow); -typedef DZNEmpty * (^DZNOffsetBlock)(CGFloat offset); -typedef DZNEmpty * (^DZNCustomBlock)(UIView * view); +typedef DZNEmpty * _Nonnull (^DZNDefaultStrBlock)(NSString * title, UIFont * font, UIColor * color); +typedef DZNEmpty * _Nonnull (^DZNButtonStrBlock)(NSString * title, UIFont * font, UIColor * color, UIControlState state); +typedef DZNEmpty * _Nonnull (^DZNAttrButtonStrBlock)(NSAttributedString * title, UIControlState state); +typedef DZNEmpty * _Nonnull (^DZNAttrStrBlock)(NSAttributedString * title); +typedef DZNEmpty * _Nonnull (^DZNButtonImageBlock)(UIImage * img, UIControlState state); +typedef DZNEmpty * _Nonnull (^DZNImageBlock)(UIImage * img); +typedef DZNEmpty * _Nonnull (^DZNShowAnimateBlock)(BOOL allow); +typedef DZNEmpty * _Nonnull (^DZNAnimationBlock)(CAAnimation * animation); +typedef DZNEmpty * _Nonnull (^DZNFloatBlock)(CGFloat spaceHeight); +typedef DZNEmpty * _Nonnull (^DZNColorBlock)(UIColor * color); +typedef DZNEmpty * _Nonnull (^DZNBoolBlock)(BOOL allow); +typedef DZNEmpty * _Nonnull (^DZNOffsetBlock)(CGFloat offset); +typedef DZNEmpty * _Nonnull (^DZNCustomBlock)(UIView * view); //_____________________________________________________________________________ @@ -87,6 +89,11 @@ typedef DZNEmpty * (^DZNCustomBlock)(UIView * view); */ @property (nonatomic, copy) DZNShowAnimateBlock allowImageAnimate; +/** + Used to eliminate swift warning instead of @discardableResult + */ +- (void)end; + @end //_____________________________________________________________________________ @@ -249,7 +256,7 @@ typedef NS_ENUM(NSInteger, DZNEmptyEditType) { typedef void (^DZNSceneChangeBlock)(DZNDisplayScene type); typedef void (^DZNEmptyViewLifeCycleBlock)(DZNEmptyViewLifeCycle status); typedef void (^DZNTapBlock)(DZNTapType tapType, UIScrollView * scrollView, UIView * view); -typedef DZNEmpty * (^DZNdisplaySceneBlock)(DZNDisplayScene type); +typedef DZNEmpty * _Nonnull (^DZNdisplaySceneBlock)(DZNDisplayScene type); @interface DZNEmptyMaker : NSObject @@ -304,3 +311,5 @@ typedef DZNEmpty * ( @interface DZNEmpty : NSObject @end + +NS_ASSUME_NONNULL_END diff --git a/Source/UIScrollView+DZNEmptyExt.m b/Source/UIScrollView+DZNEmptyExt.m index b033475c..a788e2e1 100644 --- a/Source/UIScrollView+DZNEmptyExt.m +++ b/Source/UIScrollView+DZNEmptyExt.m @@ -559,6 +559,8 @@ -(DZNButtonStrBlock)buttonTitle{ }; } +- (void)end {} + @end