From 5e0025a973fb918f9790fa950d862e713acc807f Mon Sep 17 00:00:00 2001 From: 单军华 <WindShan@danjunhuas-MacBook-Pro.local> Date: Fri, 23 Dec 2016 08:51:57 +0800 Subject: [PATCH] 右上角加号点击弹出效果demo,附上效果图 --- Popover/Popover/AppDelegate.h | 17 Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/Contents.json | 21 Popover/Popover.xcodeproj/project.pbxproj | 340 ++++++ Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small.png | 0 Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/Contents.json | 21 Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/lifution.xcuserdatad/UserInterfaceState.xcuserstate | 0 Popover/Popover/ViewController.m | 112 ++ Popover/README.md | 62 + Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/navigationItem_menu@2x.png | 0 Popover/LICENSE | 21 Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist | 87 + Popover/Popover/ViewController.h | 15 Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/Popover.xcscheme | 91 + Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/right_menu_addFri@2x.png | 0 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Contents.json | 74 + Popover/Popover/AppDelegate.m | 46 Popover/Popover/Assets.xcassets/right_menu_QR.imageset/Contents.json | 21 Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/WindShan.xcuserdatad/UserInterfaceState.xcuserstate | 0 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon@2x.png | 0 Popover/Popover/PopoverView/PopoverViewCell.h | 34 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png | 0 Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/contacts_add_scan@2x.png | 0 Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/Contents.json | 21 Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/UserInterfaceState.xcuserstate | 0 Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/right_menu_facetoface@2x.png | 0 Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/xcschememanagement.plist | 22 Popover/Popover/Assets.xcassets/right_menu_QR.imageset/right_menu_QR@2x.png | 0 Popover/Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata | 7 Popover/Popover/Assets.xcassets/contacts_add_money.imageset/Contents.json | 21 Popover/Popover/PopoverView/PopoverAction.m | 34 Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/Contents.json | 21 Popover/PopoverView/PopoverViewCell.m | 106 ++ Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png | 0 Popover/Popover/main.m | 16 Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/Popover.xcscheme | 91 + Popover/Popover/Assets.xcassets/Contents.json | 6 Popover/PopoverView/PopoverViewCell.h | 34 Popover/Popover/PopoverView/PopoverViewCell.m | 109 ++ Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png | 0 Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/contacts_add_friend@2x.png | 0 Popover/PopoverView/PopoverView.h | 32 Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/Popover.xcscheme | 91 + Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist | 5 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png | 0 Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/contacts_add_newmessage@2x.png | 0 Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/xcschememanagement.plist | 22 Popover/Popover/PopoverView/PopoverAction.h | 28 Popover/Popover/PopoverView/PopoverView.h | 32 Popover/PopoverView/PopoverView.m | 385 +++++++ Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png | 0 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon.png | 0 Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist | 5 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png | 0 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png | 0 Popover/Popover/PopoverView/PopoverView.m | 398 ++++++++ Popover/Popover.podspec | 12 Popover/Popover/Base.lproj/Main.storyboard | 190 +++ Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/right_menu_payMoney@2x.png | 0 Popover/Popover/Info.plist | 44 Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/xcschememanagement.plist | 22 Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/Contents.json | 21 Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png | 0 Popover/效果图.png | 0 Popover/PopoverView/PopoverAction.m | 34 Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/Contents.json | 21 Popover/PopoverView/PopoverAction.h | 27 Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/right_menu_multichat@2x.png | 0 Popover/Popover/Base.lproj/LaunchScreen.storyboard | 31 Popover/Popover/Assets.xcassets/contacts_add_money.imageset/contacts_add_money@2x.png | 0 Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/Contents.json | 21 Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/Contents.json | 21 Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/WorkspaceSettings.xcsettings | 16 72 files changed, 2,908 insertions(+), 0 deletions(-) diff --git a/Popover/LICENSE b/Popover/LICENSE new file mode 100755 index 0000000..239dff4 --- /dev/null +++ b/Popover/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Popover (https://github.com/lifution) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Popover/Popover.podspec b/Popover/Popover.podspec new file mode 100755 index 0000000..b3fd8c2 --- /dev/null +++ b/Popover/Popover.podspec @@ -0,0 +1,12 @@ +Pod::Spec.new do |s| + s.name = "Popover" + s.version = "1.0" + s.summary = "A simple Popover of Menu" + s.license = { :type => "MIT", :file => "LICENSE" } + s.homepage = "https://github.com/lifution/Popover" + s.author = { "Steven" => "https://github.com/lifution" } + s.source = { :git => "https://github.com/lifution/Popover.git", :tag => "1.0.0" } + s.requires_arc = true + s.platform = :ios, "6.0" + s.source_files = "PopoverView/*", "*.{h,m}" +end \ No newline at end of file diff --git a/Popover/Popover.xcodeproj/project.pbxproj b/Popover/Popover.xcodeproj/project.pbxproj new file mode 100755 index 0000000..6a8c4fa --- /dev/null +++ b/Popover/Popover.xcodeproj/project.pbxproj @@ -0,0 +1,340 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + B057A05C1E013E180076287C /* PopoverAction.m in Sources */ = {isa = PBXBuildFile; fileRef = B057A0571E013E180076287C /* PopoverAction.m */; }; + B057A05D1E013E180076287C /* PopoverView.m in Sources */ = {isa = PBXBuildFile; fileRef = B057A0591E013E180076287C /* PopoverView.m */; }; + B057A05E1E013E180076287C /* PopoverViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B057A05B1E013E180076287C /* PopoverViewCell.m */; }; + DEF76E691C3B863C00CC7AF9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF76E681C3B863C00CC7AF9 /* main.m */; }; + DEF76E6C1C3B863C00CC7AF9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF76E6B1C3B863C00CC7AF9 /* AppDelegate.m */; }; + DEF76E6F1C3B863C00CC7AF9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF76E6E1C3B863C00CC7AF9 /* ViewController.m */; }; + DEF76E721C3B863C00CC7AF9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DEF76E701C3B863C00CC7AF9 /* Main.storyboard */; }; + DEF76E741C3B863C00CC7AF9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DEF76E731C3B863C00CC7AF9 /* Assets.xcassets */; }; + DEF76E771C3B863C00CC7AF9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DEF76E751C3B863C00CC7AF9 /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + B057A0561E013E180076287C /* PopoverAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverAction.h; sourceTree = "<group>"; }; + B057A0571E013E180076287C /* PopoverAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoverAction.m; sourceTree = "<group>"; }; + B057A0581E013E180076287C /* PopoverView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverView.h; sourceTree = "<group>"; }; + B057A0591E013E180076287C /* PopoverView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoverView.m; sourceTree = "<group>"; }; + B057A05A1E013E180076287C /* PopoverViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopoverViewCell.h; sourceTree = "<group>"; }; + B057A05B1E013E180076287C /* PopoverViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PopoverViewCell.m; sourceTree = "<group>"; }; + DEF76E641C3B863C00CC7AF9 /* Popover.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Popover.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DEF76E681C3B863C00CC7AF9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; + DEF76E6A1C3B863C00CC7AF9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; + DEF76E6B1C3B863C00CC7AF9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; + DEF76E6D1C3B863C00CC7AF9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; }; + DEF76E6E1C3B863C00CC7AF9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; }; + DEF76E711C3B863C00CC7AF9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; + DEF76E731C3B863C00CC7AF9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; + DEF76E761C3B863C00CC7AF9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; + DEF76E781C3B863C00CC7AF9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DEF76E611C3B863C00CC7AF9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B057A0551E013E180076287C /* PopoverView */ = { + isa = PBXGroup; + children = ( + B057A0581E013E180076287C /* PopoverView.h */, + B057A0591E013E180076287C /* PopoverView.m */, + B057A05A1E013E180076287C /* PopoverViewCell.h */, + B057A05B1E013E180076287C /* PopoverViewCell.m */, + B057A0561E013E180076287C /* PopoverAction.h */, + B057A0571E013E180076287C /* PopoverAction.m */, + ); + path = PopoverView; + sourceTree = "<group>"; + }; + DEF76E5B1C3B863C00CC7AF9 = { + isa = PBXGroup; + children = ( + DEF76E661C3B863C00CC7AF9 /* Popover */, + DEF76E651C3B863C00CC7AF9 /* Products */, + ); + sourceTree = "<group>"; + }; + DEF76E651C3B863C00CC7AF9 /* Products */ = { + isa = PBXGroup; + children = ( + DEF76E641C3B863C00CC7AF9 /* Popover.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + DEF76E661C3B863C00CC7AF9 /* Popover */ = { + isa = PBXGroup; + children = ( + B057A0551E013E180076287C /* PopoverView */, + DEF76E6A1C3B863C00CC7AF9 /* AppDelegate.h */, + DEF76E6B1C3B863C00CC7AF9 /* AppDelegate.m */, + DEF76E6D1C3B863C00CC7AF9 /* ViewController.h */, + DEF76E6E1C3B863C00CC7AF9 /* ViewController.m */, + DEF76E701C3B863C00CC7AF9 /* Main.storyboard */, + DEF76E731C3B863C00CC7AF9 /* Assets.xcassets */, + DEF76E751C3B863C00CC7AF9 /* LaunchScreen.storyboard */, + DEF76E781C3B863C00CC7AF9 /* Info.plist */, + DEF76E671C3B863C00CC7AF9 /* Supporting Files */, + ); + path = Popover; + sourceTree = "<group>"; + }; + DEF76E671C3B863C00CC7AF9 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + DEF76E681C3B863C00CC7AF9 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DEF76E631C3B863C00CC7AF9 /* Popover */ = { + isa = PBXNativeTarget; + buildConfigurationList = DEF76E7B1C3B863C00CC7AF9 /* Build configuration list for PBXNativeTarget "Popover" */; + buildPhases = ( + DEF76E601C3B863C00CC7AF9 /* Sources */, + DEF76E611C3B863C00CC7AF9 /* Frameworks */, + DEF76E621C3B863C00CC7AF9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Popover; + productName = Popover; + productReference = DEF76E641C3B863C00CC7AF9 /* Popover.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DEF76E5C1C3B863C00CC7AF9 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = lifution; + TargetAttributes = { + DEF76E631C3B863C00CC7AF9 = { + CreatedOnToolsVersion = 7.2; + DevelopmentTeam = Q5668NKEBD; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = DEF76E5F1C3B863C00CC7AF9 /* Build configuration list for PBXProject "Popover" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DEF76E5B1C3B863C00CC7AF9; + productRefGroup = DEF76E651C3B863C00CC7AF9 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DEF76E631C3B863C00CC7AF9 /* Popover */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DEF76E621C3B863C00CC7AF9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DEF76E771C3B863C00CC7AF9 /* LaunchScreen.storyboard in Resources */, + DEF76E741C3B863C00CC7AF9 /* Assets.xcassets in Resources */, + DEF76E721C3B863C00CC7AF9 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DEF76E601C3B863C00CC7AF9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B057A05E1E013E180076287C /* PopoverViewCell.m in Sources */, + DEF76E6F1C3B863C00CC7AF9 /* ViewController.m in Sources */, + B057A05D1E013E180076287C /* PopoverView.m in Sources */, + DEF76E6C1C3B863C00CC7AF9 /* AppDelegate.m in Sources */, + DEF76E691C3B863C00CC7AF9 /* main.m in Sources */, + B057A05C1E013E180076287C /* PopoverAction.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + DEF76E701C3B863C00CC7AF9 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DEF76E711C3B863C00CC7AF9 /* Base */, + ); + name = Main.storyboard; + sourceTree = "<group>"; + }; + DEF76E751C3B863C00CC7AF9 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DEF76E761C3B863C00CC7AF9 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + DEF76E791C3B863C00CC7AF9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + DEF76E7A1C3B863C00CC7AF9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DEF76E7C1C3B863C00CC7AF9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = Q5668NKEBD; + INFOPLIST_FILE = Popover/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.lifution.Popover; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DEF76E7D1C3B863C00CC7AF9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = Q5668NKEBD; + INFOPLIST_FILE = Popover/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.lifution.Popover; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DEF76E5F1C3B863C00CC7AF9 /* Build configuration list for PBXProject "Popover" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DEF76E791C3B863C00CC7AF9 /* Debug */, + DEF76E7A1C3B863C00CC7AF9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DEF76E7B1C3B863C00CC7AF9 /* Build configuration list for PBXNativeTarget "Popover" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DEF76E7C1C3B863C00CC7AF9 /* Debug */, + DEF76E7D1C3B863C00CC7AF9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DEF76E5C1C3B863C00CC7AF9 /* Project object */; +} diff --git a/Popover/Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Popover/Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..6de6504 --- /dev/null +++ b/Popover/Popover.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:Popover.xcodeproj"> + </FileRef> +</Workspace> diff --git a/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/WindShan.xcuserdatad/UserInterfaceState.xcuserstate b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/WindShan.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..c915b6a --- /dev/null +++ b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/WindShan.xcuserdatad/UserInterfaceState.xcuserstate Binary files differ diff --git a/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/lifution.xcuserdatad/UserInterfaceState.xcuserstate b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/lifution.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100755 index 0000000..dee278b --- /dev/null +++ b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/lifution.xcuserdatad/UserInterfaceState.xcuserstate Binary files differ diff --git a/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/UserInterfaceState.xcuserstate b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100755 index 0000000..dcd222e --- /dev/null +++ b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/UserInterfaceState.xcuserstate Binary files differ diff --git a/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/WorkspaceSettings.xcsettings b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..dd7403b --- /dev/null +++ b/Popover/Popover.xcodeproj/project.xcworkspace/xcuserdata/steven.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildLocationStyle</key> + <string>UseAppPreferences</string> + <key>CustomBuildLocationType</key> + <string>RelativeToDerivedData</string> + <key>DerivedDataLocationStyle</key> + <string>Default</string> + <key>IssueFilterStyle</key> + <string>ShowActiveSchemeOnly</string> + <key>LiveSourceIssuesEnabled</key> + <true/> +</dict> +</plist> diff --git a/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..47ba729 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Bucket + type = "1" + version = "2.0"> + <Breakpoints> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "Popover/ViewController.m" + timestampString = "504146319.593284" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "60" + endingLineNumber = "60" + landmarkName = "-leftBarItemAction:" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "Popover/ViewController.m" + timestampString = "504146324.272892" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "30" + endingLineNumber = "30" + landmarkName = "-QQActions" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "Popover/ViewController.m" + timestampString = "504146330.570631" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "87" + endingLineNumber = "87" + landmarkName = "-showWithoutImage:" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "Popover/ViewController.m" + timestampString = "504146335.428569" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "80" + endingLineNumber = "80" + landmarkName = "-rightButtonAction:" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "Popover/ViewController.m" + timestampString = "504146713.885408" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "56" + endingLineNumber = "56" + landmarkName = "-buttonAction:" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + </Breakpoints> +</Bucket> diff --git a/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/Popover.xcscheme b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/Popover.xcscheme new file mode 100644 index 0000000..63ede8a --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/Popover.xcscheme @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0810" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/xcschememanagement.plist b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..8819215 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/WindShan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>SchemeUserState</key> + <dict> + <key>Popover.xcscheme</key> + <dict> + <key>orderHint</key> + <integer>0</integer> + </dict> + </dict> + <key>SuppressBuildableAutocreation</key> + <dict> + <key>DEF76E631C3B863C00CC7AF9</key> + <dict> + <key>primary</key> + <true/> + </dict> + </dict> +</dict> +</plist> diff --git a/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100755 index 0000000..fe2b454 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Bucket + type = "1" + version = "2.0"> +</Bucket> diff --git a/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/Popover.xcscheme b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/Popover.xcscheme new file mode 100755 index 0000000..b67703f --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/Popover.xcscheme @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0720" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/xcschememanagement.plist b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100755 index 0000000..8819215 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/lifution.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>SchemeUserState</key> + <dict> + <key>Popover.xcscheme</key> + <dict> + <key>orderHint</key> + <integer>0</integer> + </dict> + </dict> + <key>SuppressBuildableAutocreation</key> + <dict> + <key>DEF76E631C3B863C00CC7AF9</key> + <dict> + <key>primary</key> + <true/> + </dict> + </dict> +</dict> +</plist> diff --git a/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100755 index 0000000..fe2b454 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Bucket + type = "1" + version = "2.0"> +</Bucket> diff --git a/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/Popover.xcscheme b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/Popover.xcscheme new file mode 100755 index 0000000..63ede8a --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/Popover.xcscheme @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0810" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "DEF76E631C3B863C00CC7AF9" + BuildableName = "Popover.app" + BlueprintName = "Popover" + ReferencedContainer = "container:Popover.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/xcschememanagement.plist b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100755 index 0000000..8819215 --- /dev/null +++ b/Popover/Popover.xcodeproj/xcuserdata/steven.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>SchemeUserState</key> + <dict> + <key>Popover.xcscheme</key> + <dict> + <key>orderHint</key> + <integer>0</integer> + </dict> + </dict> + <key>SuppressBuildableAutocreation</key> + <dict> + <key>DEF76E631C3B863C00CC7AF9</key> + <dict> + <key>primary</key> + <true/> + </dict> + </dict> +</dict> +</plist> diff --git a/Popover/Popover/AppDelegate.h b/Popover/Popover/AppDelegate.h new file mode 100755 index 0000000..f4d99dd --- /dev/null +++ b/Popover/Popover/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> + +@interface AppDelegate : UIResponder <UIApplicationDelegate> + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/Popover/Popover/AppDelegate.m b/Popover/Popover/AppDelegate.m new file mode 100755 index 0000000..8738753 --- /dev/null +++ b/Popover/Popover/AppDelegate.m @@ -0,0 +1,46 @@ +// +// AppDelegate.m +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // 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. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // 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. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Contents.json b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100755 index 0000000..d54f49d --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,74 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-Notification@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-Notification@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Small-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Small-40@3x.png", + "scale" : "3x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon.png", + "scale" : "1x" + }, + { + "size" : "57x57", + "idiom" : "iphone", + "filename" : "Icon@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png new file mode 100755 index 0000000..65d52de --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png new file mode 100755 index 0000000..3910691 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png new file mode 100755 index 0000000..3da8a25 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png new file mode 100755 index 0000000..49989aa --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png new file mode 100755 index 0000000..c9d2bed --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png new file mode 100755 index 0000000..65d52de --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small.png new file mode 100755 index 0000000..f39b35d --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png new file mode 100755 index 0000000..be99e8d --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png new file mode 100755 index 0000000..342e182 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon.png new file mode 100755 index 0000000..f930d89 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon@2x.png b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon@2x.png new file mode 100755 index 0000000..04d46a0 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/AppIcon.appiconset/Icon@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/Contents.json b/Popover/Popover/Assets.xcassets/Contents.json new file mode 100755 index 0000000..da4a164 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/Contents.json b/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/Contents.json new file mode 100755 index 0000000..11ae7b4 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "contacts_add_friend@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/contacts_add_friend@2x.png b/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/contacts_add_friend@2x.png new file mode 100755 index 0000000..26f6a05 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_friend.imageset/contacts_add_friend@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/Contents.json b/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/Contents.json new file mode 100755 index 0000000..d57f18a --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "contacts_add_money@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/contacts_add_money@2x.png b/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/contacts_add_money@2x.png new file mode 100755 index 0000000..16789cb --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_money.imageset/contacts_add_money@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/Contents.json b/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/Contents.json new file mode 100755 index 0000000..5d42b36 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "contacts_add_newmessage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/contacts_add_newmessage@2x.png b/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/contacts_add_newmessage@2x.png new file mode 100755 index 0000000..06559bd --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_newmessage.imageset/contacts_add_newmessage@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/Contents.json b/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/Contents.json new file mode 100755 index 0000000..369ae34 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "contacts_add_scan@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/contacts_add_scan@2x.png b/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/contacts_add_scan@2x.png new file mode 100755 index 0000000..66602d1 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/contacts_add_scan.imageset/contacts_add_scan@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/Contents.json b/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/Contents.json new file mode 100755 index 0000000..13ee253 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "navigationItem_menu@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/navigationItem_menu@2x.png b/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/navigationItem_menu@2x.png new file mode 100755 index 0000000..d78f03d --- /dev/null +++ b/Popover/Popover/Assets.xcassets/navigationItem_menu.imageset/navigationItem_menu@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/Contents.json b/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/Contents.json new file mode 100755 index 0000000..5de09d0 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "right_menu_QR@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/right_menu_QR@2x.png b/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/right_menu_QR@2x.png new file mode 100755 index 0000000..225841c --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_QR.imageset/right_menu_QR@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/Contents.json b/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/Contents.json new file mode 100755 index 0000000..926b8dd --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "right_menu_addFri@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/right_menu_addFri@2x.png b/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/right_menu_addFri@2x.png new file mode 100755 index 0000000..5fd2256 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_addFri.imageset/right_menu_addFri@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/Contents.json b/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/Contents.json new file mode 100755 index 0000000..4b6b5ab --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "right_menu_facetoface@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/right_menu_facetoface@2x.png b/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/right_menu_facetoface@2x.png new file mode 100755 index 0000000..6e0de0f --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_facetoface.imageset/right_menu_facetoface@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/Contents.json b/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/Contents.json new file mode 100755 index 0000000..d852820 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "right_menu_multichat@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/right_menu_multichat@2x.png b/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/right_menu_multichat@2x.png new file mode 100755 index 0000000..4d71537 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_multichat.imageset/right_menu_multichat@2x.png Binary files differ diff --git a/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/Contents.json b/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/Contents.json new file mode 100755 index 0000000..ea74464 --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "right_menu_payMoney@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/right_menu_payMoney@2x.png b/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/right_menu_payMoney@2x.png new file mode 100755 index 0000000..c4b37cf --- /dev/null +++ b/Popover/Popover/Assets.xcassets/right_menu_payMoney.imageset/right_menu_payMoney@2x.png Binary files differ diff --git a/Popover/Popover/Base.lproj/LaunchScreen.storyboard b/Popover/Popover/Base.lproj/LaunchScreen.storyboard new file mode 100755 index 0000000..12982f7 --- /dev/null +++ b/Popover/Popover/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <device id="retina4_7" orientation="portrait"> + <adaptation id="fullscreen"/> + </device> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/> + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> +</document> diff --git a/Popover/Popover/Base.lproj/Main.storyboard b/Popover/Popover/Base.lproj/Main.storyboard new file mode 100755 index 0000000..a55be3a --- /dev/null +++ b/Popover/Popover/Base.lproj/Main.storyboard @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="QBF-Rp-PB9"> + <device id="retina4_7" orientation="portrait"> + <adaptation id="fullscreen"/> + </device> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--Navigation Controller--> + <scene sceneID="KFp-Vm-K4s"> + <objects> + <navigationController id="QBF-Rp-PB9" sceneMemberID="viewController"> + <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="Ozy-CH-Lu2"> + <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> + <autoresizingMask key="autoresizingMask"/> + <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <color key="barTintColor" red="0.1176470588" green="0.66666666669999997" blue="0.94509803920000002" alpha="1" colorSpace="calibratedRGB"/> + <textAttributes key="titleTextAttributes"> + <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </textAttributes> + </navigationBar> + <connections> + <segue destination="geS-fr-ReB" kind="relationship" relationship="rootViewController" id="EMz-iF-tU4"/> + </connections> + </navigationController> + <placeholder placeholderIdentifier="IBFirstResponder" id="avt-Ud-Iy2" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="266" y="107"/> + </scene> + <!--Popover--> + <scene sceneID="DAI-sZ-Mja"> + <objects> + <viewController storyboardIdentifier="ViewController" id="geS-fr-ReB" customClass="ViewController" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="ixD-XH-j9U"/> + <viewControllerLayoutGuide type="bottom" id="Fy8-B8-FAY"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="4BN-3b-jmf"> + <rect key="frame" x="0.0" y="64" width="375" height="603"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CC4-QJ-l9N"> + <rect key="frame" x="132.5" y="40" width="110" height="32"/> + <color key="backgroundColor" red="0.1176470588" green="0.66666666669999997" blue="0.94509803920000002" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="width" constant="110" id="8jt-SV-sGC"/> + <constraint firstAttribute="height" constant="32" id="nPy-0w-reU"/> + </constraints> + <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> + <state key="normal" title="showPopover"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius"> + <integer key="value" value="5"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/> + </userDefinedRuntimeAttributes> + <connections> + <action selector="buttonAction:" destination="geS-fr-ReB" eventType="touchUpInside" id="5Fb-xu-qiH"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="A0b-Ah-o6l"> + <rect key="frame" x="10" y="531" width="110" height="32"/> + <color key="backgroundColor" red="1" green="0.50196081400000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="width" constant="110" id="3Y9-zp-TGA"/> + <constraint firstAttribute="height" constant="32" id="Lqd-NN-Sqw"/> + </constraints> + <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> + <state key="normal" title="showPopover"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius"> + <integer key="value" value="5"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/> + </userDefinedRuntimeAttributes> + <connections> + <action selector="buttonAction:" destination="geS-fr-ReB" eventType="touchUpInside" id="EPh-gE-xUy"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qFV-Z6-rzD"> + <rect key="frame" x="255" y="531" width="110" height="32"/> + <color key="backgroundColor" red="0.0" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="32" id="OtP-Ah-fdc"/> + <constraint firstAttribute="width" constant="110" id="xIG-PH-GXB"/> + </constraints> + <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> + <state key="normal" title="showPopover"> + <color key="titleColor" cocoaTouchSystemColor="darkTextColor"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius"> + <integer key="value" value="5"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/> + </userDefinedRuntimeAttributes> + <connections> + <action selector="buttonAction:" destination="geS-fr-ReB" eventType="touchUpInside" id="NsQ-gX-bTF"/> + </connections> + </button> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="������������" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1cc-Xs-eD0"> + <rect key="frame" x="154.5" y="292" width="65.5" height="19.5"/> + <fontDescription key="fontDescription" type="system" pointSize="16"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="944-J4-LAc"> + <rect key="frame" x="187" y="321.5" width="0.0" height="0.0"/> + <fontDescription key="fontDescription" type="system" pointSize="16"/> + <color key="textColor" red="0.98823529409999999" green="0.0" blue="0.0039215686269999999" alpha="1" colorSpace="calibratedRGB"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HGk-11-wXz"> + <rect key="frame" x="132" y="471" width="110" height="32"/> + <color key="backgroundColor" red="1" green="0.0" blue="1" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="width" constant="110" id="N4g-ZW-09w"/> + <constraint firstAttribute="height" constant="32" id="ude-Je-Gk3"/> + </constraints> + <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> + <state key="normal" title="showPopover"> + <color key="titleColor" red="0.0" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="calibratedRGB"/> + </state> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius"> + <integer key="value" value="5"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/> + </userDefinedRuntimeAttributes> + <connections> + <action selector="showWithoutImage:" destination="geS-fr-ReB" eventType="touchUpInside" id="1EK-Wb-VAI"/> + </connections> + </button> + </subviews> + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <constraints> + <constraint firstItem="CC4-QJ-l9N" firstAttribute="centerX" secondItem="4BN-3b-jmf" secondAttribute="centerX" id="4in-U8-RTN"/> + <constraint firstItem="1cc-Xs-eD0" firstAttribute="centerY" secondItem="4BN-3b-jmf" secondAttribute="centerY" id="Acf-fv-URZ"/> + <constraint firstItem="1cc-Xs-eD0" firstAttribute="centerX" secondItem="4BN-3b-jmf" secondAttribute="centerX" id="ED4-5N-nn1"/> + <constraint firstItem="944-J4-LAc" firstAttribute="centerX" secondItem="4BN-3b-jmf" secondAttribute="centerX" id="Esz-eK-vIz"/> + <constraint firstItem="CC4-QJ-l9N" firstAttribute="top" secondItem="ixD-XH-j9U" secondAttribute="bottom" constant="40" id="IrW-Yt-MNG"/> + <constraint firstItem="Fy8-B8-FAY" firstAttribute="top" secondItem="HGk-11-wXz" secondAttribute="bottom" constant="100" id="M3e-IM-osS"/> + <constraint firstItem="A0b-Ah-o6l" firstAttribute="leading" secondItem="4BN-3b-jmf" secondAttribute="leading" constant="10" id="UTc-Ff-sfV"/> + <constraint firstItem="944-J4-LAc" firstAttribute="top" secondItem="1cc-Xs-eD0" secondAttribute="bottom" constant="10" id="UrE-SB-p9x"/> + <constraint firstItem="Fy8-B8-FAY" firstAttribute="top" secondItem="qFV-Z6-rzD" secondAttribute="bottom" constant="40" id="WvE-4Z-Zy5"/> + <constraint firstAttribute="trailing" secondItem="qFV-Z6-rzD" secondAttribute="trailing" constant="10" id="bJJ-Jq-7I8"/> + <constraint firstItem="HGk-11-wXz" firstAttribute="centerX" secondItem="4BN-3b-jmf" secondAttribute="centerX" id="maw-7u-V55"/> + <constraint firstItem="Fy8-B8-FAY" firstAttribute="top" secondItem="A0b-Ah-o6l" secondAttribute="bottom" constant="40" id="y51-UC-69M"/> + </constraints> + </view> + <navigationItem key="navigationItem" title="Popover" id="xXS-78-Yrl"> + <barButtonItem key="leftBarButtonItem" image="navigationItem_menu" id="PKd-xW-kEH"> + <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <connections> + <action selector="leftBarItemAction:" destination="geS-fr-ReB" id="CYo-d1-lzq"/> + </connections> + </barButtonItem> + <barButtonItem key="rightBarButtonItem" id="HkD-ni-VFq"> + <button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="yDx-1B-vCI"> + <rect key="frame" x="334" y="9" width="25" height="25"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <state key="normal" image="navigationItem_menu"/> + <connections> + <action selector="rightButtonAction:" destination="geS-fr-ReB" eventType="touchUpInside" id="eVe-39-zS7"/> + </connections> + </button> + <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </barButtonItem> + </navigationItem> + <connections> + <outlet property="noticeLabel" destination="944-J4-LAc" id="DfQ-z5-DtL"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="rCP-RK-tfJ" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="974" y="107"/> + </scene> + </scenes> + <resources> + <image name="navigationItem_menu" width="20" height="20"/> + </resources> +</document> diff --git a/Popover/Popover/Info.plist b/Popover/Popover/Info.plist new file mode 100755 index 0000000..91cd2d0 --- /dev/null +++ b/Popover/Popover/Info.plist @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIMainStoryboardFile</key> + <string>Main</string> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UIStatusBarHidden</key> + <true/> + <key>UIStatusBarStyle</key> + <string>UIStatusBarStyleLightContent</string> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + </array> + <key>UIViewControllerBasedStatusBarAppearance</key> + <false/> +</dict> +</plist> diff --git a/Popover/Popover/PopoverView/PopoverAction.h b/Popover/Popover/PopoverView/PopoverAction.h new file mode 100755 index 0000000..b1f335e --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverAction.h @@ -0,0 +1,28 @@ +// +// PopoverAction.h +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +typedef NS_ENUM(NSUInteger, PopoverViewStyle) +{ + PopoverViewStyleDefault = 0, // ������������, ������ + PopoverViewStyleDark, // ������������ +}; + +@interface PopoverAction : NSObject + +@property (nonatomic, strong, readonly) UIImage *image; ///< ������ (������������ 60pix*60pix ���������) +@property (nonatomic, copy, readonly) NSString *title; ///< ������ +@property (nonatomic, copy, readonly) void(^handler)(PopoverAction *action); ///< ������������, ���Block������������������������, Block���������������������������������������. + ++ (instancetype)actionWithTitle:(NSString *)title handler:(void (^)(PopoverAction *action))handler; + ++ (instancetype)actionWithImage:(UIImage *)image title:(NSString *)title handler:(void (^)(PopoverAction *action))handler; + +@end diff --git a/Popover/Popover/PopoverView/PopoverAction.m b/Popover/Popover/PopoverView/PopoverAction.m new file mode 100755 index 0000000..1ed93dc --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverAction.m @@ -0,0 +1,34 @@ +// +// PopoverAction.m +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverAction.h" + +@interface PopoverAction () + +@property (nonatomic, strong, readwrite) UIImage *image; ///< ������ +@property (nonatomic, copy, readwrite) NSString *title; ///< ������ +@property (nonatomic, copy, readwrite) void(^handler)(PopoverAction *action); ///< ������������ + +@end + +@implementation PopoverAction + ++ (instancetype)actionWithTitle:(NSString *)title handler:(void (^)(PopoverAction *action))handler { + return [self actionWithImage:nil title:title handler:handler]; +} + ++ (instancetype)actionWithImage:(UIImage *)image title:(NSString *)title handler:(void (^)(PopoverAction *action))handler { + PopoverAction *action = [[self alloc] init]; + action.image = image; + action.title = title ? : @""; + action.handler = handler ? : NULL; + + return action; +} + +@end diff --git a/Popover/Popover/PopoverView/PopoverView.h b/Popover/Popover/PopoverView/PopoverView.h new file mode 100755 index 0000000..e9fb516 --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverView.h @@ -0,0 +1,32 @@ +// +// PopoverView.h +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "PopoverAction.h" + +@interface PopoverView : UIView + +@property (nonatomic, assign) BOOL hideAfterTouchOutside; ///< ������������������������������������, ���������YES. +@property (nonatomic, assign) BOOL showShade; ///< ������������������, ���������YES���������������������������������������, ���������������, ���������NO. +@property (nonatomic, assign) PopoverViewStyle style; ///< ���������������, ��������� PopoverViewStyleDefault(������). + ++ (instancetype)popoverView; + +/*! @brief ���������������View��������������� + * @param pointView ���������������View + * @param actions ������������������<PopoverAction> + */ +- (void)showToView:(UIView *)pointView withActions:(NSArray<PopoverAction *> *)actions; + +/*! @brief ��������������������������������� + * @param toPoint ������������������(���������������������������keyWindow������������������) + * @param actions ������������������<PopoverAction> + */ +- (void)showToPoint:(CGPoint)toPoint withActions:(NSArray<PopoverAction *> *)actions; + +@end diff --git a/Popover/Popover/PopoverView/PopoverView.m b/Popover/Popover/PopoverView/PopoverView.m new file mode 100755 index 0000000..c19e2bf --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverView.m @@ -0,0 +1,398 @@ +// +// PopoverView.m +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverView.h" +#import "PopoverViewCell.h" + +static float const kPopoverViewMargin = 8.f; ///< ������ +static float const kPopoverViewCellHeight = 40.f; ///< cell������������ +static float const kPopoverViewArrowHeight = 13.f; ///< ������������ + +// convert degrees to radians +float DegreesToRadians(float angle) { + return angle*M_PI/180; +} + +@interface PopoverView () <UITableViewDelegate, UITableViewDataSource> + +#pragma mark - UI +@property (nonatomic, weak) UIWindow *keyWindow; ///< ������������ +@property (nonatomic, strong) UITableView *tableView; +@property (nonatomic, strong) UIView *shadeView; ///< ��������� +@property (nonatomic, weak) CAShapeLayer *borderLayer; ///< ������Layer +@property (nonatomic, weak) UITapGestureRecognizer *tapGesture; ///< ��������������������������� + +#pragma mark - Data +@property (nonatomic, copy) NSArray<PopoverAction *> *actions; +@property (nonatomic, assign) CGFloat windowWidth; ///< ������������ +@property (nonatomic, assign) CGFloat windowHeight; ///< ������������ +@property (nonatomic, assign) BOOL isUpward; ///< ������������, YES���������, ���������������, ���������YES. + +@end + +@implementation PopoverView + +#pragma mark - Lift Cycle +- (instancetype)initWithFrame:(CGRect)frame +{ + if (!(self = [super initWithFrame:frame])) return nil; + [self initialize]; + + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self initialize]; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + _tableView.frame = CGRectMake(0, _isUpward ? kPopoverViewArrowHeight : 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - kPopoverViewArrowHeight); +} + +#pragma mark - Setter +- (void)setHideAfterTouchOutside:(BOOL)hideAfterTouchOutside +{ + _hideAfterTouchOutside = hideAfterTouchOutside; + _tapGesture.enabled = _hideAfterTouchOutside; +} + +- (void)setShowShade:(BOOL)showShade +{ + _showShade = showShade; + _shadeView.backgroundColor = _showShade ? [UIColor colorWithWhite:0.f alpha:0.18f] : [UIColor clearColor]; + if (_borderLayer) { + _borderLayer.strokeColor = _showShade ? [UIColor clearColor].CGColor : _tableView.separatorColor.CGColor; + } +} + +- (void)setStyle:(PopoverViewStyle)style +{ + _style = style; + _tableView.separatorColor = [PopoverViewCell bottomLineColorForStyle:_style]; + if (_style == PopoverViewStyleDefault) + { + self.backgroundColor = [UIColor whiteColor]; + } + else + { + self.backgroundColor = [UIColor colorWithRed:0.29 green:0.29 blue:0.29 alpha:1.00]; + } +} + +#pragma mark - Private +/*! @brief ��������������� */ +- (void)initialize { + // data + _actions = @[]; + _isUpward = YES; + _style = PopoverViewStyleDefault; + + // current view + self.backgroundColor = [UIColor whiteColor]; + + // keyWindow + _keyWindow = [UIApplication sharedApplication].keyWindow; + _windowWidth = CGRectGetWidth(_keyWindow.bounds); + _windowHeight = CGRectGetHeight(_keyWindow.bounds); + + // shadeView + _shadeView = [[UIView alloc] initWithFrame:_keyWindow.bounds]; + [self setShowShade:NO]; + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]; + [_shadeView addGestureRecognizer:tapGesture]; + _tapGesture = tapGesture; + + // tableView + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.scrollEnabled = NO; + _tableView.showsVerticalScrollIndicator = NO; + _tableView.backgroundColor = [UIColor clearColor]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _tableView.separatorColor = [PopoverViewCell bottomLineColorForStyle:_style]; + [self addSubview:_tableView]; +} + +/*! @brief ���������������������������, */ +- (void)showToPoint:(CGPoint)toPoint { + NSAssert(_actions.count > 0, @"actions must not be nil or empty !"); + + // ��������������������������� + float arrowWidth = 28; + float cornerRadius = 6.f; + float arrowCornerRadius = 2.5f; + float arrowBottomCornerRadius = 4.f; + + // ��������������������������������������������������������������������������������� x ������������ + CGFloat minHorizontalEdge = kPopoverViewMargin + cornerRadius + arrowWidth/2 + 2; + if (toPoint.x < minHorizontalEdge) { + toPoint.x = minHorizontalEdge; + } + if (_windowWidth - toPoint.x < minHorizontalEdge) { + toPoint.x = _windowWidth - minHorizontalEdge; + } + + // ��������� + _shadeView.alpha = 0.f; + [_keyWindow addSubview:_shadeView]; + + // ������������������������������ContentSize + [_tableView reloadData]; + // ������������������ContentSize���������������������������������������������frame + CGFloat currentW = [self calculateMaxWidth]; // ��������������������������������� + CGFloat currentH = _tableView.contentSize.height + kPopoverViewArrowHeight; + + // ������������������, ��������������������������������� + CGFloat maxHeight = _isUpward ? (_windowHeight - toPoint.y - kPopoverViewMargin) : (toPoint.y - CGRectGetHeight([UIApplication sharedApplication].statusBarFrame)); + if (currentH > maxHeight) { // ������������������������������������������������������������������������������������������tableView������. + currentH = maxHeight; + _tableView.scrollEnabled = YES; + if (!_isUpward) { // ��������������������������������������� + [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_actions.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO]; + } + } + + CGFloat currentX = toPoint.x - currentW/2, currentY = toPoint.y; + // x: ������������ + if (toPoint.x <= currentW/2 + kPopoverViewMargin) { + currentX = kPopoverViewMargin; + } + // x: ������������ + if (_windowWidth - toPoint.x <= currentW/2 + kPopoverViewMargin) { + currentX = _windowWidth - kPopoverViewMargin - currentW; + } + // y: ������������ + if (!_isUpward) { + currentY = toPoint.y - currentH; + } + + self.frame = CGRectMake(currentX, currentY, currentW, currentH); + + // ������������ + CGPoint arrowPoint = CGPointMake(toPoint.x - CGRectGetMinX(self.frame), _isUpward ? 0 : currentH); // ������������������������������������ + CGFloat maskTop = _isUpward ? kPopoverViewArrowHeight : 0; // ������Y��� + CGFloat maskBottom = _isUpward ? currentH : currentH - kPopoverViewArrowHeight; // ������Y��� + UIBezierPath *maskPath = [UIBezierPath bezierPath]; + // ������������ + [maskPath moveToPoint:CGPointMake(0, cornerRadius + maskTop)]; + [maskPath addArcWithCenter:CGPointMake(cornerRadius, cornerRadius + maskTop) + radius:cornerRadius + startAngle:DegreesToRadians(180) + endAngle:DegreesToRadians(270) + clockwise:YES]; + // ������������������������������ + if (_isUpward) { + [maskPath addLineToPoint:CGPointMake(arrowPoint.x - arrowWidth/2, kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowCornerRadius, arrowCornerRadius) + controlPoint:CGPointMake(arrowPoint.x - arrowWidth/2 + arrowBottomCornerRadius, kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowCornerRadius, arrowCornerRadius) + controlPoint:arrowPoint]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowWidth/2, kPopoverViewArrowHeight) + controlPoint:CGPointMake(arrowPoint.x + arrowWidth/2 - arrowBottomCornerRadius, kPopoverViewArrowHeight)]; + } + // ������������ + [maskPath addLineToPoint:CGPointMake(currentW - cornerRadius, maskTop)]; + [maskPath addArcWithCenter:CGPointMake(currentW - cornerRadius, maskTop + cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(270) + endAngle:DegreesToRadians(0) + clockwise:YES]; + // ������������ + [maskPath addLineToPoint:CGPointMake(currentW, maskBottom - cornerRadius)]; + [maskPath addArcWithCenter:CGPointMake(currentW - cornerRadius, maskBottom - cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(0) + endAngle:DegreesToRadians(90) + clockwise:YES]; + // ������������������������������ + if (!_isUpward) { + [maskPath addLineToPoint:CGPointMake(arrowPoint.x + arrowWidth/2, currentH - kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowCornerRadius, currentH - arrowCornerRadius) + controlPoint:CGPointMake(arrowPoint.x + arrowWidth/2 - arrowBottomCornerRadius, currentH - kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowCornerRadius, currentH - arrowCornerRadius) + controlPoint:arrowPoint]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowWidth/2, currentH - kPopoverViewArrowHeight) + controlPoint:CGPointMake(arrowPoint.x - arrowWidth/2 + arrowBottomCornerRadius, currentH - kPopoverViewArrowHeight)]; + } + // ������������ + [maskPath addLineToPoint:CGPointMake(cornerRadius, maskBottom)]; + [maskPath addArcWithCenter:CGPointMake(cornerRadius, maskBottom - cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(90) + endAngle:DegreesToRadians(180) + clockwise:YES]; + [maskPath closePath]; + // ��������������������� + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.frame = self.bounds; + maskLayer.path = maskPath.CGPath; + self.layer.mask = maskLayer; + // ������ (������������������������������������������������������������) + if (!_showShade) { + CAShapeLayer *borderLayer = [CAShapeLayer layer]; + borderLayer.frame = self.bounds; + borderLayer.path = maskPath.CGPath; + borderLayer.lineWidth = 1; + borderLayer.fillColor = [UIColor clearColor].CGColor; + borderLayer.strokeColor = _tableView.separatorColor.CGColor; + [self.layer addSublayer:borderLayer]; + _borderLayer = borderLayer; + } + + [_keyWindow addSubview:self]; + + // ������������ + CGRect oldFrame = self.frame; + self.layer.anchorPoint = CGPointMake(arrowPoint.x/currentW, _isUpward ? 0.f : 1.f); + self.frame = oldFrame; + self.transform = CGAffineTransformMakeScale(0.01f, 0.01f); + [UIView animateWithDuration:0.25f animations:^{ + self.transform = CGAffineTransformIdentity; + _shadeView.alpha = 1.f; + }]; +} + +/*! @brief ������������������ */ +- (CGFloat)calculateMaxWidth { + CGFloat maxWidth = 0.f, titleLeftEdge = 0.f, imageWidth = 0.f, imageMaxHeight = kPopoverViewCellHeight - PopoverViewCellVerticalMargin*2; + CGSize imageSize = CGSizeZero; + UIFont *titleFont = [PopoverViewCell titleFont]; + for (PopoverAction *action in _actions) { + imageWidth = 0.f; + titleLeftEdge = 0.f; + + if (action.image) { // ���������������������������size������������������������������������������������ + titleLeftEdge = PopoverViewCellTitleLeftEdge; // ��������������������������������������� + imageSize = action.image.size; + if (imageSize.height > imageMaxHeight) { + imageWidth = imageMaxHeight*imageSize.width/imageSize.height; + } else { + imageWidth = imageSize.width; + } + } + + CGFloat titleWidth; + if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) { // iOS7��������������� + titleWidth = [action.title sizeWithAttributes:@{NSFontAttributeName : titleFont}].width; + } else { // iOS6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + titleWidth = [action.title sizeWithFont:titleFont].width; +#pragma GCC diagnostic pop + } + + CGFloat contentWidth = PopoverViewCellHorizontalMargin*2 + imageWidth + titleLeftEdge + titleWidth; + if (contentWidth > maxWidth) { + maxWidth = ceil(contentWidth); // ������������������������������������������, ������Cell������������������������������������������������������. + } + } + + // ������������������������(������������ - kPopoverViewMargin*2)���������������������������(������������ - kPopoverViewMargin*2) + if (maxWidth > CGRectGetWidth(_keyWindow.bounds) - kPopoverViewMargin*2) { + maxWidth = CGRectGetWidth(_keyWindow.bounds) - kPopoverViewMargin*2; + } + + return maxWidth; +} + +/*! @brief ������������������������ */ +- (void)hide { + [UIView animateWithDuration:0.25f animations:^{ + self.alpha = 0.f; + _shadeView.alpha = 0.f; + self.transform = CGAffineTransformMakeScale(0.01f, 0.01f); + } completion:^(BOOL finished) { + [_shadeView removeFromSuperview]; + [self removeFromSuperview]; + }]; +} + +#pragma mark - Public ++ (instancetype)popoverView { + return [[self alloc] init]; +} + +/*! @brief ���������������View��������������� */ +- (void)showToView:(UIView *)pointView withActions:(NSArray<PopoverAction *> *)actions +{ + // ������ pointView ��������������������� + CGRect pointViewRect = [pointView.superview convertRect:pointView.frame toView:_keyWindow]; + CGFloat pointViewUpLength = CGRectGetMinY(pointViewRect); + CGFloat pointViewDownLength = _windowHeight - CGRectGetMaxY(pointViewRect); + // ������������������������ + CGPoint toPoint = CGPointMake(CGRectGetMidX(pointViewRect), 0); + // ��������� pointView ������ + if (pointViewUpLength > pointViewDownLength) + { + toPoint.y = pointViewUpLength - 5; + } + // ��������� pointView ������ + else + { + toPoint.y = CGRectGetMaxY(pointViewRect) + 5; + } + + // ������������������ + _isUpward = pointViewUpLength <= pointViewDownLength; + _actions = [actions copy]; + [self showToPoint:toPoint]; +} + +/*! @brief ��������������������������������� */ +- (void)showToPoint:(CGPoint)toPoint withActions:(NSArray<PopoverAction *> *)actions { + _actions = [actions copy]; + // ������������������������ + _isUpward = toPoint.y <= _windowHeight - toPoint.y; + [self showToPoint:toPoint]; +} + +#pragma mark - UITableViewDelegate & UITableViewDataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _actions.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return kPopoverViewCellHeight; +} + +static NSString *kPopoverCellIdentifier = @"kPopoverCellIdentifier"; +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + PopoverViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPopoverCellIdentifier]; + if (!cell) + { + cell = [[PopoverViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kPopoverCellIdentifier]; + } + + [cell setAction:_actions[indexPath.row]]; + [cell showBottomLine: indexPath.row < _actions.count - 1]; + cell.style = _style; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [UIView animateWithDuration:0.25f animations:^{ + self.alpha = 0.f; + _shadeView.alpha = 0.f; + } completion:^(BOOL finished) { + PopoverAction *action = _actions[indexPath.row]; + action.handler ? action.handler(action) : NULL; + _actions = nil; + [_shadeView removeFromSuperview]; + [self removeFromSuperview]; + }]; +} + +@end + diff --git a/Popover/Popover/PopoverView/PopoverViewCell.h b/Popover/Popover/PopoverView/PopoverViewCell.h new file mode 100755 index 0000000..23f2491 --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverViewCell.h @@ -0,0 +1,34 @@ +// +// PopoverViewCell.h +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "PopoverAction.h" + +UIKIT_EXTERN float const PopoverViewCellHorizontalMargin; ///< ������������������ +UIKIT_EXTERN float const PopoverViewCellVerticalMargin; ///< ������������ +UIKIT_EXTERN float const PopoverViewCellTitleLeftEdge; ///< ������������������ + +@class PopoverAction; + +@interface PopoverViewCell : UITableViewCell + +@property (nonatomic, assign) PopoverViewStyle style; + +/*! @brief ������������ + */ ++ (UIFont *)titleFont; + +/*! @brief ������������������ + */ ++ (UIColor *)bottomLineColorForStyle:(PopoverViewStyle)style; + +- (void)setAction:(PopoverAction *)action; + +- (void)showBottomLine:(BOOL)show; + +@end diff --git a/Popover/Popover/PopoverView/PopoverViewCell.m b/Popover/Popover/PopoverView/PopoverViewCell.m new file mode 100755 index 0000000..1698111 --- /dev/null +++ b/Popover/Popover/PopoverView/PopoverViewCell.m @@ -0,0 +1,109 @@ +// +// PopoverViewCell.m +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverViewCell.h" + +// extern +float const PopoverViewCellHorizontalMargin = 15.f; ///< ������������ +float const PopoverViewCellVerticalMargin = 3.f; ///< ������������ +float const PopoverViewCellTitleLeftEdge = 8.f; ///< ������������������ + +@interface PopoverViewCell () + +@property (nonatomic, strong) UIButton *button; +@property (nonatomic, weak) UIView *bottomLine; + +@end + +@implementation PopoverViewCell + +#pragma mark - Life Cycle +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) return nil; + self.backgroundColor = [UIColor clearColor]; + self.contentView.backgroundColor = self.backgroundColor; + self.selectionStyle = UITableViewCellSelectionStyleNone; + // initialize + [self initialize]; + + return self; +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { + [super setHighlighted:highlighted animated:animated]; + if (highlighted) { + self.backgroundColor = _style == PopoverViewStyleDefault ? [UIColor colorWithRed:0.90 green:0.90 blue:0.90 alpha:1.00] : [UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1.00]; + } else { + [UIView animateWithDuration:0.3f animations:^{ + self.backgroundColor = [UIColor clearColor]; + }]; + } +} + +#pragma mark - Setter +- (void)setStyle:(PopoverViewStyle)style { + _style = style; + _bottomLine.backgroundColor = [self.class bottomLineColorForStyle:style]; + if (_style == PopoverViewStyleDefault) { + [_button setTitleColor:UIColor.blackColor forState:UIControlStateNormal]; + } else { + [_button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; + } +} + +#pragma mark - Private +// ��������� +- (void)initialize { + // UI + _button = [UIButton buttonWithType:UIButtonTypeCustom]; + _button.userInteractionEnabled = NO; // has no use for UserInteraction. + _button.translatesAutoresizingMaskIntoConstraints = NO; + _button.titleLabel.font = [self.class titleFont]; + _button.backgroundColor = self.contentView.backgroundColor; + _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + [_button setTitleColor:UIColor.blackColor forState:UIControlStateNormal]; + [self.contentView addSubview:_button]; + // Constraint + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[_button]-margin-|" options:kNilOptions metrics:@{@"margin" : @(PopoverViewCellHorizontalMargin)} views:NSDictionaryOfVariableBindings(_button)]]; + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margin-[_button]-margin-|" options:kNilOptions metrics:@{@"margin" : @(PopoverViewCellVerticalMargin)} views:NSDictionaryOfVariableBindings(_button)]]; + // ������������ + UIView *bottomLine = [[UIView alloc] init]; + bottomLine.backgroundColor = [UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.00]; + bottomLine.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:bottomLine]; + _bottomLine = bottomLine; + // Constraint + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomLine]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(bottomLine)]]; + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomLine(lineHeight)]|" options:kNilOptions metrics:@{@"lineHeight" : @(1/[UIScreen mainScreen].scale)} views:NSDictionaryOfVariableBindings(bottomLine)]]; +} + +#pragma mark - Public +/*! @brief ������������ */ ++ (UIFont *)titleFont +{ + return [UIFont systemFontOfSize:15.f]; +} + +/*! @brief ������������������ */ ++ (UIColor *)bottomLineColorForStyle:(PopoverViewStyle)style +{ + return style == PopoverViewStyleDefault ? [UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.00] : [UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:1.00]; +} + +- (void)setAction:(PopoverAction *)action +{ + [_button setImage:action.image forState:UIControlStateNormal]; + [_button setTitle:action.title forState:UIControlStateNormal]; + _button.titleEdgeInsets = action.image ? UIEdgeInsetsMake(0, PopoverViewCellTitleLeftEdge, 0, -PopoverViewCellTitleLeftEdge) : UIEdgeInsetsZero; +} + +- (void)showBottomLine:(BOOL)show { + _bottomLine.hidden = !show; +} + +@end diff --git a/Popover/Popover/ViewController.h b/Popover/Popover/ViewController.h new file mode 100755 index 0000000..fb4815b --- /dev/null +++ b/Popover/Popover/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> + +@interface ViewController : UIViewController + + +@end + diff --git a/Popover/Popover/ViewController.m b/Popover/Popover/ViewController.m new file mode 100755 index 0000000..c48c1dc --- /dev/null +++ b/Popover/Popover/ViewController.m @@ -0,0 +1,112 @@ + + +// +// ViewController.m +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "ViewController.h" +#import "PopoverView.h" + +@interface ViewController () + +@property (weak, nonatomic) IBOutlet UILabel *noticeLabel; + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + +} + +- (NSArray<PopoverAction *> *)QQActions +{ + // ������������������ action + PopoverAction *multichatAction = [PopoverAction actionWithImage:[UIImage imageNamed:@"right_menu_multichat"] title:@"������������������" handler:^(PopoverAction *action) { +#pragma mark - ���Block������������������������, Block���������������������������������������. + _noticeLabel.text = action.title; + }]; + // ��������� action + PopoverAction *addFriAction = [PopoverAction actionWithImage:[UIImage imageNamed:@"right_menu_addFri"] title:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + // ��������� action + PopoverAction *QRAction = [PopoverAction actionWithImage:[UIImage imageNamed:@"right_menu_QR"] title:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + // ��������������� action + PopoverAction *facetofaceAction = [PopoverAction actionWithImage:[UIImage imageNamed:@"right_menu_facetoface"] title:@"���������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + // ������ action + PopoverAction *payMoneyAction = [PopoverAction actionWithImage:[UIImage imageNamed:@"right_menu_payMoney"] title:@"������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + + return @[multichatAction, addFriAction, QRAction, facetofaceAction, payMoneyAction]; +} + +- (IBAction)buttonAction:(UIButton *)sender { + PopoverView *popoverView = [PopoverView popoverView]; + [popoverView showToView:sender withActions:[self QQActions]]; +} + +- (IBAction)leftBarItemAction:(UIBarButtonItem *)sender { + PopoverAction *action1 = [PopoverAction actionWithImage:[UIImage imageNamed:@"contacts_add_newmessage"] title:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action2 = [PopoverAction actionWithImage:[UIImage imageNamed:@"contacts_add_friend"] title:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action3 = [PopoverAction actionWithImage:[UIImage imageNamed:@"contacts_add_scan"] title:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action4 = [PopoverAction actionWithImage:[UIImage imageNamed:@"contacts_add_money"] title:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + + PopoverView *popoverView = [PopoverView popoverView]; + popoverView.style = PopoverViewStyleDark; + // ���������������������������������������������������������������������������������������������������������. + [popoverView showToPoint:CGPointMake(20, 64) withActions:@[action1, action2, action3, action4]]; +} + +- (IBAction)rightButtonAction:(UIButton *)sender { + PopoverView *popoverView = [PopoverView popoverView]; + popoverView.showShade = YES; // ������������������ + [popoverView showToView:sender withActions:[self QQActions]]; +} + +- (IBAction)showWithoutImage:(UIButton *)sender { + // ������������ + PopoverAction *action1 = [PopoverAction actionWithTitle:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action2 = [PopoverAction actionWithTitle:@"���������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action3 = [PopoverAction actionWithTitle:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action4 = [PopoverAction actionWithTitle:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action5 = [PopoverAction actionWithTitle:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + PopoverAction *action6 = [PopoverAction actionWithTitle:@"������������" handler:^(PopoverAction *action) { + _noticeLabel.text = action.title; + }]; + + PopoverView *popoverView = [PopoverView popoverView]; + popoverView.style = PopoverViewStyleDark; + popoverView.hideAfterTouchOutside = NO; // ������������������������������ + [popoverView showToView:sender withActions:@[action1, action2, action3, action4, action5, action6]]; +} + +@end diff --git a/Popover/Popover/main.m b/Popover/Popover/main.m new file mode 100755 index 0000000..051b00d --- /dev/null +++ b/Popover/Popover/main.m @@ -0,0 +1,16 @@ +// +// main.m +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Popover/PopoverView/PopoverAction.h b/Popover/PopoverView/PopoverAction.h new file mode 100755 index 0000000..984b6a1 --- /dev/null +++ b/Popover/PopoverView/PopoverAction.h @@ -0,0 +1,27 @@ +// +// PopoverAction.h +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +typedef NS_ENUM(NSUInteger, PopoverViewStyle) { + PopoverViewStyleDefault = 0, // ������������, ������ + PopoverViewStyleDark, // ������������ +}; + +@interface PopoverAction : NSObject + +@property (nonatomic, strong, readonly) UIImage *image; ///< ������ (������������ 60pix*60pix ���������) +@property (nonatomic, copy, readonly) NSString *title; ///< ������ +@property (nonatomic, copy, readonly) void(^handler)(PopoverAction *action); ///< ������������, ���Block������������������������, Block���������������������������������������. + ++ (instancetype)actionWithTitle:(NSString *)title handler:(void (^)(PopoverAction *action))handler; + ++ (instancetype)actionWithImage:(UIImage *)image title:(NSString *)title handler:(void (^)(PopoverAction *action))handler; + +@end diff --git a/Popover/PopoverView/PopoverAction.m b/Popover/PopoverView/PopoverAction.m new file mode 100755 index 0000000..1ed93dc --- /dev/null +++ b/Popover/PopoverView/PopoverAction.m @@ -0,0 +1,34 @@ +// +// PopoverAction.m +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverAction.h" + +@interface PopoverAction () + +@property (nonatomic, strong, readwrite) UIImage *image; ///< ������ +@property (nonatomic, copy, readwrite) NSString *title; ///< ������ +@property (nonatomic, copy, readwrite) void(^handler)(PopoverAction *action); ///< ������������ + +@end + +@implementation PopoverAction + ++ (instancetype)actionWithTitle:(NSString *)title handler:(void (^)(PopoverAction *action))handler { + return [self actionWithImage:nil title:title handler:handler]; +} + ++ (instancetype)actionWithImage:(UIImage *)image title:(NSString *)title handler:(void (^)(PopoverAction *action))handler { + PopoverAction *action = [[self alloc] init]; + action.image = image; + action.title = title ? : @""; + action.handler = handler ? : NULL; + + return action; +} + +@end diff --git a/Popover/PopoverView/PopoverView.h b/Popover/PopoverView/PopoverView.h new file mode 100755 index 0000000..e9fb516 --- /dev/null +++ b/Popover/PopoverView/PopoverView.h @@ -0,0 +1,32 @@ +// +// PopoverView.h +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "PopoverAction.h" + +@interface PopoverView : UIView + +@property (nonatomic, assign) BOOL hideAfterTouchOutside; ///< ������������������������������������, ���������YES. +@property (nonatomic, assign) BOOL showShade; ///< ������������������, ���������YES���������������������������������������, ���������������, ���������NO. +@property (nonatomic, assign) PopoverViewStyle style; ///< ���������������, ��������� PopoverViewStyleDefault(������). + ++ (instancetype)popoverView; + +/*! @brief ���������������View��������������� + * @param pointView ���������������View + * @param actions ������������������<PopoverAction> + */ +- (void)showToView:(UIView *)pointView withActions:(NSArray<PopoverAction *> *)actions; + +/*! @brief ��������������������������������� + * @param toPoint ������������������(���������������������������keyWindow������������������) + * @param actions ������������������<PopoverAction> + */ +- (void)showToPoint:(CGPoint)toPoint withActions:(NSArray<PopoverAction *> *)actions; + +@end diff --git a/Popover/PopoverView/PopoverView.m b/Popover/PopoverView/PopoverView.m new file mode 100755 index 0000000..bdb7c9c --- /dev/null +++ b/Popover/PopoverView/PopoverView.m @@ -0,0 +1,385 @@ +// +// PopoverView.m +// Popover +// +// Created by lifution on 16/1/5. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverView.h" +#import "PopoverViewCell.h" + +static float const kPopoverViewMargin = 8.f; ///< ������ +static float const kPopoverViewCellHeight = 40.f; ///< cell������������ +static float const kPopoverViewArrowHeight = 13.f; ///< ������������ + +// convert degrees to radians +float DegreesToRadians(float angle) { + return angle*M_PI/180; +} + +@interface PopoverView () <UITableViewDelegate, UITableViewDataSource> + +#pragma mark - UI +@property (nonatomic, weak) UIWindow *keyWindow; ///< ������������ +@property (nonatomic, strong) UITableView *tableView; +@property (nonatomic, strong) UIView *shadeView; ///< ��������� +@property (nonatomic, weak) CAShapeLayer *borderLayer; ///< ������Layer + +#pragma mark - Data +@property (nonatomic, copy) NSArray<PopoverAction *> *actions; +@property (nonatomic, assign) CGFloat windowWidth; ///< ������������ +@property (nonatomic, assign) CGFloat windowHeight; ///< ������������ +@property (nonatomic, assign) BOOL isUpward; ///< ������������, YES���������, ���������������, ���������YES. + +@end + +@implementation PopoverView + +#pragma mark - Lift Cycle +- (instancetype)initWithFrame:(CGRect)frame { + if (!(self = [super initWithFrame:frame])) return nil; + [self initialize]; + + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self initialize]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + _tableView.frame = CGRectMake(0, _isUpward ? kPopoverViewArrowHeight : 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - kPopoverViewArrowHeight); +} + +- (void)dealloc { + NSLog(@"PopoverView dealloced"); +} + +#pragma mark - Setter +- (void)setHideAfterTouchOutside:(BOOL)hideAfterTouchOutside { + _hideAfterTouchOutside = hideAfterTouchOutside; + _shadeView.userInteractionEnabled = _hideAfterTouchOutside; +} + +- (void)setShowShade:(BOOL)showShade { + _showShade = showShade; + _shadeView.backgroundColor = _showShade ? [UIColor colorWithWhite:0.f alpha:0.18f] : [UIColor clearColor]; + if (_borderLayer) { + _borderLayer.strokeColor = _showShade ? [UIColor clearColor].CGColor : _tableView.separatorColor.CGColor; + } +} + +- (void)setStyle:(PopoverViewStyle)style { + _style = style; + _tableView.separatorColor = [PopoverViewCell bottomLineColorForStyle:_style]; + if (_style == PopoverViewStyleDefault) { + self.backgroundColor = [UIColor whiteColor]; + } else { + self.backgroundColor = [UIColor colorWithRed:0.29 green:0.29 blue:0.29 alpha:1.00]; + } +} + +#pragma mark - Private +/*! @brief ��������������� */ +- (void)initialize { + // data + _actions = @[]; + _isUpward = YES; + _style = PopoverViewStyleDefault; + + // current view + self.backgroundColor = [UIColor whiteColor]; + + // keyWindow + _keyWindow = [UIApplication sharedApplication].keyWindow; + _windowWidth = CGRectGetWidth(_keyWindow.bounds); + _windowHeight = CGRectGetHeight(_keyWindow.bounds); + + // shadeView + _shadeView = [[UIView alloc] initWithFrame:_keyWindow.bounds]; + [_shadeView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]]; + [self setShowShade:NO]; + + // tableView + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.scrollEnabled = NO; + _tableView.showsVerticalScrollIndicator = NO; + _tableView.backgroundColor = [UIColor clearColor]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _tableView.separatorColor = [PopoverViewCell bottomLineColorForStyle:_style]; + [self addSubview:_tableView]; +} + +/*! @brief ���������������������������, */ +- (void)showToPoint:(CGPoint)toPoint { + NSAssert(_actions.count > 0, @"actions must not be nil or empty !"); + + // ��������������������������� + float arrowWidth = 28; + float cornerRadius = 6.f; + float arrowCornerRadius = 2.5f; + float arrowBottomCornerRadius = 4.f; + + // ��������������������������������������������������������������������������������� x ������������ + CGFloat minHorizontalEdge = kPopoverViewMargin + cornerRadius + arrowWidth/2 + 2; + if (toPoint.x < minHorizontalEdge) { + toPoint.x = minHorizontalEdge; + } + if (_windowWidth - toPoint.x < minHorizontalEdge) { + toPoint.x = _windowWidth - minHorizontalEdge; + } + + // ��������� + _shadeView.alpha = 0.f; + [_keyWindow addSubview:_shadeView]; + + // ������������������������������ContentSize + [_tableView reloadData]; + // ������������������ContentSize���������������������������������������������frame + CGFloat currentW = [self calculateMaxWidth]; // ��������������������������������� + CGFloat currentH = _tableView.contentSize.height + kPopoverViewArrowHeight; + + // ������������������, ��������������������������������� + CGFloat maxHeight = _isUpward ? (_windowHeight - toPoint.y - kPopoverViewMargin) : (toPoint.y - CGRectGetHeight([UIApplication sharedApplication].statusBarFrame)); + if (currentH > maxHeight) { // ������������������������������������������������������������������������������������������tableView������. + currentH = maxHeight; + _tableView.scrollEnabled = YES; + if (!_isUpward) { // ��������������������������������������� + [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_actions.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO]; + } + } + + CGFloat currentX = toPoint.x - currentW/2, currentY = toPoint.y; + // x: ������������ + if (toPoint.x <= currentW/2 + kPopoverViewMargin) { + currentX = kPopoverViewMargin; + } + // x: ������������ + if (_windowWidth - toPoint.x <= currentW/2 + kPopoverViewMargin) { + currentX = _windowWidth - kPopoverViewMargin - currentW; + } + // y: ������������ + if (!_isUpward) { + currentY = toPoint.y - currentH; + } + + self.frame = CGRectMake(currentX, currentY, currentW, currentH); + + // ������������ + CGPoint arrowPoint = CGPointMake(toPoint.x - CGRectGetMinX(self.frame), _isUpward ? 0 : currentH); // ������������������������������������ + CGFloat maskTop = _isUpward ? kPopoverViewArrowHeight : 0; // ������Y��� + CGFloat maskBottom = _isUpward ? currentH : currentH - kPopoverViewArrowHeight; // ������Y��� + UIBezierPath *maskPath = [UIBezierPath bezierPath]; + // ������������ + [maskPath moveToPoint:CGPointMake(0, cornerRadius + maskTop)]; + [maskPath addArcWithCenter:CGPointMake(cornerRadius, cornerRadius + maskTop) + radius:cornerRadius + startAngle:DegreesToRadians(180) + endAngle:DegreesToRadians(270) + clockwise:YES]; + // ������������������������������ + if (_isUpward) { + [maskPath addLineToPoint:CGPointMake(arrowPoint.x - arrowWidth/2, kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowCornerRadius, arrowCornerRadius) + controlPoint:CGPointMake(arrowPoint.x - arrowWidth/2 + arrowBottomCornerRadius, kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowCornerRadius, arrowCornerRadius) + controlPoint:arrowPoint]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowWidth/2, kPopoverViewArrowHeight) + controlPoint:CGPointMake(arrowPoint.x + arrowWidth/2 - arrowBottomCornerRadius, kPopoverViewArrowHeight)]; + } + // ������������ + [maskPath addLineToPoint:CGPointMake(currentW - cornerRadius, maskTop)]; + [maskPath addArcWithCenter:CGPointMake(currentW - cornerRadius, maskTop + cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(270) + endAngle:DegreesToRadians(0) + clockwise:YES]; + // ������������ + [maskPath addLineToPoint:CGPointMake(currentW, maskBottom - cornerRadius)]; + [maskPath addArcWithCenter:CGPointMake(currentW - cornerRadius, maskBottom - cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(0) + endAngle:DegreesToRadians(90) + clockwise:YES]; + // ������������������������������ + if (!_isUpward) { + [maskPath addLineToPoint:CGPointMake(arrowPoint.x + arrowWidth/2, currentH - kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x + arrowCornerRadius, currentH - arrowCornerRadius) + controlPoint:CGPointMake(arrowPoint.x + arrowWidth/2 - arrowBottomCornerRadius, currentH - kPopoverViewArrowHeight)]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowCornerRadius, currentH - arrowCornerRadius) + controlPoint:arrowPoint]; + [maskPath addQuadCurveToPoint:CGPointMake(arrowPoint.x - arrowWidth/2, currentH - kPopoverViewArrowHeight) + controlPoint:CGPointMake(arrowPoint.x - arrowWidth/2 + arrowBottomCornerRadius, currentH - kPopoverViewArrowHeight)]; + } + // ������������ + [maskPath addLineToPoint:CGPointMake(cornerRadius, maskBottom)]; + [maskPath addArcWithCenter:CGPointMake(cornerRadius, maskBottom - cornerRadius) + radius:cornerRadius + startAngle:DegreesToRadians(90) + endAngle:DegreesToRadians(180) + clockwise:YES]; + [maskPath closePath]; + // ��������������������� + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.frame = self.bounds; + maskLayer.path = maskPath.CGPath; + self.layer.mask = maskLayer; + // ������ (������������������������������������������������������������) + if (!_showShade) { + CAShapeLayer *borderLayer = [CAShapeLayer layer]; + borderLayer.frame = self.bounds; + borderLayer.path = maskPath.CGPath; + borderLayer.lineWidth = 1; + borderLayer.fillColor = [UIColor clearColor].CGColor; + borderLayer.strokeColor = _tableView.separatorColor.CGColor; + [self.layer addSublayer:borderLayer]; + _borderLayer = borderLayer; + } + + [_keyWindow addSubview:self]; + + // ������������ + CGRect oldFrame = self.frame; + self.layer.anchorPoint = CGPointMake(arrowPoint.x/currentW, _isUpward ? 0.f : 1.f); + self.frame = oldFrame; + self.transform = CGAffineTransformMakeScale(0.01f, 0.01f); + [UIView animateWithDuration:0.25f animations:^{ + self.transform = CGAffineTransformIdentity; + _shadeView.alpha = 1.f; + }]; +} + +/*! @brief ������������������ */ +- (CGFloat)calculateMaxWidth { + CGFloat maxWidth = 0.f, titleLeftEdge = 0.f, imageWidth = 0.f, imageMaxHeight = kPopoverViewCellHeight - PopoverViewCellVerticalMargin*2; + CGSize imageSize = CGSizeZero; + UIFont *titleFont = [PopoverViewCell titleFont]; + for (PopoverAction *action in _actions) { + imageWidth = 0.f; + titleLeftEdge = 0.f; + + if (action.image) { // ���������������������������size������������������������������������������������ + titleLeftEdge = PopoverViewCellTitleLeftEdge; // ��������������������������������������� + imageSize = action.image.size; + if (imageSize.height > imageMaxHeight) { + imageWidth = imageMaxHeight*imageSize.width/imageSize.height; + } else { + imageWidth = imageSize.width; + } + } + + CGFloat titleWidth; + if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) { // iOS7��������������� + titleWidth = [action.title sizeWithAttributes:@{NSFontAttributeName : titleFont}].width; + } else { // iOS6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + titleWidth = [action.title sizeWithFont:titleFont].width; +#pragma GCC diagnostic pop + } + + CGFloat contentWidth = PopoverViewCellHorizontalMargin*2 + imageWidth + titleLeftEdge + titleWidth; + if (contentWidth > maxWidth) { + maxWidth = ceil(contentWidth); // ������������������������������������������, ������Cell������������������������������������������������������. + } + } + + // ������������������������(������������ - kPopoverViewMargin*2)���������������������������(������������ - kPopoverViewMargin*2) + if (maxWidth > CGRectGetWidth(_keyWindow.bounds) - kPopoverViewMargin*2) { + maxWidth = CGRectGetWidth(_keyWindow.bounds) - kPopoverViewMargin*2; + } + + return maxWidth; +} + +/*! @brief ������������������������ */ +- (void)hide { + [UIView animateWithDuration:0.25f animations:^{ + self.alpha = 0.f; + _shadeView.alpha = 0.f; + self.transform = CGAffineTransformMakeScale(0.01f, 0.01f); + } completion:^(BOOL finished) { + [_shadeView removeFromSuperview]; + [self removeFromSuperview]; + }]; +} + +#pragma mark - Public ++ (instancetype)popoverView { + return [[self alloc] init]; +} + +/*! @brief ���������������View��������������� */ +- (void)showToView:(UIView *)pointView withActions:(NSArray<PopoverAction *> *)actions { + // ������ pointView ��������������������� + CGRect pointViewRect = [pointView.superview convertRect:pointView.frame toView:_keyWindow]; + CGFloat pointViewUpLength = CGRectGetMinY(pointViewRect); + CGFloat pointViewDownLength = _windowHeight - CGRectGetMaxY(pointViewRect); + // ������������������������ + CGPoint toPoint = CGPointMake(CGRectGetMidX(pointViewRect), 0); + // ��������� pointView ������ + if (pointViewUpLength > pointViewDownLength) { + toPoint.y = pointViewUpLength - 5; + } + // ��������� pointView ������ + else { + toPoint.y = CGRectGetMaxY(pointViewRect) + 5; + } + + // ������������������ + _isUpward = pointViewUpLength <= pointViewDownLength; + _actions = [actions copy]; + [self showToPoint:toPoint]; +} + +/*! @brief ��������������������������������� */ +- (void)showToPoint:(CGPoint)toPoint withActions:(NSArray<PopoverAction *> *)actions { + _actions = [actions copy]; + // ������������������������ + _isUpward = toPoint.y <= _windowHeight - toPoint.y; + [self showToPoint:toPoint]; +} + +#pragma mark - UITableViewDelegate & UITableViewDataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _actions.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return kPopoverViewCellHeight; +} + +static NSString *kPopoverCellIdentifier = @"kPopoverCellIdentifier"; +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + PopoverViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPopoverCellIdentifier]; + if (!cell) { + cell = [[PopoverViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kPopoverCellIdentifier]; + } + + [cell setAction:_actions[indexPath.row]]; + [cell showBottomLine: indexPath.row < _actions.count - 1]; + cell.style = _style; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [UIView animateWithDuration:0.25f animations:^{ + self.alpha = 0.f; + _shadeView.alpha = 0.f; + } completion:^(BOOL finished) { + PopoverAction *action = _actions[indexPath.row]; + action.handler ? action.handler(action) : NULL; + _actions = nil; + [_shadeView removeFromSuperview]; + [self removeFromSuperview]; + }]; +} + +@end + diff --git a/Popover/PopoverView/PopoverViewCell.h b/Popover/PopoverView/PopoverViewCell.h new file mode 100755 index 0000000..23f2491 --- /dev/null +++ b/Popover/PopoverView/PopoverViewCell.h @@ -0,0 +1,34 @@ +// +// PopoverViewCell.h +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "PopoverAction.h" + +UIKIT_EXTERN float const PopoverViewCellHorizontalMargin; ///< ������������������ +UIKIT_EXTERN float const PopoverViewCellVerticalMargin; ///< ������������ +UIKIT_EXTERN float const PopoverViewCellTitleLeftEdge; ///< ������������������ + +@class PopoverAction; + +@interface PopoverViewCell : UITableViewCell + +@property (nonatomic, assign) PopoverViewStyle style; + +/*! @brief ������������ + */ ++ (UIFont *)titleFont; + +/*! @brief ������������������ + */ ++ (UIColor *)bottomLineColorForStyle:(PopoverViewStyle)style; + +- (void)setAction:(PopoverAction *)action; + +- (void)showBottomLine:(BOOL)show; + +@end diff --git a/Popover/PopoverView/PopoverViewCell.m b/Popover/PopoverView/PopoverViewCell.m new file mode 100755 index 0000000..40f0dfb --- /dev/null +++ b/Popover/PopoverView/PopoverViewCell.m @@ -0,0 +1,106 @@ +// +// PopoverViewCell.m +// Popover +// +// Created by StevenLee on 2016/12/10. +// Copyright �� 2016��� lifution. All rights reserved. +// + +#import "PopoverViewCell.h" + +// extern +float const PopoverViewCellHorizontalMargin = 15.f; ///< ������������ +float const PopoverViewCellVerticalMargin = 3.f; ///< ������������ +float const PopoverViewCellTitleLeftEdge = 8.f; ///< ������������������ + +@interface PopoverViewCell () + +@property (nonatomic, strong) UIButton *button; +@property (nonatomic, weak) UIView *bottomLine; + +@end + +@implementation PopoverViewCell + +#pragma mark - Life Cycle +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) return nil; + self.backgroundColor = [UIColor clearColor]; + self.contentView.backgroundColor = self.backgroundColor; + self.selectionStyle = UITableViewCellSelectionStyleNone; + // initialize + [self initialize]; + + return self; +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { + [super setHighlighted:highlighted animated:animated]; + if (highlighted) { + self.backgroundColor = _style == PopoverViewStyleDefault ? [UIColor colorWithRed:0.90 green:0.90 blue:0.90 alpha:1.00] : [UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1.00]; + } else { + [UIView animateWithDuration:0.3f animations:^{ + self.backgroundColor = [UIColor clearColor]; + }]; + } +} + +#pragma mark - Setter +- (void)setStyle:(PopoverViewStyle)style { + _style = style; + _bottomLine.backgroundColor = [self.class bottomLineColorForStyle:style]; + if (_style == PopoverViewStyleDefault) { + [_button setTitleColor:UIColor.blackColor forState:UIControlStateNormal]; + } else { + [_button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; + } +} + +#pragma mark - Private +// ��������� +- (void)initialize { + // UI + _button = [UIButton buttonWithType:UIButtonTypeCustom]; + _button.userInteractionEnabled = NO; // has no use for UserInteraction. + _button.translatesAutoresizingMaskIntoConstraints = NO; + _button.titleLabel.font = [self.class titleFont]; + _button.backgroundColor = self.contentView.backgroundColor; + _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + [_button setTitleColor:UIColor.blackColor forState:UIControlStateNormal]; + [self.contentView addSubview:_button]; + // Constraint + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-margin-[_button]-margin-|" options:kNilOptions metrics:@{@"margin" : @(PopoverViewCellHorizontalMargin)} views:NSDictionaryOfVariableBindings(_button)]]; + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margin-[_button]-margin-|" options:kNilOptions metrics:@{@"margin" : @(PopoverViewCellVerticalMargin)} views:NSDictionaryOfVariableBindings(_button)]]; + // ������������ + UIView *bottomLine = [[UIView alloc] init]; + bottomLine.backgroundColor = [UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.00]; + bottomLine.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:bottomLine]; + _bottomLine = bottomLine; + // Constraint + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomLine]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(bottomLine)]]; + [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomLine(lineHeight)]|" options:kNilOptions metrics:@{@"lineHeight" : @(1/[UIScreen mainScreen].scale)} views:NSDictionaryOfVariableBindings(bottomLine)]]; +} + +#pragma mark - Public +/*! @brief ������������ */ ++ (UIFont *)titleFont { + return [UIFont systemFontOfSize:15.f]; +} + +/*! @brief ������������������ */ ++ (UIColor *)bottomLineColorForStyle:(PopoverViewStyle)style { + return style == PopoverViewStyleDefault ? [UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1.00] : [UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:1.00]; +} + +- (void)setAction:(PopoverAction *)action { + [_button setImage:action.image forState:UIControlStateNormal]; + [_button setTitle:action.title forState:UIControlStateNormal]; + _button.titleEdgeInsets = action.image ? UIEdgeInsetsMake(0, PopoverViewCellTitleLeftEdge, 0, -PopoverViewCellTitleLeftEdge) : UIEdgeInsetsZero; +} + +- (void)showBottomLine:(BOOL)show { + _bottomLine.hidden = !show; +} + +@end diff --git a/Popover/README.md b/Popover/README.md new file mode 100755 index 0000000..867a3aa --- /dev/null +++ b/Popover/README.md @@ -0,0 +1,62 @@ +# Popover +###���������������������������QQ���������������������������������������������������, ������������iOS6<p> +������������������������������������������������, ���������������������������, ������������UIAlertController������������������������, ������������������������������action���������������������������������������(CGPoint)������������������������������, ���������������������������������������������������������<p> +���������������������:<p> +![Alt text][image-5]<p> +������������������������:<p> +������������: `PopoverViewStyleDefault` (������������������)<p> +![Alt text][image-1]<p> +������������: `PopoverViewStyleDark`<p> +![Alt text][image-2]<p> +������������������������������������������: +```objc +- (IBAction)showWithoutImage:(UIButton *)sender { + PopoverAction *action1 = [PopoverAction actionWithTitle:@"Title" handler:^(PopoverAction *action) { + // ���Block������������������������, Block���������������������������������������. + }]; + ... + PopoverView *popoverView = [PopoverView popoverView]; + popoverView.style = PopoverViewStyleDark; + [popoverView showToView:sender withActions:@[action1, ...]]; +} +``` +![Alt text][image-4]<p> +������������������������������������������������������: +```objc +- (IBAction)rightButtonAction:(UIButton *)sender { + PopoverView *popoverView = [PopoverView popoverView]; + popoverView.showShade = YES; // ������������������ + [popoverView showToView:sender withActions:@[...]]; +} +``` +![Alt text][image-3]<p> +������������: (���PopoverView������������������������������������ `#import "PopoverView.h"` ) +```objc +// ��������������������� +PopoverAction *action1 = [PopoverAction actionWithImage:Image title:@"Title" handler:^(PopoverAction *action) { + // ���Block������������������������, Block���������������������������������������. +}]; +// ������������ +PopoverAction *action1 = [PopoverAction actionWithTitle:@"Title" handler:^(PopoverAction *action) { + // ���Block������������������������, Block���������������������������������������. +}]; +... +PopoverView *popoverView = [PopoverView popoverView]; +//popoverView.showShade = YES; // ������������������ +//popoverView.style = PopoverViewStyleDark; // ��������������������� +//popoverView.hideAfterTouchOutside = NO; // ������������������������������ +// ��������������������� +// 1. ������������������������ +[popoverView showToView:sender withActions:@[action1, ...]]; +// 2. ���������������������(CGPoint), ������������������������KeyWidnow���������. +[popoverView showToPoint:CGPointMake(20, 64) withActions:@[action1, ...]]; +``` +## LICENSE +PopoverView is available under the MIT license. See the LICENSE file for more info. + +[image-1]:http://oeysrv69b.bkt.clouddn.com/1.png +[image-2]:http://oeysrv69b.bkt.clouddn.com/2.png +[image-3]:http://oeysrv69b.bkt.clouddn.com/5.png +[image-4]:http://oeysrv69b.bkt.clouddn.com/4.png +[image-5]:http://oeysrv69b.bkt.clouddn.com/Popover.gif + diff --git "a/Popover/\346\225\210\346\236\234\345\233\276.png" "b/Popover/\346\225\210\346\236\234\345\233\276.png" new file mode 100644 index 0000000..0be22d4 --- /dev/null +++ "b/Popover/\346\225\210\346\236\234\345\233\276.png" Binary files differ -- Gitblit v1.8.0