├── .gitignore ├── .travis.yml ├── Example ├── FMFormSubmitKit.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── FMFormSubmitKit-Example.xcscheme ├── FMFormSubmitKit.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── FMFormSubmitKit │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── FMAppDelegate.h │ ├── FMAppDelegate.m │ ├── FMFormSubmitKit-Info.plist │ ├── FMFormSubmitKit-Prefix.pch │ ├── FMUpImageItemView.h │ ├── FMUpImageItemView.m │ ├── FMViewController.h │ ├── FMViewController.m │ ├── FormListSubmitVC.h │ ├── FormListSubmitVC.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── base_choose_no.imageset │ │ │ ├── Contents.json │ │ │ ├── 椭圆 3@2x.png │ │ │ └── 椭圆 3@3x.png │ │ ├── base_choose_yes.imageset │ │ │ ├── Contents.json │ │ │ ├── 组 5@2x.png │ │ │ └── 组 5@3x.png │ │ ├── login_eye_no.imageset │ │ │ ├── Contents.json │ │ │ ├── 组 6@2x.png │ │ │ └── 组 6@3x.png │ │ ├── login_eye_yes.imageset │ │ │ ├── Contents.json │ │ │ ├── 图层 60@2x.png │ │ │ └── 图层 60@3x.png │ │ ├── mine_arrow_right_black.imageset │ │ │ ├── Contents.json │ │ │ ├── 矢量智能对象 拷贝 2@2x.png │ │ │ └── 矢量智能对象 拷贝 2@3x.png │ │ └── upImage_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── 组 38.png │ │ │ ├── 组 38@2x.png │ │ │ └── 组 38@3x.png │ ├── SubmitViewController.h │ ├── SubmitViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── FMFormSubmitKit.podspec.json │ ├── Manifest.lock │ ├── Masonry │ │ ├── LICENSE │ │ ├── Masonry │ │ │ ├── MASCompositeConstraint.h │ │ │ ├── MASCompositeConstraint.m │ │ │ ├── MASConstraint+Private.h │ │ │ ├── MASConstraint.h │ │ │ ├── MASConstraint.m │ │ │ ├── MASConstraintMaker.h │ │ │ ├── MASConstraintMaker.m │ │ │ ├── MASLayoutConstraint.h │ │ │ ├── MASLayoutConstraint.m │ │ │ ├── MASUtilities.h │ │ │ ├── MASViewAttribute.h │ │ │ ├── MASViewAttribute.m │ │ │ ├── MASViewConstraint.h │ │ │ ├── MASViewConstraint.m │ │ │ ├── Masonry.h │ │ │ ├── NSArray+MASAdditions.h │ │ │ ├── NSArray+MASAdditions.m │ │ │ ├── NSArray+MASShorthandAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.m │ │ │ ├── View+MASAdditions.h │ │ │ ├── View+MASAdditions.m │ │ │ ├── View+MASShorthandAdditions.h │ │ │ ├── ViewController+MASAdditions.h │ │ │ └── ViewController+MASAdditions.m │ │ └── README.md │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── FMFormSubmitKit │ │ ├── FMFormSubmitKit-Info.plist │ │ ├── FMFormSubmitKit-dummy.m │ │ ├── FMFormSubmitKit-prefix.pch │ │ ├── FMFormSubmitKit-umbrella.h │ │ ├── FMFormSubmitKit.debug.xcconfig │ │ ├── FMFormSubmitKit.modulemap │ │ └── FMFormSubmitKit.release.xcconfig │ │ ├── Masonry │ │ ├── Masonry-Info.plist │ │ ├── Masonry-dummy.m │ │ ├── Masonry-prefix.pch │ │ ├── Masonry-umbrella.h │ │ ├── Masonry.debug.xcconfig │ │ ├── Masonry.modulemap │ │ └── Masonry.release.xcconfig │ │ ├── Pods-FMFormSubmitKit_Example │ │ ├── Pods-FMFormSubmitKit_Example-Info.plist │ │ ├── Pods-FMFormSubmitKit_Example-acknowledgements.markdown │ │ ├── Pods-FMFormSubmitKit_Example-acknowledgements.plist │ │ ├── Pods-FMFormSubmitKit_Example-dummy.m │ │ ├── Pods-FMFormSubmitKit_Example-frameworks.sh │ │ ├── Pods-FMFormSubmitKit_Example-umbrella.h │ │ ├── Pods-FMFormSubmitKit_Example.debug.xcconfig │ │ ├── Pods-FMFormSubmitKit_Example.modulemap │ │ └── Pods-FMFormSubmitKit_Example.release.xcconfig │ │ └── Pods-FMFormSubmitKit_Tests │ │ ├── Pods-FMFormSubmitKit_Tests-Info.plist │ │ ├── Pods-FMFormSubmitKit_Tests-acknowledgements.markdown │ │ ├── Pods-FMFormSubmitKit_Tests-acknowledgements.plist │ │ ├── Pods-FMFormSubmitKit_Tests-dummy.m │ │ ├── Pods-FMFormSubmitKit_Tests-frameworks.sh │ │ ├── Pods-FMFormSubmitKit_Tests-umbrella.h │ │ ├── Pods-FMFormSubmitKit_Tests.debug.xcconfig │ │ ├── Pods-FMFormSubmitKit_Tests.modulemap │ │ └── Pods-FMFormSubmitKit_Tests.release.xcconfig └── Tests │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── en.lproj │ └── InfoPlist.strings ├── FMFormSubmitKit.podspec ├── FMFormSubmitKit ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── FMFormSubmitKit.h │ ├── FormListCellConfigure.h │ ├── FormListCellConfigure.m │ ├── FormListConfigure.h │ ├── FormListHandle.h │ ├── FormListHandle.m │ ├── FormListSubmitView.h │ ├── FormListSubmitView.m │ ├── FormListUpImageConfigure.h │ ├── FormListUpImageConfigure.m │ ├── Model │ ├── FormListBaseModel.h │ ├── FormListBaseModel.m │ ├── FormListImageSelectModel.h │ ├── FormListImageSelectModel.m │ ├── FormListImageUpModel.h │ ├── FormListImageUpModel.m │ ├── FormListSelectModel.h │ ├── FormListSelectModel.m │ ├── FormListTextModel.h │ ├── FormListTextModel.m │ ├── FormListTitleModel.h │ └── FormListTitleModel.m │ ├── Tool │ ├── FormVerifyManager.h │ ├── FormVerifyManager.m │ ├── FormVerifyTextDelegate.h │ ├── NSString+FormEmoji.h │ ├── NSString+FormEmoji.m │ ├── UITextField+FormExtension.h │ ├── UITextField+FormExtension.m │ ├── UITextView+FormExtension.h │ └── UITextView+FormExtension.m │ └── View │ ├── FormListBaseCell.h │ ├── FormListBaseCell.m │ ├── FormListImageUpCell.h │ ├── FormListImageUpCell.m │ ├── FormListImageUpCellItemView.h │ ├── FormListImageUpCellItemView.m │ ├── FormListSelectCell.h │ ├── FormListSelectCell.m │ ├── FormListTextCell.h │ ├── FormListTextCell.m │ ├── FormListTextVCell.h │ ├── FormListTextVCell.m │ ├── FormListTitleCell.h │ ├── FormListTitleCell.m │ ├── FormTextView.h │ └── FormTextView.m ├── LICENSE ├── README.md ├── _Pods.xcodeproj └── submitNewVersion.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | # 41 | # Add this line if you want to avoid checking in source code from the Xcode workspace 42 | # *.xcworkspace 43 | 44 | # Carthage 45 | # 46 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 47 | # Carthage/Checkouts 48 | 49 | Carthage/Build/ 50 | 51 | # fastlane 52 | # 53 | # It is recommended to not store the screenshots in the git repo. 54 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 55 | # For more information about the recommended setup visit: 56 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 57 | 58 | fastlane/report.xml 59 | fastlane/Preview.html 60 | fastlane/screenshots/**/*.png 61 | fastlane/test_output 62 | 63 | # Code Injection 64 | # 65 | # After new code Injection tools there's a generated folder /iOSInjectionProject 66 | # https://github.com/johnno1962/injectionforxcode 67 | 68 | iOSInjectionProject/ 69 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/FMFormSubmitKit.xcworkspace -scheme FMFormSubmitKit-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit.xcodeproj/xcshareddata/xcschemes/FMFormSubmitKit-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 64 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMAppDelegate.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface FMAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMAppDelegate.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | #import "FMAppDelegate.h" 10 | 11 | // pod trunk push FMFormSubmitKit.podspec --allow-warnings 12 | 13 | @implementation FMAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | // Override point for customization after application launch. 18 | return YES; 19 | } 20 | 21 | - (void)applicationWillResignActive:(UIApplication *)application 22 | { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application 28 | { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application 34 | { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application 39 | { 40 | // 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. 41 | } 42 | 43 | - (void)applicationWillTerminate:(UIApplication *)application 44 | { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMFormSubmitKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | $(PRODUCT_NAME) 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMFormSubmitKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMUpImageItemView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMUpImageItemView.h 3 | // FMFormSubmitKit_Example 4 | // 5 | // Created by 周发明 on 2020/4/21. 6 | // Copyright © 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FMUpImageItemView : FormListImageUpCellItemView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMUpImageItemView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMUpImageItemView.m 3 | // FMFormSubmitKit_Example 4 | // 5 | // Created by 周发明 on 2020/4/21. 6 | // Copyright © 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | #import "FMUpImageItemView.h" 10 | #import 11 | 12 | @interface FMUpImageItemView () 13 | 14 | @property(nonatomic, weak)UIButton *btn; 15 | @property(nonatomic, weak)UIButton *deleteBtn; 16 | @end 17 | 18 | @implementation FMUpImageItemView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | UIButton *btn = [[UIButton alloc] init]; 25 | btn.backgroundColor = [UIColor redColor]; 26 | [self addSubview:btn]; 27 | [btn addTarget:self action:@selector(addImageClick) forControlEvents:UIControlEventTouchUpInside]; 28 | self.btn = btn; 29 | 30 | UIButton *delete = [[UIButton alloc] init]; 31 | [delete addTarget:self action:@selector(delButtonClick) forControlEvents:UIControlEventTouchUpInside]; 32 | [delete setTitle:@"删" forState:UIControlStateNormal]; 33 | [self addSubview:delete]; 34 | self.deleteBtn = delete; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)layoutSubviews{ 40 | [super layoutSubviews]; 41 | self.btn.frame = self.bounds; 42 | self.deleteBtn.frame = CGRectMake(0, 0, 30, 30); 43 | } 44 | 45 | - (void)setModel:(FormListImageSelectModel *)model{ 46 | [super setModel:model]; 47 | if (model.image) { 48 | self.btn.backgroundColor = [UIColor orangeColor]; 49 | } else { 50 | self.btn.backgroundColor = [UIColor redColor]; 51 | } 52 | } 53 | 54 | - (void)addImageClick{ 55 | self.model.image = [UIImage new]; 56 | [super addImageClick]; 57 | } 58 | 59 | - (void)delButtonClick{ 60 | self.model.image = nil; 61 | [super delButtonClick]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMViewController.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface FMViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMViewController.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | #import "FMViewController.h" 10 | #import "SubmitViewController.h" 11 | 12 | @interface FMViewController () 13 | 14 | @end 15 | 16 | @implementation FMViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | } 23 | 24 | - (void)didReceiveMemoryWarning 25 | { 26 | [super didReceiveMemoryWarning]; 27 | // Dispose of any resources that can be recreated. 28 | } 29 | 30 | - (IBAction)btnClick:(id)sender { 31 | SubmitViewController *submit = [[SubmitViewController alloc] init]; 32 | [self.navigationController pushViewController:submit animated:YES]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FormListSubmitVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSubmitVC.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @interface FormListSubmitVC : UIViewController 14 | @property(nonatomic, assign)UITableViewStyle tableStyle; 15 | @property(nonatomic, weak)FormListSubmitView *tableView; 16 | @property (nonatomic, strong)NSMutableArray *dataSource; 17 | - (void)addData; 18 | - (void)configurationTable; 19 | 20 | - (BOOL)verifyDataSource; 21 | - (BOOL)verifyDataSource:(BOOL)alert; 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/FormListSubmitVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSubmitVC.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListSubmitVC.h" 10 | 11 | @interface FormListSubmitVC () 12 | 13 | @end 14 | 15 | @implementation FormListSubmitVC 16 | 17 | - (UITableViewStyle)tableStyle{ 18 | return UITableViewStylePlain; 19 | } 20 | 21 | - (NSMutableArray *)dataSource 22 | { 23 | return self.tableView.handle.models; 24 | } 25 | 26 | - (void)setDataSource:(NSMutableArray *)dataSource{ 27 | self.tableView.handle.models = dataSource; 28 | } 29 | 30 | - (FormListSubmitView *)tableView{ 31 | if (_tableView == nil) { 32 | FormListSubmitView *table = [[FormListSubmitView alloc] initWithFrame:CGRectZero style:self.tableStyle]; 33 | [self.view addSubview:table]; 34 | _tableView = table; 35 | } 36 | return _tableView; 37 | } 38 | 39 | - (void)viewDidLoad { 40 | [super viewDidLoad]; 41 | self.view.backgroundColor = [UIColor whiteColor]; 42 | [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { 43 | make.left.right.top.bottom.equalTo(@0); 44 | }]; 45 | [self configurationTable]; 46 | [self addData]; 47 | } 48 | 49 | - (void)addData{ 50 | 51 | } 52 | 53 | - (void)configurationTable{ 54 | 55 | } 56 | 57 | - (BOOL)verifyDataSource{ 58 | return [self.tableView.handle verifyDataSource]; 59 | } 60 | - (BOOL)verifyDataSource:(BOOL)alert{ 61 | return [self.tableView.handle verifyDataSource:alert]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_no.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "椭圆 3@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "椭圆 3@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_no.imageset/椭圆 3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/base_choose_no.imageset/椭圆 3@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_no.imageset/椭圆 3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/base_choose_no.imageset/椭圆 3@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_yes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "组 5@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "组 5@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_yes.imageset/组 5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/base_choose_yes.imageset/组 5@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/base_choose_yes.imageset/组 5@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/base_choose_yes.imageset/组 5@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_no.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "组 6@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "组 6@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_no.imageset/组 6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/login_eye_no.imageset/组 6@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_no.imageset/组 6@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/login_eye_no.imageset/组 6@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_yes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "图层 60@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "图层 60@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_yes.imageset/图层 60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/login_eye_yes.imageset/图层 60@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/login_eye_yes.imageset/图层 60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/login_eye_yes.imageset/图层 60@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/mine_arrow_right_black.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "矢量智能对象 拷贝 2@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "矢量智能对象 拷贝 2@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/mine_arrow_right_black.imageset/矢量智能对象 拷贝 2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/mine_arrow_right_black.imageset/矢量智能对象 拷贝 2@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/mine_arrow_right_black.imageset/矢量智能对象 拷贝 2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/mine_arrow_right_black.imageset/矢量智能对象 拷贝 2@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "组 38.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "组 38@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "组 38@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38@2x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/Example/FMFormSubmitKit/Images.xcassets/upImage_icon.imageset/组 38@3x.png -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/SubmitViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SubmitViewController.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2019/12/20. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListSubmitVC.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface SubmitViewController : FormListSubmitVC 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/FMFormSubmitKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "FMAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([FMAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | platform :ios, '8.0' 4 | 5 | target 'FMFormSubmitKit_Example' do 6 | pod 'FMFormSubmitKit', :path => '../' 7 | 8 | target 'FMFormSubmitKit_Tests' do 9 | inherit! :search_paths 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMFormSubmitKit (0.1.0): 3 | - Masonry 4 | - Masonry (1.1.0) 5 | 6 | DEPENDENCIES: 7 | - FMFormSubmitKit (from `../`) 8 | - Masonry 9 | 10 | SPEC REPOS: 11 | trunk: 12 | - Masonry 13 | 14 | EXTERNAL SOURCES: 15 | FMFormSubmitKit: 16 | :path: "../" 17 | 18 | SPEC CHECKSUMS: 19 | FMFormSubmitKit: 04f965fe43962f2de563ea5c682cf65811767464 20 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 21 | 22 | PODFILE CHECKSUM: 70d9d8c25fcda8a6a1e54a889624aa9ee872640b 23 | 24 | COCOAPODS: 1.9.0 25 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/FMFormSubmitKit.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FMFormSubmitKit", 3 | "version": "0.1.0", 4 | "summary": "A short description of FMFormSubmitKit.", 5 | "description": "TODO: Add long description of the pod here.", 6 | "homepage": "https://github.com/zhoufaming251@163.com/FMFormSubmitKit", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "zhoufaming251@163.com": "zhoufaming251@163.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/zhoufaming251@163.com/FMFormSubmitKit.git", 16 | "tag": "0.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0" 20 | }, 21 | "source_files": "FMFormSubmitKit/Classes/**/*", 22 | "dependencies": { 23 | "Masonry": [ 24 | 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMFormSubmitKit (0.1.0): 3 | - Masonry 4 | - Masonry (1.1.0) 5 | 6 | DEPENDENCIES: 7 | - FMFormSubmitKit (from `../`) 8 | - Masonry 9 | 10 | SPEC REPOS: 11 | trunk: 12 | - Masonry 13 | 14 | EXTERNAL SOURCES: 15 | FMFormSubmitKit: 16 | :path: "../" 17 | 18 | SPEC CHECKSUMS: 19 | FMFormSubmitKit: 04f965fe43962f2de563ea5c682cf65811767464 20 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 21 | 22 | PODFILE CHECKSUM: 70d9d8c25fcda8a6a1e54a889624aa9ee872640b 23 | 24 | COCOAPODS: 1.9.0 25 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | /** 13 | * A group of MASConstraint objects 14 | */ 15 | @interface MASCompositeConstraint : MASConstraint 16 | 17 | /** 18 | * Creates a composite with a predefined array of children 19 | * 20 | * @param children child MASConstraints 21 | * 22 | * @return a composite constraint 23 | */ 24 | - (id)initWithChildren:(NSArray *)children; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASCompositeConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASCompositeConstraint.h" 10 | #import "MASConstraint+Private.h" 11 | 12 | @interface MASCompositeConstraint () 13 | 14 | @property (nonatomic, strong) id mas_key; 15 | @property (nonatomic, strong) NSMutableArray *childConstraints; 16 | 17 | @end 18 | 19 | @implementation MASCompositeConstraint 20 | 21 | - (id)initWithChildren:(NSArray *)children { 22 | self = [super init]; 23 | if (!self) return nil; 24 | 25 | _childConstraints = [children mutableCopy]; 26 | for (MASConstraint *constraint in _childConstraints) { 27 | constraint.delegate = self; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - MASConstraintDelegate 34 | 35 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { 36 | NSUInteger index = [self.childConstraints indexOfObject:constraint]; 37 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); 38 | [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint]; 39 | } 40 | 41 | - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 42 | id strongDelegate = self.delegate; 43 | MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 44 | newConstraint.delegate = self; 45 | [self.childConstraints addObject:newConstraint]; 46 | return newConstraint; 47 | } 48 | 49 | #pragma mark - NSLayoutConstraint multiplier proxies 50 | 51 | - (MASConstraint * (^)(CGFloat))multipliedBy { 52 | return ^id(CGFloat multiplier) { 53 | for (MASConstraint *constraint in self.childConstraints) { 54 | constraint.multipliedBy(multiplier); 55 | } 56 | return self; 57 | }; 58 | } 59 | 60 | - (MASConstraint * (^)(CGFloat))dividedBy { 61 | return ^id(CGFloat divider) { 62 | for (MASConstraint *constraint in self.childConstraints) { 63 | constraint.dividedBy(divider); 64 | } 65 | return self; 66 | }; 67 | } 68 | 69 | #pragma mark - MASLayoutPriority proxy 70 | 71 | - (MASConstraint * (^)(MASLayoutPriority))priority { 72 | return ^id(MASLayoutPriority priority) { 73 | for (MASConstraint *constraint in self.childConstraints) { 74 | constraint.priority(priority); 75 | } 76 | return self; 77 | }; 78 | } 79 | 80 | #pragma mark - NSLayoutRelation proxy 81 | 82 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { 83 | return ^id(id attr, NSLayoutRelation relation) { 84 | for (MASConstraint *constraint in self.childConstraints.copy) { 85 | constraint.equalToWithRelation(attr, relation); 86 | } 87 | return self; 88 | }; 89 | } 90 | 91 | #pragma mark - attribute chaining 92 | 93 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 94 | [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 95 | return self; 96 | } 97 | 98 | #pragma mark - Animator proxy 99 | 100 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 101 | 102 | - (MASConstraint *)animator { 103 | for (MASConstraint *constraint in self.childConstraints) { 104 | [constraint animator]; 105 | } 106 | return self; 107 | } 108 | 109 | #endif 110 | 111 | #pragma mark - debug helpers 112 | 113 | - (MASConstraint * (^)(id))key { 114 | return ^id(id key) { 115 | self.mas_key = key; 116 | int i = 0; 117 | for (MASConstraint *constraint in self.childConstraints) { 118 | constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]); 119 | } 120 | return self; 121 | }; 122 | } 123 | 124 | #pragma mark - NSLayoutConstraint constant setters 125 | 126 | - (void)setInsets:(MASEdgeInsets)insets { 127 | for (MASConstraint *constraint in self.childConstraints) { 128 | constraint.insets = insets; 129 | } 130 | } 131 | 132 | - (void)setInset:(CGFloat)inset { 133 | for (MASConstraint *constraint in self.childConstraints) { 134 | constraint.inset = inset; 135 | } 136 | } 137 | 138 | - (void)setOffset:(CGFloat)offset { 139 | for (MASConstraint *constraint in self.childConstraints) { 140 | constraint.offset = offset; 141 | } 142 | } 143 | 144 | - (void)setSizeOffset:(CGSize)sizeOffset { 145 | for (MASConstraint *constraint in self.childConstraints) { 146 | constraint.sizeOffset = sizeOffset; 147 | } 148 | } 149 | 150 | - (void)setCenterOffset:(CGPoint)centerOffset { 151 | for (MASConstraint *constraint in self.childConstraints) { 152 | constraint.centerOffset = centerOffset; 153 | } 154 | } 155 | 156 | #pragma mark - MASConstraint 157 | 158 | - (void)activate { 159 | for (MASConstraint *constraint in self.childConstraints) { 160 | [constraint activate]; 161 | } 162 | } 163 | 164 | - (void)deactivate { 165 | for (MASConstraint *constraint in self.childConstraints) { 166 | [constraint deactivate]; 167 | } 168 | } 169 | 170 | - (void)install { 171 | for (MASConstraint *constraint in self.childConstraints) { 172 | constraint.updateExisting = self.updateExisting; 173 | [constraint install]; 174 | } 175 | } 176 | 177 | - (void)uninstall { 178 | for (MASConstraint *constraint in self.childConstraints) { 179 | [constraint uninstall]; 180 | } 181 | } 182 | 183 | @end 184 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint+Private.h 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 29/04/14. 6 | // Copyright (c) 2014 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | 11 | @protocol MASConstraintDelegate; 12 | 13 | 14 | @interface MASConstraint () 15 | 16 | /** 17 | * Whether or not to check for an existing constraint instead of adding constraint 18 | */ 19 | @property (nonatomic, assign) BOOL updateExisting; 20 | 21 | /** 22 | * Usually MASConstraintMaker but could be a parent MASConstraint 23 | */ 24 | @property (nonatomic, weak) id delegate; 25 | 26 | /** 27 | * Based on a provided value type, is equal to calling: 28 | * NSNumber - setOffset: 29 | * NSValue with CGPoint - setPointOffset: 30 | * NSValue with CGSize - setSizeOffset: 31 | * NSValue with MASEdgeInsets - setInsets: 32 | */ 33 | - (void)setLayoutConstantWithValue:(NSValue *)value; 34 | 35 | @end 36 | 37 | 38 | @interface MASConstraint (Abstract) 39 | 40 | /** 41 | * Sets the constraint relation to given NSLayoutRelation 42 | * returns a block which accepts one of the following: 43 | * MASViewAttribute, UIView, NSValue, NSArray 44 | * see readme for more details. 45 | */ 46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 47 | 48 | /** 49 | * Override to set a custom chaining behaviour 50 | */ 51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 52 | 53 | @end 54 | 55 | 56 | @protocol MASConstraintDelegate 57 | 58 | /** 59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example 60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks 61 | */ 62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; 63 | 64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASConstraintMaker.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraintMaker.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | typedef NS_OPTIONS(NSInteger, MASAttribute) { 13 | MASAttributeLeft = 1 << NSLayoutAttributeLeft, 14 | MASAttributeRight = 1 << NSLayoutAttributeRight, 15 | MASAttributeTop = 1 << NSLayoutAttributeTop, 16 | MASAttributeBottom = 1 << NSLayoutAttributeBottom, 17 | MASAttributeLeading = 1 << NSLayoutAttributeLeading, 18 | MASAttributeTrailing = 1 << NSLayoutAttributeTrailing, 19 | MASAttributeWidth = 1 << NSLayoutAttributeWidth, 20 | MASAttributeHeight = 1 << NSLayoutAttributeHeight, 21 | MASAttributeCenterX = 1 << NSLayoutAttributeCenterX, 22 | MASAttributeCenterY = 1 << NSLayoutAttributeCenterY, 23 | MASAttributeBaseline = 1 << NSLayoutAttributeBaseline, 24 | 25 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 26 | 27 | MASAttributeFirstBaseline = 1 << NSLayoutAttributeFirstBaseline, 28 | MASAttributeLastBaseline = 1 << NSLayoutAttributeLastBaseline, 29 | 30 | #endif 31 | 32 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 33 | 34 | MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin, 35 | MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin, 36 | MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin, 37 | MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin, 38 | MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin, 39 | MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin, 40 | MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins, 41 | MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins, 42 | 43 | #endif 44 | 45 | }; 46 | 47 | /** 48 | * Provides factory methods for creating MASConstraints. 49 | * Constraints are collected until they are ready to be installed 50 | * 51 | */ 52 | @interface MASConstraintMaker : NSObject 53 | 54 | /** 55 | * The following properties return a new MASViewConstraint 56 | * with the first item set to the makers associated view and the appropriate MASViewAttribute 57 | */ 58 | @property (nonatomic, strong, readonly) MASConstraint *left; 59 | @property (nonatomic, strong, readonly) MASConstraint *top; 60 | @property (nonatomic, strong, readonly) MASConstraint *right; 61 | @property (nonatomic, strong, readonly) MASConstraint *bottom; 62 | @property (nonatomic, strong, readonly) MASConstraint *leading; 63 | @property (nonatomic, strong, readonly) MASConstraint *trailing; 64 | @property (nonatomic, strong, readonly) MASConstraint *width; 65 | @property (nonatomic, strong, readonly) MASConstraint *height; 66 | @property (nonatomic, strong, readonly) MASConstraint *centerX; 67 | @property (nonatomic, strong, readonly) MASConstraint *centerY; 68 | @property (nonatomic, strong, readonly) MASConstraint *baseline; 69 | 70 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 71 | 72 | @property (nonatomic, strong, readonly) MASConstraint *firstBaseline; 73 | @property (nonatomic, strong, readonly) MASConstraint *lastBaseline; 74 | 75 | #endif 76 | 77 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 78 | 79 | @property (nonatomic, strong, readonly) MASConstraint *leftMargin; 80 | @property (nonatomic, strong, readonly) MASConstraint *rightMargin; 81 | @property (nonatomic, strong, readonly) MASConstraint *topMargin; 82 | @property (nonatomic, strong, readonly) MASConstraint *bottomMargin; 83 | @property (nonatomic, strong, readonly) MASConstraint *leadingMargin; 84 | @property (nonatomic, strong, readonly) MASConstraint *trailingMargin; 85 | @property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins; 86 | @property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins; 87 | 88 | #endif 89 | 90 | /** 91 | * Returns a block which creates a new MASCompositeConstraint with the first item set 92 | * to the makers associated view and children corresponding to the set bits in the 93 | * MASAttribute parameter. Combine multiple attributes via binary-or. 94 | */ 95 | @property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs); 96 | 97 | /** 98 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges 99 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right) 100 | * with the first item set to the makers associated view 101 | */ 102 | @property (nonatomic, strong, readonly) MASConstraint *edges; 103 | 104 | /** 105 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize 106 | * which generates the appropriate MASViewConstraint children (width, height) 107 | * with the first item set to the makers associated view 108 | */ 109 | @property (nonatomic, strong, readonly) MASConstraint *size; 110 | 111 | /** 112 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter 113 | * which generates the appropriate MASViewConstraint children (centerX, centerY) 114 | * with the first item set to the makers associated view 115 | */ 116 | @property (nonatomic, strong, readonly) MASConstraint *center; 117 | 118 | /** 119 | * Whether or not to check for an existing constraint instead of adding constraint 120 | */ 121 | @property (nonatomic, assign) BOOL updateExisting; 122 | 123 | /** 124 | * Whether or not to remove existing constraints prior to installing 125 | */ 126 | @property (nonatomic, assign) BOOL removeExisting; 127 | 128 | /** 129 | * initialises the maker with a default view 130 | * 131 | * @param view any MASConstraint are created with this view as the first item 132 | * 133 | * @return a new MASConstraintMaker 134 | */ 135 | - (id)initWithView:(MAS_VIEW *)view; 136 | 137 | /** 138 | * Calls install method on any MASConstraints which have been created by this maker 139 | * 140 | * @return an array of all the installed MASConstraints 141 | */ 142 | - (NSArray *)install; 143 | 144 | - (MASConstraint * (^)(dispatch_block_t))group; 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * When you are debugging or printing the constraints attached to a view this subclass 13 | * makes it easier to identify which constraints have been created via Masonry 14 | */ 15 | @interface MASLayoutConstraint : NSLayoutConstraint 16 | 17 | /** 18 | * a key to associate with this constraint 19 | */ 20 | @property (nonatomic, strong) id mas_key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASLayoutConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASLayoutConstraint.h" 10 | 11 | @implementation MASLayoutConstraint 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASUtilities.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 19/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | #if TARGET_OS_IPHONE || TARGET_OS_TV 14 | 15 | #import 16 | #define MAS_VIEW UIView 17 | #define MAS_VIEW_CONTROLLER UIViewController 18 | #define MASEdgeInsets UIEdgeInsets 19 | 20 | typedef UILayoutPriority MASLayoutPriority; 21 | static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired; 22 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh; 23 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500; 24 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow; 25 | static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel; 26 | 27 | #elif TARGET_OS_MAC 28 | 29 | #import 30 | #define MAS_VIEW NSView 31 | #define MASEdgeInsets NSEdgeInsets 32 | 33 | typedef NSLayoutPriority MASLayoutPriority; 34 | static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired; 35 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh; 36 | static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow; 37 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501; 38 | static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut; 39 | static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow; 40 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow; 41 | static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression; 42 | 43 | #endif 44 | 45 | /** 46 | * Allows you to attach keys to objects matching the variable names passed. 47 | * 48 | * view1.mas_key = @"view1", view2.mas_key = @"view2"; 49 | * 50 | * is equivalent to: 51 | * 52 | * MASAttachKeys(view1, view2); 53 | */ 54 | #define MASAttachKeys(...) \ 55 | { \ 56 | NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__); \ 57 | for (id key in keyPairs.allKeys) { \ 58 | id obj = keyPairs[key]; \ 59 | NSAssert([obj respondsToSelector:@selector(setMas_key:)], \ 60 | @"Cannot attach mas_key to %@", obj); \ 61 | [obj setMas_key:key]; \ 62 | } \ 63 | } 64 | 65 | /** 66 | * Used to create object hashes 67 | * Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html 68 | */ 69 | #define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger)) 70 | #define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch))) 71 | 72 | /** 73 | * Given a scalar or struct value, wraps it in NSValue 74 | * Based on EXPObjectify: https://github.com/specta/expecta 75 | */ 76 | static inline id _MASBoxValue(const char *type, ...) { 77 | va_list v; 78 | va_start(v, type); 79 | id obj = nil; 80 | if (strcmp(type, @encode(id)) == 0) { 81 | id actual = va_arg(v, id); 82 | obj = actual; 83 | } else if (strcmp(type, @encode(CGPoint)) == 0) { 84 | CGPoint actual = (CGPoint)va_arg(v, CGPoint); 85 | obj = [NSValue value:&actual withObjCType:type]; 86 | } else if (strcmp(type, @encode(CGSize)) == 0) { 87 | CGSize actual = (CGSize)va_arg(v, CGSize); 88 | obj = [NSValue value:&actual withObjCType:type]; 89 | } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) { 90 | MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets); 91 | obj = [NSValue value:&actual withObjCType:type]; 92 | } else if (strcmp(type, @encode(double)) == 0) { 93 | double actual = (double)va_arg(v, double); 94 | obj = [NSNumber numberWithDouble:actual]; 95 | } else if (strcmp(type, @encode(float)) == 0) { 96 | float actual = (float)va_arg(v, double); 97 | obj = [NSNumber numberWithFloat:actual]; 98 | } else if (strcmp(type, @encode(int)) == 0) { 99 | int actual = (int)va_arg(v, int); 100 | obj = [NSNumber numberWithInt:actual]; 101 | } else if (strcmp(type, @encode(long)) == 0) { 102 | long actual = (long)va_arg(v, long); 103 | obj = [NSNumber numberWithLong:actual]; 104 | } else if (strcmp(type, @encode(long long)) == 0) { 105 | long long actual = (long long)va_arg(v, long long); 106 | obj = [NSNumber numberWithLongLong:actual]; 107 | } else if (strcmp(type, @encode(short)) == 0) { 108 | short actual = (short)va_arg(v, int); 109 | obj = [NSNumber numberWithShort:actual]; 110 | } else if (strcmp(type, @encode(char)) == 0) { 111 | char actual = (char)va_arg(v, int); 112 | obj = [NSNumber numberWithChar:actual]; 113 | } else if (strcmp(type, @encode(bool)) == 0) { 114 | bool actual = (bool)va_arg(v, int); 115 | obj = [NSNumber numberWithBool:actual]; 116 | } else if (strcmp(type, @encode(unsigned char)) == 0) { 117 | unsigned char actual = (unsigned char)va_arg(v, unsigned int); 118 | obj = [NSNumber numberWithUnsignedChar:actual]; 119 | } else if (strcmp(type, @encode(unsigned int)) == 0) { 120 | unsigned int actual = (unsigned int)va_arg(v, unsigned int); 121 | obj = [NSNumber numberWithUnsignedInt:actual]; 122 | } else if (strcmp(type, @encode(unsigned long)) == 0) { 123 | unsigned long actual = (unsigned long)va_arg(v, unsigned long); 124 | obj = [NSNumber numberWithUnsignedLong:actual]; 125 | } else if (strcmp(type, @encode(unsigned long long)) == 0) { 126 | unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long); 127 | obj = [NSNumber numberWithUnsignedLongLong:actual]; 128 | } else if (strcmp(type, @encode(unsigned short)) == 0) { 129 | unsigned short actual = (unsigned short)va_arg(v, unsigned int); 130 | obj = [NSNumber numberWithUnsignedShort:actual]; 131 | } 132 | va_end(v); 133 | return obj; 134 | } 135 | 136 | #define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value)) 137 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * An immutable tuple which stores the view and the related NSLayoutAttribute. 13 | * Describes part of either the left or right hand side of a constraint equation 14 | */ 15 | @interface MASViewAttribute : NSObject 16 | 17 | /** 18 | * The view which the reciever relates to. Can be nil if item is not a view. 19 | */ 20 | @property (nonatomic, weak, readonly) MAS_VIEW *view; 21 | 22 | /** 23 | * The item which the reciever relates to. 24 | */ 25 | @property (nonatomic, weak, readonly) id item; 26 | 27 | /** 28 | * The attribute which the reciever relates to 29 | */ 30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 31 | 32 | /** 33 | * Convenience initializer. 34 | */ 35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 36 | 37 | /** 38 | * The designated initializer. 39 | */ 40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; 41 | 42 | /** 43 | * Determine whether the layoutAttribute is a size attribute 44 | * 45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight 46 | */ 47 | - (BOOL)isSizeAttribute; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASViewAttribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | 11 | @implementation MASViewAttribute 12 | 13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { 14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; 15 | return self; 16 | } 17 | 18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { 19 | self = [super init]; 20 | if (!self) return nil; 21 | 22 | _view = view; 23 | _item = item; 24 | _layoutAttribute = layoutAttribute; 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)isSizeAttribute { 30 | return self.layoutAttribute == NSLayoutAttributeWidth 31 | || self.layoutAttribute == NSLayoutAttributeHeight; 32 | } 33 | 34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute { 35 | if ([viewAttribute isKindOfClass:self.class]) { 36 | return self.view == viewAttribute.view 37 | && self.layoutAttribute == viewAttribute.layoutAttribute; 38 | } 39 | return [super isEqual:viewAttribute]; 40 | } 41 | 42 | - (NSUInteger)hash { 43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | #import "MASUtilities.h" 13 | 14 | /** 15 | * A single constraint. 16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view 17 | */ 18 | @interface MASViewConstraint : MASConstraint 19 | 20 | /** 21 | * First item/view and first attribute of the NSLayoutConstraint 22 | */ 23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; 24 | 25 | /** 26 | * Second item/view and second attribute of the NSLayoutConstraint 27 | */ 28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; 29 | 30 | /** 31 | * initialises the MASViewConstraint with the first part of the equation 32 | * 33 | * @param firstViewAttribute view.mas_left, view.mas_width etc. 34 | * 35 | * @return a new view constraint 36 | */ 37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; 38 | 39 | /** 40 | * Returns all MASViewConstraints installed with this view as a first item. 41 | * 42 | * @param view A view to retrieve constraints for. 43 | * 44 | * @return An array of MASViewConstraints. 45 | */ 46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Masonry.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Masonry. 12 | FOUNDATION_EXPORT double MasonryVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 16 | 17 | #import "MASUtilities.h" 18 | #import "View+MASAdditions.h" 19 | #import "View+MASShorthandAdditions.h" 20 | #import "ViewController+MASAdditions.h" 21 | #import "NSArray+MASAdditions.h" 22 | #import "NSArray+MASShorthandAdditions.h" 23 | #import "MASConstraint.h" 24 | #import "MASCompositeConstraint.h" 25 | #import "MASViewAttribute.h" 26 | #import "MASViewConstraint.h" 27 | #import "MASConstraintMaker.h" 28 | #import "MASLayoutConstraint.h" 29 | #import "NSLayoutConstraint+MASDebugAdditions.h" 30 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.h 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | typedef NS_ENUM(NSUInteger, MASAxisType) { 14 | MASAxisTypeHorizontal, 15 | MASAxisTypeVertical 16 | }; 17 | 18 | @interface NSArray (MASAdditions) 19 | 20 | /** 21 | * Creates a MASConstraintMaker with each view in the callee. 22 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view 23 | * 24 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 25 | * 26 | * @return Array of created MASConstraints 27 | */ 28 | - (NSArray *)mas_makeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 29 | 30 | /** 31 | * Creates a MASConstraintMaker with each view in the callee. 32 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 33 | * If an existing constraint exists then it will be updated instead. 34 | * 35 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 36 | * 37 | * @return Array of created/updated MASConstraints 38 | */ 39 | - (NSArray *)mas_updateConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 40 | 41 | /** 42 | * Creates a MASConstraintMaker with each view in the callee. 43 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 44 | * All constraints previously installed for the views will be removed. 45 | * 46 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 47 | * 48 | * @return Array of created/updated MASConstraints 49 | */ 50 | - (NSArray *)mas_remakeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 51 | 52 | /** 53 | * distribute with fixed spacing 54 | * 55 | * @param axisType which axis to distribute items along 56 | * @param fixedSpacing the spacing between each item 57 | * @param leadSpacing the spacing before the first item and the container 58 | * @param tailSpacing the spacing after the last item and the container 59 | */ 60 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 61 | 62 | /** 63 | * distribute with fixed item size 64 | * 65 | * @param axisType which axis to distribute items along 66 | * @param fixedItemLength the fixed length of each item 67 | * @param leadSpacing the spacing before the first item and the container 68 | * @param tailSpacing the spacing after the last item and the container 69 | */ 70 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand array additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface NSArray (MASShorthandAdditions) 18 | 19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 22 | 23 | @end 24 | 25 | @implementation NSArray (MASShorthandAdditions) 26 | 27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 28 | return [self mas_makeConstraints:block]; 29 | } 30 | 31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 32 | return [self mas_updateConstraints:block]; 33 | } 34 | 35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 36 | return [self mas_remakeConstraints:block]; 37 | } 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * makes debug and log output of NSLayoutConstraints more readable 13 | */ 14 | @interface NSLayoutConstraint (MASDebugAdditions) 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/NSLayoutConstraint+MASDebugAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSLayoutConstraint+MASDebugAdditions.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | 13 | @implementation NSLayoutConstraint (MASDebugAdditions) 14 | 15 | #pragma mark - description maps 16 | 17 | + (NSDictionary *)layoutRelationDescriptionsByValue { 18 | static dispatch_once_t once; 19 | static NSDictionary *descriptionMap; 20 | dispatch_once(&once, ^{ 21 | descriptionMap = @{ 22 | @(NSLayoutRelationEqual) : @"==", 23 | @(NSLayoutRelationGreaterThanOrEqual) : @">=", 24 | @(NSLayoutRelationLessThanOrEqual) : @"<=", 25 | }; 26 | }); 27 | return descriptionMap; 28 | } 29 | 30 | + (NSDictionary *)layoutAttributeDescriptionsByValue { 31 | static dispatch_once_t once; 32 | static NSDictionary *descriptionMap; 33 | dispatch_once(&once, ^{ 34 | descriptionMap = @{ 35 | @(NSLayoutAttributeTop) : @"top", 36 | @(NSLayoutAttributeLeft) : @"left", 37 | @(NSLayoutAttributeBottom) : @"bottom", 38 | @(NSLayoutAttributeRight) : @"right", 39 | @(NSLayoutAttributeLeading) : @"leading", 40 | @(NSLayoutAttributeTrailing) : @"trailing", 41 | @(NSLayoutAttributeWidth) : @"width", 42 | @(NSLayoutAttributeHeight) : @"height", 43 | @(NSLayoutAttributeCenterX) : @"centerX", 44 | @(NSLayoutAttributeCenterY) : @"centerY", 45 | @(NSLayoutAttributeBaseline) : @"baseline", 46 | 47 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 48 | @(NSLayoutAttributeFirstBaseline) : @"firstBaseline", 49 | @(NSLayoutAttributeLastBaseline) : @"lastBaseline", 50 | #endif 51 | 52 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 53 | @(NSLayoutAttributeLeftMargin) : @"leftMargin", 54 | @(NSLayoutAttributeRightMargin) : @"rightMargin", 55 | @(NSLayoutAttributeTopMargin) : @"topMargin", 56 | @(NSLayoutAttributeBottomMargin) : @"bottomMargin", 57 | @(NSLayoutAttributeLeadingMargin) : @"leadingMargin", 58 | @(NSLayoutAttributeTrailingMargin) : @"trailingMargin", 59 | @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins", 60 | @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins", 61 | #endif 62 | 63 | }; 64 | 65 | }); 66 | return descriptionMap; 67 | } 68 | 69 | 70 | + (NSDictionary *)layoutPriorityDescriptionsByValue { 71 | static dispatch_once_t once; 72 | static NSDictionary *descriptionMap; 73 | dispatch_once(&once, ^{ 74 | #if TARGET_OS_IPHONE || TARGET_OS_TV 75 | descriptionMap = @{ 76 | @(MASLayoutPriorityDefaultHigh) : @"high", 77 | @(MASLayoutPriorityDefaultLow) : @"low", 78 | @(MASLayoutPriorityDefaultMedium) : @"medium", 79 | @(MASLayoutPriorityRequired) : @"required", 80 | @(MASLayoutPriorityFittingSizeLevel) : @"fitting size", 81 | }; 82 | #elif TARGET_OS_MAC 83 | descriptionMap = @{ 84 | @(MASLayoutPriorityDefaultHigh) : @"high", 85 | @(MASLayoutPriorityDragThatCanResizeWindow) : @"drag can resize window", 86 | @(MASLayoutPriorityDefaultMedium) : @"medium", 87 | @(MASLayoutPriorityWindowSizeStayPut) : @"window size stay put", 88 | @(MASLayoutPriorityDragThatCannotResizeWindow) : @"drag cannot resize window", 89 | @(MASLayoutPriorityDefaultLow) : @"low", 90 | @(MASLayoutPriorityFittingSizeCompression) : @"fitting size", 91 | @(MASLayoutPriorityRequired) : @"required", 92 | }; 93 | #endif 94 | }); 95 | return descriptionMap; 96 | } 97 | 98 | #pragma mark - description override 99 | 100 | + (NSString *)descriptionForObject:(id)obj { 101 | if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) { 102 | return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]]; 103 | } 104 | return [NSString stringWithFormat:@"%@:%p", [obj class], obj]; 105 | } 106 | 107 | - (NSString *)description { 108 | NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"]; 109 | 110 | [description appendString:[self.class descriptionForObject:self]]; 111 | 112 | [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]]; 113 | if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) { 114 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]]; 115 | } 116 | 117 | [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]]; 118 | 119 | if (self.secondItem) { 120 | [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]]; 121 | } 122 | if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) { 123 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]]; 124 | } 125 | 126 | if (self.multiplier != 1) { 127 | [description appendFormat:@" * %g", self.multiplier]; 128 | } 129 | 130 | if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) { 131 | [description appendFormat:@" %g", self.constant]; 132 | } else { 133 | if (self.constant) { 134 | [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)]; 135 | } 136 | } 137 | 138 | if (self.priority != MASLayoutPriorityRequired) { 139 | [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]]; 140 | } 141 | 142 | [description appendString:@">"]; 143 | return description; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | /** 14 | * Provides constraint maker block 15 | * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs 16 | */ 17 | @interface MAS_VIEW (MASAdditions) 18 | 19 | /** 20 | * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute 21 | */ 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_width; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_height; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; 31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; 32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; 33 | @property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); 34 | 35 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 36 | 37 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline; 38 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline; 39 | 40 | #endif 41 | 42 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 43 | 44 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; 49 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; 50 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; 51 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins; 52 | 53 | #endif 54 | 55 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 56 | 57 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuide API_AVAILABLE(ios(11.0),tvos(11.0)); 58 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0)); 59 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0)); 60 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0)); 61 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0)); 62 | 63 | #endif 64 | 65 | /** 66 | * a key to associate with this view 67 | */ 68 | @property (nonatomic, strong) id mas_key; 69 | 70 | /** 71 | * Finds the closest common superview between this view and another view 72 | * 73 | * @param view other view 74 | * 75 | * @return returns nil if common superview could not be found 76 | */ 77 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view; 78 | 79 | /** 80 | * Creates a MASConstraintMaker with the callee view. 81 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing 82 | * 83 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 84 | * 85 | * @return Array of created MASConstraints 86 | */ 87 | - (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 88 | 89 | /** 90 | * Creates a MASConstraintMaker with the callee view. 91 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 92 | * If an existing constraint exists then it will be updated instead. 93 | * 94 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 95 | * 96 | * @return Array of created/updated MASConstraints 97 | */ 98 | - (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 99 | 100 | /** 101 | * Creates a MASConstraintMaker with the callee view. 102 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 103 | * All constraints previously installed for the view will be removed. 104 | * 105 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 106 | * 107 | * @return Array of created/updated MASConstraints 108 | */ 109 | - (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand view additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface MAS_VIEW (MASShorthandAdditions) 18 | 19 | @property (nonatomic, strong, readonly) MASViewAttribute *left; 20 | @property (nonatomic, strong, readonly) MASViewAttribute *top; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *right; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *bottom; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *leading; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *trailing; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *width; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *height; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); 31 | 32 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 33 | 34 | @property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline; 35 | @property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline; 36 | 37 | #endif 38 | 39 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 40 | 41 | @property (nonatomic, strong, readonly) MASViewAttribute *leftMargin; 42 | @property (nonatomic, strong, readonly) MASViewAttribute *rightMargin; 43 | @property (nonatomic, strong, readonly) MASViewAttribute *topMargin; 44 | @property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins; 49 | 50 | #endif 51 | 52 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 53 | 54 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0)); 55 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0)); 56 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0)); 57 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0)); 58 | 59 | #endif 60 | 61 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 62 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 63 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 64 | 65 | @end 66 | 67 | #define MAS_ATTR_FORWARD(attr) \ 68 | - (MASViewAttribute *)attr { \ 69 | return [self mas_##attr]; \ 70 | } 71 | 72 | @implementation MAS_VIEW (MASShorthandAdditions) 73 | 74 | MAS_ATTR_FORWARD(top); 75 | MAS_ATTR_FORWARD(left); 76 | MAS_ATTR_FORWARD(bottom); 77 | MAS_ATTR_FORWARD(right); 78 | MAS_ATTR_FORWARD(leading); 79 | MAS_ATTR_FORWARD(trailing); 80 | MAS_ATTR_FORWARD(width); 81 | MAS_ATTR_FORWARD(height); 82 | MAS_ATTR_FORWARD(centerX); 83 | MAS_ATTR_FORWARD(centerY); 84 | MAS_ATTR_FORWARD(baseline); 85 | 86 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 87 | 88 | MAS_ATTR_FORWARD(firstBaseline); 89 | MAS_ATTR_FORWARD(lastBaseline); 90 | 91 | #endif 92 | 93 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 94 | 95 | MAS_ATTR_FORWARD(leftMargin); 96 | MAS_ATTR_FORWARD(rightMargin); 97 | MAS_ATTR_FORWARD(topMargin); 98 | MAS_ATTR_FORWARD(bottomMargin); 99 | MAS_ATTR_FORWARD(leadingMargin); 100 | MAS_ATTR_FORWARD(trailingMargin); 101 | MAS_ATTR_FORWARD(centerXWithinMargins); 102 | MAS_ATTR_FORWARD(centerYWithinMargins); 103 | 104 | #endif 105 | 106 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 107 | 108 | MAS_ATTR_FORWARD(safeAreaLayoutGuideTop); 109 | MAS_ATTR_FORWARD(safeAreaLayoutGuideBottom); 110 | MAS_ATTR_FORWARD(safeAreaLayoutGuideLeft); 111 | MAS_ATTR_FORWARD(safeAreaLayoutGuideRight); 112 | 113 | #endif 114 | 115 | - (MASViewAttribute *(^)(NSLayoutAttribute))attribute { 116 | return [self mas_attribute]; 117 | } 118 | 119 | - (NSArray *)makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 120 | return [self mas_makeConstraints:block]; 121 | } 122 | 123 | - (NSArray *)updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 124 | return [self mas_updateConstraints:block]; 125 | } 126 | 127 | - (NSArray *)remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 128 | return [self mas_remakeConstraints:block]; 129 | } 130 | 131 | @end 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | #ifdef MAS_VIEW_CONTROLLER 14 | 15 | @interface MAS_VIEW_CONTROLLER (MASAdditions) 16 | 17 | /** 18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute 19 | */ 20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; 26 | 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Example/Pods/Masonry/Masonry/ViewController+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "ViewController+MASAdditions.h" 10 | 11 | #ifdef MAS_VIEW_CONTROLLER 12 | 13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions) 14 | 15 | - (MASViewAttribute *)mas_topLayoutGuide { 16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 17 | } 18 | - (MASViewAttribute *)mas_topLayoutGuideTop { 19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 20 | } 21 | - (MASViewAttribute *)mas_topLayoutGuideBottom { 22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 23 | } 24 | 25 | - (MASViewAttribute *)mas_bottomLayoutGuide { 26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 27 | } 28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop { 29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 30 | } 31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom { 32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 33 | } 34 | 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FMFormSubmitKit : NSObject 3 | @end 4 | @implementation PodsDummy_FMFormSubmitKit 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "FMFormSubmitKit.h" 14 | #import "FormListCellConfigure.h" 15 | #import "FormListConfigure.h" 16 | #import "FormListSubmitView.h" 17 | #import "FormListBaseModel.h" 18 | #import "FormListImageSelectModel.h" 19 | #import "FormListImageUpModel.h" 20 | #import "FormListSelectModel.h" 21 | #import "FormListTextModel.h" 22 | #import "FormListTitleModel.h" 23 | #import "FormVerifyManager.h" 24 | #import "UITextField+FormExtension.h" 25 | #import "FormListBaseCell.h" 26 | #import "FormListImageUpCell.h" 27 | #import "FormListSelectCell.h" 28 | #import "FormListTextCell.h" 29 | #import "FormListTextVCell.h" 30 | #import "FormListTitleCell.h" 31 | #import "FormTextView.h" 32 | 33 | FOUNDATION_EXPORT double FMFormSubmitKitVersionNumber; 34 | FOUNDATION_EXPORT const unsigned char FMFormSubmitKitVersionString[]; 35 | 36 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit.modulemap: -------------------------------------------------------------------------------- 1 | framework module FMFormSubmitKit { 2 | umbrella header "FMFormSubmitKit-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FMFormSubmitKit/FMFormSubmitKit.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Masonry : NSObject 3 | @end 4 | @implementation PodsDummy_Masonry 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "MASCompositeConstraint.h" 14 | #import "MASConstraint+Private.h" 15 | #import "MASConstraint.h" 16 | #import "MASConstraintMaker.h" 17 | #import "MASLayoutConstraint.h" 18 | #import "Masonry.h" 19 | #import "MASUtilities.h" 20 | #import "MASViewAttribute.h" 21 | #import "MASViewConstraint.h" 22 | #import "NSArray+MASAdditions.h" 23 | #import "NSArray+MASShorthandAdditions.h" 24 | #import "NSLayoutConstraint+MASDebugAdditions.h" 25 | #import "View+MASAdditions.h" 26 | #import "View+MASShorthandAdditions.h" 27 | #import "ViewController+MASAdditions.h" 28 | 29 | FOUNDATION_EXPORT double MasonryVersionNumber; 30 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 31 | 32 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Masonry 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Masonry 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry.modulemap: -------------------------------------------------------------------------------- 1 | framework module Masonry { 2 | umbrella header "Masonry-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Masonry/Masonry.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Masonry 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Masonry 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FMFormSubmitKit 5 | 6 | Copyright (c) 2020 zhoufaming251@163.com 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | 27 | ## Masonry 28 | 29 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | Generated by CocoaPods - https://cocoapods.org 49 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2020 zhoufaming251@163.com <zhoufaming251@163.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | FMFormSubmitKit 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining a copy 49 | of this software and associated documentation files (the "Software"), to deal 50 | in the Software without restriction, including without limitation the rights 51 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 52 | copies of the Software, and to permit persons to whom the Software is 53 | furnished to do so, subject to the following conditions: 54 | 55 | The above copyright notice and this permission notice shall be included in 56 | all copies or substantial portions of the Software. 57 | 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 62 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 63 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 64 | THE SOFTWARE. 65 | License 66 | MIT 67 | Title 68 | Masonry 69 | Type 70 | PSGroupSpecifier 71 | 72 | 73 | FooterText 74 | Generated by CocoaPods - https://cocoapods.org 75 | Title 76 | 77 | Type 78 | PSGroupSpecifier 79 | 80 | 81 | StringsTable 82 | Acknowledgements 83 | Title 84 | Acknowledgements 85 | 86 | 87 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_FMFormSubmitKit_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_FMFormSubmitKit_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_FMFormSubmitKit_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_FMFormSubmitKit_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit/FMFormSubmitKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "FMFormSubmitKit" -framework "Foundation" -framework "Masonry" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_FMFormSubmitKit_Example { 2 | umbrella header "Pods-FMFormSubmitKit_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Example/Pods-FMFormSubmitKit_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit/FMFormSubmitKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "FMFormSubmitKit" -framework "Foundation" -framework "Masonry" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Masonry 5 | 6 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | Generated by CocoaPods - https://cocoapods.org 26 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | License 37 | MIT 38 | Title 39 | Masonry 40 | Type 41 | PSGroupSpecifier 42 | 43 | 44 | FooterText 45 | Generated by CocoaPods - https://cocoapods.org 46 | Title 47 | 48 | Type 49 | PSGroupSpecifier 50 | 51 | 52 | StringsTable 53 | Acknowledgements 54 | Title 55 | Acknowledgements 56 | 57 | 58 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_FMFormSubmitKit_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_FMFormSubmitKit_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_FMFormSubmitKit_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_FMFormSubmitKit_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit/FMFormSubmitKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "FMFormSubmitKit" -framework "Foundation" -framework "Masonry" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_FMFormSubmitKit_Tests { 2 | umbrella header "Pods-FMFormSubmitKit_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FMFormSubmitKit_Tests/Pods-FMFormSubmitKit_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMFormSubmitKit/FMFormSubmitKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "FMFormSubmitKit" -framework "Foundation" -framework "Masonry" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMFormSubmitKitTests.m 3 | // FMFormSubmitKitTests 4 | // 5 | // Created by zhoufaming251@163.com on 04/18/2020. 6 | // Copyright (c) 2020 zhoufaming251@163.com. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /FMFormSubmitKit.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint FMFormSubmitKit.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'FMFormSubmitKit' 11 | s.version = '1.2.1' 12 | s.summary = '一个表单提交库' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | TODO: Add long description of the pod here. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/CoderFM/FMFormSubmitKit' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { '周发明' => 'zhoufaming251@163.com' } 28 | s.source = { :git => 'https://github.com/CoderFM/FMFormSubmitKit.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | 31 | s.ios.deployment_target = '8.0' 32 | 33 | s.source_files = 'FMFormSubmitKit/Classes/**/*' 34 | 35 | # s.resource_bundles = { 36 | # 'FMFormSubmitKit' => ['FMFormSubmitKit/Assets/*.png'] 37 | # } 38 | 39 | # s.public_header_files = 'Pod/Classes/**/*.h' 40 | # s.frameworks = 'UIKit', 'MapKit' 41 | s.dependency 'Masonry' 42 | end 43 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/FMFormSubmitKit/Assets/.gitkeep -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderFM/FMFormSubmitKit/01f5ae33579d53e35fdbdfc74b59bf9a9165e6d5/FMFormSubmitKit/Classes/.gitkeep -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FMFormSubmitKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMFormSubmitKit.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // 7 | 8 | #ifndef FMFormSubmitKit_h 9 | #define FMFormSubmitKit_h 10 | 11 | #import "FormListConfigure.h" 12 | #import "FormListTextModel.h" 13 | #import "FormListTitleModel.h" 14 | #import "FormListImageUpModel.h" 15 | #import "FormListSelectModel.h" 16 | #import "FormListImageSelectModel.h" 17 | 18 | #import "FormListSubmitView.h" 19 | #import "FormListHandle.h" 20 | 21 | #import "FormVerifyManager.h" 22 | #import "UITextField+FormExtension.h" 23 | #import "UITextView+FormExtension.h" 24 | #import "NSString+FormEmoji.h" 25 | 26 | #import "FormListBaseCell.h" 27 | #import "FormListImageUpCell.h" 28 | #import "FormListSelectCell.h" 29 | #import "FormListTextCell.h" 30 | #import "FormListTextVCell.h" 31 | #import "FormListTitleCell.h" 32 | 33 | #import "FormListImageUpCellItemView.h" 34 | #import "FormTextView.h" 35 | 36 | 37 | #endif /* FMFormSubmitKit_h */ 38 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListCellConfigure.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListCellConfigure.h 3 | // YaLeGou 4 | // 5 | // Created by 周发明 on 2019/12/17. 6 | // Copyright © 2019 y. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "FormListConfigure.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | @class FormListUpImageConfigure; 15 | @interface FormListCellConfigure : NSObject 16 | 17 | ///默认支持的小数位数 2 18 | @property(nonatomic, assign)NSInteger inputDecimalCount; 19 | 20 | ///默认左右边距 21 | @property(nonatomic, assign)CGFloat lrMargin; 22 | ///箭头左边边距 23 | @property(nonatomic, assign)CGFloat arrowLMagin; 24 | ///默认分割线高度 25 | @property(nonatomic, assign)CGFloat bottomLineDefaultHeight; 26 | 27 | ///默认TextFieldCell高度 28 | @property(nonatomic, assign)CGFloat textDefaultHeight; 29 | ///默认TextField左边边距 30 | @property(nonatomic, assign)CGFloat tfLMagin; 31 | ///默认TextFieldCell高度 32 | @property(nonatomic, assign)CGFloat textVDefaultHeight; 33 | 34 | @property(nonatomic, assign)CGFloat tvTitleTopMargin; 35 | 36 | @property(nonatomic, strong)UIColor *bottomLineColor; 37 | @property(nonatomic, strong)UIColor *titleColor; 38 | @property(nonatomic, strong)UIColor *TFTVColor; 39 | @property(nonatomic, strong)UIColor *imageIntroColor; 40 | 41 | @property(nonatomic, strong)UIColor *placeholderColor; 42 | @property(nonatomic, strong)UIColor *textTintColor; 43 | 44 | @property(nonatomic, strong)UIFont *titleFont; 45 | @property(nonatomic, strong)UIFont *TFTVFont; 46 | @property(nonatomic, strong)UIFont *imageIntroFont; 47 | 48 | @property(nonatomic, strong)UIImage *selectNormalImage; 49 | @property(nonatomic, strong)UIImage *selectSelectedImage; 50 | 51 | @property(nonatomic, strong)UIImage *eyeNormalImage; 52 | @property(nonatomic, strong)UIImage *eyeSelectedImage; 53 | 54 | @property(nonatomic, strong)FormListUpImageConfigure *currentConfigure; 55 | 56 | @property(nonatomic, copy)void(^verifyFailAlertBlock)(NSString *text); 57 | 58 | + (instancetype)defaultConfigure; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListCellConfigure.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListCellConfigure.m 3 | // YaLeGou 4 | // 5 | // Created by 周发明 on 2019/12/17. 6 | // Copyright © 2019 y. All rights reserved. 7 | // 8 | 9 | #import "FormListCellConfigure.h" 10 | #import "FormListUpImageConfigure.h" 11 | #import "FormVerifyManager.h" 12 | 13 | @interface FormListCellConfigure () 14 | 15 | @end 16 | 17 | @implementation FormListCellConfigure 18 | 19 | + (instancetype)defaultConfigure{ 20 | static FormListCellConfigure *_FormListCellConfigureInstance; 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | _FormListCellConfigureInstance = [[FormListCellConfigure alloc] init]; 24 | 25 | _FormListCellConfigureInstance.inputDecimalCount = 2; 26 | 27 | _FormListCellConfigureInstance.lrMargin = Form_BaseSize(25); 28 | _FormListCellConfigureInstance.arrowLMagin = Form_BaseSize(8); 29 | _FormListCellConfigureInstance.bottomLineDefaultHeight = 0.5; 30 | _FormListCellConfigureInstance.textDefaultHeight = Form_BaseSize(46); 31 | _FormListCellConfigureInstance.tfLMagin = Form_BaseSize(82); 32 | _FormListCellConfigureInstance.textVDefaultHeight = Form_BaseSize(130); 33 | 34 | _FormListCellConfigureInstance.bottomLineColor = FormUIColorFromRGB(0xf2f4f5); 35 | _FormListCellConfigureInstance.titleColor = FormUIColorFromRGB(0x333333); 36 | _FormListCellConfigureInstance.TFTVColor = FormUIColorFromRGB(0x333333); 37 | _FormListCellConfigureInstance.imageIntroColor = FormUIColorFromRGB(0x888888); 38 | 39 | _FormListCellConfigureInstance.placeholderColor = FormUIColorFromRGB(0x999999); 40 | _FormListCellConfigureInstance.textTintColor = [UIColor blackColor]; 41 | 42 | _FormListCellConfigureInstance.tvTitleTopMargin = Form_BaseSize(16); 43 | 44 | _FormListCellConfigureInstance.titleFont = [UIFont systemFontOfSize:Form_BaseSize(14)]; 45 | _FormListCellConfigureInstance.TFTVFont = [UIFont systemFontOfSize:Form_BaseSize(14)]; 46 | _FormListCellConfigureInstance.imageIntroFont = [UIFont systemFontOfSize:Form_BaseSize(12)]; 47 | 48 | 49 | _FormListCellConfigureInstance.currentConfigure = [FormListUpImageConfigure defaultConfigure]; 50 | }); 51 | return _FormListCellConfigureInstance; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListConfigure.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListConfigure.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2019/12/20. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #ifndef FormListConfigure_h 10 | #define FormListConfigure_h 11 | 12 | #import 13 | #import "FormVerifyManager.h" 14 | #import "UITextField+FormExtension.h" 15 | #import "FormListCellConfigure.h" 16 | 17 | #define FormUIColorFromRGB(rgbValue) \ 18 | [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 19 | 20 | #define Form_SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width 21 | #define Form_SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height 22 | 23 | #define Form_BaseSize(x) Form_SCREEN_WIDTH*(x)/375.0 // 适配比例 24 | 25 | #define FormCellLRMargin [FormListCellConfigure defaultConfigure].lrMargin // 左右边距 26 | #define FormCellArrowLMagin [FormListCellConfigure defaultConfigure].arrowLMagin // 箭头左边距 27 | #define FormCellBottomLineDefaultHeight [FormListCellConfigure defaultConfigure].bottomLineDefaultHeight // 底部分割线默认高度 28 | 29 | #define FormCellBottomLineColor [FormListCellConfigure defaultConfigure].bottomLineColor // 底部分割线颜色 30 | 31 | #define FormCellTitleColor [FormListCellConfigure defaultConfigure].titleColor // 标题颜色 32 | #define FormCellTitleFont [FormListCellConfigure defaultConfigure].titleFont // 标题字体 33 | 34 | #define FormCellTFTVColor [FormListCellConfigure defaultConfigure].TFTVColor // 文本颜色 35 | #define FormCellTFTVFont [FormListCellConfigure defaultConfigure].TFTVFont // 文本字体 36 | 37 | #define FormCellPlaceholderColor [FormListCellConfigure defaultConfigure].placeholderColor // 标题颜色 38 | 39 | #define FormCellTVTitleTopMargin [FormListCellConfigure defaultConfigure].tvTitleTopMargin // TV的Title的顶部边距 40 | 41 | #define FormTextCellDefaultHeight [FormListCellConfigure defaultConfigure].textDefaultHeight // 默认TFCell的高度 42 | #define FormTextCellTFLMagin [FormListCellConfigure defaultConfigure].tfLMagin // 默认TF左边的边距 43 | #define FormTextVCellDefaultHeight [FormListCellConfigure defaultConfigure].textVDefaultHeight // 默认TVCell的高度 44 | 45 | #define FormUpCellDefaultImage @"form_list_image_add" // 添加图片默认 46 | #define FormSelectCellNormalImage [FormListCellConfigure defaultConfigure].selectNormalImage 47 | #define FormSelectCellSelectImage [FormListCellConfigure defaultConfigure].selectSelectedImage 48 | #define FormEyeNormalImage [FormListCellConfigure defaultConfigure].eyeNormalImage 49 | #define FormEyeCellSelectImage [FormListCellConfigure defaultConfigure].eyeSelectedImage 50 | #define FormVerifyFailAlert(message) ![FormListCellConfigure defaultConfigure].verifyFailAlertBlock?:[FormListCellConfigure defaultConfigure].verifyFailAlertBlock(message) // 验证失败的提示 51 | 52 | #define FormSubmitDefaultValue @"" // 提交默认值 53 | 54 | #define FormSubmitModelValueChangeNotiKey @"FormSubmitModelValueChangeNotiKey" //值改变的通知 55 | 56 | #endif /* FormListConfigure_h */ 57 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListHandle.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 郑桂华 on 2021/3/9. 6 | // 7 | 8 | #import 9 | #import 10 | #import "FormListBaseModel.h" 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListHandle : NSObject 14 | 15 | @property (nonatomic, strong)NSMutableArray *> *groupModels; 16 | @property (nonatomic, strong)NSMutableArray *models; 17 | @property (nonatomic, strong, readonly)NSMutableDictionary *submitParam; 18 | @property (nonatomic, assign)CGFloat cardCornerReadus; 19 | @property (nonatomic, assign)CGFloat sectionMargin; 20 | 21 | @property(nonatomic, weak)UITableView *tableView; 22 | 23 | - (instancetype)initWithTableView:(UITableView *)tableView; 24 | 25 | - (void)registerCell; 26 | 27 | - (BOOL)verifyDataSource; 28 | - (BOOL)verifyDataSource:(BOOL)alert; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListSubmitView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSubmitView.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/17. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FormListHandle.h" 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListSubmitView : UITableView 14 | 15 | @property(nonatomic, strong)FormListHandle *handle; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListSubmitView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSubmitView.m 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/17. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListSubmitView.h" 10 | 11 | 12 | @interface FormListSubmitView () 13 | 14 | @end 15 | 16 | @implementation FormListSubmitView 17 | 18 | - (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{ 19 | if (self = [super initWithFrame:frame style:style]) { 20 | self.separatorStyle = UITableViewCellSeparatorStyleNone; 21 | self.handle = [[FormListHandle alloc] initWithTableView:self]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)reloadData{ 27 | [self.handle registerCell]; 28 | [super reloadData]; 29 | [[NSNotificationCenter defaultCenter] postNotificationName:FormSubmitModelValueChangeNotiKey object:nil]; 30 | } 31 | 32 | - (void)setHandle:(FormListHandle *)handle{ 33 | _handle = handle; 34 | self.dataSource = handle; 35 | self.delegate = handle; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListUpImageConfigure.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListUpImageConfigure.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef enum : NSUInteger { 14 | FormListUpImageDirectionLTR, 15 | FormListUpImageDirectionRTL 16 | } FormListUpImageDirection; 17 | 18 | @class MASConstraintMaker, FormListImageSelectModel; 19 | @interface FormListUpImageConfigure : NSObject 20 | 21 | @property(nonatomic, assign)FormListUpImageDirection direction; 22 | @property(nonatomic, assign)CGFloat totalWidth; 23 | @property(nonatomic, assign)UIEdgeInsets inset; 24 | @property(nonatomic, assign)CGFloat imageLineSpace; 25 | @property(nonatomic, assign)CGFloat imageItemSpace; 26 | @property(nonatomic, assign)CGFloat imageHeight; 27 | @property(nonatomic, assign)CGFloat imageWidth; 28 | 29 | @property(nonatomic, strong)UIImage *placeholderImage; 30 | 31 | @property(nonatomic, assign)NSInteger column; 32 | 33 | @property(nonatomic, assign)BOOL oneLineScroll; 34 | 35 | @property(nonatomic, strong)Class imageViewClass;///需要继承自FormListImageUpCellItemView 或者自定义并遵守FormListImageUpCellItemDelegate 36 | @property(nonatomic, copy)void(^masony_makeBlock)(MASConstraintMaker *make, NSInteger index); 37 | @property(nonatomic, copy)FormListImageSelectModel *(^createAddModel)(void); 38 | + (instancetype)defaultConfigure; 39 | + (instancetype)configureWithInset:(UIEdgeInsets)inset lineSpace:(CGFloat)lineSpace itemSpace:(CGFloat)itemSpace imageSize:(CGSize)imageSize column:(NSInteger)column; 40 | - (CGFloat)heightWithCount:(NSInteger)count; 41 | - (void)oneLineScrollMasonyMake; 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/FormListUpImageConfigure.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListUpImageConfigure.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // 7 | 8 | #import "FormListUpImageConfigure.h" 9 | #import 10 | #import "FormListImageSelectModel.h" 11 | 12 | @interface FormListUpImageConfigure () 13 | 14 | @end 15 | 16 | @implementation FormListUpImageConfigure 17 | 18 | - (id)copyWithZone:(NSZone *)zone{ 19 | FormListUpImageConfigure *con = [[self class] allocWithZone:zone]; 20 | con.direction = self.direction; 21 | con.totalWidth = self.totalWidth; 22 | con.inset = self.inset; 23 | con.imageLineSpace = self.imageLineSpace; 24 | con.imageItemSpace = self.imageItemSpace; 25 | con.imageHeight = self.imageHeight; 26 | con.imageWidth = self.imageWidth; 27 | con.placeholderImage = self.placeholderImage; 28 | con.column = self.column; 29 | con.imageViewClass = self.imageViewClass; 30 | con.masony_makeBlock = [self.masony_makeBlock copy]; 31 | con.createAddModel = [self.createAddModel copy]; 32 | return con; 33 | } 34 | 35 | - (void (^)(MASConstraintMaker * _Nonnull, NSInteger index))masony_makeBlock{ 36 | if (_masony_makeBlock == nil) { 37 | __weak typeof(self) weakSelf = self; 38 | NSInteger singleCount = self.column; 39 | if (singleCount > 0) { 40 | _masony_makeBlock = ^(MASConstraintMaker * _Nonnull maker, NSInteger index){ 41 | NSInteger currentIndex = index % singleCount; 42 | NSInteger currentLine = index / singleCount; 43 | CGFloat left; 44 | CGFloat top = weakSelf.inset.top + currentLine * weakSelf.imageHeight + (currentLine == 0 ? 0 : currentLine * weakSelf.imageLineSpace); 45 | if (weakSelf.direction == FormListUpImageDirectionLTR) { 46 | left = weakSelf.inset.left + currentIndex * weakSelf.imageWidth + (currentIndex == 0 ? 0 : currentIndex * weakSelf.imageItemSpace); 47 | } else { 48 | left = weakSelf.totalWidth - weakSelf.inset.right - (currentIndex + 1) * weakSelf.imageWidth - currentIndex * weakSelf.imageItemSpace; 49 | } 50 | maker.left.mas_equalTo(left); 51 | maker.top.mas_equalTo(top); 52 | maker.width.mas_equalTo(weakSelf.imageWidth); 53 | maker.height.mas_equalTo(weakSelf.imageHeight); 54 | }; 55 | } else { 56 | _masony_makeBlock = ^(MASConstraintMaker * _Nonnull maker, NSInteger index){ 57 | NSInteger currentIndex = index; 58 | NSInteger currentLine = 0; 59 | CGFloat left; 60 | CGFloat top = weakSelf.inset.top + currentLine * weakSelf.imageHeight + (currentLine == 0 ? 0 : currentLine * weakSelf.imageLineSpace); 61 | if (weakSelf.direction == FormListUpImageDirectionLTR) { 62 | left = weakSelf.inset.left + currentIndex * weakSelf.imageWidth + (currentIndex == 0 ? 0 : currentIndex * weakSelf.imageItemSpace); 63 | } else { 64 | left = weakSelf.totalWidth - weakSelf.inset.right - (currentIndex + 1) * weakSelf.imageWidth - currentIndex * weakSelf.imageItemSpace; 65 | } 66 | maker.left.mas_equalTo(left); 67 | maker.top.mas_equalTo(top); 68 | maker.width.mas_equalTo(weakSelf.imageWidth); 69 | maker.height.mas_equalTo(weakSelf.imageHeight); 70 | }; 71 | } 72 | } 73 | return _masony_makeBlock; 74 | } 75 | 76 | - (FormListImageSelectModel *_Nonnull (^)(void))createAddModel{ 77 | if (_createAddModel == nil) { 78 | __weak typeof(self) weakSelf = self; 79 | _createAddModel = ^{ 80 | FormListImageSelectModel *model = [[FormListImageSelectModel alloc] init]; 81 | model.placeholderImage = weakSelf.placeholderImage; 82 | return model; 83 | }; 84 | } 85 | return _createAddModel; 86 | } 87 | 88 | + (instancetype)defaultConfigure{ 89 | FormListUpImageConfigure *con = [[self alloc] init]; 90 | con.totalWidth = [UIScreen mainScreen].bounds.size.width; 91 | con.inset = UIEdgeInsetsMake(10, 10, 10, 10); 92 | con.imageItemSpace = 10; 93 | con.imageLineSpace = 10; 94 | con.imageWidth = 100; 95 | con.imageHeight = con.imageWidth; 96 | con.column = 2; 97 | con.direction = FormListUpImageDirectionLTR; 98 | return con; 99 | } 100 | 101 | + (instancetype)configureWithInset:(UIEdgeInsets)inset lineSpace:(CGFloat)lineSpace itemSpace:(CGFloat)itemSpace imageSize:(CGSize)imageSize column:(NSInteger)column{ 102 | FormListUpImageConfigure *con = [[self alloc] init]; 103 | con.totalWidth = [UIScreen mainScreen].bounds.size.width; 104 | con.inset = inset; 105 | con.imageLineSpace = lineSpace; 106 | con.imageItemSpace = itemSpace; 107 | con.imageWidth = imageSize.width; 108 | con.imageHeight = imageSize.height; 109 | con.column = column; 110 | return con; 111 | } 112 | 113 | - (CGFloat)heightWithCount:(NSInteger)count{ 114 | NSInteger singleCount = self.column; 115 | NSInteger lines = count % singleCount == 0 ? (count / singleCount) : (count / singleCount + 1); 116 | return self.inset.top + lines * self.imageHeight + (lines > 0 ? lines - 1 : 0) * self.imageLineSpace + self.inset.bottom; 117 | } 118 | 119 | - (void)oneLineScrollMasonyMake{ 120 | __weak typeof(self) weakSelf = self; 121 | self.masony_makeBlock = ^(MASConstraintMaker * _Nonnull make, NSInteger index) { 122 | make.left.mas_equalTo(weakSelf.inset.left + index * (weakSelf.imageWidth + weakSelf.imageItemSpace)); 123 | make.top.mas_equalTo(weakSelf.inset.top); 124 | make.width.mas_equalTo(weakSelf.imageWidth); 125 | make.height.mas_equalTo(weakSelf.imageHeight); 126 | }; 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListBaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListBaseModel.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "FormListConfigure.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface FormListBaseModel : NSObject 16 | @property(nonatomic, assign)CGFloat cellHeight; 17 | @property(nonatomic, copy)NSString *reuseKey; 18 | @property(nonatomic, assign)BOOL isOnlyOne; 19 | @property(nonatomic, copy)NSString *cellClassName; 20 | @property(nonatomic, assign)BOOL cellIsNib; 21 | @property(nonatomic, assign)CGFloat bottomLineHeight; 22 | @property(nonatomic, assign)CGFloat bottomLineLRMargin; 23 | @property(nonatomic, assign)CGFloat bottomLineLMargin; 24 | @property(nonatomic, assign)CGFloat bottomLineRMargin; 25 | ///底部距离 给正值往上顶 26 | @property(nonatomic, assign)CGFloat bottomLineBMargin; 27 | 28 | @property(nonatomic, strong)UIColor *contentBg; 29 | @property(nonatomic, strong)UIColor *bottomLineBg; 30 | 31 | @property(nonatomic, copy)void(^configureCell)(id cell); 32 | 33 | @property(nonatomic, copy)NSString *submitKey; 34 | @property(nonatomic, strong, readonly)NSDictionary *submitValue; 35 | @property(nonatomic, copy)NSDictionary *(^submitValueBlock)(id model); 36 | 37 | - (BOOL)verifySuccess:(BOOL)alert; 38 | 39 | + (instancetype)modelWithCellHeight:(CGFloat)cellHeight bottomLineHeight:(CGFloat)bottomLineHeight bottomLineLRMargin:(CGFloat)bottomLineLRMargin; 40 | - (void)setLineHeight:(CGFloat)lineHeight leftMargin:(CGFloat)leftMargin rightMargin:(CGFloat)rightMargin; 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListBaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListBaseModel.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListBaseModel.h" 10 | 11 | @implementation FormListBaseModel 12 | 13 | - (NSString *)reuseKey{ 14 | if (_reuseKey == nil) { 15 | if (self.isOnlyOne) { 16 | _reuseKey = [NSString stringWithFormat:@"%p%@", self, self.cellClassName]; 17 | } else { 18 | _reuseKey = [NSString stringWithFormat:@"%@", self.cellClassName]; 19 | } 20 | } 21 | return _reuseKey; 22 | } 23 | 24 | + (instancetype)modelWithCellHeight:(CGFloat)cellHeight bottomLineHeight:(CGFloat)bottomLineHeight bottomLineLRMargin:(CGFloat)bottomLineLRMargin{ 25 | FormListBaseModel *model = [[self alloc] init]; 26 | model.cellHeight = cellHeight; 27 | model.bottomLineHeight = bottomLineHeight; 28 | model.bottomLineLRMargin = bottomLineLRMargin; 29 | return model; 30 | } 31 | 32 | - (instancetype)init 33 | { 34 | self = [super init]; 35 | if (self) { 36 | self.bottomLineLRMargin = FormCellLRMargin; 37 | self.bottomLineHeight = FormCellBottomLineDefaultHeight; 38 | self.cellClassName = @"FormListBaseCell"; 39 | self.contentBg = [UIColor whiteColor]; 40 | self.bottomLineBg = FormCellBottomLineColor; 41 | } 42 | return self; 43 | } 44 | 45 | - (void)setLineHeight:(CGFloat)lineHeight leftMargin:(CGFloat)leftMargin rightMargin:(CGFloat)rightMargin{ 46 | self.bottomLineHeight = lineHeight; 47 | self.bottomLineLMargin = leftMargin; 48 | self.bottomLineRMargin = rightMargin; 49 | } 50 | 51 | - (void)setBottomLineLRMargin:(CGFloat)bottomLineLRMargin{ 52 | _bottomLineLRMargin = bottomLineLRMargin; 53 | self.bottomLineRMargin = bottomLineLRMargin; 54 | self.bottomLineLMargin = bottomLineLRMargin; 55 | } 56 | 57 | - (BOOL)verifySuccess:(BOOL)alert{ 58 | return YES; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListImageSelectModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageSelectModel.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface FormListImageSelectModel : NSObject 15 | @property(nonatomic, copy)NSString *submitKey; 16 | @property(nonatomic, copy)NSString *title; 17 | @property(nonatomic, strong, nullable)UIImage *image; 18 | @property(nonatomic, strong, nullable)UIImage *placeholderImage; 19 | @property(nonatomic, copy)NSString *imageUrl; // 上传完图片保存的地址 20 | @property(nonatomic, strong)id otherData; // 其他数据 21 | + (instancetype)modelWithPlaceholderImageName:(NSString *)imageName; 22 | 23 | - (BOOL)verifySuccess; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListImageSelectModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageSelectModel.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListImageSelectModel.h" 10 | #import "FormListConfigure.h" 11 | 12 | @implementation FormListImageSelectModel 13 | - (instancetype)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | self.placeholderImage = [UIImage imageNamed:FormUpCellDefaultImage]; 18 | } 19 | return self; 20 | } 21 | + (instancetype)modelWithPlaceholderImageName:(NSString *)imageName{ 22 | FormListImageSelectModel *model = [[self alloc] init]; 23 | model.placeholderImage = [UIImage imageNamed:imageName]; 24 | return model; 25 | } 26 | 27 | - (void)setImageUrl:(NSString *)imageUrl{ 28 | _imageUrl = imageUrl; 29 | [[NSNotificationCenter defaultCenter] postNotificationName:FormSubmitModelValueChangeNotiKey object:self]; 30 | } 31 | 32 | - (BOOL)verifySuccess{ 33 | return self.imageUrl && self.imageUrl.length > 0; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListImageUpModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpModel.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class FormListImageSelectModel, FormListUpImageConfigure; 13 | @interface FormListImageUpModel : FormListTitleModel 14 | @property(nonatomic, assign)BOOL canDynamicAdd; 15 | @property(nonatomic, assign)NSInteger minCount; 16 | @property(nonatomic, assign)NSInteger maxCount; 17 | @property(nonatomic, copy)void(^refreshBlock)(void); 18 | @property(nonatomic, strong)NSArray *images; 19 | 20 | @property(nonatomic, strong)FormListUpImageConfigure *imageConfigure; 21 | 22 | @property(nonatomic, copy)void(^selectImageBlock)(FormListImageSelectModel *model, UIImage *image); 23 | @property(nonatomic, copy)void(^selectMutibleBlock)(FormListImageSelectModel *model, NSArray *images); 24 | 25 | + (instancetype)modelWithCongigure:(FormListUpImageConfigure *)configure images:(NSArray *)images; 26 | + (instancetype)modelDynamicAddWithCongigure:(FormListUpImageConfigure *)configure maxCount:(NSInteger)maxCount; 27 | 28 | @end 29 | 30 | @interface FormListBaseModel (ConvertImage) 31 | 32 | @property(readonly)FormListImageUpModel *convertImage; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListImageUpModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpModel.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListImageUpModel.h" 10 | #import "FormListImageUpCell.h" 11 | #import "FormListImageSelectModel.h" 12 | #import "FormListUpImageConfigure.h" 13 | 14 | @interface FormListImageUpModel () 15 | 16 | @property(nonatomic, assign)CGFloat interiorHeight; 17 | 18 | @end 19 | 20 | @implementation FormListImageUpModel 21 | 22 | + (instancetype)modelWithCongigure:(FormListUpImageConfigure *)configure images:(NSArray *)images{ 23 | FormListImageUpModel *model = [[self alloc] init]; 24 | model.imageConfigure = configure; 25 | model.images = images; 26 | return model; 27 | } 28 | + (instancetype)modelDynamicAddWithCongigure:(FormListUpImageConfigure *)configure maxCount:(NSInteger)maxCount{ 29 | FormListImageUpModel *model = [[self alloc] init]; 30 | model.imageConfigure = configure; 31 | model.canDynamicAdd = YES; 32 | model.maxCount = maxCount; 33 | FormListImageSelectModel *selModel = [[FormListImageSelectModel alloc] init]; 34 | selModel.placeholderImage = configure.placeholderImage; 35 | model.images = @[selModel]; 36 | return model; 37 | } 38 | 39 | - (CGFloat)cellHeight{ 40 | return self.interiorHeight; 41 | } 42 | 43 | - (CGFloat)interiorHeight{ 44 | if (self.imageConfigure.oneLineScroll) { 45 | _interiorHeight = self.imageConfigure.inset.top + self.imageConfigure.imageHeight + self.imageConfigure.inset.bottom; 46 | return _interiorHeight; 47 | } else { 48 | NSInteger count = self.canDynamicAdd ? (self.maxCount > 0 ? MIN(self.images.count, self.maxCount) : self.images.count) : self.images.count; 49 | _interiorHeight = [self.imageConfigure heightWithCount:count] + self.bottomLineHeight; 50 | return _interiorHeight; 51 | } 52 | } 53 | 54 | - (instancetype)init{ 55 | if (self = [super init]) { 56 | self.cellClassName = NSStringFromClass([FormListImageUpCell class]); 57 | self.bottomLineHeight = 0.5; 58 | self.imageConfigure = [FormListCellConfigure defaultConfigure].currentConfigure; 59 | self.maxCount = NSIntegerMax; 60 | } 61 | return self; 62 | } 63 | 64 | - (BOOL)verifySuccess:(BOOL)alert{ 65 | if (self.canDynamicAdd && self.minCount == 0) { 66 | return YES; 67 | } 68 | __block BOOL success = YES; 69 | __block NSString *message = @""; 70 | __weak typeof(self) weakSelf = self; 71 | __block NSInteger selectCount = 0; 72 | [self.images enumerateObjectsUsingBlock:^(FormListImageSelectModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 73 | if (![obj verifySuccess]) { 74 | success = NO; 75 | message = [NSString stringWithFormat:@"%@ %@\n未上传", weakSelf.title, obj.title]; 76 | *stop = YES; 77 | } else { 78 | selectCount += 1; 79 | } 80 | }]; 81 | if (self.canDynamicAdd) { 82 | if (selectCount > self.minCount) { 83 | return YES; 84 | } else { 85 | message = [NSString stringWithFormat:@"%@未上传", self.title]; 86 | } 87 | } 88 | if (!success && alert) { 89 | FormVerifyFailAlert(message); 90 | } 91 | return success; 92 | } 93 | 94 | - (NSDictionary *)submitValue{ 95 | if (self.submitValueBlock) { 96 | return self.submitValueBlock(self); 97 | } 98 | if (self.submitKey) { 99 | NSMutableArray *arrM = [NSMutableArray array]; 100 | [self.images enumerateObjectsUsingBlock:^(FormListImageSelectModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 101 | if (obj.imageUrl) { 102 | [arrM addObject:obj.imageUrl]; 103 | } 104 | }]; 105 | return @{self.submitKey:[arrM componentsJoinedByString:@"|"]}; 106 | } else { 107 | NSMutableDictionary *result = [NSMutableDictionary dictionary]; 108 | [self.images enumerateObjectsUsingBlock:^(FormListImageSelectModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 109 | if (obj.imageUrl && obj.submitKey) { 110 | [result setValue:obj.imageUrl forKey:obj.submitKey]; 111 | } 112 | }]; 113 | return result; 114 | } 115 | } 116 | 117 | @end 118 | 119 | 120 | @implementation FormListImageUpModel (ConvertImage) 121 | 122 | - (FormListImageUpModel *)convertImage{ 123 | if ([self isKindOfClass:[FormListImageUpModel class]]) { 124 | return (FormListImageUpModel *)self; 125 | } 126 | return nil; 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListSelectModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSelectModel.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/29. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListSelectModel : FormListTitleModel 14 | 15 | @property(nonatomic, strong)NSArray *selects; 16 | @property(nonatomic, assign)NSInteger selectIndex; 17 | @property(nonatomic, copy)void(^configurationBtn)(NSInteger index, UIButton *btn, NSString *title); 18 | @property(nonatomic, copy)void(^selectClick)(NSInteger index, UIButton *btn); 19 | + (instancetype)modelWithTitle:(NSString *)title; 20 | 21 | @end 22 | 23 | @interface FormListBaseModel (ConvertSelect) 24 | 25 | @property(readonly)FormListSelectModel *convertSelect; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListSelectModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSelectModel.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/29. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListSelectModel.h" 10 | 11 | #import "FormListSelectCell.h" 12 | 13 | @implementation FormListSelectModel 14 | 15 | - (instancetype)init{ 16 | if (self = [super init]) { 17 | self.cellClassName = NSStringFromClass([FormListSelectCell class]); 18 | self.cellHeight = FormTextCellDefaultHeight; 19 | } 20 | return self; 21 | } 22 | 23 | - (BOOL)verifySuccess{ 24 | return YES; 25 | } 26 | 27 | - (NSDictionary *)submitValue{ 28 | if (self.submitValueBlock) { 29 | return self.submitValueBlock(self); 30 | } 31 | if (!self.submitKey) { 32 | return nil; 33 | } 34 | return @{self.submitKey:@(self.selectIndex)}; 35 | } 36 | 37 | + (instancetype)modelWithTitle:(NSString *)title{ 38 | FormListSelectModel *model = [[self alloc] init]; 39 | model.title = title; 40 | return model; 41 | } 42 | 43 | @end 44 | 45 | @implementation FormListBaseModel (ConvertSelect) 46 | 47 | - (FormListSelectModel *)convertSelect{ 48 | if ([self isKindOfClass:[FormListSelectModel class]]) { 49 | return (FormListSelectModel *)self; 50 | } 51 | return nil; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListTextModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTextModel.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListTextModel : FormListTitleModel 14 | 15 | ///NSString NSAttributeString 16 | @property(nonatomic, copy)id placehoder; 17 | ///NSString NSAttributeString 18 | @property(nonatomic, copy)id text; 19 | ///存储一些值 20 | @property(nonatomic, copy)id value; 21 | @property(nonatomic, assign)UIKeyboardType keyboardType; 22 | @property(nonatomic, assign)BOOL hasRight; 23 | ///支持UIImage NSString NSAttributeString 24 | @property(nonatomic, strong)id rightC; 25 | @property(nonatomic, assign)BOOL isSelect; 26 | @property(nonatomic, assign)NSTextAlignment alignment; 27 | 28 | @property(nonatomic, strong)UIFont *textFont; 29 | 30 | @property(nonatomic, strong)UIColor *textColor; 31 | 32 | @property(nonatomic, strong)UIColor *placeholderColor; 33 | @property(nonatomic, strong)UIColor *textTintColor; 34 | 35 | @property(nonatomic, assign)CGFloat textFLeftMargin; 36 | @property(nonatomic, assign)CGFloat textVTopMargin; 37 | 38 | @property(nonatomic, assign)BOOL eyeEnable; 39 | @property(nonatomic, assign)BOOL isSecret; 40 | 41 | @property(nonatomic, copy)NSString *verifyPredicate; 42 | @property(nonatomic, copy)NSString *inputPredicate; 43 | @property(nonatomic, assign)NSInteger limitCount; 44 | 45 | @property(nonatomic, copy)BOOL(^verifyBlock)(id text); 46 | 47 | @property(nonatomic, copy)void(^selectBlock)(id tftv, FormListTextModel *model); 48 | @property(nonatomic, copy)void(^configurationBlock)(id tftv); 49 | 50 | @property(nonatomic, copy)void(^textLengthChange)(NSInteger length); 51 | 52 | + (instancetype)modelWithPlaceholder:(id)placeholder keyboardType:(UIKeyboardType)type hasRight:(BOOL)hasRight righrContent:(id _Nullable)rightContent title:(id)title; 53 | 54 | + (instancetype)modelWithTVPlaceholder:(id)placeholder title:(id)title; 55 | 56 | + (instancetype)modelShowWithTitle:(id)title text:(id)text aligment:(NSTextAlignment)aligment textFLeftMargin:(CGFloat)textFLeftMargin; 57 | 58 | - (void)reloadTVHeight; 59 | 60 | - (void)setTextStyle:(NSTextAlignment)aligment textFont:( UIFont * _Nullable )textFont textColor:(UIColor *_Nullable)textColor; 61 | - (void)setInputLimit:(NSString *)inputPredicate count:(NSInteger)count; 62 | @end 63 | 64 | @interface FormListBaseModel (ConvertText) 65 | 66 | @property(readonly)FormListTextModel *convertText; 67 | 68 | @end 69 | 70 | 71 | NS_ASSUME_NONNULL_END 72 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListTextModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTextModel.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTextModel.h" 10 | #import "FormListTextCell.h" 11 | #import "FormListTextVCell.h" 12 | 13 | @interface FormListTextModel () 14 | 15 | @property(nonatomic, assign)BOOL supportEmoji; 16 | 17 | @end 18 | 19 | @implementation FormListTextModel 20 | 21 | - (instancetype)init{ 22 | if (self = [super init]) { 23 | self.cellHeight = FormTextCellDefaultHeight; 24 | self.textFLeftMargin = FormTextCellTFLMagin; 25 | self.cellClassName = NSStringFromClass([FormListTextCell class]); 26 | self.alignment = NSTextAlignmentRight; 27 | self.titleFont = FormCellTitleFont; 28 | self.textFont = FormCellTFTVFont; 29 | self.titleColor = FormCellTitleColor; 30 | self.placeholderColor = FormCellPlaceholderColor; 31 | self.textTintColor = [FormListCellConfigure defaultConfigure].textTintColor; 32 | self.supportEmoji = YES; 33 | } 34 | return self; 35 | } 36 | 37 | + (instancetype)modelWithPlaceholder:(id)placeholder keyboardType:(UIKeyboardType)type hasRight:(BOOL)hasRight righrContent:(id _Nullable)rightContent title:(id)title{ 38 | FormListTextModel *model = [[self alloc] init]; 39 | model.title = title; 40 | model.placehoder = placeholder; 41 | model.keyboardType = type; 42 | model.hasRight = hasRight; 43 | model.rightC = rightContent; 44 | return model; 45 | } 46 | 47 | + (instancetype)modelWithTVPlaceholder:(id)placeholder title:(id)title{ 48 | FormListTextModel *model = [[self alloc] init]; 49 | model.title = title; 50 | model.placehoder = placeholder; 51 | model.cellHeight = FormTextVCellDefaultHeight; 52 | model.cellClassName = NSStringFromClass([FormListTextVCell class]); 53 | return model; 54 | } 55 | 56 | + (instancetype)modelShowWithTitle:(id)title text:(id)text aligment:(NSTextAlignment)aligment textFLeftMargin:(CGFloat)textFLeftMargin{ 57 | FormListTextModel *model = [[self alloc] init]; 58 | model.title = title; 59 | model.text = text; 60 | model.alignment = aligment; 61 | model.textFLeftMargin = textFLeftMargin; 62 | return model; 63 | } 64 | 65 | - (void)setText:(id)text{ 66 | _text = text; 67 | [[NSNotificationCenter defaultCenter] postNotificationName:FormSubmitModelValueChangeNotiKey object:self]; 68 | } 69 | 70 | - (void)setTextStyle:(NSTextAlignment)aligment textFont:( UIFont * _Nullable )textFont textColor:(UIColor *_Nullable)textColor{ 71 | self.alignment = aligment; 72 | if (textColor) { 73 | self.textColor = textColor; 74 | } 75 | if (textFont) { 76 | self.textFont = textFont; 77 | } 78 | } 79 | 80 | - (void)setInputLimit:(NSString *)inputPredicate count:(NSInteger)count{ 81 | self.inputPredicate = inputPredicate; 82 | self.limitCount = count; 83 | } 84 | 85 | - (void)reloadTVHeight{ 86 | CGFloat textH = 0; 87 | if ([self.text isKindOfClass:[NSString class]]) { 88 | textH = [self.text boundingRectWithSize:CGSizeMake(Form_SCREEN_WIDTH - self.textFLeftMargin - FormCellLRMargin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:FormCellTFTVFont} context:nil].size.height; 89 | } else if ([self.text isKindOfClass:[NSAttributedString class]]) { 90 | textH = [self.text boundingRectWithSize:CGSizeMake(Form_SCREEN_WIDTH - self.textFLeftMargin - FormCellLRMargin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; 91 | } 92 | CGFloat lineH = FormCellTFTVFont.lineHeight; 93 | CGFloat margin = FormTextCellDefaultHeight - lineH; 94 | if (textH + margin < FormTextCellDefaultHeight) { 95 | self.cellHeight = FormTextCellDefaultHeight; 96 | } else { 97 | self.cellHeight = textH + margin; 98 | } 99 | } 100 | 101 | - (BOOL)verifySuccess:(BOOL)alert{ 102 | BOOL success = YES; 103 | if (self.verifyBlock) { 104 | success = self.verifyBlock(self.text); 105 | } else { 106 | if (self.verifyPredicate && self.verifyPredicate.length > 0) { 107 | success = [self.text verifyPredicate:self.verifyPredicate]; 108 | } else { 109 | success = ((NSString *)self.text).length > 0; 110 | } 111 | } 112 | if (!success && alert) { 113 | FormVerifyFailAlert(self.placehoder); 114 | } 115 | return success; 116 | } 117 | 118 | - (NSDictionary *)submitValue{ 119 | if (self.submitValueBlock) { 120 | return self.submitValueBlock(self); 121 | } 122 | if (self.submitKey && self.text) { 123 | if ([self.text isKindOfClass:[NSString class]]) { 124 | return @{self.submitKey:self.text}; 125 | } 126 | if ([self.text isKindOfClass:[NSAttributedString class]]) { 127 | return @{self.submitKey:[self.text string]}; 128 | } 129 | } 130 | return nil; 131 | } 132 | 133 | @end 134 | 135 | @implementation FormListBaseModel (ConvertText) 136 | 137 | - (FormListTextModel *)convertText{ 138 | if ([self isKindOfClass:[FormListTextModel class]]) { 139 | return (FormListTextModel *)self; 140 | } 141 | return nil; 142 | } 143 | 144 | @end 145 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListTitleModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTitleModel.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListBaseModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListTitleModel : FormListBaseModel 14 | ///可以NSString NSAttrbuil..String 15 | @property(nonatomic, copy)id title; 16 | 17 | @property(nonatomic, assign)NSTextAlignment titleAligment; 18 | 19 | @property(nonatomic, strong)UIColor *titleColor; 20 | 21 | @property(nonatomic, strong)UIFont *titleFont; 22 | 23 | @property(nonatomic, copy)void(^masony_remakeBlock)(MASConstraintMaker *make); 24 | 25 | + (instancetype)modelWithTitle:(id)title; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Model/FormListTitleModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTitleModel.m 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleModel.h" 10 | #import "FormListTitleCell.h" 11 | 12 | @implementation FormListTitleModel 13 | 14 | - (instancetype)init 15 | { 16 | self = [super init]; 17 | if (self) { 18 | self.cellHeight = FormTextCellDefaultHeight; 19 | self.titleFont = FormCellTitleFont; 20 | self.titleColor = FormCellTitleColor; 21 | self.titleAligment = NSTextAlignmentLeft; 22 | self.cellClassName = NSStringFromClass([FormListTitleCell class]); 23 | } 24 | return self; 25 | } 26 | 27 | + (instancetype)modelWithTitle:(id)title{ 28 | FormListTitleModel *model = [[self alloc] init]; 29 | model.title = title; 30 | return model; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/FormVerifyManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormVerifyManager.h 3 | // QiaoKeApp 4 | // 5 | // Created by 周发明 on 2020/3/18. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | ///字符数字中文下划线中划线 13 | #define FormVerifyUnsigned @"[A-Za-z0-9_\-\u4e00-\u9fa5]+" 14 | ///手机号匹配 15 | #define FormVerifyMobile @"0?(13|14|15|16|18|17|19)[0-9]{9}" 16 | ///身份证号 17 | #define FormVerifyCardNo @"\d{17}[\d|x]|\d{15}" 18 | ///纯数字 19 | #define FormVerifyOnlyNumber @"[0-9]+" 20 | ///纯字母 21 | #define FormVerifyOnlyLetter @"[A-Za-z]+" 22 | ///数字字母 23 | #define FormVerifyLetterNumber @"[0-9A-Za-z]+" 24 | ///中文 25 | #define FormVerifyOnlyChinese @"[\u4e00-\u9fa5]+" 26 | ///中文+数字+字母 27 | #define FormVerifyChineseLetterNumber @"[A-Za-z0-9\u4e00-\u9fa5]+" 28 | /// 只能输入小数的数值 29 | #define FormVerifyOnlyDecimal @"[0-9.]+" 30 | 31 | @interface FormVerifyManager : NSObject 32 | 33 | + (void)handleTextFieldTextDidChange:(UITextField *)textF; 34 | + (void)handleTextViewTextDidChange:(UITextView *)textV; 35 | 36 | @end 37 | 38 | @interface NSString (FormVerifyManager) 39 | 40 | - (BOOL)verifyPredicate:(NSString *)predicate; 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/FormVerifyManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormVerifyManager.m 3 | // QiaoKeApp 4 | // 5 | // Created by 周发明 on 2020/3/18. 6 | // 7 | 8 | #import "FormVerifyManager.h" 9 | #import "UITextView+FormExtension.h" 10 | #import "UITextField+FormExtension.h" 11 | #import "FormListCellConfigure.h" 12 | 13 | @implementation FormVerifyManager 14 | 15 | + (void)handleTextFieldTextDidChange:(UITextField *)textF{ 16 | if (textF.inputPredicate && [textF.inputPredicate isEqualToString:FormVerifyOnlyDecimal]) { 17 | if ([textF.text containsString:@"."]) { 18 | NSArray *texts = [textF.text componentsSeparatedByString:@"."]; 19 | NSString *begin = [texts firstObject]; 20 | if ([begin integerValue] == 0) { 21 | begin = @"0"; 22 | } else { 23 | begin = [NSString stringWithFormat:@"%ld", [begin integerValue]]; 24 | } 25 | if (texts.count > 1) { 26 | NSString *last = texts[1]; 27 | if (last.length > [FormListCellConfigure defaultConfigure].inputDecimalCount) { 28 | last = [last substringToIndex:[FormListCellConfigure defaultConfigure].inputDecimalCount]; 29 | } 30 | textF.text = [@[begin, last] componentsJoinedByString:@"."]; 31 | } else { 32 | textF.text = [NSString stringWithFormat:@"%@.", begin]; 33 | } 34 | } else { 35 | NSString *begin = textF.text; 36 | if (begin.length > 0) { 37 | if ([begin integerValue] == 0) { 38 | begin = @"0"; 39 | } else { 40 | begin = [NSString stringWithFormat:@"%ld", [begin integerValue]]; 41 | } 42 | textF.text = begin; 43 | } 44 | } 45 | } 46 | 47 | if (textF.isChineseInput) { 48 | [textF matchWithPattern:textF.inputPredicate]; 49 | } 50 | 51 | if (![textF hasInputPinYin]) { 52 | if (textF.limitCount > 0) { 53 | if (textF.text.length > textF.limitCount) { 54 | textF.text = [textF.text substringToIndex:textF.limitCount]; 55 | } 56 | } 57 | } 58 | } 59 | 60 | + (void)handleTextViewTextDidChange:(UITextView *)textV{ 61 | 62 | if (textV.isChineseInput) { 63 | [textV matchWithPattern:textV.inputPredicate]; 64 | } 65 | 66 | if (![textV hasInputPinYin]) { 67 | if (textV.limitCount > 0) { 68 | if (textV.text.length > textV.limitCount) { 69 | textV.text = [textV.text substringToIndex:textV.limitCount]; 70 | } 71 | } 72 | } 73 | } 74 | 75 | @end 76 | 77 | @implementation NSString (FormVerifyManager) 78 | 79 | - (BOOL)verifyPredicate:(NSString *)predicate{ 80 | NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", predicate]; 81 | return [pre evaluateWithObject:self]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/FormVerifyTextDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormVerifyTextDelegate.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 郑桂华 on 2020/7/8. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | static void *FormTextLimitCountKey = &FormTextLimitCountKey; 13 | static void *FormTextInputPredicateKey = &FormTextInputPredicateKey; 14 | 15 | @protocol FormVerifyTextDelegate 16 | 17 | @property(nonatomic, assign)NSInteger limitCount; 18 | @property(nonatomic, copy)NSString *inputPredicate; 19 | 20 | - (void)handleTextDidChange; 21 | 22 | - (BOOL)isChineseInput; 23 | 24 | - (BOOL)isEmojiInput; 25 | 26 | - (void)matchWithPattern:(NSString *)pattern; 27 | 28 | - (BOOL)hasInputPinYin; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/NSString+FormEmoji.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+FormEmoji.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/5/12. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface NSString (FormEmoji) 13 | 14 | - (NSString *)removeEmoji; 15 | - (BOOL)containEmoji; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/NSString+FormEmoji.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+FormEmoji.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/5/12. 6 | // 7 | 8 | #import "NSString+FormEmoji.h" 9 | 10 | @implementation NSString (FormEmoji) 11 | 12 | - (NSString *)noEmoji { 13 | //去除表情规则 14 | // \u0020-\\u007E 标点符号,大小写字母,数字 15 | // \u00A0-\\u00BE 特殊标点 (¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾) 16 | // \u2E80-\\uA4CF 繁简中文,日文,韩文 彝族文字 17 | // \uFE30-\\uFE4F 特殊标点(︴︵︶︷︸︹) 18 | // \uFF00-\\uFFEF 日文 (オカキクケコサ) 19 | // \u2000-\\u201f 特殊字符(‐‑‒–—―‖‗‘’‚‛“”„‟) 20 | // 注:对照表 http://blog.csdn.net/hherima/article/details/9045765 21 | 22 | NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u2E80-\\uA4CF\\uFF00-\\uFFEF\\r\n]" options:NSRegularExpressionCaseInsensitive error:nil]; 23 | 24 | NSString* result = [expression stringByReplacingMatchesInString:self options:0 range:NSMakeRange(0, self.length) withTemplate:@""]; 25 | 26 | return result; 27 | } 28 | 29 | 30 | - (NSString *)removeEmoji{ 31 | if ([self containEmoji]) { 32 | return [self noEmoji]; 33 | } 34 | return self; 35 | } 36 | 37 | - (BOOL)containEmoji 38 | { 39 | NSUInteger len = [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 40 | if (len < 3) { // 大于2个字符需要验证Emoji(有些Emoji仅三个字符) 41 | return NO; 42 | } 43 | 44 | // 仅考虑字节长度为3的字符,大于此范围的全部做Emoji处理 45 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; 46 | 47 | Byte *bts = (Byte *)[data bytes]; 48 | Byte bt; 49 | short v; 50 | for (NSUInteger i = 0; i < len; i++) { 51 | bt = bts[i]; 52 | 53 | if ((bt | 0x7F) == 0x7F) { // 0xxxxxxx ASIIC编码 54 | continue; 55 | } 56 | if ((bt | 0x1F) == 0xDF) { // 110xxxxx 两个字节的字符 57 | i += 1; 58 | continue; 59 | } 60 | if ((bt | 0x0F) == 0xEF) { // 1110xxxx 三个字节的字符(重点过滤项目) 61 | // 计算Unicode下标 62 | v = bt & 0x0F; 63 | v = v << 6; 64 | v |= bts[i + 1] & 0x3F; 65 | v = v << 6; 66 | v |= bts[i + 2] & 0x3F; 67 | 68 | // NSLog(@"%02X%02X", (Byte)(v >> 8), (Byte)(v & 0xFF)); 69 | 70 | if ([self emojiInSoftBankUnicode:v] || [self emojiInUnicode:v]) { 71 | return YES; 72 | } 73 | 74 | i += 2; 75 | continue; 76 | } 77 | if ((bt | 0x3F) == 0xBF) { // 10xxxxxx 10开头,为数据字节,直接过滤 78 | continue; 79 | } 80 | 81 | return YES; // 不是以上情况的字符全部超过三个字节,做Emoji处理 82 | } 83 | 84 | return NO; 85 | } 86 | 87 | - (BOOL)emojiInSoftBankUnicode:(short)code 88 | { 89 | return ((code >> 8) >= 0xE0 && (code >> 8) <= 0xE5 && (Byte)(code & 0xFF) < 0x60); 90 | } 91 | 92 | - (BOOL)emojiInUnicode:(short)code 93 | { 94 | if (code == 0x0023 95 | || code == 0x002A 96 | || (code >= 0x0030 && code <= 0x0039) 97 | || code == 0x00A9 98 | || code == 0x00AE 99 | || code == 0x203C 100 | || code == 0x2049 101 | || code == 0x2122 102 | || code == 0x2139 103 | || (code >= 0x2194 && code <= 0x2199) 104 | || code == 0x21A9 || code == 0x21AA 105 | || code == 0x231A || code == 0x231B 106 | || code == 0x2328 107 | || code == 0x23CF 108 | || (code >= 0x23E9 && code <= 0x23F3) 109 | || (code >= 0x23F8 && code <= 0x23FA) 110 | || code == 0x24C2 111 | || code == 0x25AA || code == 0x25AB 112 | || code == 0x25B6 113 | || code == 0x25C0 114 | || (code >= 0x25FB && code <= 0x25FE) 115 | || (code >= 0x2600 && code <= 0x2604) 116 | || code == 0x260E 117 | || code == 0x2611 118 | || code == 0x2614 || code == 0x2615 119 | || code == 0x2618 120 | || code == 0x261D 121 | || code == 0x2620 122 | || code == 0x2622 || code == 0x2623 123 | || code == 0x2626 124 | || code == 0x262A 125 | || code == 0x262E || code == 0x262F 126 | || (code >= 0x2638 && code <= 0x263A) 127 | || (code >= 0x2648 && code <= 0x2653) 128 | || code == 0x2660 129 | || code == 0x2663 130 | || code == 0x2665 || code == 0x2666 131 | || code == 0x2668 132 | || code == 0x267B 133 | || code == 0x267F 134 | || (code >= 0x2692 && code <= 0x2694) 135 | || code == 0x2696 || code == 0x2697 136 | || code == 0x2699 137 | || code == 0x269B || code == 0x269C 138 | || code == 0x26A0 || code == 0x26A1 139 | || code == 0x26AA || code == 0x26AB 140 | || code == 0x26B0 || code == 0x26B1 141 | || code == 0x26BD || code == 0x26BE 142 | || code == 0x26C4 || code == 0x26C5 143 | || code == 0x26C8 144 | || code == 0x26CE 145 | || code == 0x26CF 146 | || code == 0x26D1 147 | || code == 0x26D3 || code == 0x26D4 148 | || code == 0x26E9 || code == 0x26EA 149 | || (code >= 0x26F0 && code <= 0x26F5) 150 | || (code >= 0x26F7 && code <= 0x26FA) 151 | || code == 0x26FD 152 | || code == 0x2702 153 | || code == 0x2705 154 | || (code >= 0x2708 && code <= 0x270D) 155 | || code == 0x270F 156 | || code == 0x2712 157 | || code == 0x2714 158 | || code == 0x2716 159 | || code == 0x271D 160 | || code == 0x2721 161 | || code == 0x2728 162 | || code == 0x2733 || code == 0x2734 163 | || code == 0x2744 164 | || code == 0x2747 165 | || code == 0x274C 166 | || code == 0x274E 167 | || (code >= 0x2753 && code <= 0x2755) 168 | || code == 0x2757 169 | || code == 0x2763 || code == 0x2764 170 | || (code >= 0x2795 && code <= 0x2797) 171 | || code == 0x27A1 172 | || code == 0x27B0 173 | || code == 0x27BF 174 | || code == 0x2934 || code == 0x2935 175 | || (code >= 0x2B05 && code <= 0x2B07) 176 | || code == 0x2B1B || code == 0x2B1C 177 | || code == 0x2B50 178 | || code == 0x2B55 179 | || code == 0x3030 180 | || code == 0x303D 181 | || code == 0x3297 182 | || code == 0x3299 183 | // 第二段 184 | || code == 0x23F0) { 185 | return YES; 186 | } 187 | return NO; 188 | } 189 | 190 | @end 191 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/UITextField+FormExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+ChineseInput.h 3 | // QiaoKeApp 4 | // 5 | // Created by 周发明 on 2020/3/30. 6 | // 7 | 8 | #import 9 | #import "FormVerifyTextDelegate.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UITextField (FormExtension) 14 | 15 | @property(nonatomic, readonly)UILabel *placeholderLabel; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/UITextField+FormExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+ChineseInput.m 3 | // QiaoKeApp 4 | // 5 | // Created by 周发明 on 2020/3/30. 6 | // 7 | 8 | #import "UITextField+FormExtension.h" 9 | #import 10 | #import "FormListConfigure.h" 11 | 12 | @implementation UITextField (FormExtension) 13 | 14 | - (UILabel *)placeholderLabel{ 15 | Ivar ivar = class_getInstanceVariable([UITextField class], "_placeholderLabel"); 16 | UILabel *placeholderLabel = object_getIvar(self, ivar); 17 | return placeholderLabel; 18 | } 19 | 20 | - (void)setLimitCount:(NSInteger)limitCount{ 21 | objc_setAssociatedObject(self, FormTextLimitCountKey, @(limitCount), OBJC_ASSOCIATION_COPY_NONATOMIC); 22 | } 23 | 24 | - (NSInteger)limitCount{ 25 | NSNumber *obj = objc_getAssociatedObject(self, FormTextLimitCountKey); 26 | if (obj == nil) { 27 | obj = @0; 28 | objc_setAssociatedObject(self, FormTextLimitCountKey, obj, OBJC_ASSOCIATION_COPY_NONATOMIC); 29 | } 30 | return [obj integerValue]; 31 | } 32 | 33 | - (void)setInputPredicate:(NSString *)inputPredicate{ 34 | objc_setAssociatedObject(self, FormTextInputPredicateKey, inputPredicate, OBJC_ASSOCIATION_COPY_NONATOMIC); 35 | } 36 | 37 | - (NSString *)inputPredicate{ 38 | NSString *obj = objc_getAssociatedObject(self, FormTextInputPredicateKey); 39 | return obj; 40 | } 41 | 42 | - (void)handleTextDidChange{ 43 | [FormVerifyManager handleTextFieldTextDidChange:self]; 44 | } 45 | 46 | - (BOOL)isChineseInput{ 47 | NSString *lang = [[self textInputMode] primaryLanguage]; 48 | if([lang isEqualToString:@"zh-Hans"]) { 49 | return YES; 50 | } else { 51 | return NO; 52 | } 53 | } 54 | 55 | - (BOOL)isEmojiInput{ 56 | return [[[self textInputMode] primaryLanguage] isEqualToString:@"emoji"]; 57 | } 58 | 59 | - (void)matchWithPattern:(NSString *)pattern{ 60 | if (![self hasInputPinYin] && pattern && pattern.length > 0) { 61 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[pattern stringByReplacingOccurrencesOfString:@"[" withString:@"[^"] options:NSRegularExpressionCaseInsensitive error:nil]; 62 | NSString *modifiedString = [regex stringByReplacingMatchesInString:self.text 63 | options:0 64 | range:NSMakeRange(0, [self.text length]) 65 | withTemplate:@""]; 66 | self.text = modifiedString; 67 | } 68 | } 69 | 70 | - (BOOL)hasInputPinYin{ 71 | UITextRange *selectedRange = self.markedTextRange; 72 | UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0]; 73 | if (!position) { 74 | return NO; 75 | } else { 76 | return YES; 77 | } 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/UITextView+FormExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+FormExtension.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/27. 6 | // 7 | 8 | #import 9 | #import "FormVerifyTextDelegate.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UITextView (FormExtension) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/Tool/UITextView+FormExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+FormExtension.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/27. 6 | // 7 | 8 | #import "UITextView+FormExtension.h" 9 | #import 10 | #import "FormVerifyManager.h" 11 | 12 | @implementation UITextView (FormExtension) 13 | 14 | - (void)setLimitCount:(NSInteger)limitCount{ 15 | objc_setAssociatedObject(self, FormTextLimitCountKey, @(limitCount), OBJC_ASSOCIATION_COPY_NONATOMIC); 16 | } 17 | 18 | - (NSInteger)limitCount{ 19 | NSNumber *obj = objc_getAssociatedObject(self, FormTextLimitCountKey); 20 | if (obj == nil) { 21 | obj = @0; 22 | objc_setAssociatedObject(self, FormTextLimitCountKey, obj, OBJC_ASSOCIATION_COPY_NONATOMIC); 23 | } 24 | return [obj integerValue]; 25 | } 26 | 27 | - (void)setInputPredicate:(NSString *)inputPredicate{ 28 | objc_setAssociatedObject(self, FormTextInputPredicateKey, inputPredicate, OBJC_ASSOCIATION_COPY_NONATOMIC); 29 | } 30 | 31 | - (NSString *)inputPredicate{ 32 | NSString *obj = objc_getAssociatedObject(self, FormTextInputPredicateKey); 33 | return obj; 34 | } 35 | 36 | - (void)handleTextDidChange{ 37 | [FormVerifyManager handleTextViewTextDidChange:self]; 38 | } 39 | 40 | - (BOOL)isChineseInput{ 41 | NSString *lang = [[self textInputMode] primaryLanguage]; 42 | if([lang isEqualToString:@"zh-Hans"]) { 43 | return YES; 44 | } else { 45 | return NO; 46 | } 47 | } 48 | 49 | - (BOOL)isEmojiInput{ 50 | return [[[self textInputMode] primaryLanguage] isEqualToString:@"emoji"]; 51 | } 52 | 53 | - (void)matchWithPattern:(NSString *)pattern{ 54 | if (![self hasInputPinYin] && pattern && pattern.length > 0) { 55 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[pattern stringByReplacingOccurrencesOfString:@"[" withString:@"[^"] options:NSRegularExpressionCaseInsensitive error:nil]; 56 | NSString *modifiedString = [regex stringByReplacingMatchesInString:self.text 57 | options:0 58 | range:NSMakeRange(0, [self.text length]) 59 | withTemplate:@""]; 60 | self.text = modifiedString; 61 | } 62 | } 63 | 64 | - (BOOL)hasInputPinYin{ 65 | UITextRange *selectedRange = self.markedTextRange; 66 | UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0]; 67 | if (!position) { 68 | return NO; 69 | } else { 70 | return YES; 71 | } 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListBaseCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListBaseCell.h 3 | // YaLeGou 4 | // 5 | // Created by 周发明 on 2019/12/14. 6 | // Copyright © 2019 y. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FormListConfigure.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @class FormListBaseModel; 14 | @interface FormListBaseCell : UITableViewCell 15 | @property(nonatomic, weak)UIView *bottomLineView; 16 | @property(nonatomic, strong)FormListBaseModel *model; 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListBaseCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListBaseCell.m 3 | // YaLeGou 4 | // 5 | // Created by 周发明 on 2019/12/14. 6 | // Copyright © 2019 y. All rights reserved. 7 | // 8 | 9 | #import "FormListBaseCell.h" 10 | #import "FormListBaseModel.h" 11 | 12 | NSInteger initCount = 0; 13 | 14 | @implementation FormListBaseCell 15 | 16 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 17 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 18 | self.selectionStyle = UITableViewCellSelectionStyleNone; 19 | self.contentView.backgroundColor = [UIColor whiteColor]; 20 | UIView *line = [[UIView alloc] init]; 21 | line.backgroundColor = FormCellBottomLineColor; 22 | [self.contentView addSubview:line]; 23 | [line mas_makeConstraints:^(MASConstraintMaker *make) { 24 | make.left.mas_equalTo(Form_BaseSize(0)); 25 | make.right.mas_equalTo(-Form_BaseSize(0)); 26 | make.bottom.mas_equalTo(0); 27 | make.height.mas_equalTo(FormCellBottomLineDefaultHeight); 28 | }]; 29 | self.bottomLineView = line; 30 | initCount += 1; 31 | NSLog(@"initCount: %ld", initCount); 32 | } 33 | return self; 34 | } 35 | 36 | - (void)setModel:(FormListBaseModel *)model{ 37 | _model = model; 38 | self.contentView.backgroundColor = model.contentBg; 39 | self.bottomLineView.backgroundColor = model.bottomLineBg; 40 | [self.bottomLineView mas_remakeConstraints:^(MASConstraintMaker *make) { 41 | make.height.mas_equalTo(model.bottomLineHeight); 42 | make.left.mas_equalTo(model.bottomLineLMargin); 43 | make.right.mas_equalTo(-model.bottomLineRMargin); 44 | make.bottom.mas_equalTo(-model.bottomLineBMargin); 45 | }]; 46 | if (model.configureCell) { 47 | model.configureCell(self); 48 | } 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListImageUpCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpCell.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleCell.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface FormListImageUpCell : FormListTitleCell 13 | @property(nonatomic, weak)UIScrollView *btnContentView; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListImageUpCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpCell.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/28. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListImageUpCell.h" 10 | #import "FormListImageUpModel.h" 11 | #import "FormListImageSelectModel.h" 12 | 13 | #import "FormListImageUpCellItemView.h" 14 | #import "FormListUpImageConfigure.h" 15 | 16 | @interface FormListImageUpCell () 17 | 18 | @property(nonatomic, assign)BOOL scrollToLast; 19 | 20 | @end 21 | 22 | @implementation FormListImageUpCell 23 | 24 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 25 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 26 | self.selectionStyle = UITableViewCellSelectionStyleNone; 27 | { 28 | UIScrollView *view = [[UIScrollView alloc] init]; 29 | view.clipsToBounds = YES; 30 | [self.contentView addSubview:view]; 31 | self.btnContentView = view; 32 | [view mas_makeConstraints:^(MASConstraintMaker *make) { 33 | make.bottom.equalTo(self.bottomLineView.mas_top); 34 | make.left.right.equalTo(@0); 35 | make.top.equalTo(self.contentView).offset(0); 36 | }]; 37 | } 38 | } 39 | return self; 40 | } 41 | 42 | - (void)setModel:(FormListImageUpModel *)model{ 43 | [super setModel:model]; 44 | [self.btnContentView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 45 | [obj removeFromSuperview]; 46 | }]; 47 | if (model.imageConfigure.oneLineScroll) { 48 | CGFloat width = model.imageConfigure.inset.left + model.images.count * model.imageConfigure.imageWidth + (model.images.count - 1) * model.imageConfigure.imageItemSpace + model.imageConfigure.inset.right; 49 | self.btnContentView.contentSize = CGSizeMake(width, 0); 50 | [model.imageConfigure oneLineScrollMasonyMake]; 51 | if (self.scrollToLast) { 52 | CGFloat scrollOffsetX = width - self.bounds.size.width; 53 | if (scrollOffsetX < 0) { 54 | scrollOffsetX = 0; 55 | } 56 | [self.btnContentView setContentOffset:CGPointMake(scrollOffsetX, 0) animated:YES]; 57 | } 58 | self.scrollToLast = NO; 59 | } else { 60 | self.btnContentView.contentSize = CGSizeZero; 61 | } 62 | for (int i = 0; i < model.images.count; i++) { 63 | FormListImageSelectModel *btnModel = model.images[i]; 64 | FormListImageUpCellItemView *view = [[model.imageConfigure.imageViewClass alloc] init]; 65 | view.model = btnModel; 66 | __weak typeof(self) weakSelf = self; 67 | [view setClickMutibleBlock:^(BOOL add, FormListImageSelectModel * _Nonnull model, NSArray * _Nonnull images) { 68 | FormListImageUpModel *upModel = (FormListImageUpModel *)weakSelf.model; 69 | if (upModel.canDynamicAdd) { 70 | NSInteger index = [upModel.images indexOfObject:model]; 71 | if (add) { 72 | if (upModel.images.count < upModel.maxCount) {// 可以再添加 73 | if (index == upModel.images.count - 1) { 74 | NSMutableArray *arrm = [NSMutableArray arrayWithArray:upModel.images]; 75 | if (images.count > 1) { 76 | NSInteger count = MIN(images.count - 1, upModel.maxCount - upModel.images.count); 77 | for (int i = 0; i < count; i++) { 78 | FormListImageSelectModel *selModel = upModel.imageConfigure.createAddModel(); 79 | selModel.image = images[i+1]; 80 | [arrm addObject:selModel]; 81 | } 82 | } 83 | if (arrm.count < upModel.maxCount) { 84 | [arrm addObject:upModel.imageConfigure.createAddModel()]; 85 | } 86 | upModel.images = [NSArray arrayWithArray:arrm]; 87 | if (upModel.imageConfigure.oneLineScroll) { 88 | weakSelf.scrollToLast = YES; 89 | } 90 | } 91 | } 92 | if (upModel.selectImageBlock) { 93 | upModel.selectImageBlock(model, model.image); 94 | } 95 | if (upModel.selectMutibleBlock) { 96 | upModel.selectMutibleBlock(model, images); 97 | } 98 | } else { 99 | NSMutableArray *arrm = [NSMutableArray arrayWithArray:upModel.images]; 100 | [arrm removeObject:model]; 101 | FormListImageSelectModel *lastModel = [arrm lastObject]; 102 | if (lastModel.image != nil) { 103 | [arrm addObject:upModel.imageConfigure.createAddModel()]; 104 | } 105 | if (arrm.count == 0) { 106 | [arrm addObject:upModel.imageConfigure.createAddModel()]; 107 | } 108 | upModel.images = [NSArray arrayWithArray:arrm]; 109 | } 110 | } else { 111 | if (!add) { 112 | model.image = nil; 113 | } else { 114 | if (upModel.selectImageBlock) { 115 | upModel.selectImageBlock(model, model.image); 116 | } 117 | } 118 | } 119 | !upModel.refreshBlock ?: upModel.refreshBlock(); 120 | }]; 121 | [view setSelectMaxCount:^NSInteger(FormListImageSelectModel * _Nonnull model) { 122 | FormListImageUpModel *upModel = (FormListImageUpModel *)weakSelf.model; 123 | if (upModel.canDynamicAdd) { 124 | return upModel.maxCount - upModel.images.count + 1; 125 | } else { 126 | return 1; 127 | } 128 | }]; 129 | [self.btnContentView addSubview:view]; 130 | [view mas_makeConstraints:^(MASConstraintMaker *make) { 131 | model.imageConfigure.masony_makeBlock(make, i); 132 | }]; 133 | } 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListImageUpCellItemView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpCellItemView.h 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | @class FormListImageSelectModel; 12 | ///是否是添加图片, 点击的model, 添加时选中的所有图片 13 | typedef void(^FormListImageUpCellItemMutibleClick)(BOOL add, FormListImageSelectModel *model, NSArray * __nullable images); 14 | typedef NSInteger(^FormListImageUpCanSelectMaxCount)(FormListImageSelectModel *model); 15 | 16 | @protocol FormListImageUpCellItemDelegate 17 | 18 | @property(nonatomic, strong)FormListImageSelectModel *model; 19 | @property(nonatomic, copy)FormListImageUpCellItemMutibleClick clickMutibleBlock; 20 | @property(nonatomic, copy)FormListImageUpCanSelectMaxCount selectMaxCount; 21 | 22 | @end 23 | 24 | @interface FormListImageUpCellItemView : UIView 25 | 26 | - (void)delButtonClick; 27 | - (void)addImageClick; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListImageUpCellItemView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListImageUpCellItemView.m 3 | // FMFormSubmitKit 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // 7 | 8 | #import "FormListImageUpCellItemView.h" 9 | #import "FormListImageSelectModel.h" 10 | 11 | @implementation FormListImageUpCellItemView{ 12 | FormListImageSelectModel *_model; 13 | FormListImageUpCellItemMutibleClick _clickMutibleBlock; 14 | FormListImageUpCanSelectMaxCount _selectMaxBlock; 15 | } 16 | 17 | - (instancetype)initWithFrame:(CGRect)frame 18 | { 19 | self = [super initWithFrame:frame]; 20 | if (self) { 21 | self.backgroundColor = [UIColor orangeColor]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)setModel:(FormListImageSelectModel *)model{ 27 | _model = model; 28 | } 29 | 30 | - (FormListImageSelectModel *)model{ 31 | return _model; 32 | } 33 | 34 | - (void)setClickMutibleBlock:(FormListImageUpCellItemMutibleClick)clickMutibleBlock{ 35 | _clickMutibleBlock = clickMutibleBlock; 36 | } 37 | 38 | - (FormListImageUpCellItemMutibleClick)clickMutibleBlock{ 39 | return _clickMutibleBlock; 40 | } 41 | 42 | - (void)setSelectMaxCount:(FormListImageUpCanSelectMaxCount)selectMaxCount{ 43 | _selectMaxBlock = selectMaxCount; 44 | } 45 | 46 | - (FormListImageUpCanSelectMaxCount)selectMaxCount{ 47 | return _selectMaxBlock; 48 | } 49 | 50 | - (void)delButtonClick{ 51 | !self.clickMutibleBlock ?: self.clickMutibleBlock(NO, self.model, nil); 52 | } 53 | 54 | - (void)addImageClick{ 55 | NSInteger maxCount = self.selectMaxCount?self.selectMaxCount(self.model):1; 56 | NSLog(@"maxCount: %ld", maxCount); 57 | !self.clickMutibleBlock ?: self.clickMutibleBlock(YES, self.model, @[[[UIImage alloc] init], [[UIImage alloc] init], [[UIImage alloc] init]]); 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListSelectCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSelectCell.h 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/29. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleCell.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListSelectCell : FormListTitleCell 14 | 15 | @property(nonatomic, weak)UIView *btnView; 16 | @property(nonatomic, weak)UIButton *selectBtn; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListSelectCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListSelectCell.m 3 | // ChengXuan 4 | // 5 | // Created by 周发明 on 2019/11/29. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListSelectCell.h" 10 | #import "FormListSelectModel.h" 11 | 12 | @interface FormListSelectCell () 13 | @property(nonatomic, strong)NSArray *titles; 14 | @end 15 | 16 | @implementation FormListSelectCell 17 | 18 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 19 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 20 | self.selectionStyle = UITableViewCellSelectionStyleNone; 21 | 22 | UIView *btnView = [[UIView alloc] init]; 23 | [self.contentView insertSubview:btnView atIndex:0]; 24 | [btnView mas_makeConstraints:^(MASConstraintMaker *make) { 25 | make.left.top.bottom.right.equalTo(@0); 26 | }]; 27 | self.btnView = btnView; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)btnSelectClick:(UIButton *)sender{ 33 | self.selectBtn = sender; 34 | FormListSelectModel *selModel = (FormListSelectModel *)self.model; 35 | selModel.selectIndex = sender.tag; 36 | if (selModel.selectClick) { 37 | selModel.selectClick(sender.tag, sender); 38 | } 39 | } 40 | 41 | - (void)setSelectBtn:(UIButton *)selectBtn{ 42 | _selectBtn.selected = NO; 43 | _selectBtn = selectBtn; 44 | _selectBtn.selected = YES; 45 | } 46 | 47 | - (void)setModel:(FormListSelectModel *)model{ 48 | [super setModel:model]; 49 | self.titles = model.selects; 50 | } 51 | 52 | - (void)setTitles:(NSArray *)titles{ 53 | if ([_titles isEqualToArray:titles]) { 54 | return; 55 | } else { 56 | _titles = titles; 57 | [self createBtns:titles selectIndex:((FormListSelectModel *)self.model).selectIndex]; 58 | } 59 | } 60 | 61 | - (void)createBtns:(NSArray *)titles selectIndex:(NSInteger)select{ 62 | 63 | [self.btnView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 64 | [obj removeFromSuperview]; 65 | }]; 66 | 67 | id left = self.btnView.mas_right; 68 | 69 | for (int i = 0; i 17 | 18 | @end 19 | 20 | @implementation FormListTextVCell 21 | 22 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 23 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 24 | self.selectionStyle = UITableViewCellSelectionStyleNone; 25 | [self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) { 26 | make.left.mas_equalTo(FormCellLRMargin); 27 | make.top.mas_equalTo(FormCellTVTitleTopMargin); 28 | }]; 29 | 30 | FormTextView *tf = [[FormTextView alloc] init]; 31 | tf.delegate = self; 32 | tf.textColor = FormCellTFTVColor; 33 | tf.placeholderTextColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.7]; 34 | tf.font = FormCellTFTVFont; 35 | tf.textAlignment = NSTextAlignmentRight; 36 | [self.contentView addSubview:tf]; 37 | [tf mas_makeConstraints:^(MASConstraintMaker *make) { 38 | make.left.mas_equalTo(FormCellLRMargin - 5); 39 | make.right.mas_equalTo(-FormCellLRMargin + 5); 40 | make.top.mas_equalTo(FormCellTVTitleTopMargin + FormCellTitleFont.lineHeight + FormCellTVTitleTopMargin - 8); 41 | make.bottom.mas_equalTo(self.bottomLineView.mas_top); 42 | }]; 43 | self.textV = tf; 44 | } 45 | return self; 46 | } 47 | 48 | - (void)setModel:(FormListTextModel *)model{ 49 | [super setModel:model]; 50 | 51 | self.textV.limitCount = model.limitCount; 52 | self.textV.inputPredicate = model.inputPredicate; 53 | 54 | self.textV.placeholderLabel.textColor = model.placeholderColor; 55 | self.textV.font = model.textFont; 56 | self.textV.textColor = model.textColor; 57 | self.textV.textAlignment = model.alignment; 58 | self.textV.tintColor = model.textTintColor; 59 | if (model.textVTopMargin > 0) { 60 | [self.textV mas_updateConstraints:^(MASConstraintMaker *make) { 61 | make.top.mas_equalTo(model.textVTopMargin - 8); 62 | }]; 63 | } else { 64 | [self.textV mas_updateConstraints:^(MASConstraintMaker *make) { 65 | make.top.mas_equalTo(FormCellTVTitleTopMargin + FormCellTitleFont.lineHeight + FormCellTVTitleTopMargin - 8); 66 | }]; 67 | } 68 | if (model.textFLeftMargin > 0) { 69 | [self.textV mas_updateConstraints:^(MASConstraintMaker *make) { 70 | make.left.mas_equalTo(model.textFLeftMargin - 8); 71 | }]; 72 | } 73 | 74 | if ([model.placehoder isKindOfClass:[NSString class]]) { 75 | self.textV.placeholder = model.placehoder; 76 | } else if ([model.placehoder isKindOfClass:[NSAttributedString class]]) { 77 | self.textV.attributedPlaceholder = model.placehoder; 78 | } else { 79 | self.textV.placeholder = @""; 80 | } 81 | 82 | if ([model.text isKindOfClass:[NSString class]]) { 83 | self.textV.text = model.text; 84 | } else if ([model.text isKindOfClass:[NSAttributedString class]]) { 85 | self.textV.attributedText = model.text; 86 | } else { 87 | self.textV.text = @""; 88 | } 89 | 90 | if (model.configurationBlock) { 91 | model.configurationBlock(self.textV); 92 | } 93 | } 94 | 95 | - (BOOL)textViewShouldBeginEditing:(UITextView *)textView{ 96 | FormListTextModel *model = (FormListTextModel *)self.model; 97 | if (model.isSelect) { 98 | !model.selectBlock ?: model.selectBlock(self.textV, model); 99 | return NO; 100 | } 101 | return YES; 102 | } 103 | 104 | - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ 105 | FormListTextModel *model = (FormListTextModel *)self.model; 106 | if (textView.isChineseInput) { 107 | return YES; 108 | } 109 | if (model.inputPredicate && text.length > 0) { 110 | return [text verifyPredicate:model.inputPredicate]; 111 | } else { 112 | return YES; 113 | } 114 | } 115 | 116 | - (void)textViewDidChange:(UITextView *)textView{ 117 | FormListTextModel *model = (FormListTextModel *)self.model; 118 | 119 | [FormVerifyManager handleTextViewTextDidChange:self.textV]; 120 | 121 | model.text = self.textV.text; 122 | if (!model.isSelect) { 123 | model.value = model.text; 124 | } 125 | 126 | if (model.textLengthChange) { 127 | model.textLengthChange(self.textV.text.length); 128 | } 129 | } 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListTitleCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTitleCell.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListBaseCell.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormListTitleCell : FormListBaseCell 14 | @property(nonatomic, weak)UILabel *titleLabel; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormListTitleCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormListTitleCell.m 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2020/4/18. 6 | // Copyright © 2020 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormListTitleCell.h" 10 | #import "FormListTitleModel.h" 11 | 12 | @interface FormListTitleCell () 13 | 14 | @end 15 | 16 | @implementation FormListTitleCell 17 | 18 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 19 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 20 | self.selectionStyle = UITableViewCellSelectionStyleNone; 21 | 22 | UILabel *label = [[UILabel alloc] init]; 23 | label.numberOfLines = 0; 24 | label.textColor = FormCellTitleColor; 25 | label.font = FormCellTitleFont; 26 | label.textAlignment = NSTextAlignmentLeft; 27 | [self.contentView addSubview:label]; 28 | self.titleLabel = label; 29 | [label mas_makeConstraints:^(MASConstraintMaker *make) { 30 | make.left.mas_equalTo(FormCellLRMargin); 31 | make.centerY.mas_equalTo(@0); 32 | }]; 33 | 34 | } 35 | return self; 36 | } 37 | 38 | - (void)setModel:(FormListTitleModel *)model{ 39 | [super setModel:model]; 40 | 41 | self.titleLabel.font = model.titleFont; 42 | self.titleLabel.textColor = model.titleColor; 43 | self.titleLabel.textAlignment = model.titleAligment; 44 | 45 | if ([model.title isKindOfClass:[NSString class]]) { 46 | self.titleLabel.text = model.title; 47 | } else if ([model.title isKindOfClass:[NSAttributedString class]]) { 48 | self.titleLabel.attributedText = model.title; 49 | } 50 | 51 | if (model.masony_remakeBlock) { 52 | [self.titleLabel mas_remakeConstraints:model.masony_remakeBlock]; 53 | } 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormTextView.h 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2019/12/20. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface FormTextView : UITextView 14 | 15 | @property(nonatomic, strong) UILabel *placeholderLabel; 16 | 17 | @property(nullable, nonatomic,copy) IBInspectable NSString *placeholder; 18 | 19 | @property(nullable, nonatomic,copy) IBInspectable NSAttributedString *attributedPlaceholder; 20 | 21 | @property(nullable, nonatomic,copy) IBInspectable UIColor *placeholderTextColor; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /FMFormSubmitKit/Classes/View/FormTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormTextView.m 3 | // FormSubmitList 4 | // 5 | // Created by 周发明 on 2019/12/20. 6 | // Copyright © 2019 周发明. All rights reserved. 7 | // 8 | 9 | #import "FormTextView.h" 10 | 11 | @interface FormTextView () 12 | 13 | @end 14 | 15 | @implementation FormTextView 16 | 17 | @synthesize placeholder = _placeholder; 18 | @synthesize placeholderLabel = _placeholderLabel; 19 | @synthesize placeholderTextColor = _placeholderTextColor; 20 | 21 | -(void)initialize 22 | { 23 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self]; 24 | } 25 | 26 | -(void)dealloc 27 | { 28 | [_placeholderLabel removeFromSuperview]; 29 | _placeholderLabel = nil; 30 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 31 | } 32 | 33 | - (instancetype)init 34 | { 35 | self = [super init]; 36 | if (self) { 37 | [self initialize]; 38 | } 39 | return self; 40 | } 41 | 42 | -(void)awakeFromNib 43 | { 44 | [super awakeFromNib]; 45 | [self initialize]; 46 | } 47 | 48 | -(void)refreshPlaceholder 49 | { 50 | if([[self text] length] || [[self attributedText] length]) 51 | { 52 | [_placeholderLabel setAlpha:0]; 53 | } 54 | else 55 | { 56 | [_placeholderLabel setAlpha:1]; 57 | } 58 | 59 | [self setNeedsLayout]; 60 | [self layoutIfNeeded]; 61 | } 62 | 63 | - (void)setText:(NSString *)text 64 | { 65 | [super setText:text]; 66 | [self refreshPlaceholder]; 67 | } 68 | 69 | -(void)setAttributedText:(NSAttributedString *)attributedText 70 | { 71 | [super setAttributedText:attributedText]; 72 | [self refreshPlaceholder]; 73 | } 74 | 75 | -(void)setFont:(UIFont *)font 76 | { 77 | [super setFont:font]; 78 | self.placeholderLabel.font = self.font; 79 | 80 | [self setNeedsLayout]; 81 | [self layoutIfNeeded]; 82 | } 83 | 84 | -(void)setTextAlignment:(NSTextAlignment)textAlignment 85 | { 86 | [super setTextAlignment:textAlignment]; 87 | self.placeholderLabel.textAlignment = textAlignment; 88 | 89 | [self setNeedsLayout]; 90 | [self layoutIfNeeded]; 91 | } 92 | 93 | -(void)layoutSubviews 94 | { 95 | [super layoutSubviews]; 96 | self.placeholderLabel.frame = [self placeholderExpectedFrame]; 97 | } 98 | 99 | -(void)setPlaceholder:(NSString *)placeholder 100 | { 101 | _placeholder = placeholder; 102 | 103 | self.placeholderLabel.text = placeholder; 104 | [self refreshPlaceholder]; 105 | } 106 | 107 | -(void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder 108 | { 109 | _attributedPlaceholder = attributedPlaceholder; 110 | 111 | self.placeholderLabel.attributedText = attributedPlaceholder; 112 | [self refreshPlaceholder]; 113 | } 114 | 115 | -(void)setPlaceholderTextColor:(UIColor*)placeholderTextColor 116 | { 117 | _placeholderTextColor = placeholderTextColor; 118 | self.placeholderLabel.textColor = placeholderTextColor; 119 | } 120 | 121 | -(UIEdgeInsets)placeholderInsets 122 | { 123 | return UIEdgeInsetsMake(self.textContainerInset.top, self.textContainerInset.left + self.textContainer.lineFragmentPadding, self.textContainerInset.bottom, self.textContainerInset.right + self.textContainer.lineFragmentPadding); 124 | } 125 | 126 | -(CGRect)placeholderExpectedFrame 127 | { 128 | UIEdgeInsets placeholderInsets = [self placeholderInsets]; 129 | CGFloat maxWidth = CGRectGetWidth(self.frame)-placeholderInsets.left-placeholderInsets.right; 130 | 131 | CGSize expectedSize = [self.placeholderLabel sizeThatFits:CGSizeMake(maxWidth, CGRectGetHeight(self.frame)-placeholderInsets.top-placeholderInsets.bottom)]; 132 | 133 | return CGRectMake(placeholderInsets.left, placeholderInsets.top, maxWidth, expectedSize.height); 134 | } 135 | 136 | -(UILabel*)placeholderLabel 137 | { 138 | if (_placeholderLabel == nil) 139 | { 140 | _placeholderLabel = [[UILabel alloc] init]; 141 | _placeholderLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight); 142 | _placeholderLabel.lineBreakMode = NSLineBreakByWordWrapping; 143 | _placeholderLabel.numberOfLines = 0; 144 | _placeholderLabel.font = self.font; 145 | _placeholderLabel.textAlignment = self.textAlignment; 146 | _placeholderLabel.backgroundColor = [UIColor clearColor]; 147 | _placeholderLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1.0]; 148 | _placeholderLabel.alpha = 0; 149 | [self addSubview:_placeholderLabel]; 150 | } 151 | 152 | return _placeholderLabel; 153 | } 154 | 155 | //When any text changes on textField, the delegate getter is called. At this time we refresh the textView's placeholder 156 | -(id)delegate 157 | { 158 | [self refreshPlaceholder]; 159 | return [super delegate]; 160 | } 161 | 162 | -(CGSize)intrinsicContentSize 163 | { 164 | if (self.hasText) { 165 | return [super intrinsicContentSize]; 166 | } 167 | 168 | UIEdgeInsets placeholderInsets = [self placeholderInsets]; 169 | CGSize newSize = [super intrinsicContentSize]; 170 | 171 | newSize.height = [self placeholderExpectedFrame].size.height + placeholderInsets.top + placeholderInsets.bottom; 172 | 173 | return newSize; 174 | } 175 | @end 176 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 zhoufaming251@163.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FMFormSubmitKit 2 | 3 | [![CI Status](https://img.shields.io/travis/zhoufaming251@163.com/FMFormSubmitKit.svg?style=flat)](https://travis-ci.org/zhoufaming251@163.com/FMFormSubmitKit) 4 | [![Version](https://img.shields.io/cocoapods/v/FMFormSubmitKit.svg?style=flat)](https://cocoapods.org/pods/FMFormSubmitKit) 5 | [![License](https://img.shields.io/cocoapods/l/FMFormSubmitKit.svg?style=flat)](https://cocoapods.org/pods/FMFormSubmitKit) 6 | [![Platform](https://img.shields.io/cocoapods/p/FMFormSubmitKit.svg?style=flat)](https://cocoapods.org/pods/FMFormSubmitKit) 7 | 8 | ## Example 9 | 10 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 11 | 12 | ## Requirements 13 | 14 | ## Installation 15 | 16 | FMFormSubmitKit is available through [CocoaPods](https://cocoapods.org). To install 17 | it, simply add the following line to your Podfile: 18 | 19 | ```ruby 20 | pod 'FMFormSubmitKit' 21 | ``` 22 | 23 | ## Author 24 | 25 | zhoufaming251@163.com, zhoufaming251@163.com 26 | 27 | ## License 28 | 29 | FMFormSubmitKit is available under the MIT license. See the LICENSE file for more info. 30 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /submitNewVersion.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | basePath=$(cd "$(dirname "$0")";pwd) 3 | cd $basePath 4 | pod repo push FMPodSpec FMFormSubmitKit.podspec --allow-warnings && 5 | pod trunk push FMFormSubmitKit.podspec --allow-warnings 6 | 7 | --------------------------------------------------------------------------------