├── ChoseGoodsType.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lanaohudong.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── lanaohudong.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── ChoseGoodsType ├── 0.jpg ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── guanbi.imageset │ │ ├── Contents.json │ │ ├── guanbi@2x.png │ │ └── guanbi@3x.png │ └── jiantou_down.imageset │ │ ├── Contents.json │ │ ├── jiantou_down@2x.png │ │ └── jiantou_down@3x.png ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── LaunchScreen.storyboard ├── ViewController.h ├── ViewController.m ├── main.m ├── source │ ├── SDAutoLayout │ │ ├── SDAutoLayout.h │ │ ├── UITableView+SDAutoTableViewCellHeight.h │ │ ├── UITableView+SDAutoTableViewCellHeight.m │ │ ├── UIView+SDAutoLayout.h │ │ └── UIView+SDAutoLayout.m │ └── SVProgressHUD │ │ ├── SVIndefiniteAnimatedView.h │ │ ├── SVIndefiniteAnimatedView.m │ │ ├── SVProgressAnimatedView.h │ │ ├── SVProgressAnimatedView.m │ │ ├── SVProgressHUD-Prefix.pch │ │ ├── SVProgressHUD.bundle │ │ ├── angle-mask.png │ │ ├── angle-mask@2x.png │ │ ├── angle-mask@3x.png │ │ ├── error.png │ │ ├── error@2x.png │ │ ├── error@3x.png │ │ ├── info.png │ │ ├── info@2x.png │ │ ├── info@3x.png │ │ ├── success.png │ │ ├── success@2x.png │ │ └── success@3x.png │ │ ├── SVProgressHUD.h │ │ ├── SVProgressHUD.m │ │ ├── SVRadialGradientLayer.h │ │ └── SVRadialGradientLayer.m └── 规格选择 │ ├── Header.h │ ├── JXUIKit.h │ ├── JXUIKit.m │ ├── Models │ ├── GoodsModel.h │ ├── GoodsModel.m │ ├── GoodsPriceModel.h │ ├── GoodsPriceModel.m │ ├── GoodsTypeModel.h │ ├── GoodsTypeModel.m │ ├── SizeAttributeModel.h │ └── SizeAttributeModel.m │ └── views │ ├── ChoosTypeTableViewCell.h │ ├── ChoosTypeTableViewCell.m │ ├── ChoseGoodsTypeAlert.h │ ├── ChoseGoodsTypeAlert.m │ ├── CountView.h │ ├── CountView.m │ ├── GoodsInfoView.h │ └── GoodsInfoView.m ├── ChoseGoodsTypeTests ├── ChoseGoodsTypeTests.m └── Info.plist ├── ChoseGoodsTypeUITests ├── ChoseGoodsTypeUITests.m └── Info.plist ├── README.md ├── chosetype.gif ├── erweima.png └── jiawo.jpg /ChoseGoodsType.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7B2D0E342020243C00C4C26D /* GoodsInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B2D0E332020243C00C4C26D /* GoodsInfoView.m */; }; 11 | 7B40E6522021BCB000EC902A /* 3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 7B40E64E2021BCB000EC902A /* 3.jpg */; }; 12 | 7B40E6532021BCB000EC902A /* 1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 7B40E64F2021BCB000EC902A /* 1.jpg */; }; 13 | 7B40E6542021BCB000EC902A /* 2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 7B40E6502021BCB000EC902A /* 2.jpg */; }; 14 | 7B40E6552021BCB000EC902A /* 0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 7B40E6512021BCB000EC902A /* 0.jpg */; }; 15 | 7B8730E9201EFEE4008979E5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8730E8201EFEE4008979E5 /* AppDelegate.m */; }; 16 | 7B8730EC201EFEE4008979E5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8730EB201EFEE4008979E5 /* ViewController.m */; }; 17 | 7B8730EF201EFEE4008979E5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B8730ED201EFEE4008979E5 /* Main.storyboard */; }; 18 | 7B8730F1201EFEE4008979E5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B8730F0201EFEE4008979E5 /* Assets.xcassets */; }; 19 | 7B8730F7201EFEE4008979E5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8730F6201EFEE4008979E5 /* main.m */; }; 20 | 7B873101201EFEE4008979E5 /* ChoseGoodsTypeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873100201EFEE4008979E5 /* ChoseGoodsTypeTests.m */; }; 21 | 7B87310C201EFEE4008979E5 /* ChoseGoodsTypeUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87310B201EFEE4008979E5 /* ChoseGoodsTypeUITests.m */; }; 22 | 7B873126201F00EA008979E5 /* GoodsTypeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87311C201F00EA008979E5 /* GoodsTypeModel.m */; }; 23 | 7B873127201F00EA008979E5 /* ChoosTypeTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87311F201F00EA008979E5 /* ChoosTypeTableViewCell.m */; }; 24 | 7B873128201F00EA008979E5 /* ChoseGoodsTypeAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873121201F00EA008979E5 /* ChoseGoodsTypeAlert.m */; }; 25 | 7B873129201F00EA008979E5 /* CountView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873123201F00EA008979E5 /* CountView.m */; }; 26 | 7B87312D201F028D008979E5 /* JXUIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87312B201F028D008979E5 /* JXUIKit.m */; }; 27 | 7B8731AD201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87317D201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.m */; }; 28 | 7B8731AE201F0419008979E5 /* UIView+SDAutoLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87317F201F0419008979E5 /* UIView+SDAutoLayout.m */; }; 29 | 7B8731AF201F0419008979E5 /* SVIndefiniteAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873182201F0419008979E5 /* SVIndefiniteAnimatedView.m */; }; 30 | 7B8731B0201F0419008979E5 /* SVProgressAnimatedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873184201F0419008979E5 /* SVProgressAnimatedView.m */; }; 31 | 7B8731B1201F0419008979E5 /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7B873186201F0419008979E5 /* SVProgressHUD.bundle */; }; 32 | 7B8731B2201F0419008979E5 /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B873188201F0419008979E5 /* SVProgressHUD.m */; }; 33 | 7B8731B3201F0419008979E5 /* SVRadialGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B87318A201F0419008979E5 /* SVRadialGradientLayer.m */; }; 34 | 7B8731B6201F0551008979E5 /* GoodsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8731B4201F0551008979E5 /* GoodsModel.m */; }; 35 | 7B8731B9201F059C008979E5 /* GoodsPriceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8731B8201F059C008979E5 /* GoodsPriceModel.m */; }; 36 | 7B8731BC201F05C5008979E5 /* SizeAttributeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B8731BA201F05C5008979E5 /* SizeAttributeModel.m */; }; 37 | 7B8731BF201F12BB008979E5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B8731BE201F12BA008979E5 /* LaunchScreen.storyboard */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXContainerItemProxy section */ 41 | 7B8730FD201EFEE4008979E5 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 7B8730DC201EFEE4008979E5 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = 7B8730E3201EFEE4008979E5; 46 | remoteInfo = ChoseGoodsType; 47 | }; 48 | 7B873108201EFEE4008979E5 /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 7B8730DC201EFEE4008979E5 /* Project object */; 51 | proxyType = 1; 52 | remoteGlobalIDString = 7B8730E3201EFEE4008979E5; 53 | remoteInfo = ChoseGoodsType; 54 | }; 55 | /* End PBXContainerItemProxy section */ 56 | 57 | /* Begin PBXFileReference section */ 58 | 7B2D0E322020243C00C4C26D /* GoodsInfoView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoodsInfoView.h; sourceTree = ""; }; 59 | 7B2D0E332020243C00C4C26D /* GoodsInfoView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoodsInfoView.m; sourceTree = ""; }; 60 | 7B40E64E2021BCB000EC902A /* 3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 3.jpg; sourceTree = ""; }; 61 | 7B40E64F2021BCB000EC902A /* 1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 1.jpg; sourceTree = ""; }; 62 | 7B40E6502021BCB000EC902A /* 2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 2.jpg; sourceTree = ""; }; 63 | 7B40E6512021BCB000EC902A /* 0.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 0.jpg; sourceTree = ""; }; 64 | 7B8730E4201EFEE4008979E5 /* ChoseGoodsType.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChoseGoodsType.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 7B8730E7201EFEE4008979E5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 66 | 7B8730E8201EFEE4008979E5 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 67 | 7B8730EA201EFEE4008979E5 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 68 | 7B8730EB201EFEE4008979E5 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 69 | 7B8730EE201EFEE4008979E5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 70 | 7B8730F0201EFEE4008979E5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 71 | 7B8730F5201EFEE4008979E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 72 | 7B8730F6201EFEE4008979E5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 73 | 7B8730FC201EFEE4008979E5 /* ChoseGoodsTypeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChoseGoodsTypeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 7B873100201EFEE4008979E5 /* ChoseGoodsTypeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChoseGoodsTypeTests.m; sourceTree = ""; }; 75 | 7B873102201EFEE4008979E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | 7B873107201EFEE4008979E5 /* ChoseGoodsTypeUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChoseGoodsTypeUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | 7B87310B201EFEE4008979E5 /* ChoseGoodsTypeUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChoseGoodsTypeUITests.m; sourceTree = ""; }; 78 | 7B87310D201EFEE4008979E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 79 | 7B87311B201F00EA008979E5 /* GoodsTypeModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoodsTypeModel.h; sourceTree = ""; }; 80 | 7B87311C201F00EA008979E5 /* GoodsTypeModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoodsTypeModel.m; sourceTree = ""; }; 81 | 7B87311E201F00EA008979E5 /* ChoosTypeTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChoosTypeTableViewCell.h; sourceTree = ""; }; 82 | 7B87311F201F00EA008979E5 /* ChoosTypeTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChoosTypeTableViewCell.m; sourceTree = ""; }; 83 | 7B873120201F00EA008979E5 /* ChoseGoodsTypeAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChoseGoodsTypeAlert.h; sourceTree = ""; }; 84 | 7B873121201F00EA008979E5 /* ChoseGoodsTypeAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChoseGoodsTypeAlert.m; sourceTree = ""; }; 85 | 7B873122201F00EA008979E5 /* CountView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountView.h; sourceTree = ""; }; 86 | 7B873123201F00EA008979E5 /* CountView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CountView.m; sourceTree = ""; }; 87 | 7B87312B201F028D008979E5 /* JXUIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JXUIKit.m; sourceTree = ""; }; 88 | 7B87312C201F028D008979E5 /* JXUIKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JXUIKit.h; sourceTree = ""; }; 89 | 7B87317B201F0419008979E5 /* SDAutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDAutoLayout.h; sourceTree = ""; }; 90 | 7B87317C201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+SDAutoTableViewCellHeight.h"; sourceTree = ""; }; 91 | 7B87317D201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+SDAutoTableViewCellHeight.m"; sourceTree = ""; }; 92 | 7B87317E201F0419008979E5 /* UIView+SDAutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SDAutoLayout.h"; sourceTree = ""; }; 93 | 7B87317F201F0419008979E5 /* UIView+SDAutoLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SDAutoLayout.m"; sourceTree = ""; }; 94 | 7B873181201F0419008979E5 /* SVIndefiniteAnimatedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVIndefiniteAnimatedView.h; sourceTree = ""; }; 95 | 7B873182201F0419008979E5 /* SVIndefiniteAnimatedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVIndefiniteAnimatedView.m; sourceTree = ""; }; 96 | 7B873183201F0419008979E5 /* SVProgressAnimatedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressAnimatedView.h; sourceTree = ""; }; 97 | 7B873184201F0419008979E5 /* SVProgressAnimatedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressAnimatedView.m; sourceTree = ""; }; 98 | 7B873185201F0419008979E5 /* SVProgressHUD-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SVProgressHUD-Prefix.pch"; sourceTree = ""; }; 99 | 7B873186201F0419008979E5 /* SVProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SVProgressHUD.bundle; sourceTree = ""; }; 100 | 7B873187201F0419008979E5 /* SVProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressHUD.h; sourceTree = ""; }; 101 | 7B873188201F0419008979E5 /* SVProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressHUD.m; sourceTree = ""; }; 102 | 7B873189201F0419008979E5 /* SVRadialGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVRadialGradientLayer.h; sourceTree = ""; }; 103 | 7B87318A201F0419008979E5 /* SVRadialGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVRadialGradientLayer.m; sourceTree = ""; }; 104 | 7B8731B4201F0551008979E5 /* GoodsModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoodsModel.m; sourceTree = ""; }; 105 | 7B8731B5201F0551008979E5 /* GoodsModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoodsModel.h; sourceTree = ""; }; 106 | 7B8731B7201F059B008979E5 /* GoodsPriceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoodsPriceModel.h; sourceTree = ""; }; 107 | 7B8731B8201F059C008979E5 /* GoodsPriceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoodsPriceModel.m; sourceTree = ""; }; 108 | 7B8731BA201F05C5008979E5 /* SizeAttributeModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SizeAttributeModel.m; sourceTree = ""; }; 109 | 7B8731BB201F05C5008979E5 /* SizeAttributeModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SizeAttributeModel.h; sourceTree = ""; }; 110 | 7B8731BD201F0666008979E5 /* Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Header.h; sourceTree = ""; }; 111 | 7B8731BE201F12BA008979E5 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 112 | /* End PBXFileReference section */ 113 | 114 | /* Begin PBXFrameworksBuildPhase section */ 115 | 7B8730E1201EFEE4008979E5 /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | 7B8730F9201EFEE4008979E5 /* Frameworks */ = { 123 | isa = PBXFrameworksBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | 7B873104201EFEE4008979E5 /* Frameworks */ = { 130 | isa = PBXFrameworksBuildPhase; 131 | buildActionMask = 2147483647; 132 | files = ( 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXFrameworksBuildPhase section */ 137 | 138 | /* Begin PBXGroup section */ 139 | 7B8730DB201EFEE4008979E5 = { 140 | isa = PBXGroup; 141 | children = ( 142 | 7B8730E6201EFEE4008979E5 /* ChoseGoodsType */, 143 | 7B8730FF201EFEE4008979E5 /* ChoseGoodsTypeTests */, 144 | 7B87310A201EFEE4008979E5 /* ChoseGoodsTypeUITests */, 145 | 7B8730E5201EFEE4008979E5 /* Products */, 146 | ); 147 | sourceTree = ""; 148 | }; 149 | 7B8730E5201EFEE4008979E5 /* Products */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 7B8730E4201EFEE4008979E5 /* ChoseGoodsType.app */, 153 | 7B8730FC201EFEE4008979E5 /* ChoseGoodsTypeTests.xctest */, 154 | 7B873107201EFEE4008979E5 /* ChoseGoodsTypeUITests.xctest */, 155 | ); 156 | name = Products; 157 | sourceTree = ""; 158 | }; 159 | 7B8730E6201EFEE4008979E5 /* ChoseGoodsType */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 7B8730E7201EFEE4008979E5 /* AppDelegate.h */, 163 | 7B8730E8201EFEE4008979E5 /* AppDelegate.m */, 164 | 7B8730EA201EFEE4008979E5 /* ViewController.h */, 165 | 7B8730EB201EFEE4008979E5 /* ViewController.m */, 166 | 7B40E64F2021BCB000EC902A /* 1.jpg */, 167 | 7B40E6502021BCB000EC902A /* 2.jpg */, 168 | 7B40E64E2021BCB000EC902A /* 3.jpg */, 169 | 7B40E6512021BCB000EC902A /* 0.jpg */, 170 | 7B87312E201F0419008979E5 /* source */, 171 | 7B873119201F00EA008979E5 /* 规格选择 */, 172 | 7B8730ED201EFEE4008979E5 /* Main.storyboard */, 173 | 7B8731BE201F12BA008979E5 /* LaunchScreen.storyboard */, 174 | 7B8730F0201EFEE4008979E5 /* Assets.xcassets */, 175 | 7B8730F5201EFEE4008979E5 /* Info.plist */, 176 | 7B8730F6201EFEE4008979E5 /* main.m */, 177 | ); 178 | path = ChoseGoodsType; 179 | sourceTree = ""; 180 | }; 181 | 7B8730FF201EFEE4008979E5 /* ChoseGoodsTypeTests */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 7B873100201EFEE4008979E5 /* ChoseGoodsTypeTests.m */, 185 | 7B873102201EFEE4008979E5 /* Info.plist */, 186 | ); 187 | path = ChoseGoodsTypeTests; 188 | sourceTree = ""; 189 | }; 190 | 7B87310A201EFEE4008979E5 /* ChoseGoodsTypeUITests */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 7B87310B201EFEE4008979E5 /* ChoseGoodsTypeUITests.m */, 194 | 7B87310D201EFEE4008979E5 /* Info.plist */, 195 | ); 196 | path = ChoseGoodsTypeUITests; 197 | sourceTree = ""; 198 | }; 199 | 7B873119201F00EA008979E5 /* 规格选择 */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 7B87312C201F028D008979E5 /* JXUIKit.h */, 203 | 7B87312B201F028D008979E5 /* JXUIKit.m */, 204 | 7B8731BD201F0666008979E5 /* Header.h */, 205 | 7B87311A201F00EA008979E5 /* Models */, 206 | 7B87311D201F00EA008979E5 /* views */, 207 | ); 208 | path = "规格选择"; 209 | sourceTree = ""; 210 | }; 211 | 7B87311A201F00EA008979E5 /* Models */ = { 212 | isa = PBXGroup; 213 | children = ( 214 | 7B8731BB201F05C5008979E5 /* SizeAttributeModel.h */, 215 | 7B8731BA201F05C5008979E5 /* SizeAttributeModel.m */, 216 | 7B8731B7201F059B008979E5 /* GoodsPriceModel.h */, 217 | 7B8731B8201F059C008979E5 /* GoodsPriceModel.m */, 218 | 7B8731B5201F0551008979E5 /* GoodsModel.h */, 219 | 7B8731B4201F0551008979E5 /* GoodsModel.m */, 220 | 7B87311B201F00EA008979E5 /* GoodsTypeModel.h */, 221 | 7B87311C201F00EA008979E5 /* GoodsTypeModel.m */, 222 | ); 223 | path = Models; 224 | sourceTree = ""; 225 | }; 226 | 7B87311D201F00EA008979E5 /* views */ = { 227 | isa = PBXGroup; 228 | children = ( 229 | 7B873120201F00EA008979E5 /* ChoseGoodsTypeAlert.h */, 230 | 7B873121201F00EA008979E5 /* ChoseGoodsTypeAlert.m */, 231 | 7B87311E201F00EA008979E5 /* ChoosTypeTableViewCell.h */, 232 | 7B87311F201F00EA008979E5 /* ChoosTypeTableViewCell.m */, 233 | 7B873122201F00EA008979E5 /* CountView.h */, 234 | 7B873123201F00EA008979E5 /* CountView.m */, 235 | 7B2D0E322020243C00C4C26D /* GoodsInfoView.h */, 236 | 7B2D0E332020243C00C4C26D /* GoodsInfoView.m */, 237 | ); 238 | path = views; 239 | sourceTree = ""; 240 | }; 241 | 7B87312E201F0419008979E5 /* source */ = { 242 | isa = PBXGroup; 243 | children = ( 244 | 7B87317A201F0419008979E5 /* SDAutoLayout */, 245 | 7B873180201F0419008979E5 /* SVProgressHUD */, 246 | ); 247 | path = source; 248 | sourceTree = ""; 249 | }; 250 | 7B87317A201F0419008979E5 /* SDAutoLayout */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | 7B87317B201F0419008979E5 /* SDAutoLayout.h */, 254 | 7B87317C201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.h */, 255 | 7B87317D201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.m */, 256 | 7B87317E201F0419008979E5 /* UIView+SDAutoLayout.h */, 257 | 7B87317F201F0419008979E5 /* UIView+SDAutoLayout.m */, 258 | ); 259 | path = SDAutoLayout; 260 | sourceTree = ""; 261 | }; 262 | 7B873180201F0419008979E5 /* SVProgressHUD */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | 7B873181201F0419008979E5 /* SVIndefiniteAnimatedView.h */, 266 | 7B873182201F0419008979E5 /* SVIndefiniteAnimatedView.m */, 267 | 7B873183201F0419008979E5 /* SVProgressAnimatedView.h */, 268 | 7B873184201F0419008979E5 /* SVProgressAnimatedView.m */, 269 | 7B873185201F0419008979E5 /* SVProgressHUD-Prefix.pch */, 270 | 7B873186201F0419008979E5 /* SVProgressHUD.bundle */, 271 | 7B873187201F0419008979E5 /* SVProgressHUD.h */, 272 | 7B873188201F0419008979E5 /* SVProgressHUD.m */, 273 | 7B873189201F0419008979E5 /* SVRadialGradientLayer.h */, 274 | 7B87318A201F0419008979E5 /* SVRadialGradientLayer.m */, 275 | ); 276 | path = SVProgressHUD; 277 | sourceTree = ""; 278 | }; 279 | /* End PBXGroup section */ 280 | 281 | /* Begin PBXNativeTarget section */ 282 | 7B8730E3201EFEE4008979E5 /* ChoseGoodsType */ = { 283 | isa = PBXNativeTarget; 284 | buildConfigurationList = 7B873110201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsType" */; 285 | buildPhases = ( 286 | 7B8730E0201EFEE4008979E5 /* Sources */, 287 | 7B8730E1201EFEE4008979E5 /* Frameworks */, 288 | 7B8730E2201EFEE4008979E5 /* Resources */, 289 | ); 290 | buildRules = ( 291 | ); 292 | dependencies = ( 293 | ); 294 | name = ChoseGoodsType; 295 | productName = ChoseGoodsType; 296 | productReference = 7B8730E4201EFEE4008979E5 /* ChoseGoodsType.app */; 297 | productType = "com.apple.product-type.application"; 298 | }; 299 | 7B8730FB201EFEE4008979E5 /* ChoseGoodsTypeTests */ = { 300 | isa = PBXNativeTarget; 301 | buildConfigurationList = 7B873113201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsTypeTests" */; 302 | buildPhases = ( 303 | 7B8730F8201EFEE4008979E5 /* Sources */, 304 | 7B8730F9201EFEE4008979E5 /* Frameworks */, 305 | 7B8730FA201EFEE4008979E5 /* Resources */, 306 | ); 307 | buildRules = ( 308 | ); 309 | dependencies = ( 310 | 7B8730FE201EFEE4008979E5 /* PBXTargetDependency */, 311 | ); 312 | name = ChoseGoodsTypeTests; 313 | productName = ChoseGoodsTypeTests; 314 | productReference = 7B8730FC201EFEE4008979E5 /* ChoseGoodsTypeTests.xctest */; 315 | productType = "com.apple.product-type.bundle.unit-test"; 316 | }; 317 | 7B873106201EFEE4008979E5 /* ChoseGoodsTypeUITests */ = { 318 | isa = PBXNativeTarget; 319 | buildConfigurationList = 7B873116201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsTypeUITests" */; 320 | buildPhases = ( 321 | 7B873103201EFEE4008979E5 /* Sources */, 322 | 7B873104201EFEE4008979E5 /* Frameworks */, 323 | 7B873105201EFEE4008979E5 /* Resources */, 324 | ); 325 | buildRules = ( 326 | ); 327 | dependencies = ( 328 | 7B873109201EFEE4008979E5 /* PBXTargetDependency */, 329 | ); 330 | name = ChoseGoodsTypeUITests; 331 | productName = ChoseGoodsTypeUITests; 332 | productReference = 7B873107201EFEE4008979E5 /* ChoseGoodsTypeUITests.xctest */; 333 | productType = "com.apple.product-type.bundle.ui-testing"; 334 | }; 335 | /* End PBXNativeTarget section */ 336 | 337 | /* Begin PBXProject section */ 338 | 7B8730DC201EFEE4008979E5 /* Project object */ = { 339 | isa = PBXProject; 340 | attributes = { 341 | LastUpgradeCheck = 0920; 342 | ORGANIZATIONNAME = "江萧"; 343 | TargetAttributes = { 344 | 7B8730E3201EFEE4008979E5 = { 345 | CreatedOnToolsVersion = 9.2; 346 | ProvisioningStyle = Automatic; 347 | }; 348 | 7B8730FB201EFEE4008979E5 = { 349 | CreatedOnToolsVersion = 9.2; 350 | ProvisioningStyle = Automatic; 351 | TestTargetID = 7B8730E3201EFEE4008979E5; 352 | }; 353 | 7B873106201EFEE4008979E5 = { 354 | CreatedOnToolsVersion = 9.2; 355 | ProvisioningStyle = Automatic; 356 | TestTargetID = 7B8730E3201EFEE4008979E5; 357 | }; 358 | }; 359 | }; 360 | buildConfigurationList = 7B8730DF201EFEE4008979E5 /* Build configuration list for PBXProject "ChoseGoodsType" */; 361 | compatibilityVersion = "Xcode 8.0"; 362 | developmentRegion = en; 363 | hasScannedForEncodings = 0; 364 | knownRegions = ( 365 | en, 366 | Base, 367 | ); 368 | mainGroup = 7B8730DB201EFEE4008979E5; 369 | productRefGroup = 7B8730E5201EFEE4008979E5 /* Products */; 370 | projectDirPath = ""; 371 | projectRoot = ""; 372 | targets = ( 373 | 7B8730E3201EFEE4008979E5 /* ChoseGoodsType */, 374 | 7B8730FB201EFEE4008979E5 /* ChoseGoodsTypeTests */, 375 | 7B873106201EFEE4008979E5 /* ChoseGoodsTypeUITests */, 376 | ); 377 | }; 378 | /* End PBXProject section */ 379 | 380 | /* Begin PBXResourcesBuildPhase section */ 381 | 7B8730E2201EFEE4008979E5 /* Resources */ = { 382 | isa = PBXResourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | 7B8731B1201F0419008979E5 /* SVProgressHUD.bundle in Resources */, 386 | 7B8730F1201EFEE4008979E5 /* Assets.xcassets in Resources */, 387 | 7B8731BF201F12BB008979E5 /* LaunchScreen.storyboard in Resources */, 388 | 7B40E6522021BCB000EC902A /* 3.jpg in Resources */, 389 | 7B8730EF201EFEE4008979E5 /* Main.storyboard in Resources */, 390 | 7B40E6552021BCB000EC902A /* 0.jpg in Resources */, 391 | 7B40E6542021BCB000EC902A /* 2.jpg in Resources */, 392 | 7B40E6532021BCB000EC902A /* 1.jpg in Resources */, 393 | ); 394 | runOnlyForDeploymentPostprocessing = 0; 395 | }; 396 | 7B8730FA201EFEE4008979E5 /* Resources */ = { 397 | isa = PBXResourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | ); 401 | runOnlyForDeploymentPostprocessing = 0; 402 | }; 403 | 7B873105201EFEE4008979E5 /* Resources */ = { 404 | isa = PBXResourcesBuildPhase; 405 | buildActionMask = 2147483647; 406 | files = ( 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | /* End PBXResourcesBuildPhase section */ 411 | 412 | /* Begin PBXSourcesBuildPhase section */ 413 | 7B8730E0201EFEE4008979E5 /* Sources */ = { 414 | isa = PBXSourcesBuildPhase; 415 | buildActionMask = 2147483647; 416 | files = ( 417 | 7B8731B9201F059C008979E5 /* GoodsPriceModel.m in Sources */, 418 | 7B2D0E342020243C00C4C26D /* GoodsInfoView.m in Sources */, 419 | 7B8730EC201EFEE4008979E5 /* ViewController.m in Sources */, 420 | 7B8730F7201EFEE4008979E5 /* main.m in Sources */, 421 | 7B8731B2201F0419008979E5 /* SVProgressHUD.m in Sources */, 422 | 7B8731B6201F0551008979E5 /* GoodsModel.m in Sources */, 423 | 7B8731B0201F0419008979E5 /* SVProgressAnimatedView.m in Sources */, 424 | 7B87312D201F028D008979E5 /* JXUIKit.m in Sources */, 425 | 7B873128201F00EA008979E5 /* ChoseGoodsTypeAlert.m in Sources */, 426 | 7B873127201F00EA008979E5 /* ChoosTypeTableViewCell.m in Sources */, 427 | 7B873126201F00EA008979E5 /* GoodsTypeModel.m in Sources */, 428 | 7B8731AD201F0419008979E5 /* UITableView+SDAutoTableViewCellHeight.m in Sources */, 429 | 7B8731AE201F0419008979E5 /* UIView+SDAutoLayout.m in Sources */, 430 | 7B8731AF201F0419008979E5 /* SVIndefiniteAnimatedView.m in Sources */, 431 | 7B8730E9201EFEE4008979E5 /* AppDelegate.m in Sources */, 432 | 7B8731BC201F05C5008979E5 /* SizeAttributeModel.m in Sources */, 433 | 7B873129201F00EA008979E5 /* CountView.m in Sources */, 434 | 7B8731B3201F0419008979E5 /* SVRadialGradientLayer.m in Sources */, 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | 7B8730F8201EFEE4008979E5 /* Sources */ = { 439 | isa = PBXSourcesBuildPhase; 440 | buildActionMask = 2147483647; 441 | files = ( 442 | 7B873101201EFEE4008979E5 /* ChoseGoodsTypeTests.m in Sources */, 443 | ); 444 | runOnlyForDeploymentPostprocessing = 0; 445 | }; 446 | 7B873103201EFEE4008979E5 /* Sources */ = { 447 | isa = PBXSourcesBuildPhase; 448 | buildActionMask = 2147483647; 449 | files = ( 450 | 7B87310C201EFEE4008979E5 /* ChoseGoodsTypeUITests.m in Sources */, 451 | ); 452 | runOnlyForDeploymentPostprocessing = 0; 453 | }; 454 | /* End PBXSourcesBuildPhase section */ 455 | 456 | /* Begin PBXTargetDependency section */ 457 | 7B8730FE201EFEE4008979E5 /* PBXTargetDependency */ = { 458 | isa = PBXTargetDependency; 459 | target = 7B8730E3201EFEE4008979E5 /* ChoseGoodsType */; 460 | targetProxy = 7B8730FD201EFEE4008979E5 /* PBXContainerItemProxy */; 461 | }; 462 | 7B873109201EFEE4008979E5 /* PBXTargetDependency */ = { 463 | isa = PBXTargetDependency; 464 | target = 7B8730E3201EFEE4008979E5 /* ChoseGoodsType */; 465 | targetProxy = 7B873108201EFEE4008979E5 /* PBXContainerItemProxy */; 466 | }; 467 | /* End PBXTargetDependency section */ 468 | 469 | /* Begin PBXVariantGroup section */ 470 | 7B8730ED201EFEE4008979E5 /* Main.storyboard */ = { 471 | isa = PBXVariantGroup; 472 | children = ( 473 | 7B8730EE201EFEE4008979E5 /* Base */, 474 | ); 475 | name = Main.storyboard; 476 | sourceTree = ""; 477 | }; 478 | /* End PBXVariantGroup section */ 479 | 480 | /* Begin XCBuildConfiguration section */ 481 | 7B87310E201EFEE4008979E5 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | ALWAYS_SEARCH_USER_PATHS = NO; 485 | CLANG_ANALYZER_NONNULL = YES; 486 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 487 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 488 | CLANG_CXX_LIBRARY = "libc++"; 489 | CLANG_ENABLE_MODULES = YES; 490 | CLANG_ENABLE_OBJC_ARC = YES; 491 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 492 | CLANG_WARN_BOOL_CONVERSION = YES; 493 | CLANG_WARN_COMMA = YES; 494 | CLANG_WARN_CONSTANT_CONVERSION = YES; 495 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 496 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 497 | CLANG_WARN_EMPTY_BODY = YES; 498 | CLANG_WARN_ENUM_CONVERSION = YES; 499 | CLANG_WARN_INFINITE_RECURSION = YES; 500 | CLANG_WARN_INT_CONVERSION = YES; 501 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 502 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 503 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 504 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 505 | CLANG_WARN_STRICT_PROTOTYPES = YES; 506 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 507 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 508 | CLANG_WARN_UNREACHABLE_CODE = YES; 509 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 510 | CODE_SIGN_IDENTITY = "iPhone Developer"; 511 | COPY_PHASE_STRIP = NO; 512 | DEBUG_INFORMATION_FORMAT = dwarf; 513 | ENABLE_STRICT_OBJC_MSGSEND = YES; 514 | ENABLE_TESTABILITY = YES; 515 | GCC_C_LANGUAGE_STANDARD = gnu11; 516 | GCC_DYNAMIC_NO_PIC = NO; 517 | GCC_NO_COMMON_BLOCKS = YES; 518 | GCC_OPTIMIZATION_LEVEL = 0; 519 | GCC_PREPROCESSOR_DEFINITIONS = ( 520 | "DEBUG=1", 521 | "$(inherited)", 522 | ); 523 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 524 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 525 | GCC_WARN_UNDECLARED_SELECTOR = YES; 526 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 527 | GCC_WARN_UNUSED_FUNCTION = YES; 528 | GCC_WARN_UNUSED_VARIABLE = YES; 529 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 530 | MTL_ENABLE_DEBUG_INFO = YES; 531 | ONLY_ACTIVE_ARCH = YES; 532 | SDKROOT = iphoneos; 533 | }; 534 | name = Debug; 535 | }; 536 | 7B87310F201EFEE4008979E5 /* Release */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | ALWAYS_SEARCH_USER_PATHS = NO; 540 | CLANG_ANALYZER_NONNULL = YES; 541 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 542 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 543 | CLANG_CXX_LIBRARY = "libc++"; 544 | CLANG_ENABLE_MODULES = YES; 545 | CLANG_ENABLE_OBJC_ARC = YES; 546 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 547 | CLANG_WARN_BOOL_CONVERSION = YES; 548 | CLANG_WARN_COMMA = YES; 549 | CLANG_WARN_CONSTANT_CONVERSION = YES; 550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 551 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 552 | CLANG_WARN_EMPTY_BODY = YES; 553 | CLANG_WARN_ENUM_CONVERSION = YES; 554 | CLANG_WARN_INFINITE_RECURSION = YES; 555 | CLANG_WARN_INT_CONVERSION = YES; 556 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 558 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 560 | CLANG_WARN_STRICT_PROTOTYPES = YES; 561 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 562 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 563 | CLANG_WARN_UNREACHABLE_CODE = YES; 564 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 565 | CODE_SIGN_IDENTITY = "iPhone Developer"; 566 | COPY_PHASE_STRIP = NO; 567 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 568 | ENABLE_NS_ASSERTIONS = NO; 569 | ENABLE_STRICT_OBJC_MSGSEND = YES; 570 | GCC_C_LANGUAGE_STANDARD = gnu11; 571 | GCC_NO_COMMON_BLOCKS = YES; 572 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 573 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 574 | GCC_WARN_UNDECLARED_SELECTOR = YES; 575 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 576 | GCC_WARN_UNUSED_FUNCTION = YES; 577 | GCC_WARN_UNUSED_VARIABLE = YES; 578 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 579 | MTL_ENABLE_DEBUG_INFO = NO; 580 | SDKROOT = iphoneos; 581 | VALIDATE_PRODUCT = YES; 582 | }; 583 | name = Release; 584 | }; 585 | 7B873111201EFEE4008979E5 /* Debug */ = { 586 | isa = XCBuildConfiguration; 587 | buildSettings = { 588 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 589 | CODE_SIGN_STYLE = Automatic; 590 | DEVELOPMENT_TEAM = C66SGFPXSJ; 591 | INFOPLIST_FILE = ChoseGoodsType/Info.plist; 592 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 593 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 594 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsType; 595 | PRODUCT_NAME = "$(TARGET_NAME)"; 596 | TARGETED_DEVICE_FAMILY = "1,2"; 597 | }; 598 | name = Debug; 599 | }; 600 | 7B873112201EFEE4008979E5 /* Release */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 604 | CODE_SIGN_STYLE = Automatic; 605 | DEVELOPMENT_TEAM = C66SGFPXSJ; 606 | INFOPLIST_FILE = ChoseGoodsType/Info.plist; 607 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 608 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 609 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsType; 610 | PRODUCT_NAME = "$(TARGET_NAME)"; 611 | TARGETED_DEVICE_FAMILY = "1,2"; 612 | }; 613 | name = Release; 614 | }; 615 | 7B873114201EFEE4008979E5 /* Debug */ = { 616 | isa = XCBuildConfiguration; 617 | buildSettings = { 618 | BUNDLE_LOADER = "$(TEST_HOST)"; 619 | CODE_SIGN_STYLE = Automatic; 620 | DEVELOPMENT_TEAM = C66SGFPXSJ; 621 | INFOPLIST_FILE = ChoseGoodsTypeTests/Info.plist; 622 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 623 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsTypeTests; 624 | PRODUCT_NAME = "$(TARGET_NAME)"; 625 | TARGETED_DEVICE_FAMILY = "1,2"; 626 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChoseGoodsType.app/ChoseGoodsType"; 627 | }; 628 | name = Debug; 629 | }; 630 | 7B873115201EFEE4008979E5 /* Release */ = { 631 | isa = XCBuildConfiguration; 632 | buildSettings = { 633 | BUNDLE_LOADER = "$(TEST_HOST)"; 634 | CODE_SIGN_STYLE = Automatic; 635 | DEVELOPMENT_TEAM = C66SGFPXSJ; 636 | INFOPLIST_FILE = ChoseGoodsTypeTests/Info.plist; 637 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 638 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsTypeTests; 639 | PRODUCT_NAME = "$(TARGET_NAME)"; 640 | TARGETED_DEVICE_FAMILY = "1,2"; 641 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChoseGoodsType.app/ChoseGoodsType"; 642 | }; 643 | name = Release; 644 | }; 645 | 7B873117201EFEE4008979E5 /* Debug */ = { 646 | isa = XCBuildConfiguration; 647 | buildSettings = { 648 | CODE_SIGN_STYLE = Automatic; 649 | DEVELOPMENT_TEAM = C66SGFPXSJ; 650 | INFOPLIST_FILE = ChoseGoodsTypeUITests/Info.plist; 651 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 652 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsTypeUITests; 653 | PRODUCT_NAME = "$(TARGET_NAME)"; 654 | TARGETED_DEVICE_FAMILY = "1,2"; 655 | TEST_TARGET_NAME = ChoseGoodsType; 656 | }; 657 | name = Debug; 658 | }; 659 | 7B873118201EFEE4008979E5 /* Release */ = { 660 | isa = XCBuildConfiguration; 661 | buildSettings = { 662 | CODE_SIGN_STYLE = Automatic; 663 | DEVELOPMENT_TEAM = C66SGFPXSJ; 664 | INFOPLIST_FILE = ChoseGoodsTypeUITests/Info.plist; 665 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 666 | PRODUCT_BUNDLE_IDENTIFIER = com.lhla.ChoseGoodsTypeUITests; 667 | PRODUCT_NAME = "$(TARGET_NAME)"; 668 | TARGETED_DEVICE_FAMILY = "1,2"; 669 | TEST_TARGET_NAME = ChoseGoodsType; 670 | }; 671 | name = Release; 672 | }; 673 | /* End XCBuildConfiguration section */ 674 | 675 | /* Begin XCConfigurationList section */ 676 | 7B8730DF201EFEE4008979E5 /* Build configuration list for PBXProject "ChoseGoodsType" */ = { 677 | isa = XCConfigurationList; 678 | buildConfigurations = ( 679 | 7B87310E201EFEE4008979E5 /* Debug */, 680 | 7B87310F201EFEE4008979E5 /* Release */, 681 | ); 682 | defaultConfigurationIsVisible = 0; 683 | defaultConfigurationName = Release; 684 | }; 685 | 7B873110201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsType" */ = { 686 | isa = XCConfigurationList; 687 | buildConfigurations = ( 688 | 7B873111201EFEE4008979E5 /* Debug */, 689 | 7B873112201EFEE4008979E5 /* Release */, 690 | ); 691 | defaultConfigurationIsVisible = 0; 692 | defaultConfigurationName = Release; 693 | }; 694 | 7B873113201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsTypeTests" */ = { 695 | isa = XCConfigurationList; 696 | buildConfigurations = ( 697 | 7B873114201EFEE4008979E5 /* Debug */, 698 | 7B873115201EFEE4008979E5 /* Release */, 699 | ); 700 | defaultConfigurationIsVisible = 0; 701 | defaultConfigurationName = Release; 702 | }; 703 | 7B873116201EFEE4008979E5 /* Build configuration list for PBXNativeTarget "ChoseGoodsTypeUITests" */ = { 704 | isa = XCConfigurationList; 705 | buildConfigurations = ( 706 | 7B873117201EFEE4008979E5 /* Debug */, 707 | 7B873118201EFEE4008979E5 /* Release */, 708 | ); 709 | defaultConfigurationIsVisible = 0; 710 | defaultConfigurationName = Release; 711 | }; 712 | /* End XCConfigurationList section */ 713 | }; 714 | rootObject = 7B8730DC201EFEE4008979E5 /* Project object */; 715 | } 716 | -------------------------------------------------------------------------------- /ChoseGoodsType.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ChoseGoodsType.xcodeproj/project.xcworkspace/xcuserdata/lanaohudong.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType.xcodeproj/project.xcworkspace/xcuserdata/lanaohudong.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ChoseGoodsType.xcodeproj/xcuserdata/lanaohudong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ChoseGoodsType.xcodeproj/xcuserdata/lanaohudong.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ChoseGoodsType.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ChoseGoodsType/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/0.jpg -------------------------------------------------------------------------------- /ChoseGoodsType/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/1.jpg -------------------------------------------------------------------------------- /ChoseGoodsType/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/2.jpg -------------------------------------------------------------------------------- /ChoseGoodsType/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/3.jpg -------------------------------------------------------------------------------- /ChoseGoodsType/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. 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 | -------------------------------------------------------------------------------- /ChoseGoodsType/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. 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 | -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/guanbi.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "guanbi@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "guanbi@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/guanbi.imageset/guanbi@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/Assets.xcassets/guanbi.imageset/guanbi@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/guanbi.imageset/guanbi@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/Assets.xcassets/guanbi.imageset/guanbi@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/jiantou_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jiantou_down@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jiantou_down@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/jiantou_down.imageset/jiantou_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/Assets.xcassets/jiantou_down.imageset/jiantou_down@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/Assets.xcassets/jiantou_down.imageset/jiantou_down@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/Assets.xcassets/jiantou_down.imageset/jiantou_down@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/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 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ChoseGoodsType/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 | -------------------------------------------------------------------------------- /ChoseGoodsType/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 | -------------------------------------------------------------------------------- /ChoseGoodsType/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ChoseGoodsType/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ChoseGoodsTypeAlert.h" 11 | #import "SizeAttributeModel.h" 12 | #import "GoodsTypeModel.h" 13 | #import "Header.h" 14 | @interface ViewController () 15 | { 16 | GoodsModel *model; 17 | } 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view, typically from a nib. 25 | model = [[GoodsModel alloc] init]; 26 | model.imageId = @"1.jpg"; 27 | model.goodsNo = @"商品名"; 28 | model.title = @"商品标题"; 29 | model.totalStock = @"100"; 30 | //价格信息 31 | model.price = [[GoodsPriceModel alloc] init]; 32 | model.price.minPrice = @"150"; 33 | model.price.maxPrice = @"158"; 34 | model.price.minOriginalPrice = @"155"; 35 | model.price.maxOriginalPrice = @"160"; 36 | //属性-应该从服务器获取属性列表 37 | GoodsTypeModel *type = [[GoodsTypeModel alloc] init]; 38 | type.selectIndex = -1; 39 | type.typeName = @"尺码"; 40 | type.typeArray = @[@"XL",@"XXL"]; 41 | 42 | 43 | GoodsTypeModel *type2 = [[GoodsTypeModel alloc] init]; 44 | type2.selectIndex = -1; 45 | type2.typeName = @"颜色"; 46 | type2.typeArray = @[@"黑色",@"白色"]; 47 | 48 | 49 | GoodsTypeModel *type3 = [[GoodsTypeModel alloc] init]; 50 | type3.selectIndex = -1; 51 | type3.typeName = @"日期"; 52 | type3.typeArray = @[@"2016",@"2017",@"2018"]; 53 | 54 | model.itemsList = @[type,type2,type3]; 55 | 56 | //属性组合数组-有时候不同的属性组合价格库存都会有差异,选择完之后要对应修改商品的价格、库存图片等信息,可能是获得商品信息时将属性数组一并返回,也可能属性选择后再请求服务器获得属性组合对应的商品信息,根据自己的实际情况调整 57 | model.sizeAttribute = [[NSMutableArray alloc] init]; 58 | NSArray *valueArr = @[@"XL、黑色、2016",@"XXL、黑色、2016",@"XL、白色、2016",@"XXL、白色、2016",@"XL、黑色、2017",@"XXL、黑色、2017",@"XL、白色、2017",@"XXL、白色、2017",@"XL、黑色、2018",@"XXL、黑色、2018",@"XL、白色、2018",@"XXL、白色、2018"]; 59 | for (int i = 0; i 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 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SDAutoLayout/SDAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDAutoLayout.h 3 | // SDAutoLayoutDemo 4 | // 5 | // Created by gsd on 16/6/27. 6 | // Copyright © 2016年 gsd. All rights reserved. 7 | // 8 | 9 | 10 | /* 11 | 12 | SDAutoLayout 13 | 版本:2.1.7 14 | 发布:2016.08.12 15 | 16 | */ 17 | 18 | #ifndef SDAutoLayout_h 19 | #define SDAutoLayout_h 20 | 21 | #import "UIView+SDAutoLayout.h" 22 | #import "UITableView+SDAutoTableViewCellHeight.h" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+SDAutoTableViewCellHeight.h 3 | // SDAutoLayout 测试 Demo 4 | // 5 | // Created by aier on 15/11/1. 6 | // Copyright © 2015年 gsd. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | ********************************************************************************* 12 | * * 13 | * 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 * 14 | * 帮您解决问题。 * 15 | * QQ : 2689718696(gsdios) * 16 | * Email : gsdios@126.com * 17 | * GitHub: https://github.com/gsdios * 18 | * 新浪微博:GSD_iOS * 19 | * * 20 | ********************************************************************************* 21 | 22 | */ 23 | 24 | 25 | 26 | 27 | /* 28 | PS:cell高度自适应前提>>应该调用cell的“- (void)setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法进行cell的自动高度设置 29 | */ 30 | 31 | #import 32 | 33 | #import "UIView+SDAutoLayout.h" 34 | 35 | @class SDCellAutoHeightManager; 36 | 37 | typedef void (^AutoCellHeightDataSettingBlock)(UITableViewCell *cell); 38 | 39 | #define kSDModelCellTag 199206 40 | 41 | 42 | 43 | #pragma mark - UITableView 方法,返回自动计算出的cell高度 44 | 45 | @interface UITableView (SDAutoTableViewCellHeight) 46 | 47 | @property (nonatomic, strong) SDCellAutoHeightManager *cellAutoHeightManager; 48 | 49 | 50 | /** 51 | * 返回计算出的cell高度(普通简化版方法,同样只需一步设置即可完成)(用法:单cell详见demo5,多cell详见demo7) 52 | * model : cell的数据模型实例 53 | * keyPath : cell的数据模型属性的属性名字符串(即kvc原理中的key) 54 | * cellClass : 当前的indexPath对应的cell的class 55 | * contentViewWidth : cell的contentView的宽度 56 | */ 57 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass contentViewWidth:(CGFloat)contentViewWidth; 58 | 59 | /** 60 | * 返回计算出的cell高度(普通简化版方法,同样只需一步设置即可完成)(用法:见DemoVC14) 61 | * cellClass : 当前的indexPath对应的cell的class 62 | * contentViewWidth : cell的contentView的宽度 63 | * cellDataSetting : 设置cell数据的block 64 | */ 65 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellClass:(Class)cellClass cellContentViewWidth:(CGFloat)width cellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting; 66 | 67 | /** 刷新tableView但不清空之前已经计算好的高度缓存,用于直接将新数据拼接在旧数据之后的tableView刷新 */ 68 | - (void)reloadDataWithExistedHeightCache; 69 | 70 | /** 刷新tableView同时调整已经计算好的高度缓存,用于直接将新数据插在旧数据前面的tableView的刷新 */ 71 | - (void)reloadDataWithInsertingDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count; 72 | 73 | /** 74 | * 刷新tableView同时调整已经计算好的高度缓存,用于直接将新数据插在旧数据前面的tableView的刷新(用于刷新多个section) 75 | * sectionNumsArray : 要刷新的所有section序号组成的数组, 例@[@(0), @(1)] 76 | * dataCountsArray : 每个section的数据条数组成的数组, 例@[@(20), @(10)] 77 | */ 78 | - (void)reloadDataWithInsertingDataAtTheBeginingOfSections:(NSArray *)sectionNumsArray newDataCounts:(NSArray *)dataCountsArray; 79 | 80 | /** 返回所有cell的高度总和 */ 81 | - (CGFloat)cellsTotalHeight; 82 | 83 | @property (nonatomic, copy) AutoCellHeightDataSettingBlock cellDataSetting; 84 | 85 | @end 86 | 87 | 88 | 89 | 90 | #pragma mark - UITableViewController 方法,返回自动计算出的cell高度 91 | 92 | @interface UITableViewController (SDTableViewControllerAutoCellHeight) 93 | 94 | /** (UITableViewController方法)升级版!一行代码(一步设置)搞定tableview的cell高度自适应,同时适用于单cell和多cell,性能比普通版稍微差一些,不建议在数据量大的tableview中使用 */ 95 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width; 96 | 97 | @end 98 | 99 | 100 | 101 | #pragma mark - NSObject 方法,返回自动计算出的cell高度 102 | 103 | @interface NSObject (SDAnyObjectAutoCellHeight) 104 | 105 | /** (NSObject方法)升级版!一行代码(一步设置)搞定tableview的cell高度自适应,同时适用于单cell和多cell,性能比普通版稍微差一些,不建议在数据量大的tableview中使用 */ 106 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width tableView:(UITableView *)tableView; 107 | 108 | @end 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | // ------------------------------- 以下为库内部使用无须了解 -------------------- 127 | 128 | @interface SDCellAutoHeightManager : NSObject 129 | 130 | @property (nonatomic, assign) BOOL shouldKeepHeightCacheWhenReloadingData; 131 | 132 | @property (nonatomic, assign) CGFloat contentViewWidth; 133 | 134 | @property (nonatomic, assign) Class cellClass; 135 | 136 | @property (nonatomic, assign) CGFloat cellHeight; 137 | 138 | @property (nonatomic, strong) UITableViewCell *modelCell; 139 | 140 | @property (nonatomic, strong) NSMutableDictionary *subviewFrameCacheDict; 141 | 142 | @property (nonatomic, strong, readonly) NSDictionary *heightCacheDict; 143 | 144 | @property (nonatomic, copy) AutoCellHeightDataSettingBlock cellDataSetting; 145 | 146 | - (void)clearHeightCache; 147 | 148 | - (void)clearHeightCacheOfIndexPaths:(NSArray *)indexPaths; 149 | 150 | - (void)deleteThenResetHeightCache:(NSIndexPath *)indexPathToDelete; 151 | 152 | - (void)insertNewDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count; 153 | 154 | - (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths; 155 | 156 | - (NSNumber *)heightCacheForIndexPath:(NSIndexPath *)indexPath; 157 | 158 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath; 159 | 160 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass; 161 | 162 | 163 | - (NSMutableArray *)subviewFrameCachesWithIndexPath:(NSIndexPath *)indexPath;; 164 | - (void)setSubviewFrameCache:(CGRect)rect WithIndexPath:(NSIndexPath *)indexPath; 165 | 166 | - (instancetype)initWithCellClass:(Class)cellClass tableView:(UITableView *)tableView; 167 | + (instancetype)managerWithCellClass:(Class)cellClass tableView:(UITableView *)tableView; 168 | @end 169 | 170 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SDAutoLayout/UITableView+SDAutoTableViewCellHeight.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableView+SDAutoTableViewCellHeight.m 3 | // SDAutoLayout 测试 Demo 4 | // 5 | // Created by aier on 15/11/1. 6 | // Copyright © 2015年 gsd. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | ********************************************************************************* 12 | * * 13 | * 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 * 14 | * 帮您解决问题。 * 15 | * QQ : 2689718696(gsdios) * 16 | * Email : gsdios@126.com * 17 | * GitHub: https://github.com/gsdios * 18 | * 新浪微博:GSD_iOS * 19 | * * 20 | ********************************************************************************* 21 | 22 | */ 23 | 24 | #import "UITableView+SDAutoTableViewCellHeight.h" 25 | #import 26 | 27 | @interface SDCellAutoHeightManager () 28 | 29 | @property (nonatomic, weak) UITableView *modelTableview; 30 | 31 | @end 32 | 33 | @implementation SDCellAutoHeightManager 34 | { 35 | NSMutableDictionary *_cacheDictionary; 36 | NSMutableDictionary *_modelCellsDict; 37 | } 38 | 39 | - (instancetype)init 40 | { 41 | if (self = [super init]) { 42 | [self setup]; 43 | } 44 | return self; 45 | } 46 | 47 | - (instancetype)initWithCellClass:(Class)cellClass tableView:(UITableView *)tableView 48 | { 49 | if (self = [super init]) { 50 | [self setup]; 51 | self.modelTableview = tableView; 52 | [self registerCellWithCellClass:cellClass]; 53 | } 54 | return self; 55 | } 56 | 57 | - (instancetype)initWithCellClasses:(NSArray *)cellClassArray tableView:(UITableView *)tableView 58 | { 59 | if (self = [super init]) { 60 | [self setup]; 61 | self.modelTableview = tableView; 62 | [cellClassArray enumerateObjectsUsingBlock:^(Class obj, NSUInteger idx, BOOL *stop) { 63 | [self registerCellWithCellClass:obj]; 64 | }]; 65 | } 66 | return self; 67 | } 68 | 69 | - (void)setup 70 | { 71 | _cacheDictionary = [NSMutableDictionary new]; 72 | _modelCellsDict = [NSMutableDictionary new]; 73 | } 74 | 75 | - (void)registerCellWithCellClass:(Class)cellClass 76 | { 77 | [_modelTableview registerClass:cellClass forCellReuseIdentifier:NSStringFromClass(cellClass)]; 78 | self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)]; 79 | 80 | if (!self.modelCell.contentView.subviews.count) { 81 | NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@.nib", NSStringFromClass(cellClass)] ofType:nil]; 82 | if (path) { 83 | self.modelCell = nil; 84 | [_modelTableview registerNib:[UINib nibWithNibName:NSStringFromClass(cellClass) bundle:nil] forCellReuseIdentifier:NSStringFromClass(cellClass)]; 85 | self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)]; 86 | } 87 | } 88 | if (self.modelCell) { 89 | [_modelCellsDict setObject:self.modelCell forKey:NSStringFromClass(cellClass)]; 90 | } 91 | } 92 | 93 | + (instancetype)managerWithCellClass:(Class)cellClass tableView:(UITableView *)tableView 94 | { 95 | SDCellAutoHeightManager *manager = [[self alloc] initWithCellClass:cellClass tableView:tableView]; 96 | return manager; 97 | } 98 | 99 | - (UITableViewCell *)modelCell 100 | { 101 | if (_modelCell.contentView.tag != kSDModelCellTag) { 102 | _modelCell.contentView.tag = kSDModelCellTag; 103 | } 104 | return _modelCell; 105 | } 106 | 107 | - (NSDictionary *)heightCacheDict 108 | { 109 | return _cacheDictionary; 110 | } 111 | 112 | - (void)clearHeightCache 113 | { 114 | [_cacheDictionary removeAllObjects]; 115 | [_subviewFrameCacheDict removeAllObjects]; 116 | } 117 | 118 | - (NSString *)cacheKeyForIndexPath:(NSIndexPath *)indexPath 119 | { 120 | return [NSString stringWithFormat:@"%ld-%ld", (long)indexPath.section, (long)indexPath.row]; 121 | } 122 | 123 | - (void)clearHeightCacheOfIndexPaths:(NSArray *)indexPaths 124 | { 125 | [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) { 126 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPath]; 127 | [_cacheDictionary removeObjectForKey:cacheKey]; 128 | [_subviewFrameCacheDict removeObjectForKey:cacheKey]; 129 | }]; 130 | } 131 | 132 | - (void)deleteThenResetHeightCache:(NSIndexPath *)indexPathToDelete 133 | { 134 | 135 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPathToDelete]; 136 | [_cacheDictionary removeObjectForKey:cacheKey]; 137 | [_subviewFrameCacheDict removeObjectForKey:cacheKey]; 138 | 139 | long sectionOfToDeleteItem = indexPathToDelete.section; 140 | long rowOfToDeleteItem = indexPathToDelete.row; 141 | NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new]; 142 | NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new]; 143 | for (NSString *key in _cacheDictionary.allKeys) { 144 | NSArray *res = [key componentsSeparatedByString:@"-"]; 145 | long section = [res.firstObject integerValue]; 146 | long row = [res.lastObject integerValue]; 147 | if (section == sectionOfToDeleteItem && row > rowOfToDeleteItem) { 148 | NSNumber *heightCache = _cacheDictionary[key]; 149 | NSArray *frameCache = _subviewFrameCacheDict[key]; 150 | NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", section, (row - 1)]; 151 | [tempHeightCacheDict setValue:heightCache forKey:newKey]; 152 | [tempFrameCacheDict setValue:frameCache forKey:newKey]; 153 | [_cacheDictionary removeObjectForKey:key]; 154 | [_subviewFrameCacheDict removeObjectForKey:key]; 155 | } 156 | } 157 | [_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict]; 158 | [_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict]; 159 | 160 | } 161 | 162 | - (void)insertNewDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count 163 | { 164 | NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new]; 165 | NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new]; 166 | for (NSString *key in _cacheDictionary.allKeys) { 167 | NSArray *res = [key componentsSeparatedByString:@"-"]; 168 | long originalSection = [res.firstObject integerValue]; 169 | long row = [res.lastObject integerValue]; 170 | if (originalSection == section) { 171 | NSNumber *heightCache = _cacheDictionary[key]; 172 | NSArray *frameCache = _subviewFrameCacheDict[key]; 173 | NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", originalSection, (row + count)]; 174 | [tempHeightCacheDict setValue:heightCache forKey:newKey]; 175 | [tempFrameCacheDict setValue:frameCache forKey:newKey]; 176 | [_cacheDictionary removeObjectForKey:key]; 177 | [_subviewFrameCacheDict removeObjectForKey:key]; 178 | } 179 | } 180 | [_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict]; 181 | [_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict]; 182 | } 183 | 184 | - (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths 185 | { 186 | NSMutableDictionary *sectionsdict = [NSMutableDictionary new]; 187 | for (NSIndexPath *indexPath in indexPaths) { 188 | NSString *sectionkey = [@(indexPath.section) stringValue]; 189 | if (![sectionsdict objectForKey:sectionkey]) { 190 | [sectionsdict setValue:[NSMutableArray new] forKey:sectionkey]; 191 | } 192 | NSMutableArray *arr = sectionsdict[sectionkey]; 193 | [arr addObject:indexPath]; 194 | } 195 | for (NSString *sectionkey in sectionsdict.allKeys) { 196 | NSMutableArray *tempHeightCaches = [NSMutableArray new]; 197 | NSMutableArray *tempFrameCaches = [NSMutableArray new]; 198 | NSInteger section = [sectionkey integerValue]; 199 | NSInteger rowCount = [self.modelTableview numberOfRowsInSection:section]; 200 | if (rowCount <= 0) { 201 | continue; 202 | } else { 203 | for (int i = 0; i < rowCount; i++) { 204 | [tempHeightCaches addObject:[NSNull null]]; 205 | [tempFrameCaches addObject:[NSNull null]]; 206 | } 207 | } 208 | 209 | for (NSString *key in _cacheDictionary.allKeys) { 210 | NSArray *res = [key componentsSeparatedByString:@"-"]; 211 | long originalSection = [res.firstObject integerValue]; 212 | long row = [res.lastObject integerValue]; 213 | if (originalSection == section) { 214 | NSNumber *heightCache = _cacheDictionary[key]; 215 | NSArray *frameCache = _subviewFrameCacheDict[key]; 216 | [tempHeightCaches setObject:heightCache atIndexedSubscript:row]; 217 | [tempFrameCaches setObject:frameCache atIndexedSubscript:row]; 218 | [_cacheDictionary removeObjectForKey:key]; 219 | [_subviewFrameCacheDict removeObjectForKey:key]; 220 | } 221 | } 222 | NSMutableArray *objsToInsert = [NSMutableArray new]; 223 | NSMutableIndexSet *indexSet = [NSMutableIndexSet new]; 224 | NSArray *indexPaths = sectionsdict[sectionkey]; 225 | [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *obj, NSUInteger idx, BOOL *stop) { 226 | [objsToInsert addObject:[NSNull null]]; 227 | [indexSet addIndex:obj.row]; 228 | }]; 229 | [tempHeightCaches insertObjects:objsToInsert atIndexes:indexSet]; 230 | [tempFrameCaches insertObjects:objsToInsert atIndexes:indexSet]; 231 | [tempHeightCaches enumerateObjectsUsingBlock:^(NSNumber *heightCache, NSUInteger idx, BOOL *stop) { 232 | if (![heightCache isKindOfClass:[NSNull class]]) { 233 | NSString *key = [NSString stringWithFormat:@"%zd-%zd", section, idx]; 234 | [_cacheDictionary setValue:heightCache forKey:key]; 235 | [_subviewFrameCacheDict setValue:[tempFrameCaches objectAtIndex:idx] forKey:key]; 236 | } 237 | }]; 238 | } 239 | } 240 | 241 | - (NSNumber *)heightCacheForIndexPath:(NSIndexPath *)indexPath 242 | { 243 | /* 244 | 如果程序卡在了这里很可能是由于你用了“dequeueReusableCellWithIdentifier:forIndexPath:”方法来重用cell,换成““dequeueReusableCellWithIdentifier:”(不带IndexPath)方法即可解决 245 | */ 246 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPath]; 247 | return (NSNumber *)[_cacheDictionary objectForKey:cacheKey]; 248 | } 249 | 250 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath 251 | { 252 | 253 | NSNumber *cacheHeight = [self heightCacheForIndexPath:indexPath]; 254 | if (cacheHeight) { 255 | return [cacheHeight floatValue]; 256 | } else { 257 | if (!self.modelCell) { 258 | return 0; 259 | } 260 | 261 | if (self.modelTableview && self.modelTableview != self.modelCell.sd_tableView) { 262 | self.modelCell.sd_tableView = self.modelTableview; 263 | } 264 | self.modelCell.sd_indexPath = indexPath; 265 | 266 | if (model && keyPath) { 267 | [self.modelCell setValue:model forKey:keyPath]; 268 | } else if (self.cellDataSetting) { 269 | self.cellDataSetting(self.modelCell); 270 | } 271 | 272 | 273 | #ifdef SDDebugWithAssert 274 | /* 275 | 如果程序卡在了这里说明你的cell还没有调用“setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法或者你传递的bottomView为nil,请检查并修改。例: 276 | 277 | //注意:bottomView不能为nil 278 | [cell setupAutoHeightWithBottomView:bottomView bottomMargin:bottomMargin]; 279 | */ 280 | NSAssert(self.modelCell.sd_bottomViewsArray.count, @">>>>>> 你的cell还没有调用“setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法或者你传递的bottomView为nil,请检查并修改"); 281 | 282 | #endif 283 | 284 | [self.modelCell.contentView layoutSubviews]; 285 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPath]; 286 | [_cacheDictionary setObject:@(self.modelCell.autoHeight) forKey:cacheKey]; 287 | 288 | 289 | if (self.modelCell.sd_indexPath && self.modelCell.sd_tableView) { 290 | if (self.modelCell.contentView.shouldReadjustFrameBeforeStoreCache) { 291 | self.modelCell.contentView.height_sd = self.modelCell.autoHeight; 292 | [self.modelCell.contentView layoutSubviews]; 293 | } 294 | [self.modelCell.contentView.autoLayoutModelsArray enumerateObjectsUsingBlock:^(SDAutoLayoutModel *model, NSUInteger idx, BOOL *stop) { 295 | [self.modelTableview.cellAutoHeightManager setSubviewFrameCache:model.needsAutoResizeView.frame WithIndexPath:self.modelCell.sd_indexPath]; 296 | }]; 297 | } 298 | 299 | 300 | return self.modelCell.autoHeight; 301 | } 302 | } 303 | 304 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass 305 | { 306 | if (![self.modelCell isKindOfClass:cellClass]) { 307 | self.modelCell = nil; 308 | self.modelCell = [_modelCellsDict objectForKey:NSStringFromClass(cellClass)]; 309 | if (!self.modelCell) { 310 | [self registerCellWithCellClass:cellClass]; 311 | } 312 | _modelCell.contentView.tag = kSDModelCellTag; 313 | } 314 | if (self.modelCell.contentView.width_sd != self.contentViewWidth) { 315 | _modelCell.contentView.width_sd = self.contentViewWidth; 316 | } 317 | return [self cellHeightForIndexPath:indexPath model:model keyPath:keyPath]; 318 | } 319 | 320 | - (void)setContentViewWidth:(CGFloat)contentViewWidth 321 | { 322 | if (_contentViewWidth == contentViewWidth) return; 323 | 324 | CGFloat lastContentViewWidth = _contentViewWidth; 325 | _contentViewWidth = contentViewWidth; 326 | 327 | self.modelCell.contentView.width_sd = self.contentViewWidth; 328 | 329 | if (lastContentViewWidth > 0) { 330 | [_subviewFrameCacheDict removeAllObjects]; 331 | dispatch_async(dispatch_get_main_queue(), ^{ 332 | [self clearHeightCache]; 333 | [self.modelTableview reloadData]; 334 | }); 335 | } 336 | } 337 | 338 | 339 | - (void)setSubviewFrameCache:(CGRect)rect WithIndexPath:(NSIndexPath *)indexPath 340 | { 341 | if (!self.subviewFrameCacheDict) { 342 | self.subviewFrameCacheDict = [NSMutableDictionary new]; 343 | } 344 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPath]; 345 | NSMutableArray *caches = [self.subviewFrameCacheDict objectForKey:cacheKey]; 346 | if (!caches) { 347 | caches = [NSMutableArray new]; 348 | [self.subviewFrameCacheDict setValue:caches forKey:cacheKey]; 349 | } 350 | [caches addObject:[NSValue valueWithCGRect:rect]]; 351 | } 352 | 353 | - (NSMutableArray *)subviewFrameCachesWithIndexPath:(NSIndexPath *)indexPath 354 | { 355 | NSString *cacheKey = [self cacheKeyForIndexPath:indexPath]; 356 | return [self.subviewFrameCacheDict valueForKey:cacheKey]; 357 | } 358 | 359 | @end 360 | 361 | 362 | @implementation UITableView (SDAutoTableViewCellHeight) 363 | 364 | + (void)load { 365 | static dispatch_once_t onceToken; 366 | dispatch_once(&onceToken, ^{ 367 | 368 | NSArray *selStringsArray = @[@"reloadData", @"reloadRowsAtIndexPaths:withRowAnimation:", @"deleteRowsAtIndexPaths:withRowAnimation:", @"insertRowsAtIndexPaths:withRowAnimation:"]; 369 | 370 | [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) { 371 | NSString *mySelString = [@"sd_" stringByAppendingString:selString]; 372 | 373 | Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString)); 374 | Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(mySelString)); 375 | method_exchangeImplementations(originalMethod, myMethod); 376 | }]; 377 | }); 378 | } 379 | 380 | - (void)sd_reloadData 381 | { 382 | if (!self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData) { 383 | [self.cellAutoHeightManager clearHeightCache]; 384 | } 385 | [self sd_reloadData]; 386 | self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = NO; 387 | } 388 | 389 | - (void)sd_reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 390 | { 391 | [self.cellAutoHeightManager clearHeightCacheOfIndexPaths:indexPaths]; 392 | [self sd_reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 393 | } 394 | 395 | - (void)sd_deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 396 | { 397 | for (NSIndexPath *indexPath in indexPaths) { 398 | [self.cellAutoHeightManager deleteThenResetHeightCache:indexPath]; 399 | } 400 | [self sd_deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 401 | } 402 | 403 | 404 | - (void)sd_insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 405 | { 406 | [self.cellAutoHeightManager insertNewDataAtIndexPaths:indexPaths]; 407 | [self sd_insertRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 408 | } 409 | 410 | /* 411 | * 下一步即将实现的功能 412 | 413 | - (void)sd_moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath 414 | { 415 | [self sd_moveRowAtIndexPath:indexPath toIndexPath:newIndexPath]; 416 | } 417 | 418 | */ 419 | 420 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass contentViewWidth:(CGFloat)contentViewWidth 421 | { 422 | self.cellAutoHeightManager.modelTableview = self; 423 | 424 | self.cellAutoHeightManager.contentViewWidth = contentViewWidth; 425 | 426 | return [self.cellAutoHeightManager cellHeightForIndexPath:indexPath model:model keyPath:keyPath cellClass:cellClass]; 427 | } 428 | 429 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellClass:(__unsafe_unretained Class)cellClass cellContentViewWidth:(CGFloat)width cellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting 430 | { 431 | 432 | self.cellDataSetting = cellDataSetting; 433 | 434 | return [self cellHeightForIndexPath:indexPath model:nil keyPath:nil cellClass:cellClass contentViewWidth:width]; 435 | } 436 | 437 | - (void)reloadDataWithExistedHeightCache 438 | { 439 | self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES; 440 | [self reloadData]; 441 | } 442 | 443 | - (void)reloadDataWithInsertingDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count 444 | { 445 | self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES; 446 | [self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:count]; 447 | [self reloadData]; 448 | } 449 | 450 | - (void)reloadDataWithInsertingDataAtTheBeginingOfSections:(NSArray *)sectionNumsArray newDataCounts:(NSArray *)dataCountsArray 451 | { 452 | self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES; 453 | [sectionNumsArray enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) { 454 | int section = [num intValue]; 455 | int dataCountForSection = [dataCountsArray[idx] intValue]; 456 | [self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:dataCountForSection]; 457 | }]; 458 | [self reloadData]; 459 | } 460 | 461 | - (CGFloat)cellsTotalHeight 462 | { 463 | CGFloat h = 0; 464 | if (!self.cellAutoHeightManager.heightCacheDict.count) { 465 | [self reloadData]; 466 | } 467 | NSArray *values = [self.cellAutoHeightManager.heightCacheDict allValues]; 468 | for (NSNumber *number in values) { 469 | h += [number floatValue]; 470 | } 471 | return h; 472 | } 473 | 474 | - (SDCellAutoHeightManager *)cellAutoHeightManager 475 | { 476 | 477 | SDCellAutoHeightManager *cellAutoHeightManager = objc_getAssociatedObject(self, _cmd); 478 | 479 | if (!cellAutoHeightManager) { 480 | 481 | cellAutoHeightManager = [[SDCellAutoHeightManager alloc] init]; 482 | 483 | [self setCellAutoHeightManager:cellAutoHeightManager]; 484 | } 485 | 486 | return cellAutoHeightManager; 487 | } 488 | 489 | - (void)setCellAutoHeightManager:(SDCellAutoHeightManager *)cellAutoHeightManager 490 | { 491 | objc_setAssociatedObject(self, @selector(cellAutoHeightManager), cellAutoHeightManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 492 | } 493 | 494 | - (void)setCellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting 495 | { 496 | self.cellAutoHeightManager.cellDataSetting = cellDataSetting; 497 | } 498 | 499 | - (AutoCellHeightDataSettingBlock)cellDataSetting 500 | { 501 | return self.cellAutoHeightManager.cellDataSetting; 502 | } 503 | 504 | @end 505 | 506 | 507 | @implementation UITableViewController (SDTableViewControllerAutoCellHeight) 508 | 509 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width 510 | { 511 | return [self cellHeightForIndexPath:indexPath cellContentViewWidth:width tableView:self.tableView]; 512 | } 513 | 514 | @end 515 | 516 | @implementation NSObject (SDAnyObjectAutoCellHeight) 517 | 518 | - (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width tableView:(UITableView *)tableView 519 | { 520 | tableView.cellAutoHeightManager.modelTableview = tableView; 521 | 522 | if (tableView.cellAutoHeightManager.contentViewWidth != width) { 523 | tableView.cellAutoHeightManager.contentViewWidth = width; 524 | } 525 | if ([tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath]) { 526 | return [[tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath] floatValue]; 527 | } 528 | UITableViewCell *cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath]; 529 | tableView.cellAutoHeightManager.modelCell = cell; 530 | if (cell.contentView.width_sd != width) { 531 | cell.contentView.width_sd = width; 532 | } 533 | return [[tableView cellAutoHeightManager] cellHeightForIndexPath:indexPath model:nil keyPath:nil]; 534 | } 535 | 536 | @end 537 | 538 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SDAutoLayout/UIView+SDAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SDAutoLayout.h 3 | // 4 | // Created by gsd on 15/10/6. 5 | // Copyright (c) 2015年 gsd. All rights reserved. 6 | // 7 | 8 | /* 9 | ************************************************************************* 10 | 11 | --------- INTRODUCTION --------- 12 | 13 | USAGE: 14 | 15 | MODE 1. >>>>>>>>>>>>>>> You can use it in this way: 16 | 17 | Demo.sd_layout 18 | .topSpaceToView(v1, 100) 19 | .bottomSpaceToView(v3, 100) 20 | .leftSpaceToView(v0, 150) 21 | .rightSpaceToView(v2, 150); 22 | 23 | MODE 2. >>>>>>>>>>>>>>> You can also use it in this way that is more brevity: 24 | 25 | Demo.sd_layout.topSpaceToView(v1, 100).bottomSpaceToView(v3, 100).leftSpaceToView(v0, 150).rightSpaceToView(v2, 150); 26 | 27 | 28 | ************************************************************************* 29 | */ 30 | 31 | 32 | /* 33 | 34 | ********************************************************************************* 35 | * 36 | * 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们,我们会及时修复bug并 37 | * 帮您解决问题。 38 | * QQ : 2689718696(gsdios) 39 | * Email : gsdios@126.com 40 | * GitHub: https://github.com/gsdios 41 | * 新浪微博:GSD_iOS 42 | * 43 | * 视频教程:http://www.letv.com/ptv/vplay/24038772.html 44 | * 用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md 45 | * 46 | ********************************************************************************* 47 | 48 | 49 | SDAutoLayout 50 | 版本:2.1.7 51 | 发布:2016.08.12 52 | 53 | */ 54 | 55 | 56 | // 如果需要用“断言”调试程序请打开此宏 57 | 58 | //#define SDDebugWithAssert 59 | 60 | #import 61 | 62 | @class SDAutoLayoutModel, SDUIViewCategoryManager; 63 | 64 | typedef SDAutoLayoutModel *(^MarginToView)(id viewOrViewsArray, CGFloat value); 65 | typedef SDAutoLayoutModel *(^Margin)(CGFloat value); 66 | typedef SDAutoLayoutModel *(^MarginEqualToView)(UIView *toView); 67 | typedef SDAutoLayoutModel *(^WidthHeight)(CGFloat value); 68 | typedef SDAutoLayoutModel *(^WidthHeightEqualToView)(UIView *toView, CGFloat ratioValue); 69 | typedef SDAutoLayoutModel *(^AutoHeightWidth)(CGFloat ratioValue); 70 | typedef SDAutoLayoutModel *(^SameWidthHeight)(); 71 | typedef SDAutoLayoutModel *(^Offset)(CGFloat value); 72 | typedef void (^SpaceToSuperView)(UIEdgeInsets insets); 73 | 74 | @interface SDAutoLayoutModel : NSObject 75 | 76 | /* 77 | *************************说明************************ 78 | 79 | 方法名中带有“SpaceToView”的需要传递2个参数:(UIView)参照view 和 (CGFloat)间距数值 80 | 方法名中带有“RatioToView”的需要传递2个参数:(UIView)参照view 和 (CGFloat)倍数 81 | 方法名中带有“EqualToView”的需要传递1个参数:(UIView)参照view 82 | 方法名中带有“Is”的需要传递1个参数:(CGFloat)数值 83 | 84 | ***************************************************** 85 | */ 86 | 87 | 88 | /* 设置距离其它view的间距 */ 89 | 90 | /** 左边到其参照view之间的间距,参数为“(View 或者 view数组, CGFloat)” */ 91 | @property (nonatomic, copy, readonly) MarginToView leftSpaceToView; 92 | /** 右边到其参照view之间的间距,参数为“(View, CGFloat)” */ 93 | @property (nonatomic, copy, readonly) MarginToView rightSpaceToView; 94 | /** 顶部到其参照view之间的间距,参数为“(View 或者 view数组, CGFloat)” */ 95 | @property (nonatomic, copy, readonly) MarginToView topSpaceToView; 96 | /** 底部到其参照view之间的间距,参数为“(View, CGFloat)” */ 97 | @property (nonatomic, copy, readonly) MarginToView bottomSpaceToView; 98 | 99 | 100 | 101 | /* 设置x、y、width、height、centerX、centerY 值 */ 102 | 103 | /** x值,参数为“(CGFloat)” */ 104 | @property (nonatomic, copy, readonly) Margin xIs; 105 | /** y值,参数为“(CGFloat)” */ 106 | @property (nonatomic, copy, readonly) Margin yIs; 107 | /** centerX值,参数为“(CGFloat)” */ 108 | @property (nonatomic, copy, readonly) Margin centerXIs; 109 | /** centerY值,参数为“(CGFloat)” */ 110 | @property (nonatomic, copy, readonly) Margin centerYIs; 111 | /** 宽度值,参数为“(CGFloat)” */ 112 | @property (nonatomic, copy, readonly) WidthHeight widthIs; 113 | /** 高度值,参数为“(CGFloat)” */ 114 | @property (nonatomic, copy, readonly) WidthHeight heightIs; 115 | 116 | 117 | 118 | /* 设置最大宽度和高度、最小宽度和高度 */ 119 | 120 | /** 最大宽度值,参数为“(CGFloat)” */ 121 | @property (nonatomic, copy, readonly) WidthHeight maxWidthIs; 122 | /** 最大高度值,参数为“(CGFloat)” */ 123 | @property (nonatomic, copy, readonly) WidthHeight maxHeightIs; 124 | /** 最小宽度值,参数为“(CGFloat)” */ 125 | @property (nonatomic, copy, readonly) WidthHeight minWidthIs; 126 | /** 最小高度值,参数为“(CGFloat)” */ 127 | @property (nonatomic, copy, readonly) WidthHeight minHeightIs; 128 | 129 | 130 | 131 | /* 设置和某个参照view的边距相同 */ 132 | 133 | /** 左间距与参照view相同,参数为“(View)” */ 134 | @property (nonatomic, copy, readonly) MarginEqualToView leftEqualToView; 135 | /** 右间距与参照view相同,参数为“(View)” */ 136 | @property (nonatomic, copy, readonly) MarginEqualToView rightEqualToView; 137 | /** 顶部间距与参照view相同,参数为“(View)” */ 138 | @property (nonatomic, copy, readonly) MarginEqualToView topEqualToView; 139 | /** 底部间距与参照view相同,参数为“(View)” */ 140 | @property (nonatomic, copy, readonly) MarginEqualToView bottomEqualToView; 141 | /** centerX与参照view相同,参数为“(View)” */ 142 | @property (nonatomic, copy, readonly) MarginEqualToView centerXEqualToView; 143 | /** centerY与参照view相同,参数为“(View)” */ 144 | @property (nonatomic, copy, readonly) MarginEqualToView centerYEqualToView; 145 | 146 | 147 | 148 | /* 设置宽度或者高度等于参照view的多少倍 */ 149 | 150 | /** 宽度是参照view宽度的多少倍,参数为“(View, CGFloat)” */ 151 | @property (nonatomic, copy, readonly) WidthHeightEqualToView widthRatioToView; 152 | /** 高度是参照view高度的多少倍,参数为“(View, CGFloat)” */ 153 | @property (nonatomic, copy, readonly) WidthHeightEqualToView heightRatioToView; 154 | /** 设置一个view的宽度和它的高度相同,参数为空“()” */ 155 | @property (nonatomic, copy, readonly) SameWidthHeight widthEqualToHeight; 156 | /** 设置一个view的高度和它的宽度相同,参数为空“()” */ 157 | @property (nonatomic, copy, readonly) SameWidthHeight heightEqualToWidth; 158 | /** 自适应高度,传入高宽比值,label可以传0实现文字高度自适应 */ 159 | @property (nonatomic, copy, readonly) AutoHeightWidth autoHeightRatio; 160 | 161 | /** 自适应宽度,参数为宽高比值 */ 162 | @property (nonatomic, copy, readonly) AutoHeightWidth autoWidthRatio; 163 | 164 | 165 | 166 | /* 填充父view(快捷方法) */ 167 | 168 | /** 传入UIEdgeInsetsMake(top, left, bottom, right),可以快捷设置view到其父view上左下右的间距 */ 169 | @property (nonatomic, copy, readonly) SpaceToSuperView spaceToSuperView; 170 | 171 | /** 设置偏移量,参数为“(CGFloat value),目前只有带有equalToView的方法可以设置offset” */ 172 | @property (nonatomic, copy, readonly) Offset offset; 173 | 174 | @property (nonatomic, weak) UIView *needsAutoResizeView; 175 | 176 | @end 177 | 178 | 179 | 180 | #pragma mark - UIView 高度、宽度自适应相关方法 181 | 182 | @interface UIView (SDAutoHeightWidth) 183 | 184 | /** 设置Cell的高度自适应,也可用于设置普通view内容高度自适应 */ 185 | - (void)setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin; 186 | 187 | /** 用于设置普通view内容宽度自适应 */ 188 | - (void)setupAutoWidthWithRightView:(UIView *)rightView rightMargin:(CGFloat)rightMargin; 189 | 190 | /** 设置Cell的高度自适应,也可用于设置普通view内容自适应(应用于当你不确定哪个view在自动布局之后会排布在最下方最为bottomView的时候可以调用次方法将所有可能在最下方的view都传过去) */ 191 | - (void)setupAutoHeightWithBottomViewsArray:(NSArray *)bottomViewsArray bottomMargin:(CGFloat)bottomMargin; 192 | 193 | /** 更新布局(主动刷新布局,如果你需要设置完布局代码就获得view的frame请调用此方法) */ 194 | - (void)updateLayout; 195 | 196 | /** 更新cell内部的控件的布局(cell内部控件专属的更新约束方法,如果启用了cell frame缓存则会自动清除缓存再更新约束) */ 197 | - (void)updateLayoutWithCellContentView:(UIView *)cellContentView; 198 | 199 | /** 清空高度自适应设置 */ 200 | - (void)clearAutoHeigtSettings; 201 | 202 | /** 清空宽度自适应设置 */ 203 | - (void)clearAutoWidthSettings; 204 | 205 | @property (nonatomic) CGFloat autoHeight; 206 | 207 | @property (nonatomic, readonly) SDUIViewCategoryManager *sd_categoryManager; 208 | 209 | @property (nonatomic, readonly) NSMutableArray *sd_bottomViewsArray; 210 | @property (nonatomic) CGFloat sd_bottomViewBottomMargin; 211 | 212 | @property (nonatomic) NSArray *sd_rightViewsArray; 213 | @property (nonatomic) CGFloat sd_rightViewRightMargin; 214 | 215 | @end 216 | 217 | 218 | 219 | #pragma mark - UIView 设置圆角半径、自动布局回调block等相关方法 220 | 221 | @interface UIView (SDLayoutExtention) 222 | 223 | /** 自动布局完成后的回调block,可以在这里获取到view的真实frame */ 224 | @property (nonatomic) void (^didFinishAutoLayoutBlock)(CGRect frame); 225 | 226 | /** 添加一组子view */ 227 | - (void)sd_addSubviews:(NSArray *)subviews; 228 | 229 | /* 设置圆角 */ 230 | 231 | /** 设置圆角半径值 */ 232 | @property (nonatomic, strong) NSNumber *sd_cornerRadius; 233 | /** 设置圆角半径值为view宽度的多少倍 */ 234 | @property (nonatomic, strong) NSNumber *sd_cornerRadiusFromWidthRatio; 235 | /** 设置圆角半径值为view高度的多少倍 */ 236 | @property (nonatomic, strong) NSNumber *sd_cornerRadiusFromHeightRatio; 237 | 238 | /** 设置等宽子view(子view需要在同一水平方向) */ 239 | @property (nonatomic, strong) NSArray *sd_equalWidthSubviews; 240 | 241 | @end 242 | 243 | 244 | 245 | #pragma mark - UIView 九宫格浮动布局效果 246 | 247 | @interface UIView (SDAutoFlowItems) 248 | 249 | /** 250 | * 设置类似collectionView效果的固定间距自动宽度浮动子view 251 | * viewsArray : 需要浮动布局的所有视图 252 | * perRowItemsCount : 每行显示的视图个数 253 | * verticalMargin : 视图之间的垂直间距 254 | * horizontalMargin : 视图之间的水平间距 255 | * vInset : 上下缩进值 256 | * hInset : 左右缩进值 257 | */ 258 | - (void)setupAutoWidthFlowItems:(NSArray *)viewsArray withPerRowItemsCount:(NSInteger)perRowItemsCount verticalMargin:(CGFloat)verticalMargin horizontalMargin:(CGFloat)horizontalMagin verticalEdgeInset:(CGFloat)vInset horizontalEdgeInset:(CGFloat)hInset; 259 | 260 | /** 清除固定间距自动宽度浮动子view设置 */ 261 | - (void)clearAutoWidthFlowItemsSettings; 262 | 263 | /** 264 | * 设置类似collectionView效果的固定宽带自动间距浮动子view 265 | * viewsArray : 需要浮动布局的所有视图 266 | * perRowItemsCount : 每行显示的视图个数 267 | * verticalMargin : 视图之间的垂直间距 268 | * vInset : 上下缩进值 269 | * hInset : 左右缩进值 270 | */ 271 | - (void)setupAutoMarginFlowItems:(NSArray *)viewsArray withPerRowItemsCount:(NSInteger)perRowItemsCount itemWidth:(CGFloat)itemWidth verticalMargin:(CGFloat)verticalMargin verticalEdgeInset:(CGFloat)vInset horizontalEdgeInset:(CGFloat)hInset; 272 | 273 | /** 清除固定宽带自动间距浮动子view设置 */ 274 | - (void)clearAutoMarginFlowItemsSettings; 275 | 276 | @end 277 | 278 | 279 | 280 | #pragma mark - UIView 设置约束、更新约束、清空约束、从父view移除并清空约束、开启cell的frame缓存等相关方法 281 | 282 | @interface UIView (SDAutoLayout) 283 | 284 | /** 开始自动布局 */ 285 | - (SDAutoLayoutModel *)sd_layout; 286 | 287 | /** 清空之前的自动布局设置,重新开始自动布局(重新生成布局约束并使其在父view的布局序列数组中位置保持不变) */ 288 | - (SDAutoLayoutModel *)sd_resetLayout; 289 | 290 | /** 清空之前的自动布局设置,重新开始自动布局(重新生成布局约束并添加到父view布局序列数组中的最后一个位置) */ 291 | - (SDAutoLayoutModel *)sd_resetNewLayout; 292 | 293 | /** 是否关闭自动布局 */ 294 | @property (nonatomic, getter = sd_isClosingAutoLayout) BOOL sd_closeAutoLayout; 295 | 296 | /** 从父view移除并清空约束 */ 297 | - (void)removeFromSuperviewAndClearAutoLayoutSettings; 298 | 299 | /** 清空之前的自动布局设置 */ 300 | - (void)sd_clearAutoLayoutSettings; 301 | 302 | /** 将自身frame清零(一般在cell内部控件重用前调用) */ 303 | - (void)sd_clearViewFrameCache; 304 | 305 | /** 将自己的需要自动布局的subviews的frame(或者frame缓存)清零 */ 306 | - (void)sd_clearSubviewsAutoLayoutFrameCaches; 307 | 308 | /** 设置固定宽度保证宽度不在自动布局过程再做中调整 */ 309 | @property (nonatomic, strong) NSNumber *fixedWidth; 310 | 311 | /** 设置固定高度保证高度不在自动布局过程中再做调整 */ 312 | @property (nonatomic, strong) NSNumber *fixedHeight; 313 | 314 | /** 启用cell frame缓存(可以提高cell滚动的流畅度, 目前为cell专用方法,后期会扩展到其他view) */ 315 | - (void)useCellFrameCacheWithIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableview; 316 | 317 | /** 所属tableview(目前为cell专用属性,后期会扩展到其他view) */ 318 | @property (nonatomic) UITableView *sd_tableView; 319 | 320 | /** cell的indexPath(目前为cell专用属性,后期会扩展到cell的其他子view) */ 321 | @property (nonatomic) NSIndexPath *sd_indexPath; 322 | 323 | - (NSMutableArray *)autoLayoutModelsArray; 324 | - (void)addAutoLayoutModel:(SDAutoLayoutModel *)model; 325 | @property (nonatomic) SDAutoLayoutModel *ownLayoutModel; 326 | @property (nonatomic, strong) NSNumber *sd_maxWidth; 327 | @property (nonatomic, strong) NSNumber *autoHeightRatioValue; 328 | @property (nonatomic, strong) NSNumber *autoWidthRatioValue; 329 | 330 | @end 331 | 332 | 333 | 334 | #pragma mark - UIScrollView 内容竖向自适应、内容横向自适应方法 335 | 336 | @interface UIScrollView (SDAutoContentSize) 337 | 338 | /** 设置scrollview内容竖向自适应 */ 339 | - (void)setupAutoContentSizeWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin; 340 | 341 | /** 设置scrollview内容横向自适应 */ 342 | - (void)setupAutoContentSizeWithRightView:(UIView *)rightView rightMargin:(CGFloat)rightMargin; 343 | 344 | @end 345 | 346 | 347 | 348 | #pragma mark - UILabel 开启富文本布局、设置单行文本label宽度自适应、 设置label最多可以显示的行数 349 | 350 | @interface UILabel (SDLabelAutoResize) 351 | 352 | /** 是否是attributedString */ 353 | @property (nonatomic) BOOL isAttributedContent; 354 | 355 | /** 设置单行文本label宽度自适应 */ 356 | - (void)setSingleLineAutoResizeWithMaxWidth:(CGFloat)maxWidth; 357 | 358 | /** 设置label最多可以显示多少行,如果传0则显示所有行文字 */ 359 | - (void)setMaxNumberOfLinesToShow:(NSInteger)lineCount; 360 | 361 | @end 362 | 363 | 364 | 365 | #pragma mark - UIButton 设置button根据单行文字自适应 366 | 367 | @interface UIButton (SDExtention) 368 | 369 | /* 370 | * 设置button根据单行文字自适应 371 | * hPadding:左右边距 372 | */ 373 | - (void)setupAutoSizeWithHorizontalPadding:(CGFloat)hPadding buttonHeight:(CGFloat)buttonHeight; 374 | 375 | @end 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | #pragma mark - 其他方法(如果有需要可以自己利用以下接口拓展更多功能) 405 | 406 | @interface SDAutoLayoutModelItem : NSObject 407 | 408 | @property (nonatomic, strong) NSNumber *value; 409 | @property (nonatomic, weak) UIView *refView; 410 | @property (nonatomic, assign) CGFloat offset; 411 | @property (nonatomic, strong) NSArray *refViewsArray; 412 | 413 | @end 414 | 415 | 416 | @interface UIView (SDChangeFrame) 417 | 418 | @property (nonatomic) BOOL shouldReadjustFrameBeforeStoreCache; 419 | 420 | @property (nonatomic) CGFloat left_sd; 421 | @property (nonatomic) CGFloat top_sd; 422 | @property (nonatomic) CGFloat right_sd; 423 | @property (nonatomic) CGFloat bottom_sd; 424 | @property (nonatomic) CGFloat centerX_sd; 425 | @property (nonatomic) CGFloat centerY_sd; 426 | 427 | @property (nonatomic) CGFloat width_sd; 428 | @property (nonatomic) CGFloat height_sd; 429 | 430 | 431 | @property (nonatomic) CGPoint origin_sd; 432 | @property (nonatomic) CGSize size_sd; 433 | 434 | 435 | // 兼容旧版本 436 | @property (nonatomic) CGFloat left; 437 | @property (nonatomic) CGFloat top; 438 | @property (nonatomic) CGFloat right; 439 | @property (nonatomic) CGFloat bottom; 440 | @property (nonatomic) CGFloat centerX; 441 | @property (nonatomic) CGFloat centerY; 442 | @property (nonatomic) CGFloat width; 443 | @property (nonatomic) CGFloat height; 444 | @property (nonatomic) CGPoint origin; 445 | @property (nonatomic) CGSize size; 446 | 447 | @end 448 | 449 | 450 | @interface SDUIViewCategoryManager : NSObject 451 | 452 | @property (nonatomic, strong) NSArray *rightViewsArray; 453 | @property (nonatomic, assign) CGFloat rightViewRightMargin; 454 | 455 | @property (nonatomic, weak) UITableView *sd_tableView; 456 | @property (nonatomic, strong) NSIndexPath *sd_indexPath; 457 | 458 | @property (nonatomic, assign) BOOL hasSetFrameWithCache; 459 | 460 | @property (nonatomic) BOOL shouldReadjustFrameBeforeStoreCache; 461 | 462 | @property (nonatomic, assign, getter = sd_isClosingAutoLayout) BOOL sd_closeAutoLayout; 463 | 464 | 465 | /** 设置类似collectionView效果的固定间距自动宽度浮动子view */ 466 | 467 | @property (nonatomic, strong) NSArray *flowItems; 468 | @property (nonatomic, assign) CGFloat verticalMargin; 469 | @property (nonatomic, assign) CGFloat horizontalMargin; 470 | @property (nonatomic, assign) NSInteger perRowItemsCount; 471 | @property (nonatomic, assign) CGFloat lastWidth; 472 | 473 | 474 | /** 设置类似collectionView效果的固定宽带自动间距浮动子view */ 475 | 476 | @property (nonatomic, assign) CGFloat flowItemWidth; 477 | @property (nonatomic, assign) BOOL shouldShowAsAutoMarginViews; 478 | 479 | 480 | @property (nonatomic) CGFloat horizontalEdgeInset; 481 | @property (nonatomic) CGFloat verticalEdgeInset; 482 | 483 | @end 484 | 485 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVIndefiniteAnimatedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVIndefiniteAnimatedView.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2017 Guillaume Campagna. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVIndefiniteAnimatedView : UIView 11 | 12 | @property (nonatomic, assign) CGFloat strokeThickness; 13 | @property (nonatomic, assign) CGFloat radius; 14 | @property (nonatomic, strong) UIColor *strokeColor; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVIndefiniteAnimatedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVIndefiniteAnimatedView.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2017 Guillaume Campagna. All rights reserved. 6 | // 7 | 8 | #import "SVIndefiniteAnimatedView.h" 9 | #import "SVProgressHUD.h" 10 | 11 | @interface SVIndefiniteAnimatedView () 12 | 13 | @property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer; 14 | 15 | @end 16 | 17 | @implementation SVIndefiniteAnimatedView 18 | 19 | - (void)willMoveToSuperview:(UIView*)newSuperview { 20 | if (newSuperview) { 21 | [self layoutAnimatedLayer]; 22 | } else { 23 | [_indefiniteAnimatedLayer removeFromSuperlayer]; 24 | _indefiniteAnimatedLayer = nil; 25 | } 26 | } 27 | 28 | - (void)layoutAnimatedLayer { 29 | CALayer *layer = self.indefiniteAnimatedLayer; 30 | [self.layer addSublayer:layer]; 31 | 32 | CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); 33 | CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); 34 | layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); 35 | } 36 | 37 | - (CAShapeLayer*)indefiniteAnimatedLayer { 38 | if(!_indefiniteAnimatedLayer) { 39 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); 40 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (M_PI/2+M_PI*5) clockwise:YES]; 41 | 42 | _indefiniteAnimatedLayer = [CAShapeLayer layer]; 43 | _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; 44 | _indefiniteAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); 45 | _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor; 46 | _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor; 47 | _indefiniteAnimatedLayer.lineWidth = self.strokeThickness; 48 | _indefiniteAnimatedLayer.lineCap = kCALineCapRound; 49 | _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel; 50 | _indefiniteAnimatedLayer.path = smoothedPath.CGPath; 51 | 52 | CALayer *maskLayer = [CALayer layer]; 53 | 54 | NSBundle *bundle = [NSBundle bundleForClass:[SVProgressHUD class]]; 55 | NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; 56 | NSBundle *imageBundle = [NSBundle bundleWithURL:url]; 57 | 58 | NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"]; 59 | 60 | maskLayer.contents = (__bridge id)[[UIImage imageWithContentsOfFile:path] CGImage]; 61 | maskLayer.frame = _indefiniteAnimatedLayer.bounds; 62 | _indefiniteAnimatedLayer.mask = maskLayer; 63 | 64 | NSTimeInterval animationDuration = 1; 65 | CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 66 | 67 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 68 | animation.fromValue = (id) 0; 69 | animation.toValue = @(M_PI*2); 70 | animation.duration = animationDuration; 71 | animation.timingFunction = linearCurve; 72 | animation.removedOnCompletion = NO; 73 | animation.repeatCount = INFINITY; 74 | animation.fillMode = kCAFillModeForwards; 75 | animation.autoreverses = NO; 76 | [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"]; 77 | 78 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; 79 | animationGroup.duration = animationDuration; 80 | animationGroup.repeatCount = INFINITY; 81 | animationGroup.removedOnCompletion = NO; 82 | animationGroup.timingFunction = linearCurve; 83 | 84 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 85 | strokeStartAnimation.fromValue = @0.015; 86 | strokeStartAnimation.toValue = @0.515; 87 | 88 | CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 89 | strokeEndAnimation.fromValue = @0.485; 90 | strokeEndAnimation.toValue = @0.985; 91 | 92 | animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation]; 93 | [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"]; 94 | 95 | } 96 | return _indefiniteAnimatedLayer; 97 | } 98 | 99 | - (void)setFrame:(CGRect)frame { 100 | if(!CGRectEqualToRect(frame, super.frame)) { 101 | [super setFrame:frame]; 102 | 103 | if(self.superview) { 104 | [self layoutAnimatedLayer]; 105 | } 106 | } 107 | 108 | } 109 | 110 | - (void)setRadius:(CGFloat)radius { 111 | if(radius != _radius) { 112 | _radius = radius; 113 | 114 | [_indefiniteAnimatedLayer removeFromSuperlayer]; 115 | _indefiniteAnimatedLayer = nil; 116 | 117 | if(self.superview) { 118 | [self layoutAnimatedLayer]; 119 | } 120 | } 121 | } 122 | 123 | - (void)setStrokeColor:(UIColor*)strokeColor { 124 | _strokeColor = strokeColor; 125 | _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor; 126 | } 127 | 128 | - (void)setStrokeThickness:(CGFloat)strokeThickness { 129 | _strokeThickness = strokeThickness; 130 | _indefiniteAnimatedLayer.lineWidth = _strokeThickness; 131 | } 132 | 133 | - (CGSize)sizeThatFits:(CGSize)size { 134 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); 135 | } 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressAnimatedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressAnimatedView.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2017 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVProgressAnimatedView : UIView 11 | 12 | @property (nonatomic, assign) CGFloat radius; 13 | @property (nonatomic, assign) CGFloat strokeThickness; 14 | @property (nonatomic, strong) UIColor *strokeColor; 15 | @property (nonatomic, assign) CGFloat strokeEnd; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressAnimatedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressAnimatedView.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2017 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import "SVProgressAnimatedView.h" 9 | 10 | @interface SVProgressAnimatedView () 11 | 12 | @property (nonatomic, strong) CAShapeLayer *ringAnimatedLayer; 13 | 14 | @end 15 | 16 | @implementation SVProgressAnimatedView 17 | 18 | - (void)willMoveToSuperview:(UIView*)newSuperview { 19 | if (newSuperview) { 20 | [self layoutAnimatedLayer]; 21 | } else { 22 | [_ringAnimatedLayer removeFromSuperlayer]; 23 | _ringAnimatedLayer = nil; 24 | } 25 | } 26 | 27 | - (void)layoutAnimatedLayer { 28 | CALayer *layer = self.ringAnimatedLayer; 29 | [self.layer addSublayer:layer]; 30 | 31 | CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); 32 | CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); 33 | layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); 34 | } 35 | 36 | - (CAShapeLayer*)ringAnimatedLayer { 37 | if(!_ringAnimatedLayer) { 38 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); 39 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat)-M_PI_2 endAngle:(CGFloat) (M_PI + M_PI_2) clockwise:YES]; 40 | 41 | _ringAnimatedLayer = [CAShapeLayer layer]; 42 | _ringAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; 43 | _ringAnimatedLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); 44 | _ringAnimatedLayer.fillColor = [UIColor clearColor].CGColor; 45 | _ringAnimatedLayer.strokeColor = self.strokeColor.CGColor; 46 | _ringAnimatedLayer.lineWidth = self.strokeThickness; 47 | _ringAnimatedLayer.lineCap = kCALineCapRound; 48 | _ringAnimatedLayer.lineJoin = kCALineJoinBevel; 49 | _ringAnimatedLayer.path = smoothedPath.CGPath; 50 | } 51 | return _ringAnimatedLayer; 52 | } 53 | 54 | - (void)setFrame:(CGRect)frame { 55 | if(!CGRectEqualToRect(frame, super.frame)) { 56 | [super setFrame:frame]; 57 | 58 | if(self.superview) { 59 | [self layoutAnimatedLayer]; 60 | } 61 | } 62 | } 63 | 64 | - (void)setRadius:(CGFloat)radius { 65 | if(radius != _radius) { 66 | _radius = radius; 67 | 68 | [_ringAnimatedLayer removeFromSuperlayer]; 69 | _ringAnimatedLayer = nil; 70 | 71 | if(self.superview) { 72 | [self layoutAnimatedLayer]; 73 | } 74 | } 75 | } 76 | 77 | - (void)setStrokeColor:(UIColor*)strokeColor { 78 | _strokeColor = strokeColor; 79 | _ringAnimatedLayer.strokeColor = strokeColor.CGColor; 80 | } 81 | 82 | - (void)setStrokeThickness:(CGFloat)strokeThickness { 83 | _strokeThickness = strokeThickness; 84 | _ringAnimatedLayer.lineWidth = _strokeThickness; 85 | } 86 | 87 | - (void)setStrokeEnd:(CGFloat)strokeEnd { 88 | _strokeEnd = strokeEnd; 89 | _ringAnimatedLayer.strokeEnd = _strokeEnd; 90 | } 91 | 92 | - (CGSize)sizeThatFits:(CGSize)size { 93 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SVProgressHUD' target in the 'SVProgressHUD' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/error@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/info@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success@2x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.bundle/success@3x.png -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressHUD.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2011-2017 Sam Vermette and contributors. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | #if __IPHONE_OS_VERSION_MAX_ALLOWED < 70000 12 | 13 | #define UI_APPEARANCE_SELECTOR 14 | 15 | #endif 16 | 17 | extern NSString * _Nonnull const SVProgressHUDDidReceiveTouchEventNotification; 18 | extern NSString * _Nonnull const SVProgressHUDDidTouchDownInsideNotification; 19 | extern NSString * _Nonnull const SVProgressHUDWillDisappearNotification; 20 | extern NSString * _Nonnull const SVProgressHUDDidDisappearNotification; 21 | extern NSString * _Nonnull const SVProgressHUDWillAppearNotification; 22 | extern NSString * _Nonnull const SVProgressHUDDidAppearNotification; 23 | 24 | extern NSString * _Nonnull const SVProgressHUDStatusUserInfoKey; 25 | 26 | typedef NS_ENUM(NSInteger, SVProgressHUDStyle) { 27 | SVProgressHUDStyleLight, // default style, white HUD with black text, HUD background will be blurred 28 | SVProgressHUDStyleDark, // black HUD and white text, HUD background will be blurred 29 | SVProgressHUDStyleCustom // uses the fore- and background color properties 30 | }; 31 | 32 | typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { 33 | SVProgressHUDMaskTypeNone = 1, // default mask type, allow user interactions while HUD is displayed 34 | SVProgressHUDMaskTypeClear, // don't allow user interactions with background objects 35 | SVProgressHUDMaskTypeBlack, // don't allow user interactions with background objects and dim the UI in the back of the HUD (as seen in iOS 7 and above) 36 | SVProgressHUDMaskTypeGradient, // don't allow user interactions with background objects and dim the UI with a a-la UIAlertView background gradient (as seen in iOS 6) 37 | SVProgressHUDMaskTypeCustom // don't allow user interactions with background objects and dim the UI in the back of the HUD with a custom color 38 | }; 39 | 40 | typedef NS_ENUM(NSUInteger, SVProgressHUDAnimationType) { 41 | SVProgressHUDAnimationTypeFlat, // default animation type, custom flat animation (indefinite animated ring) 42 | SVProgressHUDAnimationTypeNative // iOS native UIActivityIndicatorView 43 | }; 44 | 45 | typedef void (^SVProgressHUDShowCompletion)(void); 46 | typedef void (^SVProgressHUDDismissCompletion)(void); 47 | 48 | @interface SVProgressHUD : UIView 49 | 50 | #pragma mark - Customization 51 | 52 | @property (assign, nonatomic) SVProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; // default is SVProgressHUDStyleLight 53 | @property (assign, nonatomic) SVProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDMaskTypeNone 54 | @property (assign, nonatomic) SVProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; // default is SVProgressHUDAnimationTypeFlat 55 | @property (strong, nonatomic, nullable) UIView *containerView; // if nil then use default window level 56 | @property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; // default is CGSizeZero, can be used to avoid resizing for a larger message 57 | @property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; // default is 2 pt 58 | @property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; // default is 18 pt 59 | @property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; // default is 24 pt 60 | @property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; // default is 14 pt 61 | @property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] 62 | @property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor ClearColor] 63 | @property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor blackColor] 64 | @property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR;// default is [UIColor colorWithWhite:0 alpha:0.4] 65 | @property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR; // default is 28x28 pt 66 | @property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR; // default is the bundled info image provided by Freepik 67 | @property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR; // default is the bundled success image provided by Freepik 68 | @property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR; // default is the bundled error image provided by Freepik 69 | @property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR; // default is nil, only used if #define SV_APP_EXTENSIONS is set 70 | @property (assign, nonatomic) NSTimeInterval graceTimeInterval; // default is 0 seconds 71 | @property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; // default is 5.0 seconds 72 | @property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval; // default is CGFLOAT_MAX 73 | 74 | @property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; // default is 0, 0 75 | 76 | @property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 77 | @property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15 78 | 79 | @property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel; // default is UIWindowLevelNormal 80 | 81 | @property (assign, nonatomic) BOOL hapticsEnabled; // default is NO 82 | 83 | + (void)setDefaultStyle:(SVProgressHUDStyle)style; // default is SVProgressHUDStyleLight 84 | + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone 85 | + (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type; // default is SVProgressHUDAnimationTypeFlat 86 | + (void)setContainerView:(nullable UIView*)containerView; // default is window level 87 | + (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message 88 | + (void)setRingThickness:(CGFloat)ringThickness; // default is 2 pt 89 | + (void)setRingRadius:(CGFloat)radius; // default is 18 pt 90 | + (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt 91 | + (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt 92 | + (void)setBorderColor:(nonnull UIColor*)color; // default is nil 93 | + (void)setBorderWidth:(CGFloat)width; // default is 0 94 | + (void)setFont:(nonnull UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] 95 | + (void)setForegroundColor:(nonnull UIColor*)color; // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom 96 | + (void)setBackgroundColor:(nonnull UIColor*)color; // default is [UIColor ClearColor], only used for SVProgressHUDStyleCustom 97 | + (void)setBackgroundLayerColor:(nonnull UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.5], only used for SVProgressHUDMaskTypeCustom 98 | + (void)setImageViewSize:(CGSize)size; // default is 28x28 pt 99 | + (void)setInfoImage:(nonnull UIImage*)image; // default is the bundled info image provided by Freepik 100 | + (void)setSuccessImage:(nonnull UIImage*)image; // default is the bundled success image provided by Freepik 101 | + (void)setErrorImage:(nonnull UIImage*)image; // default is the bundled error image provided by Freepik 102 | + (void)setViewForExtension:(nonnull UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set 103 | + (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds 104 | + (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds 105 | + (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is infinite 106 | + (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 107 | + (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds 108 | + (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal 109 | + (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO 110 | 111 | #pragma mark - Show Methods 112 | 113 | + (void)show; 114 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead."))); 115 | + (void)showWithStatus:(nullable NSString*)status; 116 | + (void)showWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showWithStatus: and setDefaultMaskType: instead."))); 117 | 118 | + (void)showProgress:(float)progress; 119 | + (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress: and setDefaultMaskType: instead."))); 120 | + (void)showProgress:(float)progress status:(nullable NSString*)status; 121 | + (void)showProgress:(float)progress status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress:status: and setDefaultMaskType: instead."))); 122 | //只显示文字 123 | + (void)showWithString:(NSString*)string; 124 | + (void)setStatus:(nullable NSString*)status; // change the HUD loading status while it's showing 125 | 126 | // stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later 127 | + (void)showInfoWithStatus:(nullable NSString*)status; 128 | + (void)showInfoWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showInfoWithStatus: and setDefaultMaskType: instead."))); 129 | + (void)showSuccessWithStatus:(nullable NSString*)status; 130 | + (void)showSuccessWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showSuccessWithStatus: and setDefaultMaskType: instead."))); 131 | + (void)showErrorWithStatus:(nullable NSString*)status; 132 | + (void)showErrorWithStatus:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showErrorWithStatus: and setDefaultMaskType: instead."))); 133 | 134 | // shows a image + status, use white PNGs with the imageViewSize (default is 28x28 pt) 135 | + (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status; 136 | + (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status maskType:(SVProgressHUDMaskType)maskType __attribute__((deprecated("Use showImage:status: and setDefaultMaskType: instead."))); 137 | 138 | + (void)setOffsetFromCenter:(UIOffset)offset; 139 | + (void)resetOffsetFromCenter; 140 | 141 | + (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed 142 | + (void)dismiss; 143 | + (void)dismissWithCompletion:(nullable SVProgressHUDDismissCompletion)completion; 144 | + (void)dismissWithDelay:(NSTimeInterval)delay; 145 | + (void)dismissWithDelay:(NSTimeInterval)delay completion:(nullable SVProgressHUDDismissCompletion)completion; 146 | 147 | + (BOOL)isVisible; 148 | 149 | + (NSTimeInterval)displayDurationForString:(nullable NSString*)string; 150 | 151 | @end 152 | 153 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVRadialGradientLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVRadialGradientLayer.h 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2017 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SVRadialGradientLayer : CALayer 11 | 12 | @property (nonatomic) CGPoint gradientCenter; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ChoseGoodsType/source/SVProgressHUD/SVRadialGradientLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVRadialGradientLayer.m 3 | // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD 4 | // 5 | // Copyright (c) 2014-2017 Tobias Tiemerding. All rights reserved. 6 | // 7 | 8 | #import "SVRadialGradientLayer.h" 9 | 10 | @implementation SVRadialGradientLayer 11 | 12 | - (void)drawInContext:(CGContextRef)context { 13 | size_t locationsCount = 2; 14 | CGFloat locations[2] = {0.0f, 1.0f}; 15 | CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f}; 16 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 17 | CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); 18 | CGColorSpaceRelease(colorSpace); 19 | 20 | float radius = MIN(self.bounds.size.width , self.bounds.size.height); 21 | CGContextDrawRadialGradient (context, gradient, self.gradientCenter, 0, self.gradientCenter, radius, kCGGradientDrawsAfterEndLocation); 22 | CGGradientRelease(gradient); 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Header.h 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #ifndef Header_h 10 | #define Header_h 11 | 12 | #import "JXUIKit.h" 13 | #import "UIView+SDAutoLayout.h" 14 | 15 | #import "GoodsModel.h" 16 | 17 | #define MJWeakSelf __weak typeof(self) weakSelf = self; 18 | 19 | #define kWidth [UIScreen mainScreen].bounds.size.width 20 | #define kHeight [UIScreen mainScreen].bounds.size.height 21 | #define kSize(a) ceil((a)*([UIScreen mainScreen].bounds.size.width/375.0)) 22 | 23 | #define WhiteColor [UIColor whiteColor] 24 | #define KBtncol [UIColor redColor]//按钮背景颜色 25 | #define KLightGrayLinecol [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1] 26 | #define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)] 27 | 28 | #endif /* Header_h */ 29 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/JXUIKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // JXUIKit.h 3 | // PartyBuilding 4 | // 5 | // Created by 主用户 on 2016/11/28. 6 | // Copyright © 2016年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface JXUIKit : NSObject 13 | /**label 背景色 字体颜色 对齐方式 行数 字体大小 文字*/ 14 | +(UILabel *)labelWithBackgroundColor:(UIColor *)backgrountColor textColor:(UIColor *)textColor textAlignment:(NSTextAlignment)textAlignment numberOfLines:(NSInteger)numberOfLines fontSize:(float) size font:(UIFont *)font text:(NSString *)text; 15 | 16 | 17 | /**textField 背景色 字体颜色 是否密文 字体大小 文字 默认文字 文字对齐方式*/ 18 | +(UITextField *)textFieldWithBackgroundColor:(UIColor *)backgrountColor textColor:(UIColor *)textColor secureTextEntry:(BOOL)secureTextEntry fontSize:(float)size font:(UIFont *)font text:(NSString *)text placeholder:(NSString *)placeholder textAlignment:(NSTextAlignment)textAlignment; 19 | 20 | /**UIButton 背景色 默认文字颜色 默认文字 选中文字颜色 选中文字 字体大小 默认背景图片 选中背景图片 图片 选中图片*/ 21 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font backgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete; 22 | 23 | /**UIButton 默认文字颜色 默认文字 选中文字颜色 选中文字 字体大小 默认背景图片 选中背景图片*/ 24 | +(UIButton *)buttonWithTitleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font backgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete; 25 | 26 | /**UIButton 背景色 默认文字颜色 默认文字 选中文字颜色 选中文字 字体大小 图片 选中图片*/ 27 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete; 28 | 29 | /**UIButton 背景色 默认文字颜色 默认文字 选中文字颜色 选中文字 字体大小*/ 30 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font; 31 | 32 | /**UIButton 默认背景图片 选中背景图片*/ 33 | +(UIButton *)buttonWithBackgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete; 34 | 35 | /**UIButton 背景色 图片 选中图片*/ 36 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete; 37 | 38 | /**UIImageView 背景色 是否可触摸 图片名字*/ 39 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled imageName:(NSString *)imageName; 40 | 41 | /**UIImageView 背景色 是否可触摸 图片*/ 42 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled image:(UIImage *)image; 43 | 44 | /**UIImageView 背景色 是否可触摸 图片路径*/ 45 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled imagePath:(NSString *)imagePath; 46 | 47 | /**UIScrollView 背景色 是否可滑动 容量大小 是否可翻页滑动 是否显示横向滑动条 是否显示竖向滑动条*/ 48 | +(UIScrollView *)scrollViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled contentSize:(CGSize)size pagingEnabled:(BOOL)pagingEnabled showsHorizontalScrollIndicator:(BOOL)showsHorizontalScrollIndicator showsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator; 49 | 50 | /**UITableView 背景色 是否可滑动 cell分割样式*/ 51 | +(UITableView *)tableViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled separatorStyle:(UITableViewCellSeparatorStyle)separatorStyle; 52 | 53 | /**UICollectionView 背景色 是否可滑动 item大小 滚动方向 四周边距 item之间间距 行距 自定义cell的class identifier*/ 54 | +(UICollectionView *)collectionViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled itemSize:(CGSize)size scrollDirection:(UICollectionViewScrollDirection)scrollDirection sectionInset:(UIEdgeInsets)sectionInset minimumInteritemSpacing:(float)minimumInteritemSpacing minimumLineSpacing:(float)minimumLineSpacing cellClass:(NSString *)cellClass identifier:(NSString *)identifier; 55 | 56 | //切圆角 57 | +(UIView *)ViewcornerRadius:(float)radius andColor:(UIColor *)color andWidth:(float)width :(UIView *)view; 58 | 59 | +(void)showWithString:(NSString *)string; 60 | +(void)showErrorWithStatus:(NSString *)string; 61 | +(void)showSuccessWithStatus:(NSString *)string; 62 | @end 63 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/JXUIKit.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // JXUIKit.m 4 | // PartyBuilding 5 | // 6 | // Created by 主用户 on 2016/11/28. 7 | // Copyright © 2016年 江萧. All rights reserved. 8 | // 9 | 10 | #import "JXUIKit.h" 11 | #import "SVProgressHUD.h" 12 | @implementation JXUIKit 13 | +(UIView *)ViewcornerRadius:(float)radius andColor:(UIColor *)color andWidth:(float)width :(UIView *)view 14 | { 15 | view.layer.cornerRadius = radius; 16 | view.layer.borderColor = color.CGColor; 17 | view.layer.borderWidth = width; 18 | [view.layer setMasksToBounds:YES]; 19 | return view; 20 | } 21 | +(UILabel *)labelWithBackgroundColor:(UIColor *)backgrountColor textColor:(UIColor *)textColor textAlignment:(NSTextAlignment)textAlignment numberOfLines:(NSInteger)numberOfLines fontSize:(float)size font:(UIFont *)font text:(NSString *)text 22 | { 23 | UILabel *label = [[UILabel alloc] init]; 24 | if (backgrountColor) { 25 | label.backgroundColor = backgrountColor; 26 | } 27 | if (textColor) { 28 | label.textColor = textColor; 29 | } 30 | if (text) { 31 | label.text = text; 32 | } 33 | label.numberOfLines = numberOfLines; 34 | label.textAlignment = textAlignment; 35 | if (size>0) { 36 | label.font = [UIFont systemFontOfSize:size]; 37 | }else 38 | label.font = font; 39 | return label; 40 | } 41 | 42 | +(UITextField *)textFieldWithBackgroundColor:(UIColor *)backgrountColor textColor:(UIColor *)textColor secureTextEntry:(BOOL)secureTextEntry fontSize:(float)size font:(UIFont *)font text:(NSString *)text placeholder:(NSString *)placeholder textAlignment:(NSTextAlignment)textAlignment 43 | { 44 | UITextField *textField = [[UITextField alloc] init]; 45 | if (backgrountColor) { 46 | textField.backgroundColor = backgrountColor; 47 | } 48 | if (textColor) { 49 | textField.textColor = textColor; 50 | } 51 | if (text) { 52 | textField.text = text; 53 | } 54 | if (placeholder) { 55 | textField.placeholder = placeholder; 56 | } 57 | if (size>0) { 58 | textField.font = [UIFont systemFontOfSize:size]; 59 | }else 60 | textField.font = font; 61 | textField.secureTextEntry = secureTextEntry; 62 | textField.textAlignment = textAlignment; 63 | return textField; 64 | } 65 | 66 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font backgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete 67 | { 68 | 69 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 70 | if (backgrountColor) { 71 | [button setBackgroundColor:backgrountColor]; 72 | } 73 | if (titleForNormal) { 74 | [button setTitle:titleForNormal forState:0]; 75 | } 76 | if (titleForSelete) { 77 | [button setTitle:titleForSelete forState:UIControlStateSelected]; 78 | } 79 | if (titleColorForNormal) { 80 | [button setTitleColor:titleColorForNormal forState:0]; 81 | } 82 | if (titleColorForSelete) { 83 | [button setTitleColor:titleColorForSelete forState:UIControlStateSelected]; 84 | } 85 | if (size>0) { 86 | button.titleLabel.font = [UIFont systemFontOfSize:size]; 87 | }else 88 | button.titleLabel.font = font; 89 | if (backgroundImageForNormal) { 90 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForNormal] forState:0]; 91 | } 92 | if (backgroundImageForSelete) { 93 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForSelete] forState:UIControlStateSelected]; 94 | } 95 | if (imageForNormal) { 96 | [button setImage: [UIImage imageNamed:imageForNormal] forState:0]; 97 | } 98 | if (imageForSelete) { 99 | [button setImage: [UIImage imageNamed:imageForSelete] forState:UIControlStateSelected]; 100 | } 101 | return button; 102 | } 103 | 104 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete 105 | { 106 | 107 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 108 | 109 | if (backgrountColor) { 110 | [button setBackgroundColor:backgrountColor]; 111 | } 112 | if (titleForNormal) { 113 | [button setTitle:titleForNormal forState:0]; 114 | } 115 | if (titleForSelete) { 116 | [button setTitle:titleForSelete forState:UIControlStateSelected]; 117 | } 118 | if (titleColorForNormal) { 119 | [button setTitleColor:titleColorForNormal forState:0]; 120 | } 121 | if (titleColorForSelete) { 122 | [button setTitleColor:titleColorForSelete forState:UIControlStateSelected]; 123 | } 124 | if (size>0) { 125 | button.titleLabel.font = [UIFont systemFontOfSize:size]; 126 | }else 127 | button.titleLabel.font = font; 128 | if (imageForNormal) { 129 | [button setImage: [UIImage imageNamed:imageForNormal] forState:0]; 130 | } 131 | if (imageForSelete) { 132 | [button setImage: [UIImage imageNamed:imageForSelete] forState:UIControlStateSelected]; 133 | } 134 | return button; 135 | } 136 | 137 | 138 | +(UIButton *)buttonWithTitleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font backgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete 139 | { 140 | 141 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 142 | if (titleForNormal) { 143 | [button setTitle:titleForNormal forState:0]; 144 | } 145 | if (titleForSelete) { 146 | [button setTitle:titleForSelete forState:UIControlStateSelected]; 147 | } 148 | if (titleColorForNormal) { 149 | [button setTitleColor:titleColorForNormal forState:0]; 150 | } 151 | if (titleColorForSelete) { 152 | [button setTitleColor:titleColorForSelete forState:UIControlStateSelected]; 153 | } 154 | if (size>0) { 155 | button.titleLabel.font = [UIFont systemFontOfSize:size]; 156 | }else 157 | button.titleLabel.font = font; 158 | if (backgroundImageForNormal) { 159 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForNormal] forState:0]; 160 | } 161 | if (backgroundImageForSelete) { 162 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForSelete] forState:UIControlStateSelected]; 163 | } 164 | return button; 165 | } 166 | 167 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor titleColorForNormal:(UIColor *)titleColorForNormal titleForNormal:(NSString *)titleForNormal titleForSelete:(NSString *)titleForSelete titleColorForSelete:(UIColor *)titleColorForSelete fontSize:(float)size font:(UIFont *)font 168 | { 169 | 170 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 171 | if (titleForNormal) { 172 | [button setTitle:titleForNormal forState:0]; 173 | } 174 | if (titleForSelete) { 175 | [button setTitle:titleForSelete forState:UIControlStateSelected]; 176 | } 177 | if (titleColorForNormal) { 178 | [button setTitleColor:titleColorForNormal forState:0]; 179 | } 180 | if (titleColorForSelete) { 181 | [button setTitleColor:titleColorForSelete forState:UIControlStateSelected]; 182 | } 183 | if (size>0) { 184 | button.titleLabel.font = [UIFont systemFontOfSize:size]; 185 | }else 186 | button.titleLabel.font = font; 187 | if (backgrountColor) { 188 | [button setBackgroundColor:backgrountColor]; 189 | } 190 | return button; 191 | } 192 | 193 | +(UIButton *)buttonWithBackgroundImageForNormal:(NSString *)backgroundImageForNormal backgroundImageForSelete:(NSString *)backgroundImageForSelete 194 | { 195 | 196 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 197 | if (backgroundImageForNormal) { 198 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForNormal] forState:0]; 199 | } 200 | 201 | if (backgroundImageForSelete) { 202 | [button setBackgroundImage: [UIImage imageNamed:backgroundImageForSelete] forState:UIControlStateSelected]; 203 | } 204 | 205 | return button; 206 | } 207 | 208 | +(UIButton *)buttonWithBackgroundColor:(UIColor *)backgrountColor imageForNormal:(NSString *)imageForNormal imageForSelete:(NSString *)imageForSelete 209 | { 210 | 211 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 212 | if (backgrountColor) { 213 | [button setBackgroundColor:backgrountColor]; 214 | } 215 | if (imageForNormal) { 216 | [button setImage: [UIImage imageNamed:imageForNormal] forState:0]; 217 | } 218 | 219 | if (imageForSelete) { 220 | [button setImage: [UIImage imageNamed:imageForSelete] forState:UIControlStateSelected]; 221 | } 222 | 223 | return button; 224 | } 225 | 226 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled imageName:(NSString *)imageName 227 | { 228 | UIImageView *imageView = [[UIImageView alloc] init]; 229 | if (backgrountColor) { 230 | [imageView setBackgroundColor:backgrountColor]; 231 | } 232 | imageView.userInteractionEnabled = userInteractionEnabled; 233 | imageView.image = [UIImage imageNamed:imageName]; 234 | return imageView; 235 | } 236 | 237 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled image:(UIImage *)image 238 | { 239 | UIImageView *imageView = [[UIImageView alloc] init]; 240 | if (backgrountColor) { 241 | [imageView setBackgroundColor:backgrountColor]; 242 | } 243 | imageView.userInteractionEnabled = userInteractionEnabled; 244 | if (image) { 245 | imageView.image = image; 246 | } 247 | 248 | return imageView; 249 | } 250 | 251 | +(UIImageView *)imageViewWithBackgroundColor:(UIColor *)backgrountColor userInteractionEnabled:(BOOL)userInteractionEnabled imagePath:(NSString *)imagePath 252 | { 253 | UIImageView *imageView = [[UIImageView alloc] init]; 254 | if (backgrountColor) { 255 | [imageView setBackgroundColor:backgrountColor]; 256 | } 257 | imageView.userInteractionEnabled = userInteractionEnabled; 258 | //[imageView sd_setImageWithURL:[NSURL URLWithString:imagePath]]; 259 | return imageView; 260 | } 261 | 262 | +(UIScrollView *)scrollViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled contentSize:(CGSize)size pagingEnabled:(BOOL)pagingEnabled showsHorizontalScrollIndicator:(BOOL)showsHorizontalScrollIndicator showsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator 263 | { 264 | UIScrollView *scrollView = [[UIScrollView alloc] init]; 265 | if (backgrountColor) { 266 | [scrollView setBackgroundColor:backgrountColor]; 267 | } 268 | scrollView.contentSize = size; 269 | scrollView.scrollEnabled = scrollEnabled; 270 | scrollView.pagingEnabled = pagingEnabled; 271 | scrollView.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; 272 | scrollView.showsVerticalScrollIndicator = showsVerticalScrollIndicator; 273 | return scrollView; 274 | } 275 | 276 | +(UITableView *)tableViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled separatorStyle:(UITableViewCellSeparatorStyle)separatorStyle 277 | { 278 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 279 | tableView.backgroundColor = backgrountColor; 280 | tableView.scrollEnabled = scrollEnabled; 281 | tableView.separatorStyle = separatorStyle; 282 | return tableView; 283 | } 284 | 285 | +(UICollectionView *)collectionViewWithBackgroundColor:(UIColor *)backgrountColor scrollEnabled:(BOOL)scrollEnabled itemSize:(CGSize)size scrollDirection:(UICollectionViewScrollDirection)scrollDirection sectionInset:(UIEdgeInsets)sectionInset minimumInteritemSpacing:(float)minimumInteritemSpacing minimumLineSpacing:(float)minimumLineSpacing cellClass:(NSString *)cellClass identifier:(NSString *)identifier 286 | { 287 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 288 | flowLayout.itemSize = size; 289 | flowLayout.scrollDirection = scrollDirection; 290 | flowLayout.sectionInset = sectionInset; 291 | flowLayout.minimumInteritemSpacing = minimumInteritemSpacing; 292 | flowLayout.minimumLineSpacing = minimumLineSpacing; 293 | UICollectionView *collectionview = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:flowLayout]; 294 | collectionview.backgroundColor = backgrountColor; 295 | [collectionview registerClass:[cellClass class] forCellWithReuseIdentifier:identifier]; 296 | return collectionview; 297 | } 298 | +(void)showWithString:(NSString *)string 299 | { 300 | [SVProgressHUD showWithString:string]; 301 | } 302 | +(void)showErrorWithStatus:(NSString *)string 303 | { 304 | 305 | [SVProgressHUD showErrorWithStatus:string]; 306 | } 307 | +(void)showSuccessWithStatus:(NSString *)string 308 | { 309 | [SVProgressHUD showSuccessWithStatus:string]; 310 | } 311 | @end 312 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsModel.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/10/10. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GoodsPriceModel.h" 11 | 12 | @interface GoodsModel : NSObject 13 | @property(nonatomic, copy)NSString *goodsNo;//编号 14 | @property(nonatomic, copy)NSString *title;//商品标题 15 | @property(nonatomic, copy)NSString *imageId;//缩略图id 16 | @property(nonatomic, copy)NSString *totalStock;//总库存 17 | 18 | @property(nonatomic, copy)NSArray *itemsList;//属性列表 19 | @property(nonatomic, copy)NSArray *banners;//商品轮播图 20 | @property(nonatomic, strong)NSMutableArray *sizeAttribute;//属性组合列表 21 | @property(nonatomic, strong)GoodsPriceModel *price;//价格信息-一般商品不同属性组合价格不同,会有个价格范围 22 | 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsModel.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // GoodsModel.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/10/10. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "GoodsModel.h" 11 | 12 | @implementation GoodsModel 13 | //+ (NSDictionary *)replacedKeyFromPropertyName { 14 | // 15 | // return @{@"groupid": @"id"}; 16 | // 17 | //} 18 | @end 19 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsPriceModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsPriceModel.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/10/13. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | //商品价格信息 11 | @interface GoodsPriceModel : NSObject 12 | @property(nonatomic, copy)NSString *minPrice;//现价 13 | @property(nonatomic, copy)NSString *maxPrice; 14 | @property(nonatomic, copy)NSString *minOriginalPrice;//原价 15 | @property(nonatomic, copy)NSString *maxOriginalPrice; 16 | @end 17 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsPriceModel.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // GoodsPriceModel.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/10/13. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "GoodsPriceModel.h" 11 | 12 | @implementation GoodsPriceModel 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsTypeModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsTypeModel.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/9/25. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | //商品规格属性列表 11 | @interface GoodsTypeModel : NSObject 12 | @property(nonatomic, assign)int selectIndex; 13 | @property(nonatomic, copy)NSArray *typeArray; 14 | @property(nonatomic, copy)NSArray *enableArray; 15 | @property(nonatomic, copy)NSString *typeName; 16 | @end 17 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/GoodsTypeModel.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // GoodsTypeModel.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/9/25. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "GoodsTypeModel.h" 11 | 12 | @implementation GoodsTypeModel 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/SizeAttributeModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SizeAttributeModel.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/10/18. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | //商品各规格商品信息 11 | @interface SizeAttributeModel : NSObject 12 | @property(nonatomic, copy)NSString *sizeid;//属性组合id 13 | @property(nonatomic, copy)NSString *goodsNo;//商品编号 14 | @property(nonatomic, copy)NSString *value;//属性组合 15 | @property(nonatomic, copy)NSString *price;//现价 16 | @property(nonatomic, copy)NSString *originalPrice;//原价 17 | @property(nonatomic, copy)NSString *stock;//库存 18 | 19 | @property(nonatomic, copy)NSString *count;//数量 20 | @property(nonatomic, copy)NSString *imageId;//可能规格不同商品图片也不同 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/Models/SizeAttributeModel.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // SizeAttributeModel.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/10/18. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "SizeAttributeModel.h" 11 | 12 | @implementation SizeAttributeModel 13 | + (NSDictionary *)replacedKeyFromPropertyName { 14 | 15 | return @{@"sizeid": @"id"}; 16 | 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/ChoosTypeTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChoosTypeTableViewCell.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/9/26. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GoodsTypeModel.h" 11 | #define ItemHeight kSize(32) 12 | @interface ChoosTypeTableViewCell : UITableViewCell 13 | @property(nonatomic, strong)GoodsTypeModel *model; 14 | @property (nonatomic, copy) void (^selectButton)(int selectIndex); 15 | -(float)setData:(GoodsTypeModel *)model; 16 | @end 17 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/ChoosTypeTableViewCell.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // ChoosTypeTableViewCell.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/9/26. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "ChoosTypeTableViewCell.h" 11 | #import "Header.h" 12 | @interface ChoosTypeTableViewCell() 13 | { 14 | //类型名 15 | UILabel *typeNameLabel; 16 | UIView *typeView;//装载所有属性button的视图 17 | } 18 | @end 19 | @implementation ChoosTypeTableViewCell 20 | 21 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 22 | { 23 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]){ 24 | self.backgroundColor = WhiteColor; 25 | 26 | typeNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 200, 20)]; 27 | typeNameLabel.textColor = [UIColor blackColor]; 28 | typeNameLabel.font = [UIFont systemFontOfSize:14]; 29 | [self addSubview:typeNameLabel]; 30 | 31 | typeView = [[UIView alloc] initWithFrame:CGRectMake(0, 40, kWidth, 20)]; 32 | [self addSubview:typeView]; 33 | } 34 | return self; 35 | } 36 | -(float)setData:(GoodsTypeModel *)model 37 | { 38 | _model = model; 39 | typeNameLabel.text = model.typeName; 40 | return [self initTypeView];//每次刷新重绘 41 | } 42 | -(float)initTypeView 43 | { 44 | //循环删除typeView所有子视图,防止cell重用产生错乱 45 | while ([typeView.subviews lastObject] != nil) 46 | { 47 | [[typeView.subviews lastObject] removeFromSuperview]; 48 | } 49 | float upX = 10; 50 | float upY = 0; 51 | for (int i = 0; i<_model.typeArray.count; i++) { 52 | UIButton *btn= [JXUIKit buttonWithBackgroundColor:KLightGrayLinecol titleColorForNormal:[UIColor blackColor] titleForNormal:[_model.typeArray objectAtIndex:i] titleForSelete:[_model.typeArray objectAtIndex:i] titleColorForSelete:WhiteColor fontSize:13 font:nil]; 53 | [btn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled]; 54 | 55 | NSDictionary *dic = [NSDictionary dictionaryWithObject:btn.titleLabel.font forKey:NSFontAttributeName]; 56 | CGSize size = [_model.typeArray[i] sizeWithAttributes:dic]; 57 | //NSLog(@"%f",size.height); 58 | //20是左右边距各10,size.width+30是按钮宽度,间隔为10,通过计算x的位置判断是否换行显示按钮 59 | if ( upX > (self.frame.size.width-20 -size.width-40)) { 60 | upX = 10; 61 | upY += 30; 62 | } 63 | btn.frame = CGRectMake(upX, upY, size.width+30,24); 64 | [JXUIKit ViewcornerRadius:12 andColor:WhiteColor andWidth:0 :btn]; 65 | [typeView addSubview:btn]; 66 | btn.tag = 100+i; 67 | [btn addTarget:self action:@selector(touchbtn:) forControlEvents:UIControlEventTouchUpInside]; 68 | upX+=size.width+40; 69 | 70 | if (_model.selectIndex == i) { 71 | btn.selected = YES; 72 | btn.backgroundColor = KBtncol; 73 | } 74 | btn.enabled = [[_model.enableArray objectAtIndex:i] boolValue]; 75 | } 76 | 77 | upY +=30; 78 | UILabel *line = [[UILabel alloc] initWithFrame:CGRectMake(0, upY+10, self.frame.size.width, 0.5)]; 79 | line.backgroundColor = [UIColor lightGrayColor]; 80 | [typeView addSubview:line]; 81 | 82 | typeView.frame = CGRectMake(0, 40, kWidth, upY+11); 83 | return upY+11+40; 84 | 85 | } 86 | -(void)touchbtn:(UIButton *)btn 87 | { 88 | 89 | if (btn.selected == NO) { 90 | _model.selectIndex = (int)btn.tag-100; 91 | }else 92 | { 93 | //取消选中 94 | _model.selectIndex = -1; 95 | } 96 | 97 | for (int i = 0; i<_model.typeArray.count; i++) { 98 | UIButton *button =(UIButton *)[self viewWithTag:100+i]; 99 | button.selected = NO; 100 | [button setBackgroundColor:KLightGrayLinecol]; 101 | //根据seletIndex 确定用户当前点了那个按钮 102 | if (_model.selectIndex == i) { 103 | button.selected = YES; 104 | button.backgroundColor = KBtncol; 105 | } 106 | } 107 | if (self.selectButton) { 108 | self.selectButton(_model.selectIndex); 109 | } 110 | } 111 | - (void)awakeFromNib { 112 | [super awakeFromNib]; 113 | // Initialization code 114 | } 115 | 116 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 117 | [super setSelected:selected animated:animated]; 118 | 119 | // Configure the view for the selected state 120 | } 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/ChoseGoodsTypeAlert.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChoseGoodsTypeAlert.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/9/26. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SizeAttributeModel.h" 12 | @class GoodsModel; 13 | @interface ChoseGoodsTypeAlert : UIView 14 | @property (nonatomic, strong)UITableView *tableview; 15 | @property (nonatomic, strong)NSMutableArray *dataSource; 16 | @property (nonatomic, strong)GoodsModel *model; 17 | @property (nonatomic, copy)void (^selectSize)(SizeAttributeModel *sizeModel); 18 | -(void)hideView; 19 | -(void)showView; 20 | -(void)initData:(GoodsModel *)model; 21 | -(instancetype)initWithFrame:(CGRect)frame andHeight:(float)height;//height 白色弹框高度,自己想设多高设多高 22 | @end 23 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/ChoseGoodsTypeAlert.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // ChoseGoodsTypeAlert.m 4 | // MeiXiangDao_iOS 5 | // 6 | // Created by 澜海利奥 on 2017/9/26. 7 | // Copyright © 2017年 江萧. All rights reserved. 8 | // 9 | 10 | #import "ChoseGoodsTypeAlert.h" 11 | #import "ChoosTypeTableViewCell.h" 12 | #import "GoodsTypeModel.h" 13 | #import "Header.h" 14 | #import "GoodsInfoView.h" 15 | #import "CountView.h" 16 | @implementation ChoseGoodsTypeAlert 17 | { 18 | UIButton *sureButton; 19 | UIView *view; 20 | UIView *bgView; 21 | SizeAttributeModel *sizeModel; 22 | GoodsInfoView *goodsInfo; 23 | CountView *countView; 24 | } 25 | 26 | -(instancetype)initWithFrame:(CGRect)frame andHeight:(float)height { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | self.backgroundColor = [UIColor clearColor]; 30 | //半透明view 31 | view = [[UIView alloc] initWithFrame:self.bounds]; 32 | view.backgroundColor = RGBACOLOR(0, 0, 0, 0.4); 33 | [self addSubview:view]; 34 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideView)]; 35 | [view addGestureRecognizer:tap]; 36 | //白色底view 37 | bgView = [[UIView alloc] initWithFrame:CGRectMake(0, kHeight, kWidth, height)]; 38 | bgView.backgroundColor = [UIColor whiteColor]; 39 | bgView.userInteractionEnabled = YES; 40 | [self addSubview:bgView]; 41 | 42 | //商品信息 43 | goodsInfo = [[GoodsInfoView alloc] initWithFrame:CGRectMake(0, 0, kWidth, kSize(110))]; 44 | [goodsInfo.closeButton addTarget:self action:@selector(hideView) forControlEvents:UIControlEventTouchUpInside]; 45 | [bgView addSubview:goodsInfo]; 46 | 47 | sureButton = [JXUIKit buttonWithBackgroundColor:KBtncol titleColorForNormal:WhiteColor titleForNormal:@"确定" titleForSelete:nil titleColorForSelete:nil fontSize:18 font:nil]; 48 | [sureButton addTarget:self action:@selector(sure) forControlEvents:UIControlEventTouchUpInside]; 49 | [bgView addSubview:sureButton]; 50 | //kbottomHeight为了适配iphonex,不让按钮显示在x底部圆弧范围内 51 | sureButton.sd_layout.leftSpaceToView(bgView, 0).rightSpaceToView(bgView, 0).bottomSpaceToView(bgView, 0).heightIs(49); 52 | [bgView addSubview:self.tableview]; 53 | 54 | self.tableview.sd_layout.leftSpaceToView(bgView, 0).rightSpaceToView(bgView, 0).topSpaceToView(goodsInfo, 0).bottomSpaceToView(sureButton, 0); 55 | } 56 | return self; 57 | } 58 | #pragma mark - methods 59 | -(void)hideView 60 | { 61 | [self tfresignFirstResponder]; 62 | [UIView animateWithDuration:0.25 animations:^ 63 | { 64 | bgView.centerY = bgView.centerY+CGRectGetHeight(bgView.frame); 65 | 66 | } completion:^(BOOL fin){ 67 | [self removeFromSuperview]; 68 | 69 | }]; 70 | 71 | } 72 | // 73 | -(void)showView 74 | { 75 | self.alpha = 1; 76 | [UIView animateWithDuration:0.25 animations:^ 77 | { 78 | bgView.centerY = bgView.centerY-CGRectGetHeight(bgView.frame); 79 | 80 | } completion:^(BOOL fin){}]; 81 | } 82 | -(void)initData:(GoodsModel *)model 83 | { 84 | _model = model; 85 | [goodsInfo initData:model]; 86 | [_dataSource removeAllObjects]; 87 | //传入数据源创建多个属性 88 | [_dataSource addObjectsFromArray:model.itemsList]; 89 | //此方法必须在_dataSource赋值后方可调用 90 | [self reloadGoodsInfo]; 91 | [self.tableview reloadData]; 92 | } 93 | -(void)reloadGoodsInfo 94 | { 95 | for (GoodsTypeModel *model in _dataSource) { 96 | if (model.selectIndex<0) { 97 | goodsInfo.promatLabel.text =[NSString stringWithFormat:@"请选择%@",model.typeName]; 98 | break; 99 | } 100 | } 101 | //每次选择规格后将置灰情况恢复 102 | for (int i = 0; i<_model.itemsList.count; i++) { 103 | GoodsTypeModel *type = _model.itemsList[i]; 104 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 105 | for (int j = 0; j[sizeModel.stock intValue]) { 122 | countView.countTextField.text = [NSString stringWithFormat:@"%d",[sizeModel.stock intValue]]; 123 | }else if ([countView.countTextField.text intValue]<[sizeModel.stock intValue]) 124 | { 125 | if ([countView.countTextField.text intValue] == 0) { 126 | countView.countTextField.text = @"1"; 127 | } 128 | } 129 | goodsInfo.promatLabel.text = [NSString stringWithFormat:@"已选%@",model.value]; 130 | [goodsInfo resetData:model]; 131 | return; 132 | } 133 | } 134 | //没找到匹配的,显示默认数据 135 | [goodsInfo initData:_model]; 136 | } 137 | -(void)setEnableSize:(NSString *)choseSizeStr 138 | { 139 | //用、分割成已选规格数组 140 | NSArray *choseAttArr = [choseSizeStr componentsSeparatedByString:@"、"]; 141 | //遍历所有规格组合,与已选规格进行匹配 142 | for (SizeAttributeModel *model in _model.sizeAttribute) { 143 | NSArray *attArr = [model.value componentsSeparatedByString:@"、"]; 144 | //记录各个规格匹配情况 145 | NSMutableArray *containsArr = [[NSMutableArray alloc] init]; 146 | //统计规格匹配个数 147 | int count=0; 148 | for (NSString *att in attArr) { 149 | if ([choseAttArr containsObject: att]) { 150 | //规格一致设为1,不一致设为0,比如已选规格XL、黑色,与XL、黑色、2016的匹配情况就是@[@"1",@"1",@"0"],后边通过遍历找到@“0”,就能够确定哪个规格没选 151 | [containsArr addObject:@"1"]; 152 | count++; 153 | }else 154 | [containsArr addObject:@"0"]; 155 | } 156 | //当规格选项还差一个的时候才能确定完整组合对应的库存,进行置灰,比如3个规格,已选2个,当count规格匹配数量为2时,说明当前组合就是已选的2个规格跟未选的那个规格的组合,如果该组合库存为零,就可以置灰 157 | if (count == attArr.count-1&&[model.stock isEqualToString:@"0"]) { 158 | //遍历当前规格匹配情况数组 159 | for (int i = 0; i0) { 198 | if (self.selectSize) { 199 | sizeModel.count = countView.countTextField.text; 200 | self.selectSize(sizeModel); 201 | } 202 | [self hideView]; 203 | }else 204 | { 205 | [JXUIKit showErrorWithStatus:@"该规格商品暂无库存无法加入购物车"]; 206 | } 207 | 208 | } 209 | -(NSString *)getSizeStr 210 | { 211 | //拼接属性字符串 212 | NSString *str=@""; 213 | for (GoodsTypeModel *model in _dataSource) { 214 | if (model.selectIndex>=0) { 215 | if (str.length == 0) { 216 | str = model.typeArray[model.selectIndex]; 217 | }else 218 | str = [NSString stringWithFormat:@"%@、%@",str,model.typeArray[model.selectIndex]]; 219 | } 220 | } 221 | return str; 222 | } 223 | #pragma mark-数量加减 224 | -(void)add 225 | { 226 | int count =[countView.countTextField.text intValue]; 227 | //如果有选好的属性就根据选好的属性库存判断,没选择就按总库存判断,数量不能超过库存 228 | if (sizeModel) { 229 | if (count <[sizeModel.stock intValue]) { 230 | countView.countTextField.text = [NSString stringWithFormat:@"%d",count+1]; 231 | } 232 | }else 233 | { 234 | if (count < [_model.totalStock intValue]) { 235 | countView.countTextField.text = [NSString stringWithFormat:@"%d",count+1]; 236 | 237 | } 238 | } 239 | 240 | } 241 | -(void)reduce 242 | { 243 | int count =[countView.countTextField.text intValue]; 244 | if (count > 1) { 245 | 246 | countView.countTextField.text = [NSString stringWithFormat:@"%d",count-1]; 247 | 248 | } 249 | } 250 | #pragma mark-tf 251 | -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField 252 | { 253 | self.tableview.contentOffset = CGPointMake(0, countView.frame.origin.y); 254 | return YES; 255 | } 256 | -(void)textFieldDidEndEditing:(UITextField *)textField 257 | { 258 | int count =[countView.countTextField.text intValue]; 259 | if (sizeModel) { 260 | if (count >[sizeModel.stock intValue]) { 261 | [JXUIKit showWithString:@"数量超出库存"]; 262 | countView.countTextField.text = sizeModel.stock; 263 | } 264 | }else 265 | { 266 | if (count > [_model.totalStock intValue]) { 267 | [JXUIKit showWithString:@"数量超出库存"]; 268 | countView.countTextField.text = _model.totalStock; 269 | 270 | } 271 | } 272 | } 273 | -(void)tfresignFirstResponder 274 | { 275 | self.tableview.contentOffset = CGPointMake(0, 0); 276 | [countView.countTextField resignFirstResponder]; 277 | } 278 | #pragma mark - tavdelegete 279 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 280 | { 281 | 282 | return _dataSource.count; 283 | } 284 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 285 | { 286 | static NSString *ID = @"ChoosTypeTableViewCell"; 287 | ChoosTypeTableViewCell *cell = [[ChoosTypeTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID]; 288 | 289 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 290 | GoodsTypeModel *model = _dataSource[indexPath.row]; 291 | tableView.rowHeight=[cell setData:model]; 292 | MJWeakSelf 293 | cell.selectButton = ^(int selectIndex) { 294 | [weakSelf reloadGoodsInfo]; 295 | }; 296 | return cell; 297 | 298 | } 299 | 300 | -(UITableView *)tableview 301 | { 302 | if (!_tableview) { 303 | _tableview = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, kWidth, kHeight) style:UITableViewStylePlain]; 304 | _tableview.sectionHeaderHeight = 0; 305 | _tableview.backgroundColor = WhiteColor; 306 | _tableview.delegate = self; 307 | _tableview.dataSource = self; 308 | _dataSource = [[NSMutableArray alloc] init]; 309 | countView = [[CountView alloc] initWithFrame:CGRectMake(0, 0, kWidth, kSize(50))]; 310 | countView.countTextField.delegate = self; 311 | [countView.addButton addTarget:self action:@selector(add) forControlEvents:UIControlEventTouchUpInside]; 312 | [countView.reduceButton addTarget:self action:@selector(reduce) forControlEvents:UIControlEventTouchUpInside]; 313 | [countView.textFieldDownButton addTarget:self action:@selector(tfresignFirstResponder) forControlEvents:UIControlEventTouchUpInside]; 314 | _tableview.tableFooterView = countView; 315 | 316 | 317 | } 318 | return _tableview; 319 | } 320 | -(void)dealloc 321 | { 322 | NSLog(@"dddddd"); 323 | } 324 | /* 325 | // Only override drawRect: if you perform custom drawing. 326 | // An empty implementation adversely affects performance during animation. 327 | - (void)drawRect:(CGRect)rect { 328 | // Drawing code 329 | } 330 | */ 331 | 332 | @end 333 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/CountView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CountView.h 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/9/26. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CountView : UIView 12 | @property(nonatomic, strong)UILabel *label; 13 | @property(nonatomic, strong)UIButton *reduceButton;//减 14 | @property(nonatomic, strong)UITextField *countTextField;//输入框 15 | @property(nonatomic, strong)UIButton *addButton;//加 16 | @property(nonatomic, strong)UIButton *textFieldDownButton; 17 | @end 18 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/CountView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CountView.m 3 | // MeiXiangDao_iOS 4 | // 5 | // Created by 澜海利奥 on 2017/9/26. 6 | // Copyright © 2017年 江萧. All rights reserved. 7 | // 8 | 9 | #import "CountView.h" 10 | #import "Header.h" 11 | @implementation CountView 12 | @synthesize addButton,reduceButton,countTextField,label; 13 | -(instancetype)initWithFrame:(CGRect)frame { 14 | self = [super initWithFrame:frame]; 15 | if (self) { 16 | label = [[UILabel alloc] initWithFrame:CGRectMake(kSize(15), kSize(10), kSize(100), kSize(30))]; 17 | label.text = @"购买数量"; 18 | label.font = [UIFont systemFontOfSize:14]; 19 | [self addSubview:label]; 20 | 21 | addButton= [JXUIKit buttonWithBackgroundColor:WhiteColor titleColorForNormal:[UIColor blackColor] titleForNormal:@"+" titleForSelete:nil titleColorForSelete:nil fontSize:20 font:nil]; 22 | [JXUIKit ViewcornerRadius:4 andColor:KLightGrayLinecol andWidth:1 :addButton]; 23 | [self addSubview:addButton]; 24 | addButton.sd_layout.rightSpaceToView(self, kSize(15)).widthIs(kSize(30)).heightIs(kSize(30)).centerYEqualToView(self); 25 | 26 | countTextField = [JXUIKit textFieldWithBackgroundColor:WhiteColor textColor:[UIColor blackColor] secureTextEntry:NO fontSize:15 font:nil text:@"1" placeholder:nil textAlignment:NSTextAlignmentCenter]; 27 | countTextField.keyboardType = UIKeyboardTypeNumberPad; 28 | [JXUIKit ViewcornerRadius:4 andColor:KLightGrayLinecol andWidth:1 :countTextField]; 29 | [self addSubview:countTextField]; 30 | countTextField.sd_layout.rightSpaceToView(addButton, kSize(5)).widthIs(kSize(60)).heightIs(kSize(30)).centerYEqualToView(self); 31 | 32 | UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kWidth, 40)]; 33 | view.backgroundColor = WhiteColor; 34 | 35 | _textFieldDownButton= [JXUIKit buttonWithBackgroundColor:WhiteColor imageForNormal:@"jiantou_down" imageForSelete:nil]; 36 | _textFieldDownButton.frame = CGRectMake(kWidth-50, 0, 50, 40); 37 | [view addSubview:_textFieldDownButton]; 38 | countTextField.inputAccessoryView = view; 39 | 40 | reduceButton= [JXUIKit buttonWithBackgroundColor:WhiteColor titleColorForNormal:[UIColor blackColor] titleForNormal:@"-" titleForSelete:nil titleColorForSelete:nil fontSize:20 font:nil]; 41 | [JXUIKit ViewcornerRadius:4 andColor:KLightGrayLinecol andWidth:1 :reduceButton]; 42 | [self addSubview:reduceButton]; 43 | reduceButton.sd_layout.rightSpaceToView(countTextField, kSize(5)).widthIs(kSize(30)).heightIs(kSize(30)).centerYEqualToView(self); 44 | 45 | } 46 | return self; 47 | } 48 | 49 | /* 50 | // Only override drawRect: if you perform custom drawing. 51 | // An empty implementation adversely affects performance during animation. 52 | - (void)drawRect:(CGRect)rect { 53 | // Drawing code 54 | } 55 | */ 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/GoodsInfoView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsInfoView.h 3 | // ChoseGoodsType 4 | // 5 | // Created by 澜海利奥 on 2018/1/30. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | @class SizeAttributeModel; 11 | @class GoodsModel; 12 | @interface GoodsInfoView : UIView 13 | @property(nonatomic, strong)UIButton *closeButton; 14 | @property(nonatomic, strong)UILabel *promatLabel; 15 | @property (nonatomic, strong)GoodsModel *model; 16 | -(void)initData:(GoodsModel *)model; 17 | -(void)resetData:(SizeAttributeModel *)sizeModel; 18 | @end 19 | -------------------------------------------------------------------------------- /ChoseGoodsType/规格选择/views/GoodsInfoView.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // GoodsInfoView.m 4 | // ChoseGoodsType 5 | // 6 | // Created by 澜海利奥 on 2018/1/30. 7 | // Copyright © 2018年 江萧. All rights reserved. 8 | // 9 | 10 | #import "GoodsInfoView.h" 11 | #import "Header.h" 12 | #import "SizeAttributeModel.h" 13 | @interface GoodsInfoView() 14 | @property(nonatomic, strong)UIImageView *goodsImage; 15 | @property(nonatomic, strong)UILabel *goodsTitleLabel; 16 | @property(nonatomic, strong)UILabel *goodsCountLabel; 17 | @property(nonatomic, strong)UILabel *goodsPriceLabel; 18 | @end 19 | @implementation GoodsInfoView 20 | 21 | -(instancetype)initWithFrame:(CGRect)frame { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | //商品图片 25 | _goodsImage = [[UIImageView alloc] init]; 26 | _goodsImage.image = [UIImage imageNamed:@"1"]; 27 | _goodsImage.contentMode = UIViewContentModeScaleAspectFill; 28 | _goodsImage.clipsToBounds = YES; 29 | [self addSubview:_goodsImage]; 30 | _goodsImage.sd_layout.leftSpaceToView(self,kSize(15)).topSpaceToView(self,kSize(15)).widthIs(kSize(80)).heightIs(kSize(80)); 31 | //关闭按钮 32 | _closeButton = [JXUIKit buttonWithBackgroundColor:[UIColor whiteColor] imageForNormal:@"guanbi" imageForSelete:@"guanbi"]; 33 | [self addSubview:_closeButton]; 34 | _closeButton.sd_layout.rightSpaceToView(self, 0).widthIs(kSize(40)).heightIs(kSize(40)).topSpaceToView(self, 0); 35 | //标题 36 | _goodsTitleLabel = [JXUIKit labelWithBackgroundColor:WhiteColor textColor:[UIColor blackColor] textAlignment:NSTextAlignmentLeft numberOfLines:0 fontSize:0 font:[UIFont systemFontOfSize:15] text:@"标题"]; 37 | [self addSubview:_goodsTitleLabel]; 38 | _goodsTitleLabel.sd_layout.leftSpaceToView(_goodsImage, kSize(10)).rightSpaceToView(_closeButton, kSize(10)).heightIs(kSize(20)).topEqualToView(_goodsImage); 39 | 40 | //价格 41 | _goodsPriceLabel = [JXUIKit labelWithBackgroundColor:WhiteColor textColor:KBtncol textAlignment:NSTextAlignmentLeft numberOfLines:0 fontSize:0 font:[UIFont systemFontOfSize:14] text:@"197"]; 42 | [self addSubview:_goodsPriceLabel]; _goodsPriceLabel.sd_layout.leftSpaceToView(_goodsImage, kSize(10)).rightSpaceToView(_closeButton, kSize(10)).heightIs(kSize(20)).topSpaceToView(_goodsTitleLabel, 0); 43 | 44 | //库存 45 | _goodsCountLabel = [JXUIKit labelWithBackgroundColor:WhiteColor textColor:[UIColor grayColor] textAlignment:NSTextAlignmentLeft numberOfLines:0 fontSize:0 font:[UIFont systemFontOfSize:14] text:@"库存"]; 46 | [self addSubview:_goodsCountLabel]; _goodsCountLabel.sd_layout.leftSpaceToView(_goodsImage, kSize(10)).rightSpaceToView(_closeButton, kSize(10)).heightIs(kSize(20)).topSpaceToView(_goodsPriceLabel, 0); 47 | 48 | 49 | 50 | //选择提示文字 51 | _promatLabel = [JXUIKit labelWithBackgroundColor:WhiteColor textColor:[UIColor grayColor] textAlignment:NSTextAlignmentLeft numberOfLines:0 fontSize:0 font:[UIFont systemFontOfSize:14] text:@""]; 52 | [self addSubview:_promatLabel]; 53 | _promatLabel.sd_layout.leftSpaceToView(_goodsImage, kSize(10)).rightSpaceToView(_closeButton, kSize(10)).heightIs(kSize(20)).topSpaceToView(_goodsCountLabel, 0); 54 | 55 | } 56 | return self; 57 | } 58 | -(void)initData:(GoodsModel *)model 59 | { 60 | _model = model; 61 | [_goodsImage setImage:[UIImage imageNamed:model.imageId]]; 62 | //[goodsImage sd_setImageWithURL:[NSURL URLWithString:[kThumbImageUrl stringByAppendingString:model.imageId]] placeholderImage:kDefaultImage]; 63 | _goodsTitleLabel.text = model.title; 64 | _goodsCountLabel.text = [NSString stringWithFormat:@"库存:%@",model.totalStock]; 65 | _goodsPriceLabel.text = [NSString stringWithFormat:@"¥%@ ¥%@",model.price.minPrice,model.price.minOriginalPrice]; 66 | NSMutableAttributedString *attritu = [[NSMutableAttributedString alloc]initWithString:_goodsPriceLabel.text]; 67 | [attritu addAttributes:@{NSStrikethroughStyleAttributeName:@(NSUnderlineStyleThick), NSForegroundColorAttributeName: [UIColor lightGrayColor],NSBaselineOffsetAttributeName:@(0), 68 | NSFontAttributeName: [UIFont systemFontOfSize:13] 69 | } range:[_goodsPriceLabel.text rangeOfString:[NSString stringWithFormat:@"¥%@",model.price.minOriginalPrice]]]; 70 | _goodsPriceLabel.attributedText = attritu; 71 | } 72 | 73 | //根据选择的属性组合刷新商品信息 74 | -(void)resetData:(SizeAttributeModel *)sizeModel 75 | { 76 | //如果有图片就显示图片,没图片就显示默认图 77 | if (sizeModel.imageId.length>0) { 78 | [_goodsImage setImage:[UIImage imageNamed:sizeModel.imageId]]; 79 | }else 80 | [_goodsImage setImage:[UIImage imageNamed:_model.imageId]]; 81 | 82 | _goodsCountLabel.text = [NSString stringWithFormat:@"库存:%@",sizeModel.stock]; 83 | _goodsPriceLabel.text = [NSString stringWithFormat:@"¥%@ ¥%@",sizeModel.price,sizeModel.originalPrice]; 84 | NSMutableAttributedString *attritu = [[NSMutableAttributedString alloc]initWithString:_goodsPriceLabel.text]; 85 | [attritu addAttributes:@{NSStrikethroughStyleAttributeName:@(NSUnderlineStyleThick), NSForegroundColorAttributeName: [UIColor lightGrayColor],NSBaselineOffsetAttributeName:@(0), 86 | NSFontAttributeName: [UIFont systemFontOfSize:13] 87 | } range:[_goodsPriceLabel.text rangeOfString:[NSString stringWithFormat:@"¥%@",sizeModel.originalPrice]]]; 88 | _goodsPriceLabel.attributedText = attritu; 89 | } 90 | /* 91 | // Only override drawRect: if you perform custom drawing. 92 | // An empty implementation adversely affects performance during animation. 93 | - (void)drawRect:(CGRect)rect { 94 | // Drawing code 95 | } 96 | */ 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /ChoseGoodsTypeTests/ChoseGoodsTypeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChoseGoodsTypeTests.m 3 | // ChoseGoodsTypeTests 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ChoseGoodsTypeTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ChoseGoodsTypeTests 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 | -------------------------------------------------------------------------------- /ChoseGoodsTypeTests/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 | -------------------------------------------------------------------------------- /ChoseGoodsTypeUITests/ChoseGoodsTypeUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChoseGoodsTypeUITests.m 3 | // ChoseGoodsTypeUITests 4 | // 5 | // Created by 澜海利奥 on 2018/1/29. 6 | // Copyright © 2018年 江萧. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ChoseGoodsTypeUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ChoseGoodsTypeUITests 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 | -------------------------------------------------------------------------------- /ChoseGoodsTypeUITests/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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChoseGoodsType 2 | 之前写过一个仿淘宝商品详情页和加入购物车的demo,有许多朋友下载了,但是那份代码只适用于商品规格只有两种的商品,拓展性不强,可以参考思路,地址(https://github.com/qlyx/AddShoppingCart) 3 | 最近又有朋友问到这个demo是否能添加两个以上规格,所以写了这份代码,希望对大家有帮助 4 | 使用tableview可以设置多个商品规格,刷新数据源即可 5 | swift版:https://github.com/qlyx/swiftChooseGoodsType 6 | 7 | ![image](https://github.com/qlyx/ChoseGoodsType/blob/master/chosetype.gif) 8 | ## 下面代码创建即可 9 | ChoseGoodsTypeAlert *_alert = [[ChoseGoodsTypeAlert alloc] initWithFrame:CGRectMake(0, 0, kWidth, kHeight) andHeight:kSize (450)]; 10 | _alert.alpha = 0; 11 | [[UIApplication sharedApplication].keyWindow addSubview:_alert]; 12 | 13 | _alert.selectSize = ^(SizeAttributeModel *sizeModel) { 14 | //sizeModel 选择的属性模型 15 | [SVProgressHUD showWithString:[NSString stringWithFormat:@"选择了:%@",sizeModel.value]]; 16 | }; 17 | [_alert initData:model]; 18 | [_alert showView]; 19 | 20 | -(void)initData:(GoodsModel *)model 21 | { 22 | 23 | _model = model; 24 | [goodsInfo initData:model]; 25 | [_dataSource removeAllObjects]; 26 | //传入数据源创建多个属性 27 | [_dataSource addObjectsFromArray:model.itemsList]; 28 | //此方法必须在_dataSource赋值后方可调用 29 | [self reloadGoodsInfo]; 30 | [self.tableview reloadData]; 31 | } 32 | ### 页面布局使用的是SD,提示HUD用的SVProgressHUD,如果使用的是其他HUD,修改JXUIKit下列代码即可 33 | +(void)showWithString:(NSString *)string 34 | { 35 | [SVProgressHUD showWithString:string]; 36 | } 37 | 如果觉得对您有帮助请随意打赏一下吧^ _ ^,您的支持是我的无限动力,谢谢 38 | 39 | ![](https://github.com/qlyx/ChoseGoodsType/blob/master/erweima.png) 40 | 41 | 谢谢打赏,使用时如有问题可扫下方二维码加我哦 42 | 43 | ![一起交流,一起进步](https://github.com/qlyx/ChoseGoodsType/blob/master/jiawo.jpg) 44 | -------------------------------------------------------------------------------- /chosetype.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/chosetype.gif -------------------------------------------------------------------------------- /erweima.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/erweima.png -------------------------------------------------------------------------------- /jiawo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlyx/ChoseGoodsType/ba95b53a60fafa5e20dd782f3c94a395a2050a45/jiawo.jpg --------------------------------------------------------------------------------