├── .travis.yml ├── DecimalNumberDemo.xcodeproj └── project.pbxproj ├── DecimalNumberDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-40.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-72.png │ │ ├── Icon-72@2x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small-50.png │ │ ├── Icon-Small-50@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon.png │ │ ├── Icon@2x.png │ │ ├── NotificationIcon@2x.png │ │ ├── NotificationIcon@3x.png │ │ ├── NotificationIcon~ipad.png │ │ └── NotificationIcon~ipad@2x.png │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CalculatorUIViewController.h ├── CalculatorUIViewController.m ├── DecimalNumber │ ├── NSDecimalNumber+Addtion.h │ └── NSDecimalNumber+Addtion.m ├── Info.plist ├── RSDropdownControls │ ├── RSDropdownControls.h │ ├── RSDropdownControls.m │ └── Resources │ │ └── arrow_up@2x.png ├── ViewController.h ├── ViewController.m └── main.m ├── DecimalNumberDemoTests ├── DecimalNumberDemoTests.m └── Info.plist ├── DecimalNumberDemoUITests ├── DecimalNumberDemoUITests.m └── Info.plist ├── LICENSE ├── README.md ├── README_zh.md └── SwiftDemo └── DecimalDemoSwift ├── DecimalDemoSwift.xcodeproj └── project.pbxproj ├── DecimalDemoSwift ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-40.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-72.png │ │ ├── Icon-72@2x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small-50.png │ │ ├── Icon-Small-50@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ ├── Icon.png │ │ ├── Icon@2x.png │ │ ├── NotificationIcon@2x.png │ │ ├── NotificationIcon@3x.png │ │ ├── NotificationIcon~ipad.png │ │ ├── NotificationIcon~ipad@2x.png │ │ └── ios-marketing.png │ ├── Contents.json │ ├── bg_pink.imageset │ │ ├── Contents.json │ │ ├── Image.png │ │ ├── Image@2x.png │ │ └── Image@3x.png │ ├── icon_pink.imageset │ │ ├── Contents.json │ │ ├── Image.png │ │ ├── Image@2x.png │ │ └── Image@3x.png │ └── icon_welcome.imageset │ │ ├── Contents.json │ │ ├── Image.png │ │ ├── Image@2x.png │ │ └── Image@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── DecimalDemoSwift-Bridging-Header.h ├── DecimalNumber │ ├── NSDecimalNumber+Addtion.h │ └── NSDecimalNumber+Addtion.m ├── Info.plist ├── RSDropdownControls │ ├── RSDropdownControls.h │ ├── RSDropdownControls.m │ └── Resources │ │ └── arrow_up@2x.png └── ViewController.swift ├── DecimalDemoSwiftTests ├── DecimalDemoSwiftTests.swift └── Info.plist └── DecimalDemoSwiftUITests ├── DecimalDemoSwiftUITests.swift └── Info.plist /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | -------------------------------------------------------------------------------- /DecimalNumberDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 34CD13541F14C57A00F136BC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13531F14C57A00F136BC /* main.m */; }; 11 | 34CD13571F14C57A00F136BC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13561F14C57A00F136BC /* AppDelegate.m */; }; 12 | 34CD135A1F14C57A00F136BC /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13591F14C57A00F136BC /* ViewController.m */; }; 13 | 34CD135D1F14C57A00F136BC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 34CD135B1F14C57A00F136BC /* Main.storyboard */; }; 14 | 34CD135F1F14C57A00F136BC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34CD135E1F14C57A00F136BC /* Assets.xcassets */; }; 15 | 34CD13621F14C57A00F136BC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 34CD13601F14C57A00F136BC /* LaunchScreen.storyboard */; }; 16 | 34CD136D1F14C57B00F136BC /* DecimalNumberDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD136C1F14C57B00F136BC /* DecimalNumberDemoTests.m */; }; 17 | 34CD13781F14C57B00F136BC /* DecimalNumberDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13771F14C57B00F136BC /* DecimalNumberDemoUITests.m */; }; 18 | 34CD13881F14C6F600F136BC /* NSDecimalNumber+Addtion.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13871F14C6F600F136BC /* NSDecimalNumber+Addtion.m */; }; 19 | 34CD138B1F14C74300F136BC /* CalculatorUIViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD138A1F14C74300F136BC /* CalculatorUIViewController.m */; }; 20 | 34CD13911F14C77500F136BC /* arrow_up@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 34CD138E1F14C77500F136BC /* arrow_up@2x.png */; }; 21 | 34CD13921F14C77500F136BC /* RSDropdownControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CD13901F14C77500F136BC /* RSDropdownControls.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 34CD13691F14C57B00F136BC /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 34CD13471F14C57A00F136BC /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 34CD134E1F14C57A00F136BC; 30 | remoteInfo = DecimalNumberDemo; 31 | }; 32 | 34CD13741F14C57B00F136BC /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 34CD13471F14C57A00F136BC /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 34CD134E1F14C57A00F136BC; 37 | remoteInfo = DecimalNumberDemo; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 34CD134F1F14C57A00F136BC /* DecimalNumberDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DecimalNumberDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 34CD13531F14C57A00F136BC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | 34CD13551F14C57A00F136BC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 45 | 34CD13561F14C57A00F136BC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 46 | 34CD13581F14C57A00F136BC /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 47 | 34CD13591F14C57A00F136BC /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 48 | 34CD135C1F14C57A00F136BC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 34CD135E1F14C57A00F136BC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 34CD13611F14C57A00F136BC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 34CD13631F14C57B00F136BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 34CD13681F14C57B00F136BC /* DecimalNumberDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DecimalNumberDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 34CD136C1F14C57B00F136BC /* DecimalNumberDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DecimalNumberDemoTests.m; sourceTree = ""; }; 54 | 34CD136E1F14C57B00F136BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 34CD13731F14C57B00F136BC /* DecimalNumberDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DecimalNumberDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 34CD13771F14C57B00F136BC /* DecimalNumberDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DecimalNumberDemoUITests.m; sourceTree = ""; }; 57 | 34CD13791F14C57B00F136BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 34CD13861F14C6F600F136BC /* NSDecimalNumber+Addtion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDecimalNumber+Addtion.h"; sourceTree = ""; }; 59 | 34CD13871F14C6F600F136BC /* NSDecimalNumber+Addtion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDecimalNumber+Addtion.m"; sourceTree = ""; }; 60 | 34CD13891F14C74300F136BC /* CalculatorUIViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CalculatorUIViewController.h; sourceTree = ""; }; 61 | 34CD138A1F14C74300F136BC /* CalculatorUIViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CalculatorUIViewController.m; sourceTree = ""; }; 62 | 34CD138E1F14C77500F136BC /* arrow_up@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_up@2x.png"; sourceTree = ""; }; 63 | 34CD138F1F14C77500F136BC /* RSDropdownControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSDropdownControls.h; sourceTree = ""; }; 64 | 34CD13901F14C77500F136BC /* RSDropdownControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSDropdownControls.m; sourceTree = ""; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | 34CD134C1F14C57A00F136BC /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | 34CD13651F14C57B00F136BC /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | 34CD13701F14C57B00F136BC /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | 34CD13461F14C57A00F136BC = { 93 | isa = PBXGroup; 94 | children = ( 95 | 34CD13511F14C57A00F136BC /* DecimalNumberDemo */, 96 | 34CD136B1F14C57B00F136BC /* DecimalNumberDemoTests */, 97 | 34CD13761F14C57B00F136BC /* DecimalNumberDemoUITests */, 98 | 34CD13501F14C57A00F136BC /* Products */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | 34CD13501F14C57A00F136BC /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 34CD134F1F14C57A00F136BC /* DecimalNumberDemo.app */, 106 | 34CD13681F14C57B00F136BC /* DecimalNumberDemoTests.xctest */, 107 | 34CD13731F14C57B00F136BC /* DecimalNumberDemoUITests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 34CD13511F14C57A00F136BC /* DecimalNumberDemo */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 34CD13551F14C57A00F136BC /* AppDelegate.h */, 116 | 34CD13561F14C57A00F136BC /* AppDelegate.m */, 117 | 34CD13581F14C57A00F136BC /* ViewController.h */, 118 | 34CD13591F14C57A00F136BC /* ViewController.m */, 119 | 34CD13891F14C74300F136BC /* CalculatorUIViewController.h */, 120 | 34CD138A1F14C74300F136BC /* CalculatorUIViewController.m */, 121 | 34CD138C1F14C77500F136BC /* RSDropdownControls */, 122 | 34CD13851F14C6E700F136BC /* DecimalNumber */, 123 | 34CD135B1F14C57A00F136BC /* Main.storyboard */, 124 | 34CD135E1F14C57A00F136BC /* Assets.xcassets */, 125 | 34CD13601F14C57A00F136BC /* LaunchScreen.storyboard */, 126 | 34CD13631F14C57B00F136BC /* Info.plist */, 127 | 34CD13521F14C57A00F136BC /* Supporting Files */, 128 | ); 129 | path = DecimalNumberDemo; 130 | sourceTree = ""; 131 | }; 132 | 34CD13521F14C57A00F136BC /* Supporting Files */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 34CD13531F14C57A00F136BC /* main.m */, 136 | ); 137 | name = "Supporting Files"; 138 | sourceTree = ""; 139 | }; 140 | 34CD136B1F14C57B00F136BC /* DecimalNumberDemoTests */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 34CD136C1F14C57B00F136BC /* DecimalNumberDemoTests.m */, 144 | 34CD136E1F14C57B00F136BC /* Info.plist */, 145 | ); 146 | path = DecimalNumberDemoTests; 147 | sourceTree = ""; 148 | }; 149 | 34CD13761F14C57B00F136BC /* DecimalNumberDemoUITests */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 34CD13771F14C57B00F136BC /* DecimalNumberDemoUITests.m */, 153 | 34CD13791F14C57B00F136BC /* Info.plist */, 154 | ); 155 | path = DecimalNumberDemoUITests; 156 | sourceTree = ""; 157 | }; 158 | 34CD13851F14C6E700F136BC /* DecimalNumber */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 34CD13861F14C6F600F136BC /* NSDecimalNumber+Addtion.h */, 162 | 34CD13871F14C6F600F136BC /* NSDecimalNumber+Addtion.m */, 163 | ); 164 | path = DecimalNumber; 165 | sourceTree = ""; 166 | }; 167 | 34CD138C1F14C77500F136BC /* RSDropdownControls */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 34CD138D1F14C77500F136BC /* Resources */, 171 | 34CD138F1F14C77500F136BC /* RSDropdownControls.h */, 172 | 34CD13901F14C77500F136BC /* RSDropdownControls.m */, 173 | ); 174 | path = RSDropdownControls; 175 | sourceTree = ""; 176 | }; 177 | 34CD138D1F14C77500F136BC /* Resources */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 34CD138E1F14C77500F136BC /* arrow_up@2x.png */, 181 | ); 182 | path = Resources; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXGroup section */ 186 | 187 | /* Begin PBXNativeTarget section */ 188 | 34CD134E1F14C57A00F136BC /* DecimalNumberDemo */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 34CD137C1F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemo" */; 191 | buildPhases = ( 192 | 34CD134B1F14C57A00F136BC /* Sources */, 193 | 34CD134C1F14C57A00F136BC /* Frameworks */, 194 | 34CD134D1F14C57A00F136BC /* Resources */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = DecimalNumberDemo; 201 | productName = DecimalNumberDemo; 202 | productReference = 34CD134F1F14C57A00F136BC /* DecimalNumberDemo.app */; 203 | productType = "com.apple.product-type.application"; 204 | }; 205 | 34CD13671F14C57B00F136BC /* DecimalNumberDemoTests */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 34CD137F1F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemoTests" */; 208 | buildPhases = ( 209 | 34CD13641F14C57B00F136BC /* Sources */, 210 | 34CD13651F14C57B00F136BC /* Frameworks */, 211 | 34CD13661F14C57B00F136BC /* Resources */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | 34CD136A1F14C57B00F136BC /* PBXTargetDependency */, 217 | ); 218 | name = DecimalNumberDemoTests; 219 | productName = DecimalNumberDemoTests; 220 | productReference = 34CD13681F14C57B00F136BC /* DecimalNumberDemoTests.xctest */; 221 | productType = "com.apple.product-type.bundle.unit-test"; 222 | }; 223 | 34CD13721F14C57B00F136BC /* DecimalNumberDemoUITests */ = { 224 | isa = PBXNativeTarget; 225 | buildConfigurationList = 34CD13821F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemoUITests" */; 226 | buildPhases = ( 227 | 34CD136F1F14C57B00F136BC /* Sources */, 228 | 34CD13701F14C57B00F136BC /* Frameworks */, 229 | 34CD13711F14C57B00F136BC /* Resources */, 230 | ); 231 | buildRules = ( 232 | ); 233 | dependencies = ( 234 | 34CD13751F14C57B00F136BC /* PBXTargetDependency */, 235 | ); 236 | name = DecimalNumberDemoUITests; 237 | productName = DecimalNumberDemoUITests; 238 | productReference = 34CD13731F14C57B00F136BC /* DecimalNumberDemoUITests.xctest */; 239 | productType = "com.apple.product-type.bundle.ui-testing"; 240 | }; 241 | /* End PBXNativeTarget section */ 242 | 243 | /* Begin PBXProject section */ 244 | 34CD13471F14C57A00F136BC /* Project object */ = { 245 | isa = PBXProject; 246 | attributes = { 247 | LastUpgradeCheck = 0830; 248 | ORGANIZATIONNAME = StevenXie; 249 | TargetAttributes = { 250 | 34CD134E1F14C57A00F136BC = { 251 | CreatedOnToolsVersion = 8.3; 252 | DevelopmentTeam = 7QT42R489Z; 253 | ProvisioningStyle = Automatic; 254 | }; 255 | 34CD13671F14C57B00F136BC = { 256 | CreatedOnToolsVersion = 8.3; 257 | ProvisioningStyle = Automatic; 258 | TestTargetID = 34CD134E1F14C57A00F136BC; 259 | }; 260 | 34CD13721F14C57B00F136BC = { 261 | CreatedOnToolsVersion = 8.3; 262 | ProvisioningStyle = Automatic; 263 | TestTargetID = 34CD134E1F14C57A00F136BC; 264 | }; 265 | }; 266 | }; 267 | buildConfigurationList = 34CD134A1F14C57A00F136BC /* Build configuration list for PBXProject "DecimalNumberDemo" */; 268 | compatibilityVersion = "Xcode 3.2"; 269 | developmentRegion = English; 270 | hasScannedForEncodings = 0; 271 | knownRegions = ( 272 | en, 273 | Base, 274 | ); 275 | mainGroup = 34CD13461F14C57A00F136BC; 276 | productRefGroup = 34CD13501F14C57A00F136BC /* Products */; 277 | projectDirPath = ""; 278 | projectRoot = ""; 279 | targets = ( 280 | 34CD134E1F14C57A00F136BC /* DecimalNumberDemo */, 281 | 34CD13671F14C57B00F136BC /* DecimalNumberDemoTests */, 282 | 34CD13721F14C57B00F136BC /* DecimalNumberDemoUITests */, 283 | ); 284 | }; 285 | /* End PBXProject section */ 286 | 287 | /* Begin PBXResourcesBuildPhase section */ 288 | 34CD134D1F14C57A00F136BC /* Resources */ = { 289 | isa = PBXResourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | 34CD13621F14C57A00F136BC /* LaunchScreen.storyboard in Resources */, 293 | 34CD135F1F14C57A00F136BC /* Assets.xcassets in Resources */, 294 | 34CD135D1F14C57A00F136BC /* Main.storyboard in Resources */, 295 | 34CD13911F14C77500F136BC /* arrow_up@2x.png in Resources */, 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | }; 299 | 34CD13661F14C57B00F136BC /* Resources */ = { 300 | isa = PBXResourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | 34CD13711F14C57B00F136BC /* Resources */ = { 307 | isa = PBXResourcesBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXResourcesBuildPhase section */ 314 | 315 | /* Begin PBXSourcesBuildPhase section */ 316 | 34CD134B1F14C57A00F136BC /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | 34CD135A1F14C57A00F136BC /* ViewController.m in Sources */, 321 | 34CD13571F14C57A00F136BC /* AppDelegate.m in Sources */, 322 | 34CD13541F14C57A00F136BC /* main.m in Sources */, 323 | 34CD138B1F14C74300F136BC /* CalculatorUIViewController.m in Sources */, 324 | 34CD13881F14C6F600F136BC /* NSDecimalNumber+Addtion.m in Sources */, 325 | 34CD13921F14C77500F136BC /* RSDropdownControls.m in Sources */, 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | 34CD13641F14C57B00F136BC /* Sources */ = { 330 | isa = PBXSourcesBuildPhase; 331 | buildActionMask = 2147483647; 332 | files = ( 333 | 34CD136D1F14C57B00F136BC /* DecimalNumberDemoTests.m in Sources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | 34CD136F1F14C57B00F136BC /* Sources */ = { 338 | isa = PBXSourcesBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | 34CD13781F14C57B00F136BC /* DecimalNumberDemoUITests.m in Sources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | /* End PBXSourcesBuildPhase section */ 346 | 347 | /* Begin PBXTargetDependency section */ 348 | 34CD136A1F14C57B00F136BC /* PBXTargetDependency */ = { 349 | isa = PBXTargetDependency; 350 | target = 34CD134E1F14C57A00F136BC /* DecimalNumberDemo */; 351 | targetProxy = 34CD13691F14C57B00F136BC /* PBXContainerItemProxy */; 352 | }; 353 | 34CD13751F14C57B00F136BC /* PBXTargetDependency */ = { 354 | isa = PBXTargetDependency; 355 | target = 34CD134E1F14C57A00F136BC /* DecimalNumberDemo */; 356 | targetProxy = 34CD13741F14C57B00F136BC /* PBXContainerItemProxy */; 357 | }; 358 | /* End PBXTargetDependency section */ 359 | 360 | /* Begin PBXVariantGroup section */ 361 | 34CD135B1F14C57A00F136BC /* Main.storyboard */ = { 362 | isa = PBXVariantGroup; 363 | children = ( 364 | 34CD135C1F14C57A00F136BC /* Base */, 365 | ); 366 | name = Main.storyboard; 367 | sourceTree = ""; 368 | }; 369 | 34CD13601F14C57A00F136BC /* LaunchScreen.storyboard */ = { 370 | isa = PBXVariantGroup; 371 | children = ( 372 | 34CD13611F14C57A00F136BC /* Base */, 373 | ); 374 | name = LaunchScreen.storyboard; 375 | sourceTree = ""; 376 | }; 377 | /* End PBXVariantGroup section */ 378 | 379 | /* Begin XCBuildConfiguration section */ 380 | 34CD137A1F14C57B00F136BC /* Debug */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | ALWAYS_SEARCH_USER_PATHS = NO; 384 | CLANG_ANALYZER_NONNULL = YES; 385 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 386 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 387 | CLANG_CXX_LIBRARY = "libc++"; 388 | CLANG_ENABLE_MODULES = YES; 389 | CLANG_ENABLE_OBJC_ARC = YES; 390 | CLANG_WARN_BOOL_CONVERSION = YES; 391 | CLANG_WARN_CONSTANT_CONVERSION = YES; 392 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 393 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 394 | CLANG_WARN_EMPTY_BODY = YES; 395 | CLANG_WARN_ENUM_CONVERSION = YES; 396 | CLANG_WARN_INFINITE_RECURSION = YES; 397 | CLANG_WARN_INT_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 400 | CLANG_WARN_UNREACHABLE_CODE = YES; 401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 403 | COPY_PHASE_STRIP = NO; 404 | DEBUG_INFORMATION_FORMAT = dwarf; 405 | ENABLE_STRICT_OBJC_MSGSEND = YES; 406 | ENABLE_TESTABILITY = YES; 407 | GCC_C_LANGUAGE_STANDARD = gnu99; 408 | GCC_DYNAMIC_NO_PIC = NO; 409 | GCC_NO_COMMON_BLOCKS = YES; 410 | GCC_OPTIMIZATION_LEVEL = 0; 411 | GCC_PREPROCESSOR_DEFINITIONS = ( 412 | "DEBUG=1", 413 | "$(inherited)", 414 | ); 415 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 416 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 417 | GCC_WARN_UNDECLARED_SELECTOR = YES; 418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 419 | GCC_WARN_UNUSED_FUNCTION = YES; 420 | GCC_WARN_UNUSED_VARIABLE = YES; 421 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 422 | MTL_ENABLE_DEBUG_INFO = YES; 423 | ONLY_ACTIVE_ARCH = YES; 424 | SDKROOT = iphoneos; 425 | }; 426 | name = Debug; 427 | }; 428 | 34CD137B1F14C57B00F136BC /* Release */ = { 429 | isa = XCBuildConfiguration; 430 | buildSettings = { 431 | ALWAYS_SEARCH_USER_PATHS = NO; 432 | CLANG_ANALYZER_NONNULL = YES; 433 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 434 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 435 | CLANG_CXX_LIBRARY = "libc++"; 436 | CLANG_ENABLE_MODULES = YES; 437 | CLANG_ENABLE_OBJC_ARC = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_CONSTANT_CONVERSION = YES; 440 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 441 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 442 | CLANG_WARN_EMPTY_BODY = YES; 443 | CLANG_WARN_ENUM_CONVERSION = YES; 444 | CLANG_WARN_INFINITE_RECURSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 447 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 448 | CLANG_WARN_UNREACHABLE_CODE = YES; 449 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 451 | COPY_PHASE_STRIP = NO; 452 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 453 | ENABLE_NS_ASSERTIONS = NO; 454 | ENABLE_STRICT_OBJC_MSGSEND = YES; 455 | GCC_C_LANGUAGE_STANDARD = gnu99; 456 | GCC_NO_COMMON_BLOCKS = YES; 457 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 458 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 459 | GCC_WARN_UNDECLARED_SELECTOR = YES; 460 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 461 | GCC_WARN_UNUSED_FUNCTION = YES; 462 | GCC_WARN_UNUSED_VARIABLE = YES; 463 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 464 | MTL_ENABLE_DEBUG_INFO = NO; 465 | SDKROOT = iphoneos; 466 | VALIDATE_PRODUCT = YES; 467 | }; 468 | name = Release; 469 | }; 470 | 34CD137D1F14C57B00F136BC /* Debug */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 474 | DEVELOPMENT_TEAM = 7QT42R489Z; 475 | INFOPLIST_FILE = DecimalNumberDemo/Info.plist; 476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 477 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemo; 478 | PRODUCT_NAME = "$(TARGET_NAME)"; 479 | }; 480 | name = Debug; 481 | }; 482 | 34CD137E1F14C57B00F136BC /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 486 | DEVELOPMENT_TEAM = 7QT42R489Z; 487 | INFOPLIST_FILE = DecimalNumberDemo/Info.plist; 488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 489 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemo; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | }; 492 | name = Release; 493 | }; 494 | 34CD13801F14C57B00F136BC /* Debug */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | BUNDLE_LOADER = "$(TEST_HOST)"; 498 | INFOPLIST_FILE = DecimalNumberDemoTests/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 500 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemoTests; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DecimalNumberDemo.app/DecimalNumberDemo"; 503 | }; 504 | name = Debug; 505 | }; 506 | 34CD13811F14C57B00F136BC /* Release */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | BUNDLE_LOADER = "$(TEST_HOST)"; 510 | INFOPLIST_FILE = DecimalNumberDemoTests/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 512 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemoTests; 513 | PRODUCT_NAME = "$(TARGET_NAME)"; 514 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DecimalNumberDemo.app/DecimalNumberDemo"; 515 | }; 516 | name = Release; 517 | }; 518 | 34CD13831F14C57B00F136BC /* Debug */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | INFOPLIST_FILE = DecimalNumberDemoUITests/Info.plist; 522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 523 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemoUITests; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | TEST_TARGET_NAME = DecimalNumberDemo; 526 | }; 527 | name = Debug; 528 | }; 529 | 34CD13841F14C57B00F136BC /* Release */ = { 530 | isa = XCBuildConfiguration; 531 | buildSettings = { 532 | INFOPLIST_FILE = DecimalNumberDemoUITests/Info.plist; 533 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 534 | PRODUCT_BUNDLE_IDENTIFIER = R.S.DecimalNumberDemoUITests; 535 | PRODUCT_NAME = "$(TARGET_NAME)"; 536 | TEST_TARGET_NAME = DecimalNumberDemo; 537 | }; 538 | name = Release; 539 | }; 540 | /* End XCBuildConfiguration section */ 541 | 542 | /* Begin XCConfigurationList section */ 543 | 34CD134A1F14C57A00F136BC /* Build configuration list for PBXProject "DecimalNumberDemo" */ = { 544 | isa = XCConfigurationList; 545 | buildConfigurations = ( 546 | 34CD137A1F14C57B00F136BC /* Debug */, 547 | 34CD137B1F14C57B00F136BC /* Release */, 548 | ); 549 | defaultConfigurationIsVisible = 0; 550 | defaultConfigurationName = Release; 551 | }; 552 | 34CD137C1F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemo" */ = { 553 | isa = XCConfigurationList; 554 | buildConfigurations = ( 555 | 34CD137D1F14C57B00F136BC /* Debug */, 556 | 34CD137E1F14C57B00F136BC /* Release */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | 34CD137F1F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemoTests" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 34CD13801F14C57B00F136BC /* Debug */, 565 | 34CD13811F14C57B00F136BC /* Release */, 566 | ); 567 | defaultConfigurationIsVisible = 0; 568 | defaultConfigurationName = Release; 569 | }; 570 | 34CD13821F14C57B00F136BC /* Build configuration list for PBXNativeTarget "DecimalNumberDemoUITests" */ = { 571 | isa = XCConfigurationList; 572 | buildConfigurations = ( 573 | 34CD13831F14C57B00F136BC /* Debug */, 574 | 34CD13841F14C57B00F136BC /* Release */, 575 | ); 576 | defaultConfigurationIsVisible = 0; 577 | defaultConfigurationName = Release; 578 | }; 579 | /* End XCConfigurationList section */ 580 | }; 581 | rootObject = 34CD13471F14C57A00F136BC /* Project object */; 582 | } 583 | -------------------------------------------------------------------------------- /DecimalNumberDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DecimalNumberDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "NotificationIcon@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "NotificationIcon@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-Small@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "Icon.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "Icon@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "Icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "Icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "NotificationIcon~ipad.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "NotificationIcon~ipad@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-Small.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-Small@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-Small-50.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-Small-50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-72.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "Icon-72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "Icon-76.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "Icon-76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "Icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "idiom" : "ios-marketing", 149 | "size" : "1024x1024", 150 | "scale" : "1x" 151 | } 152 | ], 153 | "info" : { 154 | "version" : 1, 155 | "author" : "xcode" 156 | } 157 | } -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DecimalNumberDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DecimalNumberDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 154 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /DecimalNumberDemo/CalculatorUIViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CalculatorUIViewController.h 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RSDropdownControls.h" 11 | 12 | @interface CalculatorUIViewController : UIViewController 13 | // 基数 14 | @property (weak, nonatomic) IBOutlet UITextField *cardinalNumberTextField; 15 | // 补数 16 | @property (weak, nonatomic) IBOutlet UITextField *complementNumberTextField; 17 | // 运算符 18 | @property (weak, nonatomic) IBOutlet RSDropdownControls *operatorView; 19 | // 结果方式 20 | @property (weak, nonatomic) IBOutlet RSDropdownControls *resultTypeView; 21 | // 运算结果 22 | @property (weak, nonatomic) IBOutlet UILabel *resultLabel; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /DecimalNumberDemo/CalculatorUIViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CalculatorUIViewController.m 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import "CalculatorUIViewController.h" 10 | #import "NSDecimalNumber+Addtion.h" 11 | 12 | 13 | @interface CalculatorUIViewController () 14 | @property (nonatomic, strong)NSArray *operatorArray; 15 | @property (nonatomic, strong)NSArray *resultTypeArray; 16 | @property (nonatomic, assign)NSInteger afterIndex; 17 | @end 18 | 19 | @implementation CalculatorUIViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view. 24 | 25 | self.operatorArray = @[@"+", @"-", @"×", @"÷"]; 26 | self.resultTypeArray = @[@"==", @"min=", @"max=", @"≈≈", @"up≈", @"down≈", @"bankers≈"]; 27 | 28 | [self setupOperatorAndResultType]; 29 | } 30 | - (void)setupOperatorAndResultType { 31 | _operatorView.placeholder = @"运算符"; 32 | _operatorView.listArray = _operatorArray; 33 | _operatorView.delegate = self; 34 | 35 | _resultTypeView.placeholder = @"结果符"; 36 | _resultTypeView.listArray = _resultTypeArray; 37 | _resultTypeView.maxDropdownCount = 7; //可选,默认是4行 38 | _resultTypeView.delegate = self; 39 | } 40 | 41 | - (void)downSelectedView:(RSDropdownControls *)selectedView didSelectedAtIndex:(NSIndexPath *)indexPath { 42 | if ([_cardinalNumberTextField.text isEqualToString:@""] || [_complementNumberTextField.text isEqualToString:@""]) { 43 | [self setupAlertView]; 44 | return; 45 | } 46 | if ([selectedView isEqual:_operatorView]) { 47 | _afterIndex = indexPath.row; 48 | _resultLabel.text = [NSString stringWithFormat:@"%@", [self DecimalFuncWithOperatorType:indexPath.row]]; 49 | } else { 50 | _resultLabel.text = [self DecimalFuncWithNumber:[NSString stringWithFormat:@"%@", [self DecimalFuncWithOperatorType:_afterIndex]] operatorType:indexPath.row]; 51 | } 52 | } 53 | // 设置提醒窗 54 | - (void)setupAlertView { 55 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请先填写数额" message:nil preferredStyle:UIAlertControllerStyleAlert]; 56 | [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 57 | }]]; 58 | [self presentViewController:alert animated:YES completion:nil]; 59 | } 60 | // 计算方式 61 | - (NSDecimalNumber *)DecimalFuncWithOperatorType:(NSInteger)operatorType { 62 | NSDecimalNumber *resultNumber = [[NSDecimalNumber alloc]initWithString:@"0"]; 63 | switch (operatorType) { 64 | case 0: 65 | resultNumber = SNAdd(_cardinalNumberTextField.text, _complementNumberTextField.text); 66 | break; 67 | case 1: 68 | resultNumber = SNSub(_cardinalNumberTextField.text, _complementNumberTextField.text); 69 | break; 70 | case 2: 71 | resultNumber = SNMul(_cardinalNumberTextField.text, _complementNumberTextField.text); 72 | break; 73 | case 3: 74 | resultNumber = SNDiv(_cardinalNumberTextField.text, _complementNumberTextField.text); 75 | break; 76 | } 77 | return resultNumber; 78 | } 79 | // 计算结果处理方法 80 | - (NSString *)DecimalFuncWithNumber:(NSString *)number operatorType:(NSInteger)operatorType { 81 | NSString *resultNumber; 82 | switch (operatorType) { 83 | case 0: 84 | resultNumber = number; 85 | break; 86 | case 1: 87 | resultNumber = [NSString stringWithFormat:@"%@", SNMin(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 88 | break; 89 | case 2: 90 | resultNumber = [NSString stringWithFormat:@"%@", SNMax(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 91 | break; 92 | case 3: 93 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundPlain, 2)]; 94 | break; 95 | case 4: 96 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundUp, 2)]; 97 | break; 98 | case 5: 99 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundDown, 2)]; 100 | break; 101 | case 6: 102 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundBankers, 2)]; 103 | break; 104 | } 105 | return resultNumber; 106 | } 107 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 108 | [_operatorView close]; 109 | [_resultTypeView close]; 110 | [self.view endEditing:YES]; 111 | } 112 | - (void)didReceiveMemoryWarning { 113 | [super didReceiveMemoryWarning]; 114 | // Dispose of any resources that can be recreated. 115 | } 116 | 117 | /* 118 | #pragma mark - Navigation 119 | 120 | // In a storyboard-based application, you will often want to do a little preparation before navigation 121 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 122 | // Get the new view controller using [segue destinationViewController]. 123 | // Pass the selected object to the new view controller. 124 | } 125 | */ 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /DecimalNumberDemo/DecimalNumber/NSDecimalNumber+Addtion.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDecimalNumber+Addtion.h 3 | // 有应用应用 4 | // 5 | // Created by xuliying on 15/10/15. 6 | // Copyright (c) 2015年 xly. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, calculationType) { 12 | Add, 13 | Subtract, 14 | Multiply, 15 | Divide 16 | }; 17 | @interface NSDecimalNumber (Addtion) 18 | + (NSDecimalNumber *)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 type:(calculationType)type anotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2 andDecimalNumberHandler:(NSDecimalNumberHandler *)handler; 19 | 20 | + (NSComparisonResult)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2; 21 | 22 | + (NSString *)stringWithDecimalNumber:(NSDecimalNumber *)str1 scale:(NSInteger)scale; 23 | 24 | extern NSComparisonResult StrNumCompare(id str1,id str2); 25 | extern NSDecimalNumber *handlerDecimalNumber(id strOrNum,NSRoundingMode mode,int scale); 26 | extern NSComparisonResult SNCompare(id strOrNum1,id strOrNum2); 27 | 28 | 29 | extern NSDecimalNumber *SNAdd(id strOrNum1,id strOrNum2); 30 | extern NSDecimalNumber *SNSub(id strOrNum1,id strOrNum2); 31 | extern NSDecimalNumber *SNMul(id strOrNum1,id strOrNum2); 32 | extern NSDecimalNumber *SNDiv(id strOrNum1,id strOrNum2); 33 | 34 | 35 | extern NSDecimalNumber *SNMin(id strOrNum1,id strOrNum2); 36 | extern NSDecimalNumber *SNMax(id strOrNum1,id strOrNum2); 37 | 38 | 39 | extern NSDecimalNumber *SNAdd_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 40 | extern NSDecimalNumber *SNSub_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 41 | extern NSDecimalNumber *SNMul_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 42 | extern NSDecimalNumber *SNDiv_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 43 | 44 | 45 | extern NSDecimalNumber *SNMin_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 46 | extern NSDecimalNumber *SNMax_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /DecimalNumberDemo/DecimalNumber/NSDecimalNumber+Addtion.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDecimalNumber+Addtion.m 3 | // 有应用应用 4 | // 5 | // Created by xuliying on 15/10/15. 6 | // Copyright (c) 2015年 xly. All rights reserved. 7 | // 8 | 9 | #import "NSDecimalNumber+Addtion.h" 10 | 11 | @implementation NSDecimalNumber (Addtion) 12 | + (NSDecimalNumber *)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 type:(calculationType)type anotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2 andDecimalNumberHandler:(NSDecimalNumberHandler *)handler{ 13 | if (!stringOrNumber2 || !stringOrNumber1) { 14 | NSLog(@"输入正确类型"); 15 | return nil; 16 | } 17 | NSDecimalNumber *one; 18 | NSDecimalNumber *another; 19 | NSDecimalNumber *returnNum; 20 | if ([stringOrNumber1 isKindOfClass:[NSString class]]) { 21 | one = [NSDecimalNumber decimalNumberWithString:stringOrNumber1]; 22 | } else if ([stringOrNumber1 isKindOfClass:[NSDecimalNumber class]]){ 23 | one = stringOrNumber1; 24 | } else if ([stringOrNumber1 isKindOfClass:[NSNumber class]]){ 25 | one = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber1 decimalValue]]; 26 | } else { 27 | NSLog(@"输入正确的类型"); 28 | return nil; 29 | } 30 | 31 | if ([stringOrNumber2 isKindOfClass:[NSString class]]) { 32 | another = [NSDecimalNumber decimalNumberWithString:stringOrNumber2]; 33 | } else if ([stringOrNumber2 isKindOfClass:[NSDecimalNumber class]]){ 34 | another = stringOrNumber2; 35 | } else if ([stringOrNumber2 isKindOfClass:[NSNumber class]]){ 36 | another = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber2 decimalValue]]; 37 | } else { 38 | NSLog(@"输入正确的类型"); 39 | return nil; 40 | } 41 | 42 | if (type == Add) { 43 | returnNum = [one decimalNumberByAdding:another]; 44 | } else if (type == Subtract){ 45 | returnNum = [one decimalNumberBySubtracting:another]; 46 | } else if (type == Multiply){ 47 | returnNum = [one decimalNumberByMultiplyingBy:another]; 48 | } else if (type == Divide){ 49 | if ([NSDecimalNumber aDecimalNumberWithStringOrNumberOrDecimalNumber:another compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:@(0)] == 0) { 50 | returnNum = nil; 51 | } else { returnNum = [one decimalNumberByDividingBy:another]; 52 | } 53 | } else { returnNum = nil; 54 | } 55 | if (returnNum) { 56 | if (handler) { return [returnNum decimalNumberByRoundingAccordingToBehavior:handler]; 57 | } else { return returnNum; 58 | } 59 | } else { 60 | NSLog(@"输入正确的类型"); 61 | return nil; 62 | } 63 | } 64 | 65 | + (NSComparisonResult)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2{ 66 | if (!stringOrNumber2 || !stringOrNumber1) { 67 | NSLog(@"输入正确类型"); 68 | return -404; 69 | } 70 | NSDecimalNumber *one; 71 | NSDecimalNumber *another; 72 | if ([stringOrNumber1 isKindOfClass:[NSString class]]) { 73 | one = [NSDecimalNumber decimalNumberWithString:stringOrNumber1]; 74 | } else if ([stringOrNumber1 isKindOfClass:[NSDecimalNumber class]]){ 75 | one = stringOrNumber1; 76 | } else if ([stringOrNumber1 isKindOfClass:[NSNumber class]]){ 77 | one = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber1 decimalValue]]; 78 | } else { 79 | NSLog(@"输入正确的类型"); 80 | return -404; 81 | } 82 | 83 | if ([stringOrNumber2 isKindOfClass:[NSString class]]) { 84 | another = [NSDecimalNumber decimalNumberWithString:stringOrNumber2]; 85 | } else if ([stringOrNumber2 isKindOfClass:[NSDecimalNumber class]]){ 86 | another = stringOrNumber2; 87 | } else if ([stringOrNumber2 isKindOfClass:[NSNumber class]]){ 88 | another = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber2 decimalValue]]; 89 | } else { 90 | NSLog(@"输入正确的类型"); 91 | return -404; 92 | } 93 | return [one compare:another]; 94 | } 95 | 96 | + (NSString *)stringWithDecimalNumber:(NSDecimalNumber *)str1 scale:(NSInteger)scale{ 97 | if (!str1) { return @""; 98 | } 99 | NSString *str = [NSString stringWithFormat:@"%@",str1]; 100 | if (str && str.length) { 101 | if ([str rangeOfString:@"."].length == 1) {//有小数点 102 | NSArray *arr = [str componentsSeparatedByString:@"."]; 103 | if (scale > 0) { 104 | NSInteger count = [arr[1] length]; 105 | for (NSInteger i = count; i 0) { 117 | str = [str stringByAppendingString:@"."]; 118 | for (int i = 0; i 0 ? strOrNum2 : strOrNum1; 178 | } 179 | NSDecimalNumber *SNMax(id strOrNum1,id strOrNum2){ 180 | return SNCompare(strOrNum1, strOrNum2) > 0 ? strOrNum1 : strOrNum2; 181 | } 182 | NSDecimalNumber *SNAdd_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 183 | return handlerDecimalNumber(SNAdd(strOrNum1, strOrNum2), mode, scale); 184 | } 185 | NSDecimalNumber *SNSub_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 186 | return handlerDecimalNumber(SNSub(strOrNum1, strOrNum2), mode, scale); 187 | } 188 | NSDecimalNumber *SNMul_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 189 | return handlerDecimalNumber(SNMul(strOrNum1, strOrNum2), mode, scale); 190 | } 191 | NSDecimalNumber *SNDiv_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 192 | return handlerDecimalNumber(SNDiv(strOrNum1, strOrNum2), mode, scale); 193 | } 194 | 195 | 196 | NSDecimalNumber *SNMin_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 197 | return handlerDecimalNumber(SNMin(strOrNum1, strOrNum2), mode, scale); 198 | } 199 | NSDecimalNumber *SNMax_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 200 | return handlerDecimalNumber(SNMax(strOrNum1, strOrNum2), mode, scale); 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /DecimalNumberDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /DecimalNumberDemo/RSDropdownControls/RSDropdownControls.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSDropdownControls.h 3 | // RSDropdownControlsDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RSDropdownControls; 12 | @protocol RSDropdownControlsDelegate 13 | @required 14 | - (void)downSelectedView:(RSDropdownControls *)selectedView didSelectedAtIndex:(NSIndexPath *)indexPath; 15 | @end 16 | 17 | @interface RSDropdownControls : UIView 18 | @property (nonatomic, copy, readonly) NSString *text; 19 | // Delegate 20 | @property (nonatomic, weak) id delegate; 21 | 22 | // Data 23 | @property (nonatomic, strong) NSArray *listArray; 24 | 25 | // Preferences(Optional) 26 | @property (nonatomic, strong) UIFont *font; 27 | @property (nonatomic, strong) UIColor *textColor; 28 | @property (nonatomic, assign) NSTextAlignment textAlignment; 29 | @property (nonatomic, copy) NSString *placeholder; 30 | @property (nonatomic, assign) NSInteger maxDropdownCount; // 最大展示列表行数 31 | 32 | // Function 33 | - (void)show; 34 | - (void)close; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /DecimalNumberDemo/RSDropdownControls/RSDropdownControls.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSDropdownControls.m 3 | // RSDropdownControlsDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import "RSDropdownControls.h" 10 | 11 | // 动画的时间 12 | NSTimeInterval const animationDuration = 0.2f; 13 | // 分割线的颜色 14 | #define kLineColor [UIColor colorWithRed:219/255.0 green:217/255.0 blue:216/255.0 alpha:1] 15 | // 旋转角度 16 | CGFloat angleValue(CGFloat angle) { 17 | return (angle * M_PI) / 180; 18 | } 19 | 20 | @interface RSDropdownControls () 21 | @property (nonatomic, strong) UITextField *contentLabel; 22 | @property (nonatomic, strong) UIButton *clickBtn; 23 | @property (nonatomic, strong) UIImageView *arrowImgView; 24 | @property (nonatomic, strong) UIView *arrowImgBgView; 25 | @property (nonatomic, strong) UITableView *listTableView; 26 | // 执行打开关闭动画 开始结束 27 | @property (nonatomic, assign) BOOL isOpen; 28 | @property (nonatomic, assign) BOOL beDone; 29 | @end 30 | 31 | @implementation RSDropdownControls 32 | - (instancetype)initWithFrame:(CGRect)frame { 33 | self = [super initWithFrame:frame]; 34 | if (self) { 35 | [self _commintInit]; 36 | } 37 | return self; 38 | } 39 | 40 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 41 | self = [super initWithCoder:aDecoder]; 42 | if (self) { 43 | [self _commintInit]; 44 | } 45 | return self; 46 | } 47 | 48 | #pragma mark - private 49 | - (void)_commintInit { 50 | // 默认设置 51 | //self.backgroundColor = [UIColor whiteColor]; 52 | 53 | _font = [UIFont systemFontOfSize:14.f]; 54 | _textColor = [UIColor blackColor]; 55 | _textAlignment = NSTextAlignmentLeft; 56 | 57 | // 默认不展开 58 | _isOpen = NO; 59 | 60 | // 默认是完成动画的 61 | _beDone = YES; 62 | 63 | // 默认 最大展示列表行数是4 64 | _maxDropdownCount = 4; 65 | 66 | // 初始化UI 67 | [self.arrowImgBgView addSubview:self.arrowImgView]; 68 | [self addSubview:self.arrowImgBgView]; 69 | [self addSubview:self.contentLabel]; 70 | [self addSubview:self.clickBtn]; 71 | } 72 | 73 | #pragma mark - action 74 | - (void)clickBtnClicked { 75 | if (!_beDone) return; 76 | // 关闭页面上其他下拉控件 77 | for (UIView *subview in self.superview.subviews) { 78 | if ([subview isKindOfClass:[RSDropdownControls class]] && subview != self) { 79 | RSDropdownControls *donwnSelectedView = (RSDropdownControls *)subview; 80 | if (donwnSelectedView.isOpen) { 81 | [donwnSelectedView close]; 82 | } 83 | } 84 | } 85 | 86 | if (_isOpen) { 87 | [self close]; 88 | } else { 89 | [self show]; 90 | } 91 | } 92 | 93 | #pragma mark - public 94 | - (void)show { 95 | if (_isOpen || _listArray.count == 0) return; 96 | 97 | _beDone = NO; 98 | 99 | [self.superview addSubview:self.listTableView]; 100 | // 避免被其他子视图遮盖住 101 | [self.superview bringSubviewToFront:self.listTableView]; 102 | CGRect frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMaxY(self.frame), CGRectGetWidth(self.frame), 0); 103 | [self.listTableView setFrame:frame]; 104 | self.listTableView.rowHeight = CGRectGetHeight(self.frame); 105 | 106 | [UIView animateWithDuration:animationDuration 107 | delay:0.0f 108 | options:UIViewAnimationOptionCurveEaseOut 109 | animations:^{ 110 | 111 | if (self.listArray.count > 0) { 112 | [self.listTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 113 | atScrollPosition:UITableViewScrollPositionTop 114 | animated:YES]; 115 | } 116 | 117 | CGRect frame = self.listTableView.frame; 118 | NSInteger count = MIN(self.maxDropdownCount, self.listArray.count); 119 | 120 | // 防止超出屏幕 121 | if (frame.origin.y + frame.size.height > [UIScreen mainScreen].bounds.size.height) { 122 | frame.size.height -= frame.origin.y + frame.size.height - [UIScreen mainScreen].bounds.size.height; 123 | } else { 124 | frame.size.height = count * self.frame.size.height; 125 | } 126 | 127 | [self.listTableView setFrame:frame]; 128 | 129 | self.arrowImgView.transform = CGAffineTransformIdentity; 130 | }completion:^(BOOL finished) { 131 | 132 | _beDone = YES; 133 | _isOpen = YES; 134 | 135 | }]; 136 | } 137 | 138 | - (void)close { 139 | if (!_isOpen) return; 140 | 141 | _beDone = NO; 142 | 143 | [UIView animateWithDuration:animationDuration 144 | delay:0.0f 145 | options:UIViewAnimationOptionCurveEaseOut 146 | animations:^{ 147 | 148 | CGRect frame = self.listTableView.frame; 149 | frame.size.height = 0.f; 150 | [self.listTableView setFrame:frame]; 151 | 152 | self.arrowImgView.transform = CGAffineTransformRotate(self.arrowImgView.transform, angleValue(-180)); 153 | }completion:^(BOOL finished) { 154 | 155 | [self.listTableView setContentOffset:CGPointZero animated:NO]; 156 | if (self.listTableView.superview) [self.listTableView removeFromSuperview]; 157 | 158 | _beDone = YES; 159 | _isOpen = NO; 160 | }]; 161 | } 162 | 163 | #pragma mark - UITableViewDataSource 164 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 165 | return 1; 166 | } 167 | 168 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 169 | return _listArray.count; 170 | } 171 | 172 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 173 | static NSString *cellIndentifier = @"cellIndentifier"; 174 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier]; 175 | if(!cell) { 176 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier]; 177 | cell.backgroundColor = [UIColor clearColor]; 178 | cell.selectionStyle = UITableViewCellSelectionStyleDefault; 179 | 180 | UILabel *contentLable = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, self.frame.size.width-10, self.frame.size.height-4)]; 181 | contentLable.tag = 1000; 182 | contentLable.textColor = _textColor; 183 | contentLable.font = _font; 184 | [cell addSubview:contentLable]; 185 | 186 | UIView *lineView = [UIView new]; 187 | lineView.backgroundColor = kLineColor; 188 | lineView.frame = CGRectMake(0, self.frame.size.height-0.5, self.frame.size.width, 0.5); 189 | [cell addSubview:lineView]; 190 | } 191 | UILabel *contentLabel = (UILabel *)[cell viewWithTag:1000]; 192 | contentLabel.text = _listArray[indexPath.row]; 193 | return cell; 194 | } 195 | 196 | #pragma mark - UITableViewDelegate 197 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 198 | } 199 | 200 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 201 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 202 | self.contentLabel.text = [_listArray objectAtIndex:indexPath.row]; 203 | [self close]; 204 | if ([self.delegate respondsToSelector:@selector(downSelectedView:didSelectedAtIndex:)]) { 205 | [self.delegate downSelectedView:self didSelectedAtIndex:indexPath]; 206 | } 207 | } 208 | 209 | 210 | #pragma mark - Public 211 | - (void)setFont:(UIFont *)font { 212 | _font = font; 213 | self.contentLabel.font = font; 214 | } 215 | 216 | - (void)setTextColor:(UIColor *)textColor { 217 | _textColor = textColor; 218 | self.contentLabel.textColor = textColor; 219 | } 220 | 221 | - (void)setTextAlignment:(NSTextAlignment)textAlignment { 222 | _textAlignment = textAlignment; 223 | self.contentLabel.textAlignment = textAlignment; 224 | } 225 | 226 | - (void)setPlaceholder:(NSString *)placeholder { 227 | self.contentLabel.placeholder = placeholder; 228 | } 229 | 230 | - (void)setListArray:(NSArray *)listArray { 231 | _listArray = listArray; 232 | 233 | [self.listTableView reloadData]; 234 | } 235 | 236 | - (NSString *)text { 237 | return self.contentLabel.text; 238 | } 239 | 240 | #pragma mark - getter 241 | - (UITextField *)contentLabel { 242 | if (!_contentLabel) { 243 | _contentLabel = [UITextField new]; 244 | _contentLabel.placeholder = @"点击进行选择"; 245 | _contentLabel.enabled = NO; 246 | _contentLabel.backgroundColor = [UIColor clearColor]; 247 | _contentLabel.textColor = _textColor; 248 | _contentLabel.font = _font; 249 | _contentLabel.textAlignment = _textAlignment; 250 | } 251 | return _contentLabel; 252 | } 253 | 254 | - (UIButton *)clickBtn { 255 | if (!_clickBtn) { 256 | _clickBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 257 | _clickBtn.backgroundColor = [UIColor clearColor]; 258 | _clickBtn.layer.borderColor = kLineColor.CGColor; 259 | _clickBtn.layer.borderWidth = 0.5f; 260 | [_clickBtn addTarget:self action:@selector(clickBtnClicked) forControlEvents:UIControlEventTouchUpInside]; 261 | } 262 | return _clickBtn; 263 | } 264 | 265 | - (UIImageView *)arrowImgView { 266 | if (!_arrowImgView) { 267 | _arrowImgView = [UIImageView new]; 268 | _arrowImgView.image = [UIImage imageNamed:@"arrow_up.png"]; 269 | _arrowImgView.transform = CGAffineTransformRotate(self.arrowImgView.transform, angleValue(-180)); 270 | } 271 | return _arrowImgView; 272 | } 273 | 274 | - (UIView *)arrowImgBgView { 275 | if (!_arrowImgBgView) { 276 | _arrowImgBgView = [[UIView alloc] initWithFrame:CGRectZero]; 277 | _arrowImgBgView.backgroundColor = [UIColor clearColor]; 278 | } 279 | return _arrowImgBgView; 280 | } 281 | 282 | - (UITableView *)listTableView { 283 | if (!_listTableView) { 284 | _listTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 285 | _listTableView.layer.borderWidth = 0.5; 286 | _listTableView.layer.borderColor = kLineColor.CGColor; 287 | _listTableView.scrollsToTop = NO; 288 | _listTableView.bounces = NO; 289 | _listTableView.dataSource = self; 290 | _listTableView.delegate = self; 291 | _listTableView.separatorColor = kLineColor; 292 | _listTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 293 | } 294 | return _listTableView; 295 | } 296 | 297 | #pragma mark - Layout 298 | - (void)updateConstraints { 299 | //NSLog(@"updateConstraints"); 300 | 301 | // 箭头 302 | self.arrowImgView.translatesAutoresizingMaskIntoConstraints = NO; 303 | [NSLayoutConstraint activateConstraints:@[ 304 | [NSLayoutConstraint constraintWithItem:self.arrowImgView 305 | attribute:NSLayoutAttributeCenterX 306 | relatedBy:NSLayoutRelationEqual 307 | toItem:self.arrowImgBgView 308 | attribute:NSLayoutAttributeCenterX 309 | multiplier:1.0 310 | constant:0.0], 311 | [NSLayoutConstraint constraintWithItem:self.arrowImgView 312 | attribute:NSLayoutAttributeCenterY 313 | relatedBy:NSLayoutRelationEqual 314 | toItem:self.arrowImgBgView 315 | attribute:NSLayoutAttributeCenterY 316 | multiplier:1.0 317 | constant:0.0] 318 | ]]; 319 | 320 | self.arrowImgBgView.translatesAutoresizingMaskIntoConstraints = NO; 321 | 322 | [NSLayoutConstraint activateConstraints:@[ 323 | [NSLayoutConstraint constraintWithItem:self 324 | attribute:NSLayoutAttributeRight 325 | relatedBy:NSLayoutRelationEqual 326 | toItem:self.arrowImgBgView 327 | attribute:NSLayoutAttributeRight 328 | multiplier:1.0 329 | constant:0.0], 330 | [NSLayoutConstraint constraintWithItem:self 331 | attribute:NSLayoutAttributeTop 332 | relatedBy:NSLayoutRelationEqual 333 | toItem:self.arrowImgBgView 334 | attribute:NSLayoutAttributeTop 335 | multiplier:1.0 336 | constant:0.0], 337 | [NSLayoutConstraint constraintWithItem:self 338 | attribute:NSLayoutAttributeBottom 339 | relatedBy:NSLayoutRelationEqual 340 | toItem:self.arrowImgBgView 341 | attribute:NSLayoutAttributeBottom 342 | multiplier:1.0 343 | constant:0.0], 344 | [NSLayoutConstraint constraintWithItem:self.arrowImgBgView 345 | attribute:NSLayoutAttributeWidth 346 | relatedBy:NSLayoutRelationEqual 347 | toItem:nil 348 | attribute:NSLayoutAttributeNotAnAttribute 349 | multiplier:1.0 350 | constant:30] 351 | ]]; 352 | 353 | // 内容label 354 | self.contentLabel.translatesAutoresizingMaskIntoConstraints = NO; 355 | [NSLayoutConstraint activateConstraints:@[ 356 | [NSLayoutConstraint constraintWithItem:self.contentLabel 357 | attribute:NSLayoutAttributeLeft 358 | relatedBy:NSLayoutRelationEqual 359 | toItem:self 360 | attribute:NSLayoutAttributeLeft 361 | multiplier:1.0 362 | constant:5.0], 363 | [NSLayoutConstraint constraintWithItem:self.contentLabel 364 | attribute:NSLayoutAttributeTop 365 | relatedBy:NSLayoutRelationEqual 366 | toItem:self 367 | attribute:NSLayoutAttributeTop 368 | multiplier:1.0 369 | constant:0.0], 370 | [NSLayoutConstraint constraintWithItem:self.contentLabel 371 | attribute:NSLayoutAttributeBottom 372 | relatedBy:NSLayoutRelationEqual 373 | toItem:self 374 | attribute:NSLayoutAttributeBottom 375 | multiplier:1.0 376 | constant:0.0], 377 | [NSLayoutConstraint constraintWithItem:self.contentLabel 378 | attribute:NSLayoutAttributeRight 379 | relatedBy:NSLayoutRelationEqual 380 | toItem:self.arrowImgBgView 381 | attribute:NSLayoutAttributeLeft 382 | multiplier:1.0 383 | constant:0.0] 384 | ]]; 385 | 386 | self.clickBtn.translatesAutoresizingMaskIntoConstraints = NO; 387 | [NSLayoutConstraint activateConstraints:@[ 388 | [NSLayoutConstraint constraintWithItem:self.clickBtn 389 | attribute:NSLayoutAttributeLeft 390 | relatedBy:NSLayoutRelationEqual 391 | toItem:self 392 | attribute:NSLayoutAttributeLeft 393 | multiplier:1.0 394 | constant:0.0], 395 | [NSLayoutConstraint constraintWithItem:self.clickBtn 396 | attribute:NSLayoutAttributeTop 397 | relatedBy:NSLayoutRelationEqual 398 | toItem:self 399 | attribute:NSLayoutAttributeTop 400 | multiplier:1.0 401 | constant:0.0], 402 | [NSLayoutConstraint constraintWithItem:self.clickBtn 403 | attribute:NSLayoutAttributeBottom 404 | relatedBy:NSLayoutRelationEqual 405 | toItem:self 406 | attribute:NSLayoutAttributeBottom 407 | multiplier:1.0 408 | constant:0.0], 409 | [NSLayoutConstraint constraintWithItem:self.clickBtn 410 | attribute:NSLayoutAttributeRight 411 | relatedBy:NSLayoutRelationEqual 412 | toItem:self 413 | attribute:NSLayoutAttributeRight 414 | multiplier:1.0 415 | constant:0.0] 416 | ]]; 417 | [super updateConstraints]; 418 | } 419 | 420 | @end 421 | -------------------------------------------------------------------------------- /DecimalNumberDemo/RSDropdownControls/Resources/arrow_up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/DecimalNumberDemo/RSDropdownControls/Resources/arrow_up@2x.png -------------------------------------------------------------------------------- /DecimalNumberDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /DecimalNumberDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /DecimalNumberDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DecimalNumberDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DecimalNumberDemoTests/DecimalNumberDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DecimalNumberDemoTests.m 3 | // DecimalNumberDemoTests 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DecimalNumberDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DecimalNumberDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /DecimalNumberDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DecimalNumberDemoUITests/DecimalNumberDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DecimalNumberDemoUITests.m 3 | // DecimalNumberDemoUITests 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DecimalNumberDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DecimalNumberDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /DecimalNumberDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ReverseScale 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DecimalNumberDemo 2 | 3 | ![](https://img.shields.io/badge/platform-iOS-red.svg) 4 | ![](https://img.shields.io/badge/language-Objective--C-orange.svg) 5 | ![](https://img.shields.io/badge/download-30.9MB-brightgreen.svg) 6 | ![](https://img.shields.io/badge/license-MIT%20License-brightgreen.svg) 7 | [![Build Status](https://travis-ci.org/ReverseScale/RSPayAWA.svg?branch=master)](https://travis-ci.org/ReverseScale/RSPayAWA) 8 | 9 | [EN](https://github.com/ReverseScale/DecimalNumberDemo) | [中文](https://github.com/ReverseScale/DecimalNumberDemo/blob/master/README_zh.md) 10 | 11 | Since Everbright financial management ideas are deeply rooted in people's minds, various financial products are also mushroomed in general. Since the amount involved, the precision of float can not meet the needs of financial computing. However, the use of NSDecimal in OC is too complicated to use. Therefore, Based on the people were encapsulated and demonstrated through a Demo. 12 | (Swift version included reference examples, with UI Oh 😯 ~) 13 | 14 | | 1. List Page | 2. Display Page | 3. Display Page | 4.UI Page | 15 | | ------------- | ------------- | ------------- | ------------- | 16 | | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/85062598.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/20224916.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/66547467.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/26123470.jpg) | 17 | | Building a List Page via storyboard | Values Equal to Calculations | Handling Calculated Values | Swift UI Showcase | 18 | 19 | ## 🚀 Advantage 20 | * 1. Less file, code concise, high degree of packaging 21 | * 2. Do not rely on any other third-party libraries 22 | * 3. Through a good demo, learning curve is good 23 | * 4. Has a high custom 24 | 25 | ## 🤖 Requirements 26 | * iOS 7+ 27 | * Xcode 8+ 28 | 29 | 30 | ## 🛠 Usage 31 | ### The first step is to introduce header files 32 | ``` 33 | #import "NSDecimalNumber+Addtion.h" 34 | ``` 35 | ### The second step is simple to use 36 | #### value is equal to the calculation method 37 | ``` 38 | /* 39 | * The parameter value corresponds to the basic operator 40 | * 0: + 41 | * 1: - 42 | * 2: × 43 | * 3: ÷ 44 | */ 45 | NSDecimalNumber *resultNumber = [[NSDecimalNumber alloc]initWithString:@"0"]; 46 | switch (operatorType) { 47 | case 0: 48 | resultNumber = SNAdd(_cardinalNumberTextField.text, _complementNumberTextField.text); 49 | break; 50 | case 1: 51 | resultNumber = SNSub(_cardinalNumberTextField.text, _complementNumberTextField.text); 52 | break; 53 | case 2: 54 | resultNumber = SNMul(_cardinalNumberTextField.text, _complementNumberTextField.text); 55 | break; 56 | case 3: 57 | resultNumber = SNDiv(_cardinalNumberTextField.text, _complementNumberTextField.text); 58 | break; 59 | } 60 | ``` 61 | #### Processes the calculated value 62 | ``` 63 | /* 64 | * The parameter value corresponds to the result processing method 65 | * 0: == is equal to 66 | * 1: min = minimum value 67 | * 2: max = maximum 68 | * 3: ≈≈ approximately equal to 69 | * 4: up≈ up approx 70 | * 5: down≈ down approximation 71 | * 6: bankers≈ Bankers calculation 72 | */ 73 | NSString *resultNumber; 74 | switch (operatorType) { 75 | case 0: 76 | resultNumber = number; 77 | break; 78 | case 1: 79 | resultNumber = [NSString stringWithFormat:@"%@", SNMin(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 80 | break; 81 | case 2: 82 | resultNumber = [NSString stringWithFormat:@"%@", SNMax(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 83 | break; 84 | case 3: 85 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundPlain, 2)]; 86 | break; 87 | case 4: 88 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundUp, 2)]; 89 | break; 90 | case 5: 91 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundDown, 2)]; 92 | break; 93 | case 6: 94 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundBankers, 2)]; 95 | break; 96 | } 97 | ``` 98 | 99 | ## ⚖ License 100 | 101 | ``` 102 | MIT License 103 | 104 | Copyright (c) 2017 ReverseScale 105 | 106 | Permission is hereby granted, free of charge, to any person obtaining a copy 107 | of this software and associated documentation files (the "Software"), to deal 108 | in the Software without restriction, including without limitation the rights 109 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 110 | copies of the Software, and to permit persons to whom the Software is 111 | furnished to do so, subject to the following conditions: 112 | 113 | The above copyright notice and this permission notice shall be included in all 114 | copies or substantial portions of the Software. 115 | 116 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 117 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 118 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 119 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 120 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 121 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 122 | SOFTWARE. 123 | ``` 124 | 125 | ## 😬 Contributions 126 | 127 | * WeChat : WhatsXie 128 | * Email : ReverseScale@iCloud.com 129 | * Blog : https://reversescale.github.io 130 | 131 | -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | 2 | ![](https://img.shields.io/badge/platform-iOS-red.svg) 3 | ![](https://img.shields.io/badge/language-Objective--C-orange.svg) 4 | ![](https://img.shields.io/badge/download-30.9MB-brightgreen.svg) 5 | ![](https://img.shields.io/badge/license-MIT%20License-brightgreen.svg) 6 | [![Build Status](https://travis-ci.org/ReverseScale/RSPayAWA.svg?branch=master)](https://travis-ci.org/ReverseScale/RSPayAWA) 7 | 8 | [EN](https://github.com/ReverseScale/DecimalNumberDemo) | [中文](https://github.com/ReverseScale/DecimalNumberDemo/blob/master/README_zh.md) 9 | 10 | 自从余额宝理财思想在人们心中根深蒂固,各种理财产品也如雨后春笋一般出现,既然涉及到金额,float的精度一定不能满足金融类计算的需要,但是OC的NSDecimal使用起来有过于复杂,所以在前人的基础上进行了封装,并通过一个Demo展示出来。 11 | (内附 Swift 版引用示例,带 UI 的哦😯~) 12 | 13 | ## 🎨 测试 UI 什么样子? 14 | 15 | |1.列表页 |2.展示页 |3.展示页 |4.UI页 | 16 | | ------------- | ------------- | ------------- | ------------- | 17 | | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/85062598.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/20224916.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/66547467.jpg) | ![](http://ghexoblogimages.oss-cn-beijing.aliyuncs.com/18-11-22/26123470.jpg) | 18 | | 通过 storyboard 搭建列表页 | 值等于计算方式 | 处理计算后的值 | Swift 版 UI 展示 | 19 | 20 | ## 🚀 框架的优势 21 | * 1.文件少,代码简洁,封装程度高 22 | * 2.不依赖任何其他第三方库 23 | * 3.通过良好的Demo展示,学习曲线好 24 | * 4.具备较高自定义性 25 | 26 | ## 🤖 要求 27 | * iOS 7+ 28 | * Xcode 8+ 29 | 30 | 31 | ## 🛠 使用方法 32 | ### 第一步 引入头文件 33 | ``` 34 | #import "NSDecimalNumber+Addtion.h" 35 | ``` 36 | ### 第二步 简单使用 37 | #### 值等于计算方式 38 | ``` 39 | /* 40 | * 参数值对应基本运算符 41 | * 0: + 42 | * 1: - 43 | * 2: × 44 | * 3: ÷ 45 | */ 46 | NSDecimalNumber *resultNumber = [[NSDecimalNumber alloc]initWithString:@"0"]; 47 | switch (operatorType) { 48 | case 0: 49 | resultNumber = SNAdd(_cardinalNumberTextField.text, _complementNumberTextField.text); 50 | break; 51 | case 1: 52 | resultNumber = SNSub(_cardinalNumberTextField.text, _complementNumberTextField.text); 53 | break; 54 | case 2: 55 | resultNumber = SNMul(_cardinalNumberTextField.text, _complementNumberTextField.text); 56 | break; 57 | case 3: 58 | resultNumber = SNDiv(_cardinalNumberTextField.text, _complementNumberTextField.text); 59 | break; 60 | } 61 | ``` 62 | #### 处理计算后的值 63 | ``` 64 | /* 65 | * 参数值对应结果处理方式 66 | * 0: == 等于 67 | * 1: min= 最小值 68 | * 2: max= 最大值 69 | * 3: ≈≈ 约等于 70 | * 4: up≈ 向上约值 71 | * 5: down≈ 向下约值 72 | * 6: bankers≈ Bankers计算 73 | */ 74 | NSString *resultNumber; 75 | switch (operatorType) { 76 | case 0: 77 | resultNumber = number; 78 | break; 79 | case 1: 80 | resultNumber = [NSString stringWithFormat:@"%@", SNMin(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 81 | break; 82 | case 2: 83 | resultNumber = [NSString stringWithFormat:@"%@", SNMax(_cardinalNumberTextField.text, _complementNumberTextField.text)]; 84 | break; 85 | case 3: 86 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundPlain, 2)]; 87 | break; 88 | case 4: 89 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundUp, 2)]; 90 | break; 91 | case 5: 92 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundDown, 2)]; 93 | break; 94 | case 6: 95 | resultNumber = [NSString stringWithFormat:@"%@", handlerDecimalNumber(number, NSRoundBankers, 2)]; 96 | break; 97 | } 98 | ``` 99 | 使用简单、效率高效、进程安全~~~如果你有更好的建议,希望不吝赐教! 100 | 101 | 102 | ## ⚖ 协议 103 | 104 | ``` 105 | MIT License 106 | 107 | Copyright (c) 2017 ReverseScale 108 | 109 | Permission is hereby granted, free of charge, to any person obtaining a copy 110 | of this software and associated documentation files (the "Software"), to deal 111 | in the Software without restriction, including without limitation the rights 112 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 113 | copies of the Software, and to permit persons to whom the Software is 114 | furnished to do so, subject to the following conditions: 115 | 116 | The above copyright notice and this permission notice shall be included in all 117 | copies or substantial portions of the Software. 118 | 119 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 120 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 121 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 122 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 123 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 124 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 125 | SOFTWARE. 126 | ``` 127 | 128 | ## 😬 联系 129 | 130 | * 微信 : WhatsXie 131 | * 邮件 : ReverseScale@iCloud.com 132 | * 博客 : https://reversescale.github.io 133 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DecimalDemoSwift 4 | // 5 | // Created by WhatsXie on 2017/11/21. 6 | // Copyright © 2017年 R.S. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "NotificationIcon@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "NotificationIcon@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-Small@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "Icon.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "Icon@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "Icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "Icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "NotificationIcon~ipad.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "NotificationIcon~ipad@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-Small.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-Small@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-Small-50.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-Small-50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-72.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "Icon-72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "Icon-76.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "Icon-76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "Icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "size" : "1024x1024", 149 | "idiom" : "ios-marketing", 150 | "filename" : "ios-marketing.png", 151 | "scale" : "1x" 152 | } 153 | ], 154 | "info" : { 155 | "version" : 1, 156 | "author" : "xcode" 157 | } 158 | } -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/ios-marketing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/AppIcon.appiconset/ios-marketing.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Image.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Image@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Image@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/bg_pink.imageset/Image@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Image.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Image@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Image@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_pink.imageset/Image@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Image.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Image@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Image@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Assets.xcassets/icon_welcome.imageset/Image@3x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 40 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/DecimalDemoSwift-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // DecimalDemoSwift-Bridging-Header.h 3 | // DecimalDemoSwift 4 | // 5 | // Created by WhatsXie on 2017/11/21. 6 | // Copyright © 2017年 R.S. All rights reserved. 7 | // 8 | 9 | #ifndef DecimalDemoSwift_Bridging_Header_h 10 | #define DecimalDemoSwift_Bridging_Header_h 11 | 12 | #import "RSDropdownControls.h" 13 | #import "NSDecimalNumber+Addtion.h" 14 | 15 | #endif /* DecimalDemoSwift_Bridging_Header_h */ 16 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/DecimalNumber/NSDecimalNumber+Addtion.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDecimalNumber+Addtion.h 3 | // 有应用应用 4 | // 5 | // Created by xuliying on 15/10/15. 6 | // Copyright (c) 2015年 xly. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, calculationType) { 12 | Add, 13 | Subtract, 14 | Multiply, 15 | Divide 16 | }; 17 | @interface NSDecimalNumber (Addtion) 18 | + (NSDecimalNumber *)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 type:(calculationType)type anotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2 andDecimalNumberHandler:(NSDecimalNumberHandler *)handler; 19 | 20 | + (NSComparisonResult)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2; 21 | 22 | + (NSString *)stringWithDecimalNumber:(NSDecimalNumber *)str1 scale:(NSInteger)scale; 23 | 24 | extern NSComparisonResult StrNumCompare(id str1,id str2); 25 | extern NSDecimalNumber *handlerDecimalNumber(id strOrNum,NSRoundingMode mode,int scale); 26 | extern NSComparisonResult SNCompare(id strOrNum1,id strOrNum2); 27 | 28 | 29 | extern NSDecimalNumber *SNAdd(id strOrNum1,id strOrNum2); 30 | extern NSDecimalNumber *SNSub(id strOrNum1,id strOrNum2); 31 | extern NSDecimalNumber *SNMul(id strOrNum1,id strOrNum2); 32 | extern NSDecimalNumber *SNDiv(id strOrNum1,id strOrNum2); 33 | 34 | 35 | extern NSDecimalNumber *SNMin(id strOrNum1,id strOrNum2); 36 | extern NSDecimalNumber *SNMax(id strOrNum1,id strOrNum2); 37 | 38 | 39 | extern NSDecimalNumber *SNAdd_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 40 | extern NSDecimalNumber *SNSub_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 41 | extern NSDecimalNumber *SNMul_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 42 | extern NSDecimalNumber *SNDiv_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 43 | 44 | 45 | extern NSDecimalNumber *SNMin_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 46 | extern NSDecimalNumber *SNMax_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale); 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/DecimalNumber/NSDecimalNumber+Addtion.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDecimalNumber+Addtion.m 3 | // 有应用应用 4 | // 5 | // Created by xuliying on 15/10/15. 6 | // Copyright (c) 2015年 xly. All rights reserved. 7 | // 8 | 9 | #import "NSDecimalNumber+Addtion.h" 10 | 11 | @implementation NSDecimalNumber (Addtion) 12 | + (NSDecimalNumber *)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 type:(calculationType)type anotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2 andDecimalNumberHandler:(NSDecimalNumberHandler *)handler{ 13 | if (!stringOrNumber2 || !stringOrNumber1) { 14 | NSLog(@"输入正确类型"); 15 | return nil; 16 | } 17 | NSDecimalNumber *one; 18 | NSDecimalNumber *another; 19 | NSDecimalNumber *returnNum; 20 | if ([stringOrNumber1 isKindOfClass:[NSString class]]) { 21 | one = [NSDecimalNumber decimalNumberWithString:stringOrNumber1]; 22 | } else if ([stringOrNumber1 isKindOfClass:[NSDecimalNumber class]]){ 23 | one = stringOrNumber1; 24 | } else if ([stringOrNumber1 isKindOfClass:[NSNumber class]]){ 25 | one = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber1 decimalValue]]; 26 | } else { 27 | NSLog(@"输入正确的类型"); 28 | return nil; 29 | } 30 | 31 | if ([stringOrNumber2 isKindOfClass:[NSString class]]) { 32 | another = [NSDecimalNumber decimalNumberWithString:stringOrNumber2]; 33 | } else if ([stringOrNumber2 isKindOfClass:[NSDecimalNumber class]]){ 34 | another = stringOrNumber2; 35 | } else if ([stringOrNumber2 isKindOfClass:[NSNumber class]]){ 36 | another = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber2 decimalValue]]; 37 | } else { 38 | NSLog(@"输入正确的类型"); 39 | return nil; 40 | } 41 | 42 | if (type == Add) { 43 | returnNum = [one decimalNumberByAdding:another]; 44 | } else if (type == Subtract){ 45 | returnNum = [one decimalNumberBySubtracting:another]; 46 | } else if (type == Multiply){ 47 | returnNum = [one decimalNumberByMultiplyingBy:another]; 48 | } else if (type == Divide){ 49 | if ([NSDecimalNumber aDecimalNumberWithStringOrNumberOrDecimalNumber:another compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:@(0)] == 0) { 50 | returnNum = nil; 51 | } else { returnNum = [one decimalNumberByDividingBy:another]; 52 | } 53 | } else { returnNum = nil; 54 | } 55 | if (returnNum) { 56 | if (handler) { return [returnNum decimalNumberByRoundingAccordingToBehavior:handler]; 57 | } else { return returnNum; 58 | } 59 | } else { 60 | NSLog(@"输入正确的类型"); 61 | return nil; 62 | } 63 | } 64 | 65 | + (NSComparisonResult)aDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber1 compareAnotherDecimalNumberWithStringOrNumberOrDecimalNumber:(id)stringOrNumber2{ 66 | if (!stringOrNumber2 || !stringOrNumber1) { 67 | NSLog(@"输入正确类型"); 68 | return -404; 69 | } 70 | NSDecimalNumber *one; 71 | NSDecimalNumber *another; 72 | if ([stringOrNumber1 isKindOfClass:[NSString class]]) { 73 | one = [NSDecimalNumber decimalNumberWithString:stringOrNumber1]; 74 | } else if ([stringOrNumber1 isKindOfClass:[NSDecimalNumber class]]){ 75 | one = stringOrNumber1; 76 | } else if ([stringOrNumber1 isKindOfClass:[NSNumber class]]){ 77 | one = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber1 decimalValue]]; 78 | } else { 79 | NSLog(@"输入正确的类型"); 80 | return -404; 81 | } 82 | 83 | if ([stringOrNumber2 isKindOfClass:[NSString class]]) { 84 | another = [NSDecimalNumber decimalNumberWithString:stringOrNumber2]; 85 | } else if ([stringOrNumber2 isKindOfClass:[NSDecimalNumber class]]){ 86 | another = stringOrNumber2; 87 | } else if ([stringOrNumber2 isKindOfClass:[NSNumber class]]){ 88 | another = [NSDecimalNumber decimalNumberWithDecimal:[stringOrNumber2 decimalValue]]; 89 | } else { 90 | NSLog(@"输入正确的类型"); 91 | return -404; 92 | } 93 | return [one compare:another]; 94 | } 95 | 96 | + (NSString *)stringWithDecimalNumber:(NSDecimalNumber *)str1 scale:(NSInteger)scale{ 97 | if (!str1) { return @""; 98 | } 99 | NSString *str = [NSString stringWithFormat:@"%@",str1]; 100 | if (str && str.length) { 101 | if ([str rangeOfString:@"."].length == 1) {//有小数点 102 | NSArray *arr = [str componentsSeparatedByString:@"."]; 103 | if (scale > 0) { 104 | NSInteger count = [arr[1] length]; 105 | for (NSInteger i = count; i 0) { 117 | str = [str stringByAppendingString:@"."]; 118 | for (int i = 0; i 0 ? strOrNum2 : strOrNum1; 178 | } 179 | NSDecimalNumber *SNMax(id strOrNum1,id strOrNum2){ 180 | return SNCompare(strOrNum1, strOrNum2) > 0 ? strOrNum1 : strOrNum2; 181 | } 182 | NSDecimalNumber *SNAdd_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 183 | return handlerDecimalNumber(SNAdd(strOrNum1, strOrNum2), mode, scale); 184 | } 185 | NSDecimalNumber *SNSub_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 186 | return handlerDecimalNumber(SNSub(strOrNum1, strOrNum2), mode, scale); 187 | } 188 | NSDecimalNumber *SNMul_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 189 | return handlerDecimalNumber(SNMul(strOrNum1, strOrNum2), mode, scale); 190 | } 191 | NSDecimalNumber *SNDiv_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 192 | return handlerDecimalNumber(SNDiv(strOrNum1, strOrNum2), mode, scale); 193 | } 194 | 195 | 196 | NSDecimalNumber *SNMin_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 197 | return handlerDecimalNumber(SNMin(strOrNum1, strOrNum2), mode, scale); 198 | } 199 | NSDecimalNumber *SNMax_handler(id strOrNum1,id strOrNum2,NSRoundingMode mode,int scale){ 200 | return handlerDecimalNumber(SNMax(strOrNum1, strOrNum2), mode, scale); 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/RSDropdownControls/RSDropdownControls.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSDropdownControls.h 3 | // RSDropdownControlsDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RSDropdownControls; 12 | @protocol RSDropdownControlsDelegate 13 | @required 14 | - (void)downSelectedView:(RSDropdownControls *)selectedView didSelectedAtIndex:(NSIndexPath *)indexPath; 15 | @end 16 | 17 | @interface RSDropdownControls : UIView 18 | @property (nonatomic, copy, readonly) NSString *text; 19 | // Delegate 20 | @property (nonatomic, weak) id delegate; 21 | 22 | // Data 23 | @property (nonatomic, strong) NSArray *listArray; 24 | 25 | // Preferences(Optional) 26 | @property (nonatomic, strong) UIFont *font; 27 | @property (nonatomic, strong) UIColor *textColor; 28 | @property (nonatomic, assign) NSTextAlignment textAlignment; 29 | @property (nonatomic, copy) NSString *placeholder; 30 | @property (nonatomic, assign) NSInteger maxDropdownCount; // 最大展示列表行数 31 | @property (nonatomic, strong) UIColor *listColor; // 下拉列表背景颜色 32 | 33 | // Function 34 | - (void)show; 35 | - (void)close; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/RSDropdownControls/RSDropdownControls.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSDropdownControls.m 3 | // RSDropdownControlsDemo 4 | // 5 | // Created by WhatsXie on 2017/7/11. 6 | // Copyright © 2017年 StevenXie. All rights reserved. 7 | // 8 | 9 | #import "RSDropdownControls.h" 10 | 11 | // 动画的时间 12 | NSTimeInterval const animationDuration = 0.2f; 13 | // 分割线的颜色 14 | #define kLineColor [UIColor colorWithRed:219/255.0 green:217/255.0 blue:216/255.0 alpha:1] 15 | // 旋转角度 16 | CGFloat angleValue(CGFloat angle) { 17 | return (angle * M_PI) / 180; 18 | } 19 | 20 | @interface RSDropdownControls () 21 | @property (nonatomic, strong) UITextField *contentLabel; 22 | @property (nonatomic, strong) UIButton *clickBtn; 23 | @property (nonatomic, strong) UIImageView *arrowImgView; 24 | @property (nonatomic, strong) UIView *arrowImgBgView; 25 | @property (nonatomic, strong) UITableView *listTableView; 26 | // 执行打开关闭动画 开始结束 27 | @property (nonatomic, assign) BOOL isOpen; 28 | @property (nonatomic, assign) BOOL beDone; 29 | @end 30 | 31 | @implementation RSDropdownControls 32 | - (instancetype)initWithFrame:(CGRect)frame { 33 | self = [super initWithFrame:frame]; 34 | if (self) { 35 | [self _commintInit]; 36 | } 37 | return self; 38 | } 39 | 40 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 41 | self = [super initWithCoder:aDecoder]; 42 | if (self) { 43 | [self _commintInit]; 44 | } 45 | return self; 46 | } 47 | 48 | #pragma mark - private 49 | - (void)_commintInit { 50 | // 默认设置 51 | //self.backgroundColor = [UIColor whiteColor]; 52 | 53 | _font = [UIFont systemFontOfSize:14.f]; 54 | _textColor = [UIColor blackColor]; 55 | _textAlignment = NSTextAlignmentLeft; 56 | 57 | // 默认不展开 58 | _isOpen = NO; 59 | 60 | // 默认是完成动画的 61 | _beDone = YES; 62 | 63 | // 默认 最大展示列表行数是4 64 | _maxDropdownCount = 4; 65 | 66 | // 初始化UI 67 | [self.arrowImgBgView addSubview:self.arrowImgView]; 68 | [self addSubview:self.arrowImgBgView]; 69 | [self addSubview:self.contentLabel]; 70 | [self addSubview:self.clickBtn]; 71 | } 72 | 73 | #pragma mark - action 74 | - (void)clickBtnClicked { 75 | if (!_beDone) return; 76 | // 关闭页面上其他下拉控件 77 | for (UIView *subview in self.superview.subviews) { 78 | if ([subview isKindOfClass:[RSDropdownControls class]] && subview != self) { 79 | RSDropdownControls *donwnSelectedView = (RSDropdownControls *)subview; 80 | if (donwnSelectedView.isOpen) { 81 | [donwnSelectedView close]; 82 | } 83 | } 84 | } 85 | 86 | if (_isOpen) { 87 | [self close]; 88 | } else { 89 | [self show]; 90 | } 91 | } 92 | 93 | #pragma mark - public 94 | - (void)show { 95 | if (_isOpen || _listArray.count == 0) return; 96 | 97 | _beDone = NO; 98 | 99 | [self.superview addSubview:self.listTableView]; 100 | // 避免被其他子视图遮盖住 101 | [self.superview bringSubviewToFront:self.listTableView]; 102 | CGRect frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMaxY(self.frame), CGRectGetWidth(self.frame), 0); 103 | [self.listTableView setFrame:frame]; 104 | self.listTableView.rowHeight = CGRectGetHeight(self.frame); 105 | 106 | [UIView animateWithDuration:animationDuration 107 | delay:0.0f 108 | options:UIViewAnimationOptionCurveEaseOut 109 | animations:^{ 110 | 111 | if (self.listArray.count > 0) { 112 | [self.listTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 113 | atScrollPosition:UITableViewScrollPositionTop 114 | animated:YES]; 115 | } 116 | 117 | CGRect frame = self.listTableView.frame; 118 | NSInteger count = MIN(self.maxDropdownCount, self.listArray.count); 119 | 120 | // 防止超出屏幕 121 | if (frame.origin.y + frame.size.height > [UIScreen mainScreen].bounds.size.height) { 122 | frame.size.height -= frame.origin.y + frame.size.height - [UIScreen mainScreen].bounds.size.height; 123 | } else { 124 | frame.size.height = count * self.frame.size.height; 125 | } 126 | 127 | [self.listTableView setFrame:frame]; 128 | 129 | self.arrowImgView.transform = CGAffineTransformIdentity; 130 | }completion:^(BOOL finished) { 131 | 132 | _beDone = YES; 133 | _isOpen = YES; 134 | 135 | }]; 136 | } 137 | 138 | - (void)close { 139 | if (!_isOpen) return; 140 | 141 | _beDone = NO; 142 | 143 | [UIView animateWithDuration:animationDuration 144 | delay:0.0f 145 | options:UIViewAnimationOptionCurveEaseOut 146 | animations:^{ 147 | 148 | CGRect frame = self.listTableView.frame; 149 | frame.size.height = 0.f; 150 | [self.listTableView setFrame:frame]; 151 | 152 | self.arrowImgView.transform = CGAffineTransformRotate(self.arrowImgView.transform, angleValue(-180)); 153 | }completion:^(BOOL finished) { 154 | 155 | [self.listTableView setContentOffset:CGPointZero animated:NO]; 156 | if (self.listTableView.superview) [self.listTableView removeFromSuperview]; 157 | 158 | _beDone = YES; 159 | _isOpen = NO; 160 | }]; 161 | } 162 | 163 | #pragma mark - UITableViewDataSource 164 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 165 | return 1; 166 | } 167 | 168 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 169 | return _listArray.count; 170 | } 171 | 172 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 173 | static NSString *cellIndentifier = @"cellIndentifier"; 174 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier]; 175 | if(!cell) { 176 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier]; 177 | cell.backgroundColor = [UIColor clearColor]; 178 | cell.selectionStyle = UITableViewCellSelectionStyleDefault; 179 | 180 | UILabel *contentLable = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, self.frame.size.width-10, self.frame.size.height-4)]; 181 | contentLable.tag = 1000; 182 | contentLable.textColor = _textColor; 183 | contentLable.font = _font; 184 | [cell addSubview:contentLable]; 185 | 186 | UIView *lineView = [UIView new]; 187 | lineView.backgroundColor = kLineColor; 188 | lineView.frame = CGRectMake(0, self.frame.size.height-0.5, self.frame.size.width, 0.5); 189 | [cell addSubview:lineView]; 190 | } 191 | UILabel *contentLabel = (UILabel *)[cell viewWithTag:1000]; 192 | contentLabel.text = _listArray[indexPath.row]; 193 | return cell; 194 | } 195 | 196 | #pragma mark - UITableViewDelegate 197 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 198 | } 199 | 200 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 201 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 202 | self.contentLabel.text = [_listArray objectAtIndex:indexPath.row]; 203 | [self close]; 204 | if ([self.delegate respondsToSelector:@selector(downSelectedView:didSelectedAtIndex:)]) { 205 | [self.delegate downSelectedView:self didSelectedAtIndex:indexPath]; 206 | } 207 | } 208 | 209 | 210 | #pragma mark - Public 211 | - (void)setFont:(UIFont *)font { 212 | _font = font; 213 | self.contentLabel.font = font; 214 | } 215 | 216 | - (void)setTextColor:(UIColor *)textColor { 217 | _textColor = textColor; 218 | self.contentLabel.textColor = textColor; 219 | } 220 | 221 | - (void)setTextAlignment:(NSTextAlignment)textAlignment { 222 | _textAlignment = textAlignment; 223 | self.contentLabel.textAlignment = textAlignment; 224 | } 225 | 226 | - (void)setPlaceholder:(NSString *)placeholder { 227 | self.contentLabel.placeholder = placeholder; 228 | } 229 | 230 | - (void)setListArray:(NSArray *)listArray { 231 | _listArray = listArray; 232 | 233 | [self.listTableView reloadData]; 234 | } 235 | 236 | - (NSString *)text { 237 | return self.contentLabel.text; 238 | } 239 | 240 | #pragma mark - getter 241 | - (UITextField *)contentLabel { 242 | if (!_contentLabel) { 243 | _contentLabel = [UITextField new]; 244 | _contentLabel.placeholder = @"点击进行选择"; 245 | _contentLabel.enabled = NO; 246 | _contentLabel.backgroundColor = [UIColor clearColor]; 247 | _contentLabel.textColor = _textColor; 248 | _contentLabel.font = _font; 249 | _contentLabel.textAlignment = _textAlignment; 250 | } 251 | return _contentLabel; 252 | } 253 | 254 | - (UIButton *)clickBtn { 255 | if (!_clickBtn) { 256 | _clickBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 257 | _clickBtn.backgroundColor = [UIColor clearColor]; 258 | _clickBtn.layer.borderColor = kLineColor.CGColor; 259 | _clickBtn.layer.borderWidth = 0.5f; 260 | [_clickBtn addTarget:self action:@selector(clickBtnClicked) forControlEvents:UIControlEventTouchUpInside]; 261 | } 262 | return _clickBtn; 263 | } 264 | 265 | - (UIImageView *)arrowImgView { 266 | if (!_arrowImgView) { 267 | _arrowImgView = [UIImageView new]; 268 | _arrowImgView.image = [UIImage imageNamed:@"arrow_up.png"]; 269 | _arrowImgView.transform = CGAffineTransformRotate(self.arrowImgView.transform, angleValue(-180)); 270 | } 271 | return _arrowImgView; 272 | } 273 | 274 | - (UIView *)arrowImgBgView { 275 | if (!_arrowImgBgView) { 276 | _arrowImgBgView = [[UIView alloc] initWithFrame:CGRectZero]; 277 | _arrowImgBgView.backgroundColor = [UIColor clearColor]; 278 | } 279 | return _arrowImgBgView; 280 | } 281 | 282 | - (UITableView *)listTableView { 283 | if (!_listTableView) { 284 | _listTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 285 | _listTableView.layer.borderWidth = 0.5; 286 | _listTableView.layer.borderColor = kLineColor.CGColor; 287 | _listTableView.scrollsToTop = NO; 288 | _listTableView.bounces = NO; 289 | _listTableView.dataSource = self; 290 | _listTableView.delegate = self; 291 | _listTableView.separatorColor = kLineColor; 292 | _listTableView.backgroundColor = _listColor; 293 | _listTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 294 | } 295 | return _listTableView; 296 | } 297 | 298 | #pragma mark - Layout 299 | - (void)updateConstraints { 300 | //NSLog(@"updateConstraints"); 301 | 302 | // 箭头 303 | self.arrowImgView.translatesAutoresizingMaskIntoConstraints = NO; 304 | [NSLayoutConstraint activateConstraints:@[ 305 | [NSLayoutConstraint constraintWithItem:self.arrowImgView 306 | attribute:NSLayoutAttributeCenterX 307 | relatedBy:NSLayoutRelationEqual 308 | toItem:self.arrowImgBgView 309 | attribute:NSLayoutAttributeCenterX 310 | multiplier:1.0 311 | constant:0.0], 312 | [NSLayoutConstraint constraintWithItem:self.arrowImgView 313 | attribute:NSLayoutAttributeCenterY 314 | relatedBy:NSLayoutRelationEqual 315 | toItem:self.arrowImgBgView 316 | attribute:NSLayoutAttributeCenterY 317 | multiplier:1.0 318 | constant:0.0] 319 | ]]; 320 | 321 | self.arrowImgBgView.translatesAutoresizingMaskIntoConstraints = NO; 322 | 323 | [NSLayoutConstraint activateConstraints:@[ 324 | [NSLayoutConstraint constraintWithItem:self 325 | attribute:NSLayoutAttributeRight 326 | relatedBy:NSLayoutRelationEqual 327 | toItem:self.arrowImgBgView 328 | attribute:NSLayoutAttributeRight 329 | multiplier:1.0 330 | constant:0.0], 331 | [NSLayoutConstraint constraintWithItem:self 332 | attribute:NSLayoutAttributeTop 333 | relatedBy:NSLayoutRelationEqual 334 | toItem:self.arrowImgBgView 335 | attribute:NSLayoutAttributeTop 336 | multiplier:1.0 337 | constant:0.0], 338 | [NSLayoutConstraint constraintWithItem:self 339 | attribute:NSLayoutAttributeBottom 340 | relatedBy:NSLayoutRelationEqual 341 | toItem:self.arrowImgBgView 342 | attribute:NSLayoutAttributeBottom 343 | multiplier:1.0 344 | constant:0.0], 345 | [NSLayoutConstraint constraintWithItem:self.arrowImgBgView 346 | attribute:NSLayoutAttributeWidth 347 | relatedBy:NSLayoutRelationEqual 348 | toItem:nil 349 | attribute:NSLayoutAttributeNotAnAttribute 350 | multiplier:1.0 351 | constant:30] 352 | ]]; 353 | 354 | // 内容label 355 | self.contentLabel.translatesAutoresizingMaskIntoConstraints = NO; 356 | [NSLayoutConstraint activateConstraints:@[ 357 | [NSLayoutConstraint constraintWithItem:self.contentLabel 358 | attribute:NSLayoutAttributeLeft 359 | relatedBy:NSLayoutRelationEqual 360 | toItem:self 361 | attribute:NSLayoutAttributeLeft 362 | multiplier:1.0 363 | constant:5.0], 364 | [NSLayoutConstraint constraintWithItem:self.contentLabel 365 | attribute:NSLayoutAttributeTop 366 | relatedBy:NSLayoutRelationEqual 367 | toItem:self 368 | attribute:NSLayoutAttributeTop 369 | multiplier:1.0 370 | constant:0.0], 371 | [NSLayoutConstraint constraintWithItem:self.contentLabel 372 | attribute:NSLayoutAttributeBottom 373 | relatedBy:NSLayoutRelationEqual 374 | toItem:self 375 | attribute:NSLayoutAttributeBottom 376 | multiplier:1.0 377 | constant:0.0], 378 | [NSLayoutConstraint constraintWithItem:self.contentLabel 379 | attribute:NSLayoutAttributeRight 380 | relatedBy:NSLayoutRelationEqual 381 | toItem:self.arrowImgBgView 382 | attribute:NSLayoutAttributeLeft 383 | multiplier:1.0 384 | constant:0.0] 385 | ]]; 386 | 387 | self.clickBtn.translatesAutoresizingMaskIntoConstraints = NO; 388 | [NSLayoutConstraint activateConstraints:@[ 389 | [NSLayoutConstraint constraintWithItem:self.clickBtn 390 | attribute:NSLayoutAttributeLeft 391 | relatedBy:NSLayoutRelationEqual 392 | toItem:self 393 | attribute:NSLayoutAttributeLeft 394 | multiplier:1.0 395 | constant:0.0], 396 | [NSLayoutConstraint constraintWithItem:self.clickBtn 397 | attribute:NSLayoutAttributeTop 398 | relatedBy:NSLayoutRelationEqual 399 | toItem:self 400 | attribute:NSLayoutAttributeTop 401 | multiplier:1.0 402 | constant:0.0], 403 | [NSLayoutConstraint constraintWithItem:self.clickBtn 404 | attribute:NSLayoutAttributeBottom 405 | relatedBy:NSLayoutRelationEqual 406 | toItem:self 407 | attribute:NSLayoutAttributeBottom 408 | multiplier:1.0 409 | constant:0.0], 410 | [NSLayoutConstraint constraintWithItem:self.clickBtn 411 | attribute:NSLayoutAttributeRight 412 | relatedBy:NSLayoutRelationEqual 413 | toItem:self 414 | attribute:NSLayoutAttributeRight 415 | multiplier:1.0 416 | constant:0.0] 417 | ]]; 418 | [super updateConstraints]; 419 | } 420 | 421 | @end 422 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/RSDropdownControls/Resources/arrow_up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseScale/DecimalNumberDemo/211dac53c1f224ed33b7fee2a8a1a36631ccae93/SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/RSDropdownControls/Resources/arrow_up@2x.png -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwift/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // DecimalDemoSwift 4 | // 5 | // Created by WhatsXie on 2017/11/21. 6 | // Copyright © 2017年 R.S. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController,RSDropdownControlsDelegate { 12 | // 基数 13 | @IBOutlet weak var cardinalNumberTextField: UITextField! 14 | // 补数 15 | @IBOutlet weak var complementNumberTextField: UITextField! 16 | // 运算结果 17 | @IBOutlet weak var resultLabel: UILabel! 18 | // 结果方式 19 | @IBOutlet weak var resultTypeView: RSDropdownControls! 20 | // 运算符 21 | @IBOutlet weak var operatorView: RSDropdownControls! 22 | // 最终输出文本 23 | @IBOutlet weak var finishedLabel: UILabel! 24 | // 最终运算符文本 25 | @IBOutlet weak var operatorLabel: UILabel! 26 | // 运算符解释 27 | @IBOutlet weak var operatorTextLabel: UILabel! 28 | 29 | var operatorArray = [Any]() 30 | var resultTypeArray = [Any]() 31 | var resultTypeTextArray = [Any]() 32 | var afterIndex: Int = 0 33 | 34 | override func viewDidLoad() { 35 | super.viewDidLoad() 36 | // Do any additional setup after loading the view, typically from a nib. 37 | operatorArray = ["+", "-", "×", "÷"] 38 | resultTypeArray = ["==", "min=", "max=", "≈≈", "up≈", "down≈", "bankers≈"] 39 | resultTypeTextArray = ["等于", "最小值", "最大值", "约等于", "向上约值", "向下约值", "Bankers 计算"] 40 | 41 | setupOperatorAndResultType() 42 | } 43 | func setupOperatorAndResultType() { 44 | operatorView.placeholder = "运算符" 45 | operatorView.listColor = UIColor.white 46 | operatorView.listArray = operatorArray as! [String] 47 | operatorView.delegate = self 48 | 49 | resultTypeView.placeholder = "结果符" 50 | resultTypeView.listColor = UIColor.white 51 | resultTypeView.listArray = resultTypeArray as! [String] 52 | resultTypeView.maxDropdownCount = 7 53 | //可选,默认是4行 54 | resultTypeView.delegate = self 55 | } 56 | 57 | func downSelectedView(_ selectedView: RSDropdownControls, didSelectedAtIndex indexPath: IndexPath) { 58 | if (cardinalNumberTextField.text == "") || (complementNumberTextField.text == "") { 59 | setupAlertView() 60 | return 61 | } 62 | if selectedView.isEqual(operatorView) { 63 | afterIndex = indexPath.row 64 | resultLabel.text = "\(decimalFunc(withOperatorType: indexPath.row))" 65 | } else { 66 | let finishedString = decimalFunc(withNumber: "\(decimalFunc(withOperatorType: afterIndex))", operatorType: indexPath.row) 67 | resultLabel.text = finishedString 68 | if finishedString.count <= 6 { 69 | finishedLabel.text = getSeparatedString(orgStr: finishedString) 70 | } else { 71 | finishedLabel.text = "过长" 72 | } 73 | } 74 | } 75 | 76 | // 设置提醒窗 77 | func setupAlertView() { 78 | let alert = UIAlertController(title: "请先填写数额", message: nil, preferredStyle: .alert) 79 | alert.addAction(UIAlertAction(title: "确定", style: .default, handler: {(_ action: UIAlertAction) -> Void in 80 | })) 81 | present(alert, animated: true) 82 | } 83 | 84 | // 计算方式 85 | func decimalFunc(withOperatorType operatorType: Int) -> NSDecimalNumber { 86 | var resultNumber = NSDecimalNumber(string: "0") 87 | switch operatorType { 88 | case 0: 89 | resultNumber = SNAdd(cardinalNumberTextField.text, complementNumberTextField.text) 90 | case 1: 91 | resultNumber = SNSub(cardinalNumberTextField.text, complementNumberTextField.text) 92 | case 2: 93 | resultNumber = SNMul(cardinalNumberTextField.text, complementNumberTextField.text) 94 | default: 95 | resultNumber = SNDiv(cardinalNumberTextField.text, complementNumberTextField.text) 96 | } 97 | return resultNumber 98 | } 99 | 100 | // 计算结果处理方法 101 | func decimalFunc(withNumber number: String, operatorType: Int) -> String { 102 | operatorLabel.text = resultTypeArray[operatorType] as? String 103 | operatorTextLabel.text = resultTypeTextArray[operatorType] as? String 104 | var resultNumber: String 105 | switch operatorType { 106 | case 0: 107 | resultNumber = number 108 | case 1: 109 | resultNumber = "\(SNMin(cardinalNumberTextField.text, complementNumberTextField.text))" 110 | case 2: 111 | resultNumber = "\(SNMax(cardinalNumberTextField.text, complementNumberTextField.text))" 112 | case 3: 113 | resultNumber = "\(handlerDecimalNumber(number, .plain, 2))" 114 | case 4: 115 | resultNumber = "\(handlerDecimalNumber(number, .up, 2))" 116 | case 5: 117 | resultNumber = "\(handlerDecimalNumber(number, .down, 2))" 118 | default: 119 | resultNumber = "\(handlerDecimalNumber(number, .bankers, 2))" 120 | } 121 | return resultNumber 122 | } 123 | 124 | func getSeparatedString(orgStr: String) -> String { 125 | let length = orgStr.utf16.count 126 | if length < 4 { 127 | return orgStr 128 | } 129 | var dstStr = String() 130 | var orgChars = orgStr.characters 131 | let startIndex = orgChars.startIndex 132 | var counter = 0 133 | var i = length - 1 134 | repeat { 135 | counter += 1 136 | dstStr.insert(orgChars.popLast()!, at: startIndex) 137 | if counter == 3 { 138 | dstStr.insert(",", at: startIndex) 139 | counter = 0; 140 | } 141 | i -= 1 142 | } 143 | while i > 0 144 | dstStr.insert(orgChars.popLast()!, at: startIndex) 145 | return dstStr; 146 | } 147 | 148 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 149 | operatorView.close() 150 | resultTypeView.close() 151 | view.endEditing(true) 152 | } 153 | 154 | override func didReceiveMemoryWarning() { 155 | super.didReceiveMemoryWarning() 156 | // Dispose of any resources that can be recreated. 157 | } 158 | } 159 | 160 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwiftTests/DecimalDemoSwiftTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DecimalDemoSwiftTests.swift 3 | // DecimalDemoSwiftTests 4 | // 5 | // Created by WhatsXie on 2017/11/21. 6 | // Copyright © 2017年 R.S. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import DecimalDemoSwift 11 | 12 | class DecimalDemoSwiftTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwiftTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwiftUITests/DecimalDemoSwiftUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DecimalDemoSwiftUITests.swift 3 | // DecimalDemoSwiftUITests 4 | // 5 | // Created by WhatsXie on 2017/11/21. 6 | // Copyright © 2017年 R.S. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class DecimalDemoSwiftUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SwiftDemo/DecimalDemoSwift/DecimalDemoSwiftUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | --------------------------------------------------------------------------------