Full Code of RockChanel/SWForm for AI

master 526a711149b4 cached
476 files
1.7 MB
463.8k tokens
20 symbols
1 requests
Download .txt
Showing preview only (1,958K chars total). Download the full file or copy to clipboard to get everything.
Repository: RockChanel/SWForm
Branch: master
Commit: 526a711149b4
Files: 476
Total size: 1.7 MB

Directory structure:
gitextract_fysrm9id/

├── README.md
├── SWForm/
│   ├── SWForm.bundle/
│   │   ├── Root.plist
│   │   └── en.lproj/
│   │       └── Root.strings
│   ├── SWForm.h
│   ├── SWFormBaseController.h
│   ├── SWFormBaseController.m
│   ├── SWFormCell/
│   │   ├── SWFormBaseCell.h
│   │   ├── SWFormBaseCell.m
│   │   ├── SWFormImageCell.h
│   │   ├── SWFormImageCell.m
│   │   ├── SWFormInputCell.h
│   │   ├── SWFormInputCell.m
│   │   ├── SWFormSelectCell.h
│   │   ├── SWFormSelectCell.m
│   │   ├── SWFormTextViewInputCell.h
│   │   ├── SWFormTextViewInputCell.m
│   │   ├── SWImageCollectionCell.h
│   │   └── SWImageCollectionCell.m
│   ├── SWFormHandler.h
│   ├── SWFormHandler.m
│   ├── SWFormImageCell+ImageHandle.h
│   ├── SWFormImageCell+ImageHandle.m
│   ├── SWFormItem/
│   │   ├── SWFormItem.h
│   │   ├── SWFormItem.m
│   │   ├── SWFormSectionItem.h
│   │   └── SWFormSectionItem.m
│   ├── SWFormManager/
│   │   ├── NSString+SWForm.h
│   │   ├── NSString+SWForm.m
│   │   ├── SWFormCompat.h
│   │   ├── SWFormCompat.m
│   │   ├── SelwynExpandableTextView.h
│   │   ├── SelwynExpandableTextView.m
│   │   ├── UITextView+TextLimit.h
│   │   └── UITextView+TextLimit.m
│   ├── UIImageView+FormImage.h
│   └── UIImageView+FormImage.m
└── SWFormExample/
    ├── SWForm/
    │   ├── SWForm.bundle/
    │   │   ├── Root.plist
    │   │   └── en.lproj/
    │   │       └── Root.strings
    │   ├── SWForm.h
    │   ├── SWFormBaseController.h
    │   ├── SWFormBaseController.m
    │   ├── SWFormCell/
    │   │   ├── SWFormBaseCell.h
    │   │   ├── SWFormBaseCell.m
    │   │   ├── SWFormImageCell.h
    │   │   ├── SWFormImageCell.m
    │   │   ├── SWFormInputCell.h
    │   │   ├── SWFormInputCell.m
    │   │   ├── SWFormSelectCell.h
    │   │   ├── SWFormSelectCell.m
    │   │   ├── SWFormTextViewInputCell.h
    │   │   ├── SWFormTextViewInputCell.m
    │   │   ├── SWImageCollectionCell.h
    │   │   └── SWImageCollectionCell.m
    │   ├── SWFormHandler.h
    │   ├── SWFormHandler.m
    │   ├── SWFormImageCell+ImageHandle.h
    │   ├── SWFormImageCell+ImageHandle.m
    │   ├── SWFormItem/
    │   │   ├── SWFormItem.h
    │   │   ├── SWFormItem.m
    │   │   ├── SWFormSectionItem.h
    │   │   └── SWFormSectionItem.m
    │   ├── SWFormManager/
    │   │   ├── NSString+SWForm.h
    │   │   ├── NSString+SWForm.m
    │   │   ├── SWFormCompat.h
    │   │   ├── SWFormCompat.m
    │   │   ├── SelwynExpandableTextView.h
    │   │   ├── SelwynExpandableTextView.m
    │   │   ├── UITextView+TextLimit.h
    │   │   └── UITextView+TextLimit.m
    │   ├── UIImageView+FormImage.h
    │   └── UIImageView+FormImage.m
    ├── SWFormExample/
    │   ├── AppDelegate.h
    │   ├── AppDelegate.m
    │   ├── Assets.xcassets/
    │   │   ├── AppIcon.appiconset/
    │   │   │   └── Contents.json
    │   │   └── Contents.json
    │   ├── Base.lproj/
    │   │   ├── LaunchScreen.storyboard
    │   │   └── Main.storyboard
    │   ├── Info.plist
    │   ├── SWFormCommonController.h
    │   ├── SWFormCommonController.m
    │   ├── SWFormExample.pch
    │   ├── SWFormInfoController.h
    │   ├── SWFormInfoController.m
    │   ├── Vendors/
    │   │   ├── MBProgressHUD/
    │   │   │   ├── .svn/
    │   │   │   │   ├── all-wcprops
    │   │   │   │   ├── entries
    │   │   │   │   ├── prop-base/
    │   │   │   │   │   ├── MBProgressHUD.h.svn-base
    │   │   │   │   │   └── MBProgressHUD.m.svn-base
    │   │   │   │   └── text-base/
    │   │   │   │       ├── Factory.h.svn-base
    │   │   │   │       ├── Factory.m.svn-base
    │   │   │   │       ├── MBProgressHUD+Add.h.svn-base
    │   │   │   │       ├── MBProgressHUD+Add.m.svn-base
    │   │   │   │       ├── MBProgressHUD.h.svn-base
    │   │   │   │       ├── MBProgressHUD.m.svn-base
    │   │   │   │       └── MacroDef.h.svn-base
    │   │   │   ├── Factory.h
    │   │   │   ├── Factory.m
    │   │   │   ├── MBProgressHUD+Add.h
    │   │   │   ├── MBProgressHUD+Add.m
    │   │   │   ├── MBProgressHUD.h
    │   │   │   ├── MBProgressHUD.m
    │   │   │   └── MacroDef.h
    │   │   ├── MWPhotoBrowser/
    │   │   │   ├── .svn/
    │   │   │   │   ├── all-wcprops
    │   │   │   │   └── entries
    │   │   │   ├── Classes/
    │   │   │   │   ├── .svn/
    │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   ├── entries
    │   │   │   │   │   └── text-base/
    │   │   │   │   │       ├── MWCaptionView.h.svn-base
    │   │   │   │   │       ├── MWCaptionView.m.svn-base
    │   │   │   │   │       ├── MWCommon.h.svn-base
    │   │   │   │   │       ├── MWGridCell.h.svn-base
    │   │   │   │   │       ├── MWGridCell.m.svn-base
    │   │   │   │   │       ├── MWGridViewController.h.svn-base
    │   │   │   │   │       ├── MWGridViewController.m.svn-base
    │   │   │   │   │       ├── MWPhoto.h.svn-base
    │   │   │   │   │       ├── MWPhoto.m.svn-base
    │   │   │   │   │       ├── MWPhotoBrowser.h.svn-base
    │   │   │   │   │       ├── MWPhotoBrowser.m.svn-base
    │   │   │   │   │       ├── MWPhotoBrowserPrivate.h.svn-base
    │   │   │   │   │       ├── MWPhotoProtocol.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingImageView.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingImageView.m.svn-base
    │   │   │   │   │       ├── MWTapDetectingView.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingView.m.svn-base
    │   │   │   │   │       ├── MWZoomingScrollView.h.svn-base
    │   │   │   │   │       └── MWZoomingScrollView.m.svn-base
    │   │   │   │   ├── MWCaptionView.h
    │   │   │   │   ├── MWCaptionView.m
    │   │   │   │   ├── MWCommon.h
    │   │   │   │   ├── MWGridCell.h
    │   │   │   │   ├── MWGridCell.m
    │   │   │   │   ├── MWGridViewController.h
    │   │   │   │   ├── MWGridViewController.m
    │   │   │   │   ├── MWPhoto.h
    │   │   │   │   ├── MWPhoto.m
    │   │   │   │   ├── MWPhotoBrowser.h
    │   │   │   │   ├── MWPhotoBrowser.m
    │   │   │   │   ├── MWPhotoBrowserPrivate.h
    │   │   │   │   ├── MWPhotoProtocol.h
    │   │   │   │   ├── MWTapDetectingImageView.h
    │   │   │   │   ├── MWTapDetectingImageView.m
    │   │   │   │   ├── MWTapDetectingView.h
    │   │   │   │   ├── MWTapDetectingView.m
    │   │   │   │   ├── MWZoomingScrollView.h
    │   │   │   │   └── MWZoomingScrollView.m
    │   │   │   ├── Libraries/
    │   │   │   │   ├── .svn/
    │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   └── entries
    │   │   │   │   ├── DACircularProgress/
    │   │   │   │   │   ├── .svn/
    │   │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   │   ├── entries
    │   │   │   │   │   │   ├── prop-base/
    │   │   │   │   │   │   │   ├── DACircularProgressView.h.svn-base
    │   │   │   │   │   │   │   └── DACircularProgressView.m.svn-base
    │   │   │   │   │   │   └── text-base/
    │   │   │   │   │   │       ├── DACircularProgressView.h.svn-base
    │   │   │   │   │   │       └── DACircularProgressView.m.svn-base
    │   │   │   │   │   ├── DACircularProgressView.h
    │   │   │   │   │   └── DACircularProgressView.m
    │   │   │   │   ├── EMSDWebImage/
    │   │   │   │   │   ├── .svn/
    │   │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   │   ├── entries
    │   │   │   │   │   │   ├── prop-base/
    │   │   │   │   │   │   │   ├── EMSDImageCache.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDImageCache.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageCompat.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageCompat.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDecoder.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDecoder.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloader.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloader.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageManager.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageManager.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageOperation.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImagePrefetcher.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImagePrefetcher.m.svn-base
    │   │   │   │   │   │   │   ├── MKAnnotationView+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── MKAnnotationView+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── NSData+EMImageContentType.h.svn-base
    │   │   │   │   │   │   │   ├── NSData+EMImageContentType.m.svn-base
    │   │   │   │   │   │   │   ├── UIButton+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIButton+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMGIF.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMGIF.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMMultiFormat.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMMultiFormat.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMWebP.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMWebP.m.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIView+EMWebCacheOperation.h.svn-base
    │   │   │   │   │   │   │   └── UIView+EMWebCacheOperation.m.svn-base
    │   │   │   │   │   │   └── text-base/
    │   │   │   │   │   │       ├── EMSDImageCache.h.svn-base
    │   │   │   │   │   │       ├── EMSDImageCache.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageCompat.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageCompat.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDecoder.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDecoder.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloader.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloader.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloaderOperation.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloaderOperation.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageManager.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageManager.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageOperation.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImagePrefetcher.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImagePrefetcher.m.svn-base
    │   │   │   │   │   │       ├── MKAnnotationView+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── MKAnnotationView+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── NSData+EMImageContentType.h.svn-base
    │   │   │   │   │   │       ├── NSData+EMImageContentType.m.svn-base
    │   │   │   │   │   │       ├── UIButton+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIButton+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMGIF.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMGIF.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMMultiFormat.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMMultiFormat.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMWebP.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMWebP.m.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMHighlightedWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMHighlightedWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIView+EMWebCacheOperation.h.svn-base
    │   │   │   │   │   │       └── UIView+EMWebCacheOperation.m.svn-base
    │   │   │   │   │   ├── EMSDImageCache.h
    │   │   │   │   │   ├── EMSDImageCache.m
    │   │   │   │   │   ├── EMSDWebImageCompat.h
    │   │   │   │   │   ├── EMSDWebImageCompat.m
    │   │   │   │   │   ├── EMSDWebImageDecoder.h
    │   │   │   │   │   ├── EMSDWebImageDecoder.m
    │   │   │   │   │   ├── EMSDWebImageDownloader.h
    │   │   │   │   │   ├── EMSDWebImageDownloader.m
    │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.h
    │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.m
    │   │   │   │   │   ├── EMSDWebImageManager.h
    │   │   │   │   │   ├── EMSDWebImageManager.m
    │   │   │   │   │   ├── EMSDWebImageOperation.h
    │   │   │   │   │   ├── EMSDWebImagePrefetcher.h
    │   │   │   │   │   ├── EMSDWebImagePrefetcher.m
    │   │   │   │   │   ├── MKAnnotationView+EMWebCache.h
    │   │   │   │   │   ├── MKAnnotationView+EMWebCache.m
    │   │   │   │   │   ├── NSData+EMImageContentType.h
    │   │   │   │   │   ├── NSData+EMImageContentType.m
    │   │   │   │   │   ├── UIButton+EMWebCache.h
    │   │   │   │   │   ├── UIButton+EMWebCache.m
    │   │   │   │   │   ├── UIImage+EMGIF.h
    │   │   │   │   │   ├── UIImage+EMGIF.m
    │   │   │   │   │   ├── UIImage+EMMultiFormat.h
    │   │   │   │   │   ├── UIImage+EMMultiFormat.m
    │   │   │   │   │   ├── UIImage+EMWebP.h
    │   │   │   │   │   ├── UIImage+EMWebP.m
    │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.h
    │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.m
    │   │   │   │   │   ├── UIImageView+EMWebCache.h
    │   │   │   │   │   ├── UIImageView+EMWebCache.m
    │   │   │   │   │   ├── UIView+EMWebCacheOperation.h
    │   │   │   │   │   └── UIView+EMWebCacheOperation.m
    │   │   │   │   └── PSTCollectionView/
    │   │   │   │       ├── .svn/
    │   │   │   │       │   ├── all-wcprops
    │   │   │   │       │   ├── entries
    │   │   │   │       │   ├── prop-base/
    │   │   │   │       │   │   ├── NSIndexPath+PSTCollectionViewAdditions.h.svn-base
    │   │   │   │       │   │   ├── NSIndexPath+PSTCollectionViewAdditions.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionView.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionView.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCell.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCell.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCommon.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewController.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewController.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewData.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewData.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewFlowLayout.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewFlowLayout.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewItemKey.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewItemKey.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout+Internals.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewUpdateItem.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewUpdateItem.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutInfo.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutInfo.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutItem.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutItem.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutRow.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutRow.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutSection.h.svn-base
    │   │   │   │       │   │   └── PSTGridLayoutSection.m.svn-base
    │   │   │   │       │   └── text-base/
    │   │   │   │       │       ├── NSIndexPath+PSTCollectionViewAdditions.h.svn-base
    │   │   │   │       │       ├── NSIndexPath+PSTCollectionViewAdditions.m.svn-base
    │   │   │   │       │       ├── PSTCollectionView.h.svn-base
    │   │   │   │       │       ├── PSTCollectionView.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCell.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCell.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCommon.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewController.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewController.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewData.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewData.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewFlowLayout.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewFlowLayout.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewItemKey.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewItemKey.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout+Internals.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewUpdateItem.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewUpdateItem.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutInfo.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutInfo.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutItem.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutItem.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutRow.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutRow.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutSection.h.svn-base
    │   │   │   │       │       └── PSTGridLayoutSection.m.svn-base
    │   │   │   │       ├── NSIndexPath+PSTCollectionViewAdditions.h
    │   │   │   │       ├── NSIndexPath+PSTCollectionViewAdditions.m
    │   │   │   │       ├── PSTCollectionView.h
    │   │   │   │       ├── PSTCollectionView.m
    │   │   │   │       ├── PSTCollectionViewCell.h
    │   │   │   │       ├── PSTCollectionViewCell.m
    │   │   │   │       ├── PSTCollectionViewCommon.h
    │   │   │   │       ├── PSTCollectionViewController.h
    │   │   │   │       ├── PSTCollectionViewController.m
    │   │   │   │       ├── PSTCollectionViewData.h
    │   │   │   │       ├── PSTCollectionViewData.m
    │   │   │   │       ├── PSTCollectionViewFlowLayout.h
    │   │   │   │       ├── PSTCollectionViewFlowLayout.m
    │   │   │   │       ├── PSTCollectionViewItemKey.h
    │   │   │   │       ├── PSTCollectionViewItemKey.m
    │   │   │   │       ├── PSTCollectionViewLayout+Internals.h
    │   │   │   │       ├── PSTCollectionViewLayout.h
    │   │   │   │       ├── PSTCollectionViewLayout.m
    │   │   │   │       ├── PSTCollectionViewUpdateItem.h
    │   │   │   │       ├── PSTCollectionViewUpdateItem.m
    │   │   │   │       ├── PSTGridLayoutInfo.h
    │   │   │   │       ├── PSTGridLayoutInfo.m
    │   │   │   │       ├── PSTGridLayoutItem.h
    │   │   │   │       ├── PSTGridLayoutItem.m
    │   │   │   │       ├── PSTGridLayoutRow.h
    │   │   │   │       ├── PSTGridLayoutRow.m
    │   │   │   │       ├── PSTGridLayoutSection.h
    │   │   │   │       └── PSTGridLayoutSection.m
    │   │   │   └── MWPhotoBrowser.bundle/
    │   │   │       ├── .svn/
    │   │   │       │   ├── all-wcprops
    │   │   │       │   └── entries
    │   │   │       └── images/
    │   │   │           └── .svn/
    │   │   │               ├── all-wcprops
    │   │   │               ├── entries
    │   │   │               ├── prop-base/
    │   │   │               │   ├── Checkmark.png.svn-base
    │   │   │               │   ├── Checkmark@2x.png.svn-base
    │   │   │               │   ├── ImageError.png.svn-base
    │   │   │               │   ├── ImageError@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedOff.png.svn-base
    │   │   │               │   ├── ImageSelectedOff@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedOn.png.svn-base
    │   │   │               │   ├── ImageSelectedOn@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOff.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOff@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOn.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOn@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowLeft.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowLeft@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineLeft.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineLeft@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineRight.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineRight@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowRight.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowRight@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGrid.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGrid@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGridiOS6.png.svn-base
    │   │   │               │   └── UIBarButtonItemGridiOS6@2x.png.svn-base
    │   │   │               └── text-base/
    │   │   │                   ├── Checkmark.png.svn-base
    │   │   │                   ├── Checkmark@2x.png.svn-base
    │   │   │                   ├── ImageError.png.svn-base
    │   │   │                   ├── ImageError@2x.png.svn-base
    │   │   │                   ├── ImageSelectedOff.png.svn-base
    │   │   │                   ├── ImageSelectedOff@2x.png.svn-base
    │   │   │                   ├── ImageSelectedOn.png.svn-base
    │   │   │                   ├── ImageSelectedOn@2x.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOff.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOff@2x.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOn.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOn@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowLeft.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowLeft@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineLeft.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineLeft@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineRight.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineRight@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowRight.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowRight@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemGrid.png.svn-base
    │   │   │                   ├── UIBarButtonItemGrid@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemGridiOS6.png.svn-base
    │   │   │                   └── UIBarButtonItemGridiOS6@2x.png.svn-base
    │   │   └── TZImagePickerController/
    │   │       ├── .svn/
    │   │       │   ├── all-wcprops
    │   │       │   ├── entries
    │   │       │   ├── prop-base/
    │   │       │   │   ├── UIView+Layout.h.svn-base
    │   │       │   │   └── UIView+Layout.m.svn-base
    │   │       │   └── text-base/
    │   │       │       ├── TZAssetCell.h.svn-base
    │   │       │       ├── TZAssetCell.m.svn-base
    │   │       │       ├── TZAssetModel.h.svn-base
    │   │       │       ├── TZAssetModel.m.svn-base
    │   │       │       ├── TZImageManager.h.svn-base
    │   │       │       ├── TZImageManager.m.svn-base
    │   │       │       ├── TZImagePickerController.h.svn-base
    │   │       │       ├── TZImagePickerController.m.svn-base
    │   │       │       ├── TZPhotoPickerController.h.svn-base
    │   │       │       ├── TZPhotoPickerController.m.svn-base
    │   │       │       ├── TZPhotoPreviewCell.h.svn-base
    │   │       │       ├── TZPhotoPreviewCell.m.svn-base
    │   │       │       ├── TZPhotoPreviewController.h.svn-base
    │   │       │       ├── TZPhotoPreviewController.m.svn-base
    │   │       │       ├── TZVideoPlayerController.h.svn-base
    │   │       │       ├── TZVideoPlayerController.m.svn-base
    │   │       │       ├── UIView+Layout.h.svn-base
    │   │       │       └── UIView+Layout.m.svn-base
    │   │       ├── TZAssetCell.h
    │   │       ├── TZAssetCell.m
    │   │       ├── TZAssetModel.h
    │   │       ├── TZAssetModel.m
    │   │       ├── TZImageManager.h
    │   │       ├── TZImageManager.m
    │   │       ├── TZImagePickerController.bundle/
    │   │       │   ├── .svn/
    │   │       │   │   ├── all-wcprops
    │   │       │   │   ├── entries
    │   │       │   │   ├── prop-base/
    │   │       │   │   │   ├── MMVideoPreviewPlay@2x.png.svn-base
    │   │       │   │   │   ├── MMVideoPreviewPlayHL@2x.png.svn-base
    │   │       │   │   │   ├── TableViewArrow@2x.png.svn-base
    │   │       │   │   │   ├── VideoSendIcon@2x.png.svn-base
    │   │       │   │   │   ├── navi_back@2x.png.svn-base
    │   │       │   │   │   ├── photo_def_photoPickerVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_def_previewVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_number_icon@2x.png.svn-base
    │   │       │   │   │   ├── photo_original_def@2x.png.svn-base
    │   │       │   │   │   ├── photo_original_sel@2x.png.svn-base
    │   │       │   │   │   ├── photo_sel_photoPickerVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_sel_previewVc@2x.png.svn-base
    │   │       │   │   │   ├── preview_number_icon@2x.png.svn-base
    │   │       │   │   │   ├── preview_original_def@2x.png.svn-base
    │   │       │   │   │   └── takePicture@2x.png.svn-base
    │   │       │   │   └── text-base/
    │   │       │   │       ├── MMVideoPreviewPlay@2x.png.svn-base
    │   │       │   │       ├── MMVideoPreviewPlayHL@2x.png.svn-base
    │   │       │   │       ├── Root.plist.svn-base
    │   │       │   │       ├── TZAlbumCell.xib.svn-base
    │   │       │   │       ├── TZAssetCell.xib.svn-base
    │   │       │   │       ├── TableViewArrow@2x.png.svn-base
    │   │       │   │       ├── VideoSendIcon@2x.png.svn-base
    │   │       │   │       ├── navi_back@2x.png.svn-base
    │   │       │   │       ├── photo_def_photoPickerVc@2x.png.svn-base
    │   │       │   │       ├── photo_def_previewVc@2x.png.svn-base
    │   │       │   │       ├── photo_number_icon@2x.png.svn-base
    │   │       │   │       ├── photo_original_def@2x.png.svn-base
    │   │       │   │       ├── photo_original_sel@2x.png.svn-base
    │   │       │   │       ├── photo_sel_photoPickerVc@2x.png.svn-base
    │   │       │   │       ├── photo_sel_previewVc@2x.png.svn-base
    │   │       │   │       ├── preview_number_icon@2x.png.svn-base
    │   │       │   │       ├── preview_original_def@2x.png.svn-base
    │   │       │   │       └── takePicture@2x.png.svn-base
    │   │       │   ├── Root.plist
    │   │       │   ├── TZAlbumCell.xib
    │   │       │   └── TZAssetCell.xib
    │   │       ├── TZImagePickerController.h
    │   │       ├── TZImagePickerController.m
    │   │       ├── TZPhotoPickerController.h
    │   │       ├── TZPhotoPickerController.m
    │   │       ├── TZPhotoPreviewCell.h
    │   │       ├── TZPhotoPreviewCell.m
    │   │       ├── TZPhotoPreviewController.h
    │   │       ├── TZPhotoPreviewController.m
    │   │       ├── TZVideoPlayerController.h
    │   │       ├── TZVideoPlayerController.m
    │   │       ├── UIView+Layout.h
    │   │       └── UIView+Layout.m
    │   ├── ViewController.h
    │   ├── ViewController.m
    │   └── main.m
    └── SWFormExample.xcodeproj/
        ├── project.pbxproj
        └── project.xcworkspace/
            ├── contents.xcworkspacedata
            └── xcshareddata/
                └── IDEWorkspaceChecks.plist

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# SWForm

>详细说明戳这里:[iOS 高度封装自适应表单(重构版)](https://www.jianshu.com/p/2d2f742622fa)

![image](https://github.com/RockChanel/SWGIF/blob/master/SWForm/SWForm.gif)

![image](https://github.com/RockChanel/SWGIF/blob/master/SWForm/SWForm_1.png)

`SWForm` 旨在快捷构建表单系统框架,支持大部分表单系统所需条目样式,且包含了图片附件、编辑、新增、详情等功能的拓展.

### Warning

若下载项目之后,运行报错 `incompatible project version`,是由于此项目创建 Xcode 版本为 `9.4.1`。若运行 Xcode 版本低于此版本,解决方法如下:

方法一:更新 Xcode 版本

方法二:右键 `SWFormExample.xcodeproj`, 点击显示包内容,打开 `project.pbxproj` 文件,修改降低 `objectVersion` 即可运行

### 使用方式

使用 `SWForm` 框架只需将 `SWForm`文件夹导入项目中,将所有可定制化配置的接口都已经统一入口,方便使用者根据自身需求实现定制化功能.

本项目中提供了所有定制化接口的示例 `SWFormDemo`,以作为参考。

<br/>

`SWForm` 根据需求提供了三个接口文件,以方便使用者实现高度定制化,分别为 `UIImageView+FormImage`、`SWFormImageCell+ImageHandle`、`SWFormHandler`.

<br/>

`UIImageView+FormImage` 针对表单图片条目图片加载提供接口:
```objective-c
- (void)sw_setImageItemWithUrl:(NSURL *)url;
```
<br/>

`SWFormImageCell+ImageHandle` 提供图片添加接口以及图片预览接口,使用者可以在此接口添加自定义图片选择以及图片预览功能:
```objective-c
/**
 选择图片数据回调
 
 @param maxImages 最大可选择图片数
 @param currentImages 当前选择图片数
 @param completion 选择图片数组回调
 */
- (void)sw_selectImageWithMaxImages:(NSInteger)maxImages currentImages:(NSInteger)currentImages completion:(void(^)(NSArray *selectImages))completion;

/**
 图片浏览

 @param images 图片数组
 @param currentIndex 当前浏览的index
 */
- (void)sw_photoBrowserWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex;
```

<br/>

`SWFormHandler` 为数据校验文件,提供了相机权限、相册权限以及表单空数据校验功能:
```objective-c
/**
 必选(必填)数据空数据校验,可根据需求定制

 @param datas 表单数据源
 @param success 必选(必填)数据全部校验成功
 @param failure 必选(必填)数据某一项校验失败
 */
+ (void)sw_checkFormNullDataWithWithDatas:(NSArray *)datas success:(void(^)(void))success failure:(void(^)(NSString *error))failure;

/**
 校验是否有相机权限
 */
+ (void)sw_checkCameraAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;

/**
 校验是否有相册权限
 */
+ (void)sw_checkAlbumAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;
```


================================================
FILE: SWForm/SWForm.bundle/Root.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>StringsTable</key>
	<string>Root</string>
	<key>PreferenceSpecifiers</key>
	<array>
		<dict>
			<key>Type</key>
			<string>PSGroupSpecifier</string>
			<key>Title</key>
			<string>Group</string>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSTextFieldSpecifier</string>
			<key>Title</key>
			<string>Name</string>
			<key>Key</key>
			<string>name_preference</string>
			<key>DefaultValue</key>
			<string></string>
			<key>IsSecure</key>
			<false/>
			<key>KeyboardType</key>
			<string>Alphabet</string>
			<key>AutocapitalizationType</key>
			<string>None</string>
			<key>AutocorrectionType</key>
			<string>No</string>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSToggleSwitchSpecifier</string>
			<key>Title</key>
			<string>Enabled</string>
			<key>Key</key>
			<string>enabled_preference</string>
			<key>DefaultValue</key>
			<true/>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSSliderSpecifier</string>
			<key>Key</key>
			<string>slider_preference</string>
			<key>DefaultValue</key>
			<real>0.5</real>
			<key>MinimumValue</key>
			<integer>0</integer>
			<key>MaximumValue</key>
			<integer>1</integer>
			<key>MinimumValueImage</key>
			<string></string>
			<key>MaximumValueImage</key>
			<string></string>
		</dict>
	</array>
</dict>
</plist>


================================================
FILE: SWForm/SWForm.h
================================================
//
//  SWForm.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#ifndef SWForm_h
#define SWForm_h

#import "SWFormItem.h"
#import "SWFormSectionItem.h"
#import "SWFormHandler.h"
#import "SWFormCompat.h"

#endif /* SWForm_h */


================================================
FILE: SWForm/SWFormBaseController.h
================================================
//
//  SWFormBaseController.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 SWFormBaseController 表单基类,所有表单必须继承于BaseController,实现了表单动态配置
 */
@interface SWFormBaseController : UIViewController

/**
 表单tableView
 */
@property (nonatomic, strong) UITableView *formTableView;

/**
 表单数据源,数据源格式应为 @[SWFormSection..],否则断言会直接崩溃
 */
@property (nonatomic, strong) NSMutableArray *mutableItems;

/**
 表单页面初始化方法
 
 @param style 表单tableView样式
 */
- (instancetype)initWithStyle:(UITableViewStyle)style;

@end


================================================
FILE: SWForm/SWFormBaseController.m
================================================
//
//  SWFormBaseController.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseController.h"
#import "SWForm.h"
#import "SWFormInputCell.h"
#import "SWFormTextViewInputCell.h"
#import "SWFormSelectCell.h"
#import "SWFormImageCell.h"

@interface SWFormBaseController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, readonly) UITableViewStyle style;
@end

@implementation SWFormBaseController

- (NSMutableArray *)mutableItems {
    if (!_mutableItems) {
        _mutableItems = [[NSMutableArray alloc]init];
    }
    return _mutableItems;
}

- (instancetype)initWithStyle:(UITableViewStyle)style {
    self = [super init];
    if (self) {
        _style = style;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:_style];
    [self addChildViewController:tableViewController];
    [tableViewController.view setFrame:self.view.bounds];
    
    // 获取tableViewController的tableView实现表单自动上移
    _formTableView = tableViewController.tableView;
    _formTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    _formTableView.dataSource = self;
    _formTableView.delegate = self;
    //_formTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    _formTableView.showsVerticalScrollIndicator = NO;
    _formTableView.showsHorizontalScrollIndicator = NO;
    _formTableView.backgroundColor = [UIColor whiteColor];
    _formTableView.tableHeaderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)];
    _formTableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)];
    
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fingerTapped:)];
    //  加上这句不会影响你 tableview 上的 action (button,cell selected...)
    singleTap.cancelsTouchesInView = NO;
    [_formTableView addGestureRecognizer:singleTap];
    
    [self.view addSubview:_formTableView];
}

- (void)fingerTapped:(UITapGestureRecognizer *)gestureRecognizer {
    [self.view endEditing:YES];
}

#pragma mark -- TableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.mutableItems.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSParameterAssert([self.mutableItems[section] isKindOfClass:[SWFormSectionItem class]]);
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    NSParameterAssert([sectionItem.items[indexPath.row] isKindOfClass:[SWFormItem class]]);
    SWFormItem *item = sectionItem.items[indexPath.row];
    
    SWWeakSelf
    // 表单条目类别判断
    if (item.itemType == SWFormItemTypeTextViewInput) {
        static NSString *textViewInput_cell_id = @"textViewInput_cell_id";
        SWFormTextViewInputCell *cell = [tableView textViewInputCellWithId:textViewInput_cell_id];
        cell.item = item;
        cell.textViewInputCompletion = ^(NSString *text) {
            [weakSelf updateTextViewInputWithText:text indexPath:indexPath];
        };
        return cell;
    }
    else if (item.itemType == SWFormItemTypeSelect) {
        static NSString *select_cell_id = @"select_cell_id";
        SWFormSelectCell *cell = [tableView selectCellWithId:select_cell_id];
        cell.item = item;
        return cell;
    }
    else if (item.itemType == SWFormItemTypeImage) {
        static NSString *image_cell_id = @"image_cell_id";
        SWFormImageCell *cell = [tableView imageCellWithId:image_cell_id];
        cell.item = item;
        cell.imageCompletion = ^(NSArray *images) {
            [weakSelf updateImageWithImages:images indexPath:indexPath];
        };
        return cell;
    }
    else {
        static NSString *input_cell_id = @"input_cell_id";
        SWFormInputCell *cell = [tableView inputCellWithId:input_cell_id];
        cell.item = item;
        cell.inputCompletion = ^(NSString *text) {
            [weakSelf updateInputWithText:text indexPath:indexPath];
        };
        return cell;
    }
}

#pragma mark -- TableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    if (item.itemType == SWFormItemTypeTextViewInput) {
        return [SWFormTextViewInputCell heightWithItem:item];
    }
    else if (item.itemType == SWFormItemTypeSelect) {
        return [SWFormSelectCell heightWithItem:item];
    }
    else if (item.itemType == SWFormItemTypeImage) {
        return [SWFormImageCell heightWithItem:item];
    }
    else {
        return [SWFormInputCell heightWithItem:item];
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    if (item.itemType == SWFormItemTypeSelect && item.itemSelectCompletion) {
        item.itemSelectCompletion(item);
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.headerHeight > 0 ? sectionItem.headerHeight:0.01;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.footerHeight > 0 ? sectionItem.footerHeight:0.01;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    UIView *header = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, sectionItem.headerHeight)];
    return sectionItem.headerView ? sectionItem.headerView:header;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    UIView *footer = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, sectionItem.footerHeight)];
    return sectionItem.footerView ? sectionItem.footerView:footer;
}

#pragma mark -- 表单条目响应block处理
- (void)updateInputWithText:(NSString *)text indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.info = text;
}

- (void)updateTextViewInputWithText:(NSString *)text indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.info = text;
}

- (void)updateImageWithImages:(NSArray *)images indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.images = images;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end


================================================
FILE: SWForm/SWFormCell/SWFormBaseCell.h
================================================
//
//  SWFormBaseCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

@class SelwynExpandableTextView;

/**
 SWFormBaseCell 表单条目基类,所有表单条目都继承于BaseCell
 */
@interface SWFormBaseCell : UITableViewCell

@property (nonatomic, strong) SelwynExpandableTextView *expandableTextView;

/**
 表单标题
 */
@property (nonatomic, strong) UILabel *titleLabel;

/**
 表单条目所在的tableView
 */
@property (nonatomic, weak) UITableView *expandableTableView;

@end


================================================
FILE: SWForm/SWFormCell/SWFormBaseCell.m
================================================
//
//  SWFormBaseCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"

@interface SWFormBaseCell()<UITextViewDelegate>
@end

@implementation SWFormBaseCell

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc]init];
        _titleLabel.font = [UIFont systemFontOfSize:SW_TitleFont];
        _titleLabel.adjustsFontSizeToFitWidth = YES;
        [self.contentView addSubview:_titleLabel];
    }
    return _titleLabel;
}

- (SelwynExpandableTextView *)expandableTextView {
    if (!_expandableTextView) {
        _expandableTextView = [[SelwynExpandableTextView alloc]init];
        _expandableTextView.delegate = self;
        _expandableTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
        _expandableTextView.textContainer.lineFragmentPadding = 0;
        _expandableTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        _expandableTextView.backgroundColor = [UIColor clearColor];
        _expandableTextView.font = [UIFont systemFontOfSize:SW_InfoFont];
        _expandableTextView.scrollEnabled = NO;
        _expandableTextView.autocorrectionType = UITextAutocorrectionTypeNo;
        _expandableTextView.layoutManager.allowsNonContiguousLayout = NO;
        _expandableTextView.showsVerticalScrollIndicator = NO;
        _expandableTextView.showsHorizontalScrollIndicator = NO;
        [self.contentView addSubview:_expandableTextView];
    }
    return _expandableTextView;
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


================================================
FILE: SWForm/SWFormCell/SWFormImageCell.h
================================================
//
//  SWFormImageCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 图片选择或删除block

 @param images 当前已存在图片数组
 */
typedef void(^SWImageCompletion)(NSArray *images);

/**
 SWFormImageCell 表单图片选择条目
 */
@interface SWFormImageCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;
@property (nonatomic, copy) SWImageCompletion imageCompletion;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormImageCell)

- (SWFormImageCell *)imageCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWForm/SWFormCell/SWFormImageCell.m
================================================
//
//  SWFormImageCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell.h"
#import "SWFormItem.h"
#import "SWImageCollectionCell.h"
#import "SWFormCompat.h"
#import "SWFormImageCell+ImageHandle.h"

static NSString *image_cell_id = @"image_cell_id";
static CGFloat const SW_ImageWidth = 80.0f;
static NSInteger const SW_RowImageCount = 4;

@interface SWFormImageCell()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

@property (nonatomic, strong) UIImageView *icon;
@property (nonatomic, strong) UICollectionView *imageCollection;
@property (nonatomic, strong) UIButton *selectBtn;

@property (nonatomic, strong) NSMutableArray *mutableImages;

@end

@implementation SWFormImageCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.selectBtn.enabled = item.editable;
    self.mutableImages = [NSMutableArray arrayWithArray:item.images];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_TitleWidth, SW_TitleHeight);
    self.icon.frame = CGRectMake(self.frame.size.width - 38, SW_EdgeMargin + 2, 23, SW_TitleHeight - 4);
    self.selectBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.item.defaultHeight);
    
    if (self.mutableImages.count > 0) {
        self.imageCollection.frame = CGRectMake(0, self.item.defaultHeight, self.frame.size.width, self.frame.size.height - self.item.defaultHeight);
        self.imageCollection.hidden = NO;
        [self.imageCollection reloadData];
    }
    else {
        self.imageCollection.frame = CGRectZero;
        self.imageCollection.hidden = YES;
    }
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.mutableImages.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    SWImageCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:image_cell_id forIndexPath:indexPath];
    cell.image = self.mutableImages[indexPath.item];
    cell.editable = self.item.editable;
    cell.deleteImageCompletion = ^{
        [self.mutableImages removeObjectAtIndex:indexPath.item];
        [self sw_reloadData];
    };
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [self sw_photoBrowserWithImages:self.mutableImages currentIndex:indexPath.item];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(SW_ImageWidth, SW_ImageWidth);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 10, 10, 10);
}

- (void)selectImageAction {
    if (self.mutableImages.count >= self.item.maxImageCount) {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:[NSString stringWithFormat:@"最多选择%ld张附件",(long)self.item.maxImageCount] message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alertView show];
        return;
    }
    
    __weak typeof(self) weakSelf = self;
    // 选择图片事件函数
    [self sw_selectImageWithMaxImages:self.item.maxImageCount currentImages:self.mutableImages.count completion:^(NSArray *selectImages) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf.mutableImages addObjectsFromArray:selectImages];
        [strongSelf sw_reloadData];
    }];
}

#pragma mark -- 刷新当前图片数据
- (void)sw_reloadData {
    if (self.imageCompletion) {
        self.imageCompletion(self.mutableImages);
    }
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    NSInteger rows = item.images.count%SW_RowImageCount > 0 ? item.images.count/SW_RowImageCount+1:item.images.count/SW_RowImageCount;
    return item.images.count > 0 ? item.defaultHeight + 10*(rows+1) + rows*SW_ImageWidth:item.defaultHeight;
}

#pragma mark -- 懒加载实现
- (NSMutableArray *)mutableImages {
    if (!_mutableImages) {
        _mutableImages = [[NSMutableArray alloc]init];
    }
    return _mutableImages;
}

- (UICollectionView *)imageCollection {
    if (!_imageCollection) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
        layout.minimumInteritemSpacing = 10;
        layout.minimumLineSpacing = 10;
        _imageCollection = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
        _imageCollection.backgroundColor = [UIColor whiteColor];
        _imageCollection.delegate = self;
        _imageCollection.dataSource = self;
        _imageCollection.hidden = YES;
        _imageCollection.scrollEnabled = NO;
        _imageCollection.showsVerticalScrollIndicator = NO;
        _imageCollection.showsHorizontalScrollIndicator = NO;
        [_imageCollection registerClass:[SWImageCollectionCell class] forCellWithReuseIdentifier:image_cell_id];
        [self.contentView addSubview:_imageCollection];
    }
    return _imageCollection;
}

- (UIButton *)selectBtn {
    if (!_selectBtn) {
        _selectBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_selectBtn addTarget:self action:@selector(selectImageAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:_selectBtn];
    }
    return _selectBtn;
}

- (UIImageView *)icon {
    if (!_icon) {
        _icon = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SWForm.bundle/SWImageIcon"]];
        [self.contentView addSubview:_icon];
    }
    return _icon;
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


@implementation UITableView (SWFormImageCell)

- (SWFormImageCell *)imageCellWithId:(NSString *)cellId
{
    SWFormImageCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (cell == nil) {
        cell = [[SWFormImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}
@end


================================================
FILE: SWForm/SWFormCell/SWFormInputCell.h
================================================
//
//  SWFormInputCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 输入内容block

 @param text 当前输入内容
 */
typedef void(^SWInputCompletion)(NSString *text);

/**
 SWFormInputCell 表单输入条目,标题居左,详情居右,支持单行与多行输入
 */
@interface SWFormInputCell : SWFormBaseCell

/**
 条目配置参数
 */
@property (nonatomic, strong) SWFormItem *item;

@property (nonatomic, copy) SWInputCompletion inputCompletion;

/**
 获取条目高度
 */
+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


/**
 SWFormInputCell 对于UITableView的分类,实现SWFormInputCell初始化
 */
@interface UITableView (SWFormInputCell)

- (SWFormInputCell *)inputCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWForm/SWFormCell/SWFormInputCell.m
================================================
//
//  SWFormInputCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormInputCell.h"
#import "SWFormItem.h"
#import "SWFormCompat.h"
#import "SelwynExpandableTextView.h"
#import "UITextView+TextLimit.h"
#import "NSString+SWForm.h"

@interface SWFormInputCell()<UITextViewDelegate>
@end

@implementation SWFormInputCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.expandableTextView.keyboardType = item.keyboardType;
    self.accessoryType = UITableViewCellAccessoryNone;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_TitleWidth, SW_TitleHeight);
    
    CGFloat newHeight = [SWFormInputCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_TitleWidth + 2*SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - (SW_TitleWidth + 3*SW_EdgeMargin), newHeight - 2*SW_EdgeMargin);
}

- (void)textViewDidBeginEditing:(UITextView *)textView {
    self.expandableTextView.text = self.item.info;
}

- (void)textViewDidChange:(UITextView *)textView {
    if (self.item.maxInputLength > 0) {
        // 限制输入字数
        [self.expandableTextView textLimitWithMaxLength:self.item.maxInputLength];
    }
    if (self.inputCompletion) {
        self.inputCompletion(self.expandableTextView.text);
    }
    // 防止输入时表单因刷新动画抖动
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

- (void)textViewDidEndEditing:(UITextView *)textView {
    self.expandableTextView.text = [self.item.info addUnit:self.item.unit];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - (SW_TitleWidth + 3*SW_EdgeMargin), MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + 2*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


@implementation UITableView (SWFormInputCell)

- (SWFormInputCell *)inputCellWithId:(NSString *)cellId
{
    SWFormInputCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormInputCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWForm/SWFormCell/SWFormSelectCell.h
================================================
//
//  SWFormSelectCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 SWFormSelectCell 表单选择条目
 */
@interface SWFormSelectCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormSelectCell)

- (SWFormSelectCell *)selectCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWForm/SWFormCell/SWFormSelectCell.m
================================================
//
//  SWFormSelectCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormSelectCell.h"
#import "SWFormItem.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"
#import "NSString+SWForm.h"

@implementation SWFormSelectCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, (self.item.defaultHeight - SW_TitleHeight)/2, SW_TitleWidth, SW_TitleHeight);
    self.expandableTextView.userInteractionEnabled = NO;
    
    CGFloat newHeight = [SWFormSelectCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_TitleWidth + 2*SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - (SW_TitleWidth + 2*SW_EdgeMargin + 30),  newHeight - 2*SW_EdgeMargin);
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - SW_TitleWidth - 2*SW_EdgeMargin - 30, MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + 2*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end

@implementation UITableView (SWFormSelectCell)

- (SWFormSelectCell *)selectCellWithId:(NSString *)cellId
{
    SWFormSelectCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormSelectCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWForm/SWFormCell/SWFormTextViewInputCell.h
================================================
//
//  SWFormTextViewInputCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

typedef void(^SWTextViewInputCompletion)(NSString *text);

/**
 SWFormTextViewInputCell 表单输入条目,标题居上,详情居下,支持单行与多行输入
 */
@interface SWFormTextViewInputCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;
@property (nonatomic, copy) SWTextViewInputCompletion textViewInputCompletion;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormTextViewInputCell)

- (SWFormTextViewInputCell *)textViewInputCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWForm/SWFormCell/SWFormTextViewInputCell.m
================================================
//
//  SWFormTextViewInputCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormTextViewInputCell.h"
#import "SWFormItem.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"
#import "UITextView+TextLimit.h"
#import "NSString+SWForm.h"

@interface SWFormTextViewInputCell()<UITextViewDelegate>
@end

@implementation SWFormTextViewInputCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.expandableTextView.keyboardType = item.keyboardType;
    self.expandableTextView.currentLength = item.info.length;
    self.expandableTextView.showLength = item.showLength;
    self.expandableTextView.maxLength = item.maxInputLength;
    self.accessoryType = UITableViewCellAccessoryNone;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - 2*SW_EdgeMargin, SW_TitleHeight);
    
    //重置 expandableTextView 内边距
    self.expandableTextView.textContainerInset = UIEdgeInsetsMake(SW_EdgeMargin, SW_EdgeMargin, SW_EdgeMargin, SW_EdgeMargin);
    self.expandableTextView.backgroundColor = SW_TEXTVIEW_BACKGROUNDCOLOR;
    
    CGFloat newHeight = [SWFormTextViewInputCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_EdgeMargin, CGRectGetMaxY(self.titleLabel.frame) + SW_EdgeMargin, SW_SCRREN_WIDTH - 2*SW_EdgeMargin, newHeight - 3*SW_EdgeMargin - SW_TitleHeight);
}

- (void)textViewDidBeginEditing:(UITextView *)textView {
    self.expandableTextView.text = self.item.info;
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
}

- (void)textViewDidChange:(UITextView *)textView {
    if (self.item.maxInputLength > 0) {
        [self.expandableTextView textLimitWithMaxLength:self.item.maxInputLength];
    }
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
    if (self.textViewInputCompletion) {
        self.textViewInputCompletion(self.expandableTextView.text);
    }
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

- (void)textViewDidEndEditing:(UITextView *)textView {
    
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
    self.expandableTextView.text = [self.item.info addUnit:self.item.unit];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - 4*SW_EdgeMargin, MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + SW_TitleHeight + 5*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end

@implementation UITableView (SWFormTextViewInputCell)

- (SWFormTextViewInputCell *)textViewInputCellWithId:(NSString *)cellId
{
    SWFormTextViewInputCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormTextViewInputCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWForm/SWFormCell/SWImageCollectionCell.h
================================================
//
//  SWImageCollectionCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef void(^SWDeleteImageCompletion)(void);

/**
 表单图片条目图片展示
 */
@interface SWImageCollectionCell : UICollectionViewCell

/**
 当前图片删除操作block
 */
@property (nonatomic, copy) SWDeleteImageCompletion deleteImageCompletion;

/**
 当前图片,支持UIImage、NSURL、NSString(图片URLString)类型
 */
@property (nonatomic, strong) id image;

/**
 当前图片是否可编辑
 */
@property (nonatomic, assign) BOOL editable;

@end


================================================
FILE: SWForm/SWFormCell/SWImageCollectionCell.m
================================================
//
//  SWImageCollectionCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWImageCollectionCell.h"
#import "SWFormCompat.h"
#import "UIImageView+FormImage.h"
/**
 删除图标宽高
 */
static CGFloat const SWDeleteIconWidth = 22.0f;
/**
 删除按钮宽高,大于图标宽高,增强交互性
 */
static CGFloat const SWDeleteBtnWidth = 25.0f;

@interface SWImageCollectionCell()

@property (nonatomic, strong) UIImageView *currentImageView;
@property (nonatomic, strong) UIImageView *deleteIcon;
@property (nonatomic, strong) UIButton *deleteBtn;

@end

@implementation SWImageCollectionCell

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        
        self.currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, SWDeleteIconWidth/2, self.frame.size.width - SWDeleteIconWidth/2, self.frame.size.height - SWDeleteIconWidth/2)];
        self.currentImageView.clipsToBounds = YES;
        self.currentImageView.contentMode = UIViewContentModeScaleAspectFill;
        [self.contentView addSubview:self.currentImageView];
        
        self.deleteIcon = [[UIImageView alloc]initWithFrame:CGRectMake(self.frame.size.width - SWDeleteIconWidth, 0, SWDeleteIconWidth, SWDeleteIconWidth)];
        self.deleteIcon.image = [UIImage imageNamed:SW_DeleteIcon];
        [self.contentView addSubview:self.deleteIcon];
        
        self.deleteBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        self.deleteBtn.frame = CGRectMake(self.frame.size.width - SWDeleteBtnWidth, 0, SWDeleteBtnWidth, SWDeleteBtnWidth);
        [self.deleteBtn addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.deleteBtn];
    }
    return self;
}

- (void)deleteAction {
    if (self.deleteImageCompletion) {
        self.deleteImageCompletion();
    }
}

- (void)setEditable:(BOOL)editable {
    _editable = editable;
    self.deleteBtn.hidden = !editable;
    self.deleteIcon.hidden = !editable;
}

#pragma mark -- 设置当前图片
- (void)setImage:(id)image {
    _image = image;
    if ([image isKindOfClass:[UIImage class]]) {
        self.currentImageView.image = image;
    }
    else if ([image isKindOfClass:[NSURL class]]) {
        [self.currentImageView sw_setImageItemWithUrl:image];
    }
    else if ([image isKindOfClass:[NSString class]]) {
        [self.currentImageView sw_setImageItemWithUrl:[NSURL URLWithString:image]];
    }
    else {
        self.currentImageView.image = [UIImage imageNamed:SW_PlaceholderImage];
    }
}

@end


================================================
FILE: SWForm/SWFormHandler.h
================================================
//
//  SWFormHandler.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 SWFormHandler 数据校验文件,包含相机权限、相册权限以及表单空数据校验
 */
@interface SWFormHandler : NSObject

/**
 必选(必填)数据空数据校验,可根据需求定制

 @param datas 表单数据源
 @param success 必选(必填)数据全部校验成功
 @param failure 必选(必填)数据某一项校验失败
 */
+ (void)sw_checkFormNullDataWithWithDatas:(NSArray *)datas success:(void(^)(void))success failure:(void(^)(NSString *error))failure;

/**
 校验是否有相机权限
 */
+ (void)sw_checkCameraAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;

/**
 校验是否有相册权限
 */
+ (void)sw_checkAlbumAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;

@end


================================================
FILE: SWForm/SWFormHandler.m
================================================
//
//  SWFormHandler.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormHandler.h"
#import <Photos/PHPhotoLibrary.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <UIKit/UIKit.h>
#import "SWFormItem.h"
#import "SWFormSectionItem.h"

@implementation SWFormHandler

+ (void)sw_checkFormNullDataWithWithDatas:(NSArray *)datas success:(void(^)(void))success failure:(void(^)(NSString *error))failure {
    for (int sec = 0; sec < datas.count; sec++) {
        SWFormSectionItem *sectionItem = datas[sec];
        for (int row = 0; row < sectionItem.items.count; row++) {
            SWFormItem *rowItem = sectionItem.items[row];
            if (rowItem.required) {
                if (rowItem.itemType == SWFormItemTypeInput || rowItem.itemType == SWFormItemTypeTextViewInput) {
                    if (!rowItem.info || [rowItem.info isEqualToString:@""]) {
                        failure([NSString stringWithFormat:@"请输入%@", rowItem.title]);
                        return;
                    }
                }
                else if (rowItem.itemType == SWFormItemTypeSelect) {
                    if (!rowItem.info || [rowItem.info isEqualToString:@""]) {
                        failure([NSString stringWithFormat:@"请选择%@", rowItem.title]);
                        return;
                    }
                }
                else if (rowItem.itemType == SWFormItemTypeImage) {
                    if (!rowItem.images || rowItem.images.count == 0) {
                        failure([NSString stringWithFormat:@"请选择%@", rowItem.title]);
                        return;
                    }
                }
            }
        }
    }
    success();
}

#pragma mark -- 校验相机相册权限
+ (void)sw_checkCameraAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted
{
    AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (videoAuthStatus) {
            // 已授权
        case AVAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case AVAuthorizationStatusNotDetermined:
        {
            // 提示用户授权
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                permissionGranted(granted);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相机”选项中,允许访问你的相机" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
}

+ (void)sw_checkAlbumAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted {
    
    PHAuthorizationStatus photoAuthStatus = [PHPhotoLibrary authorizationStatus];
    switch (photoAuthStatus) {
            // 已授权
        case PHAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case PHAuthorizationStatusNotDetermined:
        {
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                permissionGranted(status == PHAuthorizationStatusAuthorized);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case PHAuthorizationStatusRestricted:
        case PHAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相片”选项中,允许访问你的相册" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
    
}

@end


================================================
FILE: SWForm/SWFormImageCell+ImageHandle.h
================================================
//
//  SWFormImageCell+ImageHandle.h
//  SWFormDemo
//
//  Created by zijin on 2018/6/1.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell.h"

@interface SWFormImageCell (ImageHandle)

/**
 选择图片数据回调
 
 @param maxImages 最大可选择图片数
 @param currentImages 当前选择图片数
 @param completion 选择图片数组回调
 */
- (void)sw_selectImageWithMaxImages:(NSInteger)maxImages currentImages:(NSInteger)currentImages completion:(void(^)(NSArray *selectImages))completion;

/**
 图片浏览

 @param images 图片数组
 @param currentIndex 当前浏览的index
 */
- (void)sw_photoBrowserWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex;


@end


================================================
FILE: SWForm/SWFormImageCell+ImageHandle.m
================================================
//
//  SWFormImageCell+ImageHandle.m
//  SWFormDemo
//
//  Created by zijin on 2018/6/1.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell+ImageHandle.h"
#import "objc/runtime.h"

static char SW_MAXIMAGECOUNT;
static char SW_CURRENTIMAGECOUNT;
static char SW_SELECTCOMPLETION;
static char SW_BROWSERPHOTOS;

typedef void(^SWSelectImageCompletion)(NSArray *images);

@interface UITableViewCell()
@end

@implementation SWFormImageCell (ImageHandle)

- (void)sw_selectImageWithMaxImages:(NSInteger)maxImages currentImages:(NSInteger)currentImages completion:(void(^)(NSArray *selectImages))completion {
    
    [self sw_setMaxImagesCount:maxImages];
    [self sw_setCurrentImagesCount:currentImages];
    [self sw_setSelectImagesCompletion:completion];
}

- (void)sw_photoBrowserWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex {

}

#pragma mark -- 设置图片选择block
- (void)sw_setSelectImagesCompletion:(SWSelectImageCompletion)completion {
    objc_setAssociatedObject(self, &SW_SELECTCOMPLETION, completion, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (SWSelectImageCompletion)sw_selectImagesCompletion {
    return objc_getAssociatedObject(self, &SW_SELECTCOMPLETION);
}

#pragma mark -- 设置当前获取的图片
- (void)sw_setBrowserPhotos:(NSArray *)photos {
    objc_setAssociatedObject(self, &SW_BROWSERPHOTOS, photos, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSArray *)sw_browserPhotos {
    return objc_getAssociatedObject(self, &SW_BROWSERPHOTOS);
}

#pragma mark -- 设置最大图片数
- (void)sw_setMaxImagesCount:(NSInteger)count {
    objc_setAssociatedObject(self, &SW_MAXIMAGECOUNT, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)sw_maxImagesCount {
    return [objc_getAssociatedObject(self, &SW_MAXIMAGECOUNT) integerValue];
}

#pragma mark -- 设置当前图片数
- (void)sw_setCurrentImagesCount:(NSInteger)count {
    objc_setAssociatedObject(self, &SW_CURRENTIMAGECOUNT, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)sw_currentImagesCount {
    return [objc_getAssociatedObject(self, &SW_CURRENTIMAGECOUNT) integerValue];
}

#pragma mark -- 获取当前View所在的ViewController
- (UIViewController *)superViewController:(UIView *)view{
    UIResponder *responder = view;
    while ((responder = [responder nextResponder]))
        if ([responder isKindOfClass: [UIViewController class]])
            return (UIViewController *)responder;
    
    return nil;
}

@end


================================================
FILE: SWForm/SWFormItem/SWFormItem.h
================================================
//
//  SWFormItem.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class SWFormItem;

typedef NS_ENUM(NSInteger, SWFormItemType) {
    /**
     表单条目可单行或多行输入(标题居左)
     */
    SWFormItemTypeInput = 0,
    /**
     表单条目可选择(标题居左)
     */
    SWFormItemTypeSelect = 1,
    /**
     表单条目可多行输入(标题居上)
     */
    SWFormItemTypeTextViewInput = 2,
    /**
     表单条目包含图片选择
     */
    SWFormItemTypeImage = 3,
};

typedef NS_ENUM(NSInteger, SWFormItemUnitType) {
    SWFormItemUnitTypeNone = 0, // 无单位
    SWFormItemUnitTypeYuan, // 元
    SWFormItemUnitTypeYear, // 年
    SWFormItemUnitTypeMillion, // 万元
    SWFormItemUnitTypeCustom, // 自定义单位
};

typedef void(^SWItemSelectCompletion)(SWFormItem *item);

/**
 SWFormItem 主要对表单条目提供动态配置属性
 */
@interface SWFormItem : NSObject

/**
 表单条目缺省高度,缺省值为44.0f, 可根据需求设置
 */
@property (nonatomic, assign) CGFloat defaultHeight;

/**
 表单条目类型
 */
@property (nonatomic, assign) SWFormItemType itemType;

/**
 表单条目标题,表单标题为单行显示,尽可能简短,若标题太长,会牺牲字体大小以达到显示完全的效果
 */
@property (nonatomic, copy, nonnull) NSString *title;
@property (nonatomic, strong, nonnull) NSAttributedString *attributedTitle;

/**
 表单条目详情
 */
@property (nonatomic, copy, nullable) NSString *info;

/**
 表单条目占位字符
 */
@property (nonatomic, copy, nullable) NSString *placeholder;
@property (nonatomic, strong, nullable) NSAttributedString *attributedPlaceholder;

/**
 是否显示表单条目占位字符 YES:显示 NO:不显示 --- 新增 default is YES;详情 default is NO
 */
@property (nonatomic, assign) BOOL showPlaceholder;

/**
 图片附件条目图片数组,支持UIImage、NSURL、NSString(图片URLString)类型元素
 */
@property (nonatomic, strong, nullable) NSArray *images;

/**
 images 图片数组中类型筛选出为UIImage的数组子集,以实现图片上传筛选
 */
@property (nonatomic, strong, readonly) NSArray *selectImages;

/**
 表单条目键盘类型
 */
@property (nonatomic, assign) UIKeyboardType keyboardType;

/**
 表单条目是否可编辑 YES:可编辑 NO:不可编辑
 */
@property (nonatomic, assign) BOOL editable;

/**
 表单条目是否必填(必选) YES:必填(必选) NO:可填(可选)
 */
@property (nonatomic, assign) BOOL required;

/**
 SWFormItemTypeInput 以及 SWFormItemTypeTextViewInput 类别中表示最大输入字数
 0 表示无限制
 */
@property (nonatomic, assign) NSUInteger maxInputLength;

/**
 SWFormItemTypeImage 类别中表示最大选择图片数
 */
@property (nonatomic, assign) NSUInteger maxImageCount;

/**
 表单条目点击选择事件block
 */
@property (nonatomic, copy, nullable) SWItemSelectCompletion itemSelectCompletion;

/**
 条目附带单位
 */
@property (nonatomic, copy, nullable) NSString *unit;

/**
 表单条目单位类别
 */
@property (nonatomic, assign) SWFormItemUnitType itemUnitType;

/**
 是否显示当前字数
 只在 SWFormItemTypeTextViewInput 类型下有效,若无最大字数限制,则只显示字数; 若有字数限制,则显示 "当前字数/最大字数"
 */
@property (nonatomic, assign) BOOL showLength;

@end

/**
 SWFormItem_Add 快捷构建新增表单条目

 @param title 标题
 @param info 详情
 @param itemType 条目类别
 @param editable 是否可编辑
 @param required 是否必填
 @param keyboardType 键盘类别
 */
FOUNDATION_EXPORT SWFormItem *SWFormItem_Add(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType, BOOL editable, BOOL required, UIKeyboardType keyboardType);

/**
 SWFormItem_Info 快捷构建详情表单条目
 */
FOUNDATION_EXPORT SWFormItem *SWFormItem_Info(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType);


================================================
FILE: SWForm/SWFormItem/SWFormItem.m
================================================
//
//  SWFormItem.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormItem.h"
#import "SWFormCompat.h"

static NSString *const SWUnitYuan = @"元";
static NSString *const SWUnitYear = @"年";
static NSString *const SWUnitMillion = @"万元";

@interface SWFormItem()

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType;

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType;

@end

inline SWFormItem *SWFormItem_Add(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType, BOOL editable, BOOL required, UIKeyboardType keyboardType) {
    return [SWFormItem sw_itemWithTitle:title info:info itemType:itemType editable:editable required:required keyboardType:keyboardType];
}

inline SWFormItem *SWFormItem_Info(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType) {
    return [SWFormItem sw_itemWithTitle:title info:info itemType:itemType];
}

@implementation SWFormItem

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType {
    return [[self alloc]initWithTitle:title info:info itemType:itemType editable:editable required:required keyboardType:keyboardType images:nil showPlaceholder:YES];
}

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType {
    return [[self alloc]initWithTitle:title info:info itemType:itemType editable:NO required:NO keyboardType:UIKeyboardTypeDefault images:nil showPlaceholder:NO];
}

- (instancetype)initWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType images:(NSArray *)images showPlaceholder:(BOOL)showPlaceholder{
    self = [super init];
    if (self) {
        self.itemUnitType = SWFormItemUnitTypeNone;
        self.maxInputLength = SW_GlobalMaxInputLength;
        self.maxImageCount = SW_GlobalMaxImages;
        self.title = title;
        self.info = info;
        self.itemType = itemType;
        self.editable = editable;
        self.required = required;
        self.keyboardType = keyboardType;
        self.images = images;
        self.showPlaceholder = showPlaceholder;
        [self sw_setDefaultHeight:itemType];
        [self sw_setPlaceholderWithShow:showPlaceholder itemType:itemType];
        [self sw_setAttributedTitleWithRequired:required title:title itemType:itemType];
    }
    return self;
}

#pragma mark -- 根据表单条目类型设置条目缺省高度
- (void)sw_setDefaultHeight:(SWFormItemType)itemType {
    self.defaultHeight = itemType == SWFormItemTypeTextViewInput ? SW_DefaultTextViewItemHeight:SW_DefaultItemHeight;
}

#pragma mark -- 设置是否显示输入框占位字符
- (void)sw_setPlaceholderWithShow:(BOOL)show itemType:(SWFormItemType)itemType {
    if (!show) {
        self.placeholder = @"";
        return;
    }
    switch (itemType) {
        case SWFormItemTypeInput:
        case SWFormItemTypeTextViewInput:
        {
            self.placeholder = @"请输入";
        }
            break;
        case SWFormItemTypeSelect:
        {
            self.placeholder = @"请选择";
        }
            break;
        default:
            self.placeholder = @"";
            break;
    }
}

#pragma mark -- 设置标题显示
- (void)sw_setAttributedTitleWithRequired:(BOOL)required title:(NSString *)title itemType:(SWFormItemType)itemType{
    if (required) {
        if (SW_TitleShowType == SWTitleShowTypeDefault) {
            switch (self.itemType) {
                case SWFormItemTypeInput:
                case SWFormItemTypeTextViewInput:
                {
                    title = [NSString stringWithFormat:@"%@(必填)", title];
                }
                    break;
                case SWFormItemTypeSelect:
                case SWFormItemTypeImage:
                {
                    title = [NSString stringWithFormat:@"%@(必选)", title];
                }
                    break;
                default:
                    break;
            }
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarFront) {
            title = [NSString stringWithFormat:@"*%@", title];
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarBack) {
            title = [NSString stringWithFormat:@"%@*", title];
        }
    }
    
    NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc]initWithString:title attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:SW_TitleFont], NSForegroundColorAttributeName:SW_TITLECOLOR}];
    
    if (required) {
        if (SW_TitleShowType == SWTitleShowTypeRedStarFront) {
            [attributedTitle addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarBack) {
            [attributedTitle addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(title.length - 1, 1)];
        }
    }
    _attributedTitle = attributedTitle;
}

#pragma mark -- 重写get方法
- (NSArray *)selectImages {
    NSMutableArray *tempImages = [NSMutableArray array];
    for (id temp in self.images) {
        if ([temp isKindOfClass:[UIImage class]]) {
            [tempImages addObject:temp];
        }
    }
    return tempImages;
}

#pragma mark -- 重写属性set方法,防止单独改变属性无响应效果
/**
 设置表单条目附带单位
 */
- (void)setItemUnitType:(SWFormItemUnitType)itemUnitType {
    NSString *tempUnit = self.unit ?: @"";
    switch (itemUnitType) {
        case SWFormItemUnitTypeNone:
        {
            tempUnit = @"";
        }
            break;
        case SWFormItemUnitTypeYuan:
        {
            tempUnit = SWUnitYuan;
        }
            break;
        case SWFormItemUnitTypeYear:
        {
            tempUnit = SWUnitYear;
        }
            break;
        case SWFormItemUnitTypeMillion:
        {
            tempUnit = SWUnitMillion;
        }
        default:
            break;
    }
    _unit = tempUnit;
}

/**
 根据单位设置单元格单位类别,防止单位与单元格式不一致
 */
- (void)setUnit:(NSString *)unit {
    _unit = unit;
    if ([unit isEqualToString:@""]) {
        _itemUnitType = SWFormItemUnitTypeNone;
    }
    else if (unit == SWUnitYuan) {
        _itemUnitType = SWFormItemUnitTypeYuan;
    }
    else if (unit == SWUnitYear) {
        _itemUnitType = SWFormItemUnitTypeYear;
    }
    else if (unit == SWUnitMillion) {
        _itemUnitType = SWFormItemUnitTypeMillion;
    }
    else {
        _itemUnitType = SWFormItemUnitTypeCustom;
    }
}

- (void)setImages:(NSArray *)images {
    _images = images;
    [self selectImages];
}

- (void)setTitle:(NSString *)title {
    _title = title;
    [self sw_setAttributedTitleWithRequired:self.required title:title itemType:self.itemType];
}

- (void)setRequired:(BOOL)required {
    _required = required;
    [self sw_setAttributedTitleWithRequired:required title:self.title itemType:self.itemType];
}

- (void)setItemType:(SWFormItemType)itemType {
    _itemType = itemType;
    [self sw_setDefaultHeight:itemType];
    [self sw_setAttributedTitleWithRequired:self.required title:self.title itemType:itemType];
    [self sw_setPlaceholderWithShow:self.showPlaceholder itemType:itemType];
}

- (void)setShowPlaceholder:(BOOL)showPlaceholder {
    _showPlaceholder = showPlaceholder;
    [self sw_setPlaceholderWithShow:showPlaceholder itemType:self.itemType];
}

- (void)setPlaceholder:(NSString *)placeholder {
    _placeholder = placeholder;
    NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc]initWithString:placeholder ?: @"" attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:SW_InfoFont],NSForegroundColorAttributeName:SW_PLACEHOLDERCOLOR}];
    _attributedPlaceholder = attributedPlaceholder;
}

- (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder {
    _attributedPlaceholder = attributedPlaceholder ?: [[NSAttributedString alloc]initWithString:@""];
}

@end


================================================
FILE: SWForm/SWFormItem/SWFormSectionItem.h
================================================
//
//  SWFormSectionItem.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**
 SWFormSectionItem 主要对表单section条目提供动态配置属性
 */
@interface SWFormSectionItem : NSObject

/**
 表单section包含的条目集合
 */
@property (nonatomic, strong, nonnull) NSArray *items;

/**
 表单section头部高度
 */
@property (nonatomic, assign) CGFloat headerHeight;

/**
 表单section尾部高度
 */
@property (nonatomic, assign) CGFloat footerHeight;

/**
 表单section头部视图
 */
@property (nonatomic, strong, nullable) UIView *headerView;

/**
 表单section尾部视图
 */
@property (nonatomic, strong, nullable) UIView *footerView;

@end

/**
 SWSectionItem 快捷构建表单section条目

 @param items 表单section包含的条目集合
 */
FOUNDATION_EXPORT SWFormSectionItem *SWSectionItem(NSArray * _Nonnull items);


================================================
FILE: SWForm/SWFormItem/SWFormSectionItem.m
================================================
//
//  SWFormSectionItem.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormSectionItem.h"

@interface SWFormSectionItem()

+ (instancetype)sw_sectionItem:(NSArray *)items;

@end

inline SWFormSectionItem *SWSectionItem(NSArray * _Nonnull items) {
    return [SWFormSectionItem sw_sectionItem:items];
}

@implementation SWFormSectionItem

+ (instancetype)sw_sectionItem:(NSArray *)items {
    return [[self alloc]initWithItems:items];
}

- (instancetype)initWithItems:(NSArray *)items {
    self = [super init];
    if (self) {
        self.items = items;
    }
    return self;
}

@end


================================================
FILE: SWForm/SWFormManager/NSString+SWForm.h
================================================
//
//  NSString+SWForm.h
//  SWFormDemo
//
//  Created by zijin on 2018/6/26.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSString (SWForm)

/**
 字符串添加单位

 @param unit 单位
 */
- (NSString *)addUnit:(NSString *)unit;

/**
 获取字符串的Size大小

 @param fontSize 字体大小
 @param maxSize 最大显示Size
 */
- (CGSize)sizeWithFontSize:(CGFloat)fontSize maxSize:(CGSize)maxSize;

@end


================================================
FILE: SWForm/SWFormManager/NSString+SWForm.m
================================================
//
//  NSString+SWForm.m
//  SWFormDemo
//
//  Created by zijin on 2018/6/26.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "NSString+SWForm.h"

@implementation NSString (SWForm)

- (NSString *)addUnit:(NSString *)unit {
    if ([self isEqualToString:@""] || [unit isEqualToString:@""]) {
        return self;
    }
    return [NSString stringWithFormat:@"%@ %@", self, unit];
}

- (CGSize)sizeWithFontSize:(CGFloat)fontSize maxSize:(CGSize)maxSize {
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size;
}

@end


================================================
FILE: SWForm/SWFormManager/SWFormCompat.h
================================================
//
//  SWFormCompat.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

/**
 SWFormCompat 主要配置表单涉及的相关常量参数,可根据需求修改配置
 */
#import <UIKit/UIKit.h>

/**
 必选条目标题呈现形式类别
 */
typedef NS_ENUM(NSInteger, SWTitleShowType) {
    /**
     默认呈现形式,如: 标题(必填)
     */
    SWTitleShowTypeDefault,
    /**
     标题前部加红色*,如: *标题
     */
    SWTitleShowTypeRedStarFront,
    /**
     标题后部加红色*,如: 标题*
     */
    SWTitleShowTypeRedStarBack,
    /**
     仅显示标题
     */
    SWTitleShowTypeOnlyTitle,
};

/**
 表单标题字体大小,缺省为16
 */
extern CGFloat const SW_TitleFont;

/**
 表单详情字体大小,缺省为16
 */
extern CGFloat const SW_InfoFont;

/**
 表单条目边缘距离,缺省为10.0f
 */
extern CGFloat const SW_EdgeMargin;

/**
 表单标题宽度,缺省为100.0f
 */
extern CGFloat const SW_TitleWidth;

/**
 表单标题高度,缺省为24.0f
 */
extern CGFloat const SW_TitleHeight;

/**
 表单条目初始高度,缺省为44.0f,SWFormItemTypeTextViewInput 类型缺省高度为200,为确保显示正常,设置值>= 44
 */
extern CGFloat const SW_DefaultItemHeight;
extern CGFloat const SW_DefaultTextViewItemHeight;

/**
 表单标题显示类别,缺省为 SWTitleShowTypeRedStarFront
 */
extern NSInteger const SW_TitleShowType;

/**
 表单输入字数限制,缺省为200
 0 表示无限制
 */
extern NSUInteger const SW_GlobalMaxInputLength;

/**
 表单选择图片附件数,缺省为6
 */
extern NSUInteger const SW_GlobalMaxImages;

/**
 表单图片条目图片加载失败占位图
 */
extern NSString *const SW_PlaceholderImage;

/**
 表单附件删除图标
 */
extern NSString *const SW_DeleteIcon;

/**
 表单TextView字数提示文字大小
 */
extern CGFloat const SW_LengHintFont;

/**
 表单条目输入框占位符字体颜色
 */
#define SW_PLACEHOLDERCOLOR [UIColor colorWithRed:187/255.0 green:187/255.0 blue:187/255.0 alpha:1/1.0]

/**
 SWFormItemTypeTextViewInput 类别 TextView 背景颜色
 */
#define SW_TEXTVIEW_BACKGROUNDCOLOR [UIColor colorWithRed:250/255.0 green:250/255.0 blue:250/255.0 alpha:1/1.0]
/**
 表单条目标题颜色
 */
#define SW_TITLECOLOR [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1/1.0]

/**
 获取屏幕宽度
 */
#define SW_SCRREN_WIDTH [UIScreen mainScreen].bounds.size.width

/// 弱引用
#define SWWeakSelf __weak typeof(self) weakSelf = self;


================================================
FILE: SWForm/SWFormManager/SWFormCompat.m
================================================
//
//  SWFormCompat.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormCompat.h"

// 表单标题字体大小
CGFloat const SW_TitleFont = 16.0f;

// 表单详情字体大小
CGFloat const SW_InfoFont = 16.0f;

// 表单条目边缘距离
CGFloat const SW_EdgeMargin = 10.0f;

// 表单标题宽度
CGFloat const SW_TitleWidth = 80.0f;

// 表单标题高度
CGFloat const SW_TitleHeight = 24.0f;

// 表单条目初始高度
CGFloat const SW_DefaultItemHeight = 44.0f;
CGFloat const SW_DefaultTextViewItemHeight = 200.0f;

// 表单标题显示类别
NSInteger const SW_TitleShowType = SWTitleShowTypeRedStarFront;

// 表单输入字数限制
NSUInteger const SW_GlobalMaxInputLength = 200;

// 表单选择图片附件数
NSUInteger const SW_GlobalMaxImages = 6;

// 表单TextView字数提示文字大小
CGFloat const SW_LengHintFont = 12;

// 表单图片条目图片加载失败占位图
NSString *const SW_PlaceholderImage = @"SWForm.bundle/SWPlaceholderIcon";

// 表单附件删除图标
NSString *const SW_DeleteIcon = @"SWForm.bundle/SWDeleteIcon";


================================================
FILE: SWForm/SWFormManager/SelwynExpandableTextView.h
================================================
//
//  SelwynExpandableTextView.h
//  SelwynFormDemo
//
//  Created by BSW on 2017/6/24.
//  Copyright © 2017年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 SelwynExpandableTextView 可高度自适应的UITextView
 */
@interface SelwynExpandableTextView : UITextView

@property (nonatomic, assign) NSUInteger currentLength;
@property (nonatomic, assign) NSUInteger maxLength;
@property (nonatomic, assign) BOOL showLength;

@property (copy, nonatomic) IBInspectable NSString *placeholder;
@property (copy, nonatomic) NSAttributedString *attributedPlaceholder;

@property (nonatomic) IBInspectable double fadeTime;
@property (retain, nonatomic) UIColor *placeholderTextColor UI_APPEARANCE_SELECTOR;

@end


================================================
FILE: SWForm/SWFormManager/SelwynExpandableTextView.m
================================================
//
//  SelwynExpandableTextView.m
//  SelwynFormDemo
//
//  Created by BSW on 2017/6/24.
//  Copyright © 2017年 selwyn. All rights reserved.
//

#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"

#define HAS_TEXT_CONTAINER [self respondsToSelector:@selector(textContainer)]
#define HAS_TEXT_CONTAINER_INSETS(x) [(x) respondsToSelector:@selector(textContainerInset)]

@interface SelwynExpandableTextView()
@property (strong, nonatomic) UITextView *_placeholderTextView;
@property (nonatomic, strong) UILabel *lenthLab;
@end

static NSString * const kAttributedPlaceholderKey = @"attributedPlaceholder";
static NSString * const kPlaceholderKey = @"placeholder";
static NSString * const kFontKey = @"font";
static NSString * const kAttributedTextKey = @"attributedText";
static NSString * const kTextKey = @"text";
static NSString * const kExclusionPathsKey = @"exclusionPaths";
static NSString * const kLineFragmentPaddingKey = @"lineFragmentPadding";
static NSString * const kTextContainerInsetKey = @"textContainerInset";
static NSString * const kTextAlignmentKey = @"textAlignment";

@implementation SelwynExpandableTextView

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer
{
    self = [super initWithFrame:frame textContainer:textContainer];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}
#else
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}
#endif

- (void)preparePlaceholder
{
    NSAssert(!self._placeholderTextView, @"placeholder has been prepared already: %@", self._placeholderTextView);
    // the label which displays the placeholder
    // needs to inherit some properties from its parent text view
    
    // account for standard UITextViewPadding
    
    CGRect frame = self.bounds;
    self._placeholderTextView = [[UITextView alloc] initWithFrame:frame];
    self._placeholderTextView.opaque = NO;
    self._placeholderTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self._placeholderTextView.backgroundColor = [UIColor clearColor];
    self._placeholderTextView.textColor = [UIColor colorWithWhite:0.7f alpha:0.7f];
    self._placeholderTextView.editable = NO;
    self._placeholderTextView.scrollEnabled = YES;
    self._placeholderTextView.userInteractionEnabled = NO;
    self._placeholderTextView.font = self.font;
    self._placeholderTextView.isAccessibilityElement = NO;
    self._placeholderTextView.contentOffset = self.contentOffset;
    self._placeholderTextView.contentInset = self.contentInset;
    
    if ([self._placeholderTextView respondsToSelector:@selector(setSelectable:)]) {
        self._placeholderTextView.selectable = NO;
    }
    
    if (HAS_TEXT_CONTAINER) {
        self._placeholderTextView.textContainer.exclusionPaths = self.textContainer.exclusionPaths;
        self._placeholderTextView.textContainer.lineFragmentPadding = self.textContainer.lineFragmentPadding;
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        self._placeholderTextView.textContainerInset = self.textContainerInset;
    }
    
    if (_attributedPlaceholder) {
        self._placeholderTextView.attributedText = _attributedPlaceholder;
    } else if (_placeholder) {
        self._placeholderTextView.text = _placeholder;
    }
    
    [self setPlaceholderVisibleForText:self.text];
    
    self.clipsToBounds = YES;
    
    // some observations
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(textDidChange:)
                          name:UITextViewTextDidChangeNotification object:self];
    [defaultCenter addObserver:self selector:@selector(textDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:self];
    
    [self addObserver:self forKeyPath:kAttributedPlaceholderKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kPlaceholderKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kFontKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kAttributedTextKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kTextKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kTextAlignmentKey
              options:NSKeyValueObservingOptionNew context:nil];
    
    if (HAS_TEXT_CONTAINER) {
        [self.textContainer addObserver:self forKeyPath:kExclusionPathsKey
                                options:NSKeyValueObservingOptionNew context:nil];
        [self.textContainer addObserver:self forKeyPath:kLineFragmentPaddingKey
                                options:NSKeyValueObservingOptionNew context:nil];
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        [self addObserver:self forKeyPath:kTextContainerInsetKey
                  options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)setPlaceholder:(NSString *)placeholderText
{
    _placeholder = [placeholderText copy];
    _attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholderText];
    
    [self resizePlaceholderFrame];
}

- (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholderText
{
    _placeholder = attributedPlaceholderText.string;
    _attributedPlaceholder = [attributedPlaceholderText copy];
    
    [self resizePlaceholderFrame];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    self._placeholderTextView.textAlignment = self.textAlignment;
    [self resizePlaceholderFrame];
    [self resizeLengthFrame];
}

- (void)setCurrentLength:(NSUInteger)currentLength {
    _currentLength = currentLength;
    [self resizeLengthFrame];
}

- (void)resizePlaceholderFrame
{
    CGRect frame = self._placeholderTextView.frame;
    frame.size = self.bounds.size;
    self._placeholderTextView.frame = frame;
}

- (void)resizeLengthFrame {
    if (self.showLength) {
        NSString *length = [NSString stringWithFormat:@"%lu", self.currentLength];
        if (self.maxLength > 0) {
            length = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)self.currentLength, (unsigned long)self.maxLength];
        }
        self.lenthLab.text = length;
        self.lenthLab.frame = CGRectMake(self.frame.size.width - 210, self.frame.size.height - 10 - 14, 200, 14);
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:kAttributedPlaceholderKey]) {
        self._placeholderTextView.attributedText = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kPlaceholderKey]) {
        self._placeholderTextView.text = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kFontKey]) {
        self._placeholderTextView.font = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kAttributedTextKey]) {
        NSAttributedString *newAttributedText = [change valueForKey:NSKeyValueChangeNewKey];
        [self setPlaceholderVisibleForText:newAttributedText.string];
    }
    else if ([keyPath isEqualToString:kTextKey]) {
        NSString *newText = [change valueForKey:NSKeyValueChangeNewKey];
        [self setPlaceholderVisibleForText:newText];
    }
    else if ([keyPath isEqualToString:kExclusionPathsKey]) {
        self._placeholderTextView.textContainer.exclusionPaths = [change objectForKey:NSKeyValueChangeNewKey];
        [self resizePlaceholderFrame];
    }
    else if ([keyPath isEqualToString:kLineFragmentPaddingKey]) {
        self._placeholderTextView.textContainer.lineFragmentPadding = [[change objectForKey:NSKeyValueChangeNewKey] floatValue];
        [self resizePlaceholderFrame];
    }
    else if ([keyPath isEqualToString:kTextContainerInsetKey]) {
        NSValue *value = [change objectForKey:NSKeyValueChangeNewKey];
        self._placeholderTextView.textContainerInset = value.UIEdgeInsetsValue;
    }
    else if ([keyPath isEqualToString:kTextAlignmentKey]) {
        NSNumber *alignment = [change objectForKey:NSKeyValueChangeNewKey];
        self._placeholderTextView.textAlignment = alignment.intValue;
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor
{
    self._placeholderTextView.textColor = placeholderTextColor;
}

- (UIColor *)placeholderTextColor
{
    return self._placeholderTextView.textColor;
}

- (void)textDidChange:(NSNotification *)aNotification
{
    [self setPlaceholderVisibleForText:self.text];
}

- (void)textDidBeginEditing:(NSNotification *)aNotification {
    [self setPlaceholderVisibleForText:self.text];
}

/**
 - (BOOL)becomeFirstResponder
 {
 [self setPlaceholderVisibleForText:self.text];
 
 return [super becomeFirstResponder];
 }
 */

- (void)setPlaceholderVisibleForText:(NSString *)text
{
    if (text.length < 1) {
        if (self.fadeTime > 0.0) {
            if (![self._placeholderTextView isDescendantOfView:self]) {
                self._placeholderTextView.alpha = 0;
                [self addSubview:self._placeholderTextView];
                [self sendSubviewToBack:self._placeholderTextView];
            }
            [UIView animateWithDuration:_fadeTime animations:^{
                self._placeholderTextView.alpha = 1;
            }];
        }
        else {
            [self addSubview:self._placeholderTextView];
            [self sendSubviewToBack:self._placeholderTextView];
            self._placeholderTextView.alpha = 1;
        }
    }
    else {
        if (self.fadeTime > 0.0) {
            [UIView animateWithDuration:_fadeTime animations:^{
                self._placeholderTextView.alpha = 0;
            }];
        }
        else {
            [self._placeholderTextView removeFromSuperview];
        }
    }
}

- (UILabel *)lenthLab {
    if (!_lenthLab) {
        _lenthLab = [[UILabel alloc]init];
        _lenthLab.font = [UIFont systemFontOfSize:SW_LengHintFont];
        _lenthLab.backgroundColor = [UIColor clearColor];
        _lenthLab.textAlignment = NSTextAlignmentRight;
        _lenthLab.textColor = SW_PLACEHOLDERCOLOR;
        [self addSubview:_lenthLab];
    }
    return _lenthLab;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self removeObserver:self forKeyPath:kAttributedPlaceholderKey];
    [self removeObserver:self forKeyPath:kPlaceholderKey];
    [self removeObserver:self forKeyPath:kFontKey];
    [self removeObserver:self forKeyPath:kAttributedTextKey];
    [self removeObserver:self forKeyPath:kTextKey];
    [self removeObserver:self forKeyPath:kTextAlignmentKey];
    
    if (HAS_TEXT_CONTAINER) {
        [self.textContainer removeObserver:self forKeyPath:kExclusionPathsKey];
        [self.textContainer removeObserver:self forKeyPath:kLineFragmentPaddingKey];
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        [self removeObserver:self forKeyPath:kTextContainerInsetKey];
    }
}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect {
 // Drawing code
 }
 */

@end


================================================
FILE: SWForm/SWFormManager/UITextView+TextLimit.h
================================================
//
//  UITextView+TextLimit.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UITextView (TextLimit)

/**
 TextView 添加字数限制

 @param maxLength 限制字数
 */
- (void)textLimitWithMaxLength:(NSInteger)maxLength;

@end


================================================
FILE: SWForm/SWFormManager/UITextView+TextLimit.m
================================================
//
//  UITextView+TextLimit.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "UITextView+TextLimit.h"

@implementation UITextView (TextLimit)

- (void)textLimitWithMaxLength:(NSInteger)maxLength {
    NSString *toBeString = self.text;
    NSArray *inputModes = [UITextInputMode activeInputModes];
    UITextInputMode *currentMode = [inputModes firstObject];
    
    // 输入内容中文校验
    if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) {
        UITextRange *selectedRange = [self markedTextRange];
        UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
        if (!position) {
            if (toBeString.length > maxLength) {
                self.text = [toBeString substringToIndex:maxLength];
            }
        }
    }
    else{
        if (toBeString.length > maxLength) {
            self.text = [toBeString substringToIndex:maxLength];
        }
    }
}

@end


================================================
FILE: SWForm/UIImageView+FormImage.h
================================================
//
//  UIImageView+FormImage.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 图片附件加载
 */
@interface UIImageView (FormImage)


/**
 图片附件条目图片加载
 可以在此使用 SDWebImage
 @param url 图片加载的url
 */
- (void)sw_setImageItemWithUrl:(NSURL *)url;

@end


================================================
FILE: SWForm/UIImageView+FormImage.m
================================================
//
//  UIImageView+FormImage.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "UIImageView+FormImage.h"
#import "SWFormCompat.h"

@implementation UIImageView (FormImage)

- (void)sw_setImageItemWithUrl:(NSURL *)url {
//    [self sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:SW_PlaceholderImage]];
}

@end


================================================
FILE: SWFormExample/SWForm/SWForm.bundle/Root.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>StringsTable</key>
	<string>Root</string>
	<key>PreferenceSpecifiers</key>
	<array>
		<dict>
			<key>Type</key>
			<string>PSGroupSpecifier</string>
			<key>Title</key>
			<string>Group</string>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSTextFieldSpecifier</string>
			<key>Title</key>
			<string>Name</string>
			<key>Key</key>
			<string>name_preference</string>
			<key>DefaultValue</key>
			<string></string>
			<key>IsSecure</key>
			<false/>
			<key>KeyboardType</key>
			<string>Alphabet</string>
			<key>AutocapitalizationType</key>
			<string>None</string>
			<key>AutocorrectionType</key>
			<string>No</string>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSToggleSwitchSpecifier</string>
			<key>Title</key>
			<string>Enabled</string>
			<key>Key</key>
			<string>enabled_preference</string>
			<key>DefaultValue</key>
			<true/>
		</dict>
		<dict>
			<key>Type</key>
			<string>PSSliderSpecifier</string>
			<key>Key</key>
			<string>slider_preference</string>
			<key>DefaultValue</key>
			<real>0.5</real>
			<key>MinimumValue</key>
			<integer>0</integer>
			<key>MaximumValue</key>
			<integer>1</integer>
			<key>MinimumValueImage</key>
			<string></string>
			<key>MaximumValueImage</key>
			<string></string>
		</dict>
	</array>
</dict>
</plist>


================================================
FILE: SWFormExample/SWForm/SWForm.h
================================================
//
//  SWForm.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#ifndef SWForm_h
#define SWForm_h

#import "SWFormItem.h"
#import "SWFormSectionItem.h"
#import "SWFormHandler.h"
#import "SWFormCompat.h"

#endif /* SWForm_h */


================================================
FILE: SWFormExample/SWForm/SWFormBaseController.h
================================================
//
//  SWFormBaseController.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 SWFormBaseController 表单基类,所有表单必须继承于BaseController,实现了表单动态配置
 */
@interface SWFormBaseController : UIViewController

/**
 表单tableView
 */
@property (nonatomic, strong) UITableView *formTableView;

/**
 表单数据源,数据源格式应为 @[SWFormSection..],否则断言会直接崩溃
 */
@property (nonatomic, strong) NSMutableArray *mutableItems;

/**
 表单页面初始化方法

 @param style 表单tableView样式
 */
- (instancetype)initWithStyle:(UITableViewStyle)style;

@end


================================================
FILE: SWFormExample/SWForm/SWFormBaseController.m
================================================
//
//  SWFormBaseController.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseController.h"
#import "SWForm.h"
#import "SWFormInputCell.h"
#import "SWFormTextViewInputCell.h"
#import "SWFormSelectCell.h"
#import "SWFormImageCell.h"

@interface SWFormBaseController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, readonly) UITableViewStyle style;
@end

@implementation SWFormBaseController

- (NSMutableArray *)mutableItems {
    if (!_mutableItems) {
        _mutableItems = [[NSMutableArray alloc]init];
    }
    return _mutableItems;
}

- (instancetype)initWithStyle:(UITableViewStyle)style {
    self = [super init];
    if (self) {
        _style = style;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:_style];
    [self addChildViewController:tableViewController];
    [tableViewController.view setFrame:self.view.bounds];
    
    // 获取tableViewController的tableView实现表单自动上移
    _formTableView = tableViewController.tableView;
    _formTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    _formTableView.dataSource = self;
    _formTableView.delegate = self;
    //_formTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    _formTableView.showsVerticalScrollIndicator = NO;
    _formTableView.showsHorizontalScrollIndicator = NO;
    _formTableView.backgroundColor = [UIColor whiteColor];
    _formTableView.tableHeaderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)];
    _formTableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, CGFLOAT_MIN)];
    
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fingerTapped:)];
    //  加上这句不会影响你 tableview 上的 action (button,cell selected...)
    singleTap.cancelsTouchesInView = NO;
    [_formTableView addGestureRecognizer:singleTap];
    
    [self.view addSubview:_formTableView];
}

- (void)fingerTapped:(UITapGestureRecognizer *)gestureRecognizer {
    [self.view endEditing:YES];
}

#pragma mark -- TableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.mutableItems.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSParameterAssert([self.mutableItems[section] isKindOfClass:[SWFormSectionItem class]]);
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    NSParameterAssert([sectionItem.items[indexPath.row] isKindOfClass:[SWFormItem class]]);
    SWFormItem *item = sectionItem.items[indexPath.row];
    
    SWWeakSelf
    // 表单条目类别判断
    if (item.itemType == SWFormItemTypeTextViewInput) {
        static NSString *textViewInput_cell_id = @"textViewInput_cell_id";
        SWFormTextViewInputCell *cell = [tableView textViewInputCellWithId:textViewInput_cell_id];
        cell.item = item;
        cell.textViewInputCompletion = ^(NSString *text) {
            [weakSelf updateTextViewInputWithText:text indexPath:indexPath];
        };
        return cell;
    }
    else if (item.itemType == SWFormItemTypeSelect) {
        static NSString *select_cell_id = @"select_cell_id";
        SWFormSelectCell *cell = [tableView selectCellWithId:select_cell_id];
        cell.item = item;
        return cell;
    }
    else if (item.itemType == SWFormItemTypeImage) {
        static NSString *image_cell_id = @"image_cell_id";
        SWFormImageCell *cell = [tableView imageCellWithId:image_cell_id];
        cell.item = item;
        cell.imageCompletion = ^(NSArray *images) {
            [weakSelf updateImageWithImages:images indexPath:indexPath];
        };
        return cell;
    }
    else {
        static NSString *input_cell_id = @"input_cell_id";
        SWFormInputCell *cell = [tableView inputCellWithId:input_cell_id];
        cell.item = item;
        cell.inputCompletion = ^(NSString *text) {
            [weakSelf updateInputWithText:text indexPath:indexPath];
        };
        return cell;
    }
}

#pragma mark -- TableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    if (item.itemType == SWFormItemTypeTextViewInput) {
        return [SWFormTextViewInputCell heightWithItem:item];
    }
    else if (item.itemType == SWFormItemTypeSelect) {
        return [SWFormSelectCell heightWithItem:item];
    }
    else if (item.itemType == SWFormItemTypeImage) {
        return [SWFormImageCell heightWithItem:item];
    }
    else {
        return [SWFormInputCell heightWithItem:item];
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    if (item.itemType == SWFormItemTypeSelect && item.itemSelectCompletion) {
        item.itemSelectCompletion(item);
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.headerHeight > 0 ? sectionItem.headerHeight:0.01;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    return sectionItem.footerHeight > 0 ? sectionItem.footerHeight:0.01;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    UIView *header = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, sectionItem.headerHeight)];
    return sectionItem.headerView ? sectionItem.headerView:header;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    SWFormSectionItem *sectionItem = self.mutableItems[section];
    UIView *footer = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, sectionItem.footerHeight)];
    return sectionItem.footerView ? sectionItem.footerView:footer;
}

#pragma mark -- 表单条目响应block处理
- (void)updateInputWithText:(NSString *)text indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.info = text;
}

- (void)updateTextViewInputWithText:(NSString *)text indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.info = text;
}

- (void)updateImageWithImages:(NSArray *)images indexPath:(NSIndexPath *)indexPath {
    SWFormSectionItem *sectionItem = self.mutableItems[indexPath.section];
    SWFormItem *item = sectionItem.items[indexPath.row];
    item.images = images;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormBaseCell.h
================================================
//
//  SWFormBaseCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

@class SelwynExpandableTextView;

/**
 SWFormBaseCell 表单条目基类,所有表单条目都继承于BaseCell
 */
@interface SWFormBaseCell : UITableViewCell

@property (nonatomic, strong) SelwynExpandableTextView *expandableTextView;

/**
 表单标题
 */
@property (nonatomic, strong) UILabel *titleLabel;

/**
 表单条目所在的tableView
 */
@property (nonatomic, weak) UITableView *expandableTableView;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormBaseCell.m
================================================
//
//  SWFormBaseCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"

@interface SWFormBaseCell()<UITextViewDelegate>
@end

@implementation SWFormBaseCell

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc]init];
        _titleLabel.font = [UIFont systemFontOfSize:SW_TitleFont];
        _titleLabel.adjustsFontSizeToFitWidth = YES;
        [self.contentView addSubview:_titleLabel];
    }
    return _titleLabel;
}

- (SelwynExpandableTextView *)expandableTextView {
    if (!_expandableTextView) {
        _expandableTextView = [[SelwynExpandableTextView alloc]init];
        _expandableTextView.delegate = self;
        _expandableTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
        _expandableTextView.textContainer.lineFragmentPadding = 0;
        _expandableTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        _expandableTextView.backgroundColor = [UIColor clearColor];
        _expandableTextView.font = [UIFont systemFontOfSize:SW_InfoFont];
        _expandableTextView.scrollEnabled = NO;
        _expandableTextView.autocorrectionType = UITextAutocorrectionTypeNo;
        _expandableTextView.layoutManager.allowsNonContiguousLayout = NO;
        _expandableTextView.showsVerticalScrollIndicator = NO;
        _expandableTextView.showsHorizontalScrollIndicator = NO;
        [self.contentView addSubview:_expandableTextView];
    }
    return _expandableTextView;
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormImageCell.h
================================================
//
//  SWFormImageCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 图片选择或删除block

 @param images 当前已存在图片数组
 */
typedef void(^SWImageCompletion)(NSArray *images);

/**
 SWFormImageCell 表单图片选择条目
 */
@interface SWFormImageCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;
@property (nonatomic, copy) SWImageCompletion imageCompletion;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormImageCell)

- (SWFormImageCell *)imageCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormImageCell.m
================================================
//
//  SWFormImageCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell.h"
#import "SWFormItem.h"
#import "SWImageCollectionCell.h"
#import "SWFormCompat.h"
#import "SWFormImageCell+ImageHandle.h"

static NSString *image_cell_id = @"image_cell_id";
static CGFloat const SW_ImageWidth = 80.0f;
static NSInteger const SW_RowImageCount = 4;

@interface SWFormImageCell()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

@property (nonatomic, strong) UIImageView *icon;
@property (nonatomic, strong) UICollectionView *imageCollection;
@property (nonatomic, strong) UIButton *selectBtn;

@property (nonatomic, strong) NSMutableArray *mutableImages;

@end

@implementation SWFormImageCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.selectBtn.enabled = item.editable;
    self.mutableImages = [NSMutableArray arrayWithArray:item.images];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_TitleWidth, SW_TitleHeight);
    self.icon.frame = CGRectMake(self.frame.size.width - 38, SW_EdgeMargin + 2, 23, SW_TitleHeight - 4);
    self.selectBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.item.defaultHeight);
    
    if (self.mutableImages.count > 0) {
        self.imageCollection.frame = CGRectMake(0, self.item.defaultHeight, self.frame.size.width, self.frame.size.height - self.item.defaultHeight);
        self.imageCollection.hidden = NO;
        [self.imageCollection reloadData];
    }
    else {
        self.imageCollection.frame = CGRectZero;
        self.imageCollection.hidden = YES;
    }
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.mutableImages.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    SWImageCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:image_cell_id forIndexPath:indexPath];
    cell.image = self.mutableImages[indexPath.item];
    cell.editable = self.item.editable;
    cell.deleteImageCompletion = ^{
        [self.mutableImages removeObjectAtIndex:indexPath.item];
        [self sw_reloadData];
    };
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [self sw_photoBrowserWithImages:self.mutableImages currentIndex:indexPath.item];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(SW_ImageWidth, SW_ImageWidth);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 10, 10, 10);
}

- (void)selectImageAction {
    if (self.mutableImages.count >= self.item.maxImageCount) {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:[NSString stringWithFormat:@"最多选择%ld张附件",(long)self.item.maxImageCount] message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alertView show];
        return;
    }
    
    __weak typeof(self) weakSelf = self;
    // 选择图片事件函数
    [self sw_selectImageWithMaxImages:self.item.maxImageCount currentImages:self.mutableImages.count completion:^(NSArray *selectImages) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf.mutableImages addObjectsFromArray:selectImages];
        [strongSelf sw_reloadData];
    }];
}

#pragma mark -- 刷新当前图片数据
- (void)sw_reloadData {
    if (self.imageCompletion) {
        self.imageCompletion(self.mutableImages);
    }
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    NSInteger rows = item.images.count%SW_RowImageCount > 0 ? item.images.count/SW_RowImageCount+1:item.images.count/SW_RowImageCount;
    return item.images.count > 0 ? item.defaultHeight + 10*(rows+1) + rows*SW_ImageWidth:item.defaultHeight;
}

#pragma mark -- 懒加载实现
- (NSMutableArray *)mutableImages {
    if (!_mutableImages) {
        _mutableImages = [[NSMutableArray alloc]init];
    }
    return _mutableImages;
}

- (UICollectionView *)imageCollection {
    if (!_imageCollection) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
        layout.minimumInteritemSpacing = 10;
        layout.minimumLineSpacing = 10;
        _imageCollection = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
        _imageCollection.backgroundColor = [UIColor whiteColor];
        _imageCollection.delegate = self;
        _imageCollection.dataSource = self;
        _imageCollection.hidden = YES;
        _imageCollection.scrollEnabled = NO;
        _imageCollection.showsVerticalScrollIndicator = NO;
        _imageCollection.showsHorizontalScrollIndicator = NO;
        [_imageCollection registerClass:[SWImageCollectionCell class] forCellWithReuseIdentifier:image_cell_id];
        [self.contentView addSubview:_imageCollection];
    }
    return _imageCollection;
}

- (UIButton *)selectBtn {
    if (!_selectBtn) {
        _selectBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_selectBtn addTarget:self action:@selector(selectImageAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:_selectBtn];
    }
    return _selectBtn;
}

- (UIImageView *)icon {
    if (!_icon) {
        _icon = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SWForm.bundle/SWImageIcon"]];
        [self.contentView addSubview:_icon];
    }
    return _icon;
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


@implementation UITableView (SWFormImageCell)

- (SWFormImageCell *)imageCellWithId:(NSString *)cellId
{
    SWFormImageCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (cell == nil) {
        cell = [[SWFormImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}
@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormInputCell.h
================================================
//
//  SWFormInputCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 输入内容block

 @param text 当前输入内容
 */
typedef void(^SWInputCompletion)(NSString *text);

/**
 SWFormInputCell 表单输入条目,标题居左,详情居右,支持单行与多行输入
 */
@interface SWFormInputCell : SWFormBaseCell

/**
 条目配置参数
 */
@property (nonatomic, strong) SWFormItem *item;

@property (nonatomic, copy) SWInputCompletion inputCompletion;

/**
 获取条目高度
 */
+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


/**
 SWFormInputCell 对于UITableView的分类,实现SWFormInputCell初始化
 */
@interface UITableView (SWFormInputCell)

- (SWFormInputCell *)inputCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormInputCell.m
================================================
//
//  SWFormInputCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormInputCell.h"
#import "SWFormItem.h"
#import "SWFormCompat.h"
#import "SelwynExpandableTextView.h"
#import "UITextView+TextLimit.h"
#import "NSString+SWForm.h"

@interface SWFormInputCell()<UITextViewDelegate>
@end

@implementation SWFormInputCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.expandableTextView.keyboardType = item.keyboardType;
    self.accessoryType = UITableViewCellAccessoryNone;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_TitleWidth, SW_TitleHeight);
    
    CGFloat newHeight = [SWFormInputCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_TitleWidth + 2*SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - (SW_TitleWidth + 3*SW_EdgeMargin), newHeight - 2*SW_EdgeMargin);
}

- (void)textViewDidBeginEditing:(UITextView *)textView {
    self.expandableTextView.text = self.item.info;
}

- (void)textViewDidChange:(UITextView *)textView {
    if (self.item.maxInputLength > 0) {
        // 限制输入字数
        [self.expandableTextView textLimitWithMaxLength:self.item.maxInputLength];
    }
    if (self.inputCompletion) {
        self.inputCompletion(self.expandableTextView.text);
    }
    // 防止输入时表单因刷新动画抖动
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

- (void)textViewDidEndEditing:(UITextView *)textView {
    self.expandableTextView.text = [self.item.info addUnit:self.item.unit];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - (SW_TitleWidth + 3*SW_EdgeMargin), MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + 2*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end


@implementation UITableView (SWFormInputCell)

- (SWFormInputCell *)inputCellWithId:(NSString *)cellId
{
    SWFormInputCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormInputCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormSelectCell.h
================================================
//
//  SWFormSelectCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

/**
 SWFormSelectCell 表单选择条目
 */
@interface SWFormSelectCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormSelectCell)

- (SWFormSelectCell *)selectCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormSelectCell.m
================================================
//
//  SWFormSelectCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormSelectCell.h"
#import "SWFormItem.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"
#import "NSString+SWForm.h"

@implementation SWFormSelectCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, (self.item.defaultHeight - SW_TitleHeight)/2, SW_TitleWidth, SW_TitleHeight);
    self.expandableTextView.userInteractionEnabled = NO;
    
    CGFloat newHeight = [SWFormSelectCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_TitleWidth + 2*SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - (SW_TitleWidth + 2*SW_EdgeMargin + 30),  newHeight - 2*SW_EdgeMargin);
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - SW_TitleWidth - 2*SW_EdgeMargin - 30, MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + 2*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end

@implementation UITableView (SWFormSelectCell)

- (SWFormSelectCell *)selectCellWithId:(NSString *)cellId
{
    SWFormSelectCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormSelectCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormTextViewInputCell.h
================================================
//
//  SWFormTextViewInputCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseCell.h"

@class SWFormItem;

typedef void(^SWTextViewInputCompletion)(NSString *text);

/**
 SWFormTextViewInputCell 表单输入条目,标题居上,详情居下,支持单行与多行输入
 */
@interface SWFormTextViewInputCell : SWFormBaseCell

@property (nonatomic, strong) SWFormItem *item;
@property (nonatomic, copy) SWTextViewInputCompletion textViewInputCompletion;

+ (CGFloat)heightWithItem:(SWFormItem *)item;

@end


@interface UITableView (SWFormTextViewInputCell)

- (SWFormTextViewInputCell *)textViewInputCellWithId:(NSString *)cellId;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWFormTextViewInputCell.m
================================================
//
//  SWFormTextViewInputCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormTextViewInputCell.h"
#import "SWFormItem.h"
#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"
#import "UITextView+TextLimit.h"
#import "NSString+SWForm.h"

@interface SWFormTextViewInputCell()<UITextViewDelegate>
@end

@implementation SWFormTextViewInputCell

- (void)setItem:(SWFormItem *)item {
    _item = item;
    self.titleLabel.attributedText = item.attributedTitle;
    self.expandableTextView.text = [item.info addUnit:item.unit];
    self.expandableTextView.attributedPlaceholder = item.attributedPlaceholder;
    self.expandableTextView.editable = item.editable;
    self.expandableTextView.keyboardType = item.keyboardType;
    self.expandableTextView.currentLength = item.info.length;
    self.expandableTextView.showLength = item.showLength;
    self.expandableTextView.maxLength = item.maxInputLength;
    self.accessoryType = UITableViewCellAccessoryNone;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.titleLabel.frame = CGRectMake(SW_EdgeMargin, SW_EdgeMargin, SW_SCRREN_WIDTH - 2*SW_EdgeMargin, SW_TitleHeight);
    
    //重置 expandableTextView 内边距
    self.expandableTextView.textContainerInset = UIEdgeInsetsMake(SW_EdgeMargin, SW_EdgeMargin, SW_EdgeMargin, SW_EdgeMargin);
    self.expandableTextView.backgroundColor = SW_TEXTVIEW_BACKGROUNDCOLOR;
    
    CGFloat newHeight = [SWFormTextViewInputCell heightWithItem:self.item];
    self.expandableTextView.frame = CGRectMake(SW_EdgeMargin, CGRectGetMaxY(self.titleLabel.frame) + SW_EdgeMargin, SW_SCRREN_WIDTH - 2*SW_EdgeMargin, newHeight - 3*SW_EdgeMargin - SW_TitleHeight);
}

- (void)textViewDidBeginEditing:(UITextView *)textView {
    self.expandableTextView.text = self.item.info;
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
}

- (void)textViewDidChange:(UITextView *)textView {
    if (self.item.maxInputLength > 0) {
        [self.expandableTextView textLimitWithMaxLength:self.item.maxInputLength];
    }
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
    if (self.textViewInputCompletion) {
        self.textViewInputCompletion(self.expandableTextView.text);
    }
    [UIView performWithoutAnimation:^{
        [self.expandableTableView beginUpdates];
        [self.expandableTableView endUpdates];
    }];
}

- (void)textViewDidEndEditing:(UITextView *)textView {
    
    self.expandableTextView.currentLength = self.expandableTextView.text.length;
    self.expandableTextView.text = [self.item.info addUnit:self.item.unit];
}

+ (CGFloat)heightWithItem:(SWFormItem *)item {
    CGFloat infoHeight = [item.info sizeWithFontSize:SW_InfoFont maxSize:CGSizeMake(SW_SCRREN_WIDTH - 4*SW_EdgeMargin, MAXFLOAT)].height;
    return MAX(item.defaultHeight, infoHeight + SW_TitleHeight + 5*SW_EdgeMargin);
}

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end

@implementation UITableView (SWFormTextViewInputCell)

- (SWFormTextViewInputCell *)textViewInputCellWithId:(NSString *)cellId
{
    SWFormTextViewInputCell *cell = [self dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[SWFormTextViewInputCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.expandableTableView = self;
    }
    return cell;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWImageCollectionCell.h
================================================
//
//  SWImageCollectionCell.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef void(^SWDeleteImageCompletion)(void);

/**
 表单图片条目图片展示
 */
@interface SWImageCollectionCell : UICollectionViewCell

/**
 当前图片删除操作block
 */
@property (nonatomic, copy) SWDeleteImageCompletion deleteImageCompletion;

/**
 当前图片,支持UIImage、NSURL、NSString(图片URLString)类型
 */
@property (nonatomic, strong) id image;

/**
 当前图片是否可编辑
 */
@property (nonatomic, assign) BOOL editable;

@end


================================================
FILE: SWFormExample/SWForm/SWFormCell/SWImageCollectionCell.m
================================================
//
//  SWImageCollectionCell.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWImageCollectionCell.h"
#import "SWFormCompat.h"
#import "UIImageView+FormImage.h"
/**
 删除图标宽高
 */
static CGFloat const SWDeleteIconWidth = 22.0f;
/**
 删除按钮宽高,大于图标宽高,增强交互性
 */
static CGFloat const SWDeleteBtnWidth = 25.0f;

@interface SWImageCollectionCell()

@property (nonatomic, strong) UIImageView *currentImageView;
@property (nonatomic, strong) UIImageView *deleteIcon;
@property (nonatomic, strong) UIButton *deleteBtn;

@end

@implementation SWImageCollectionCell

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        
        self.currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, SWDeleteIconWidth/2, self.frame.size.width - SWDeleteIconWidth/2, self.frame.size.height - SWDeleteIconWidth/2)];
        self.currentImageView.clipsToBounds = YES;
        self.currentImageView.contentMode = UIViewContentModeScaleAspectFill;
        [self.contentView addSubview:self.currentImageView];
        
        self.deleteIcon = [[UIImageView alloc]initWithFrame:CGRectMake(self.frame.size.width - SWDeleteIconWidth, 0, SWDeleteIconWidth, SWDeleteIconWidth)];
        self.deleteIcon.image = [UIImage imageNamed:SW_DeleteIcon];
        [self.contentView addSubview:self.deleteIcon];
        
        self.deleteBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        self.deleteBtn.frame = CGRectMake(self.frame.size.width - SWDeleteBtnWidth, 0, SWDeleteBtnWidth, SWDeleteBtnWidth);
        [self.deleteBtn addTarget:self action:@selector(deleteAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.deleteBtn];
    }
    return self;
}

- (void)deleteAction {
    if (self.deleteImageCompletion) {
        self.deleteImageCompletion();
    }
}

- (void)setEditable:(BOOL)editable {
    _editable = editable;
    self.deleteBtn.hidden = !editable;
    self.deleteIcon.hidden = !editable;
}

#pragma mark -- 设置当前图片
- (void)setImage:(id)image {
    _image = image;
    if ([image isKindOfClass:[UIImage class]]) {
        self.currentImageView.image = image;
    }
    else if ([image isKindOfClass:[NSURL class]]) {
        [self.currentImageView sw_setImageItemWithUrl:image];
    }
    else if ([image isKindOfClass:[NSString class]]) {
        [self.currentImageView sw_setImageItemWithUrl:[NSURL URLWithString:image]];
    }
    else {
        self.currentImageView.image = [UIImage imageNamed:SW_PlaceholderImage];
    }
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormHandler.h
================================================
//
//  SWFormHandler.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 SWFormHandler 数据校验文件,包含相机权限、相册权限以及表单空数据校验
 */
@interface SWFormHandler : NSObject

/**
 必选(必填)数据空数据校验,可根据需求定制

 @param datas 表单数据源
 @param success 必选(必填)数据全部校验成功
 @param failure 必选(必填)数据某一项校验失败
 */
+ (void)sw_checkFormNullDataWithWithDatas:(NSArray *)datas success:(void(^)(void))success failure:(void(^)(NSString *error))failure;

/**
 校验是否有相机权限
 */
+ (void)sw_checkCameraAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;

/**
 校验是否有相册权限
 */
+ (void)sw_checkAlbumAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted;

@end


================================================
FILE: SWFormExample/SWForm/SWFormHandler.m
================================================
//
//  SWFormHandler.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/30.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormHandler.h"
#import <Photos/PHPhotoLibrary.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <UIKit/UIKit.h>
#import "SWFormItem.h"
#import "SWFormSectionItem.h"

@implementation SWFormHandler

+ (void)sw_checkFormNullDataWithWithDatas:(NSArray *)datas success:(void(^)(void))success failure:(void(^)(NSString *error))failure {
    for (int sec = 0; sec < datas.count; sec++) {
        SWFormSectionItem *sectionItem = datas[sec];
        for (int row = 0; row < sectionItem.items.count; row++) {
            SWFormItem *rowItem = sectionItem.items[row];
            if (rowItem.required) {
                if (rowItem.itemType == SWFormItemTypeInput || rowItem.itemType == SWFormItemTypeTextViewInput) {
                    if (!rowItem.info || [rowItem.info isEqualToString:@""]) {
                        failure([NSString stringWithFormat:@"请输入%@", rowItem.title]);
                        return;
                    }
                }
                else if (rowItem.itemType == SWFormItemTypeSelect) {
                    if (!rowItem.info || [rowItem.info isEqualToString:@""]) {
                        failure([NSString stringWithFormat:@"请选择%@", rowItem.title]);
                        return;
                    }
                }
                else if (rowItem.itemType == SWFormItemTypeImage) {
                    if (!rowItem.images || rowItem.images.count == 0) {
                        failure([NSString stringWithFormat:@"请选择%@", rowItem.title]);
                        return;
                    }
                }
            }
        }
    }
    success();
}

#pragma mark -- 校验相机相册权限
+ (void)sw_checkCameraAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted
{
    AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (videoAuthStatus) {
            // 已授权
        case AVAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case AVAuthorizationStatusNotDetermined:
        {
            // 提示用户授权
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                permissionGranted(granted);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相机”选项中,允许访问你的相机" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
}

+ (void)sw_checkAlbumAuthorizationStatusWithGrand:(void(^)(BOOL granted))permissionGranted {
    
    PHAuthorizationStatus photoAuthStatus = [PHPhotoLibrary authorizationStatus];
    switch (photoAuthStatus) {
            // 已授权
        case PHAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case PHAuthorizationStatusNotDetermined:
        {
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                permissionGranted(status == PHAuthorizationStatusAuthorized);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case PHAuthorizationStatusRestricted:
        case PHAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相片”选项中,允许访问你的相册" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
    
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormImageCell+ImageHandle.h
================================================
//
//  SWFormImageCell+ImageHandle.h
//  SWFormDemo
//
//  Created by zijin on 2018/6/1.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell.h"

@interface SWFormImageCell (ImageHandle)

/**
 选择图片数据回调
 
 @param maxImages 最大可选择图片数
 @param currentImages 当前选择图片数
 @param completion 选择图片数组回调
 */
- (void)sw_selectImageWithMaxImages:(NSInteger)maxImages currentImages:(NSInteger)currentImages completion:(void(^)(NSArray *selectImages))completion;

/**
 图片浏览

 @param images 图片数组
 @param currentIndex 当前浏览的index
 */
- (void)sw_photoBrowserWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex;


@end


================================================
FILE: SWFormExample/SWForm/SWFormImageCell+ImageHandle.m
================================================
//
//  SWFormImageCell+ImageHandle.m
//  SWFormDemo
//
//  Created by zijin on 2018/6/1.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormImageCell+ImageHandle.h"
#import "SWFormHandler.h"
#import "TZImagePickerController.h"
#import "objc/runtime.h"
#import "MWPhotoBrowser.h"
#import <UIKit/UIKit.h>

static char SW_MAXIMAGECOUNT;
static char SW_CURRENTIMAGECOUNT;
static char SW_SELECTCOMPLETION;
static char SW_BROWSERPHOTOS;

typedef void(^SWSelectImageCompletion)(NSArray *images);

@interface UITableViewCell() <UIActionSheetDelegate, TZImagePickerControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, MWPhotoBrowserDelegate>
@end

@implementation SWFormImageCell (ImageHandle)

- (void)sw_selectImageWithMaxImages:(NSInteger)maxImages currentImages:(NSInteger)currentImages completion:(void(^)(NSArray *selectImages))completion {
    
    [self sw_setMaxImagesCount:maxImages];
    [self sw_setCurrentImagesCount:currentImages];
    
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照",@"从相册选取", nil];
    actionSheet.tag = 10;
    [actionSheet showInView:self.superview];
    
    [self sw_setSelectImagesCompletion:completion];
}

#pragma mark -- MWPhotoBrowserDelegate
- (void)sw_photoBrowserWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex {
    NSMutableArray *photos = [NSMutableArray array];
    for (int i = 0; i < images.count; i++) {
        id object = images[i];
        MWPhoto *photo;
        if ([object isKindOfClass:[UIImage class]]) {
            photo = [MWPhoto photoWithImage:object];
        }
        else if ([object isKindOfClass:[NSURL class]]) {
            photo = [MWPhoto photoWithURL:object];
        }
        else if ([object isKindOfClass:[NSString class]]) {
            photo = [MWPhoto photoWithURL:[NSURL URLWithString:object]];
        }
        if (photo) {
            [photos addObject:photo];
        }
    }
    [self sw_setBrowserPhotos:photos];
    
    MWPhotoBrowser *photoBrowser = [[MWPhotoBrowser alloc] initWithDelegate:self];
    photoBrowser.displayActionButton = YES;
    photoBrowser.displayNavArrows = YES;
    photoBrowser.displaySelectionButtons = NO;
    photoBrowser.alwaysShowControls = NO;
    photoBrowser.zoomPhotosToFill = YES;
    photoBrowser.enableGrid = NO;
    photoBrowser.startOnGrid = NO;
    [photoBrowser setCurrentPhotoIndex:currentIndex];
    
    UINavigationController *photoNavigationController = [[UINavigationController alloc] initWithRootViewController:photoBrowser];
    photoNavigationController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [[self superViewController:self] presentViewController:photoNavigationController animated:YES completion:nil];
}

- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
    return [self sw_browserPhotos].count;
}

- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index
{
    if (index < [self sw_browserPhotos].count) {
        return [[self sw_browserPhotos] objectAtIndex:index];
    }
    return nil;
}

#pragma mark -- 从相册选择图片或者拍照
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (actionSheet.tag == 10) {
        switch (buttonIndex) {
            case 0:
            {
                [self takePhoto];
            }
                break;
            case 1:
            {
                [self localPhoto];
            }
                break;
            default:
                break;
        }
    }
}

/**
 拍照
 */
- (void)takePhoto {
    [SWFormHandler sw_checkCameraAuthorizationStatusWithGrand:^(BOOL granted) {
        if (granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self selectFromTakePhoto];
            });
        }
    }];
}

/**
 本地相册选择
 */
- (void)localPhoto {
    [SWFormHandler sw_checkAlbumAuthorizationStatusWithGrand:^(BOOL granted) {
        if (granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self selectFromLocalPhoto];
            });
        }
    }];
}

- (void)selectFromTakePhoto {
    if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.delegate = self;
        picker.allowsEditing = YES;
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        [[self superViewController:self] presentViewController:picker animated:YES completion:nil];
    }else
    {
        NSLog(@"无法打开照相机,请检查后重试");
    }
}

/** 选取本地图片 */
- (void)selectFromLocalPhoto{
    TZImagePickerController  *imagePickerVC = [[TZImagePickerController alloc] initWithMaxImagesCount:([self sw_maxImagesCount] - [self sw_currentImagesCount]) delegate:self];
    imagePickerVC.allowPickingVideo = NO;
    if ([self superViewController:self]) {
        [[self superViewController:self] presentViewController:imagePickerVC animated:YES completion:nil];
    }
}

#pragma mark -- UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    UIImage *selectImage = [info valueForKey:UIImagePickerControllerOriginalImage];
    SWSelectImageCompletion completion = [self sw_selectImagesCompletion];
    if (completion) {
        completion(@[selectImage]);
    }
    [picker dismissViewControllerAnimated:YES completion:nil];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark -- TZImagePickerControllerDelegate
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto {
    SWSelectImageCompletion completion = [self sw_selectImagesCompletion];
    if (completion) {
        completion(photos);
    }
}

#pragma mark -- 设置图片选择block
- (void)sw_setSelectImagesCompletion:(SWSelectImageCompletion)completion {
    objc_setAssociatedObject(self, &SW_SELECTCOMPLETION, completion, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (SWSelectImageCompletion)sw_selectImagesCompletion {
    return objc_getAssociatedObject(self, &SW_SELECTCOMPLETION);
}

#pragma mark -- 设置当前获取的图片
- (void)sw_setBrowserPhotos:(NSArray *)photos {
    objc_setAssociatedObject(self, &SW_BROWSERPHOTOS, photos, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSArray *)sw_browserPhotos {
    return objc_getAssociatedObject(self, &SW_BROWSERPHOTOS);
}

#pragma mark -- 设置最大图片数
- (void)sw_setMaxImagesCount:(NSInteger)count {
    objc_setAssociatedObject(self, &SW_MAXIMAGECOUNT, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)sw_maxImagesCount {
    return [objc_getAssociatedObject(self, &SW_MAXIMAGECOUNT) integerValue];
}

#pragma mark -- 设置当前图片数
- (void)sw_setCurrentImagesCount:(NSInteger)count {
    objc_setAssociatedObject(self, &SW_CURRENTIMAGECOUNT, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)sw_currentImagesCount {
    return [objc_getAssociatedObject(self, &SW_CURRENTIMAGECOUNT) integerValue];
}

#pragma mark -- 获取当前View所在的ViewController
- (UIViewController *)superViewController:(UIView *)view{
    UIResponder *responder = view;
    while ((responder = [responder nextResponder]))
        if ([responder isKindOfClass: [UIViewController class]])
            return (UIViewController *)responder;
    
    return nil;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormItem/SWFormItem.h
================================================
//
//  SWFormItem.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class SWFormItem;

typedef NS_ENUM(NSInteger, SWFormItemType) {
    /**
     表单条目可单行或多行输入(标题居左)
     */
    SWFormItemTypeInput = 0,
    /**
     表单条目可选择(标题居左)
     */
    SWFormItemTypeSelect = 1,
    /**
     表单条目可多行输入(标题居上)
     */
    SWFormItemTypeTextViewInput = 2,
    /**
     表单条目包含图片选择
     */
    SWFormItemTypeImage = 3,
};

typedef NS_ENUM(NSInteger, SWFormItemUnitType) {
    SWFormItemUnitTypeNone = 0, // 无单位
    SWFormItemUnitTypeYuan, // 元
    SWFormItemUnitTypeYear, // 年
    SWFormItemUnitTypeMillion, // 万元
    SWFormItemUnitTypeCustom, // 自定义单位
};

typedef void(^SWItemSelectCompletion)(SWFormItem *item);

/**
 SWFormItem 主要对表单条目提供动态配置属性
 */
@interface SWFormItem : NSObject

/**
 表单条目缺省高度,缺省值为44.0f, 可根据需求设置
 */
@property (nonatomic, assign) CGFloat defaultHeight;

/**
 表单条目类型
 */
@property (nonatomic, assign) SWFormItemType itemType;

/**
 表单条目标题,表单标题为单行显示,尽可能简短,若标题太长,会牺牲字体大小以达到显示完全的效果
 */
@property (nonatomic, copy, nonnull) NSString *title;
@property (nonatomic, strong, nonnull) NSAttributedString *attributedTitle;

/**
 表单条目详情
 */
@property (nonatomic, copy, nullable) NSString *info;

/**
 表单条目占位字符
 */
@property (nonatomic, copy, nullable) NSString *placeholder;
@property (nonatomic, strong, nullable) NSAttributedString *attributedPlaceholder;

/**
 是否显示表单条目占位字符 YES:显示 NO:不显示 --- 新增 default is YES;详情 default is NO
 */
@property (nonatomic, assign) BOOL showPlaceholder;

/**
 图片附件条目图片数组,支持UIImage、NSURL、NSString(图片URLString)类型元素
 */
@property (nonatomic, strong, nullable) NSArray *images;

/**
 images 图片数组中类型筛选出为UIImage的数组子集,以实现图片上传筛选
 */
@property (nonatomic, strong, readonly) NSArray *selectImages;

/**
 表单条目键盘类型
 */
@property (nonatomic, assign) UIKeyboardType keyboardType;

/**
 表单条目是否可编辑 YES:可编辑 NO:不可编辑
 */
@property (nonatomic, assign) BOOL editable;

/**
 表单条目是否必填(必选) YES:必填(必选) NO:可填(可选)
 */
@property (nonatomic, assign) BOOL required;

/**
 SWFormItemTypeInput 以及 SWFormItemTypeTextViewInput 类别中表示最大输入字数
 0 表示无限制
 */
@property (nonatomic, assign) NSUInteger maxInputLength;

/**
 SWFormItemTypeImage 类别中表示最大选择图片数
 */
@property (nonatomic, assign) NSUInteger maxImageCount;

/**
 表单条目点击选择事件block
 */
@property (nonatomic, copy, nullable) SWItemSelectCompletion itemSelectCompletion;

/**
 条目附带单位
 */
@property (nonatomic, copy, nullable) NSString *unit;

/**
 表单条目单位类别
 */
@property (nonatomic, assign) SWFormItemUnitType itemUnitType;

/**
 是否显示当前字数
 只在 SWFormItemTypeTextViewInput 类型下有效,若无最大字数限制,则只显示字数; 若有字数限制,则显示 "当前字数/最大字数"
 */
@property (nonatomic, assign) BOOL showLength;

@end

/**
 SWFormItem_Add 快捷构建新增表单条目

 @param title 标题
 @param info 详情
 @param itemType 条目类别
 @param editable 是否可编辑
 @param required 是否必填
 @param keyboardType 键盘类别
 */
FOUNDATION_EXPORT SWFormItem *SWFormItem_Add(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType, BOOL editable, BOOL required, UIKeyboardType keyboardType);

/**
 SWFormItem_Info 快捷构建详情表单条目
 */
FOUNDATION_EXPORT SWFormItem *SWFormItem_Info(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType);


================================================
FILE: SWFormExample/SWForm/SWFormItem/SWFormItem.m
================================================
//
//  SWFormItem.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormItem.h"
#import "SWFormCompat.h"

static NSString *const SWUnitYuan = @"元";
static NSString *const SWUnitYear = @"年";
static NSString *const SWUnitMillion = @"万元";

@interface SWFormItem()

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType;

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType;

@end

inline SWFormItem *SWFormItem_Add(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType, BOOL editable, BOOL required, UIKeyboardType keyboardType) {
    return [SWFormItem sw_itemWithTitle:title info:info itemType:itemType editable:editable required:required keyboardType:keyboardType];
}

inline SWFormItem *SWFormItem_Info(NSString * _Nonnull title, NSString * _Nullable info, SWFormItemType itemType) {
    return [SWFormItem sw_itemWithTitle:title info:info itemType:itemType];
}

@implementation SWFormItem

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType {
    return [[self alloc]initWithTitle:title info:info itemType:itemType editable:editable required:required keyboardType:keyboardType images:nil showPlaceholder:YES];
}

+ (instancetype)sw_itemWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType {
    return [[self alloc]initWithTitle:title info:info itemType:itemType editable:NO required:NO keyboardType:UIKeyboardTypeDefault images:nil showPlaceholder:NO];
}

- (instancetype)initWithTitle:(NSString *)title info:(NSString *)info itemType:(SWFormItemType)itemType editable:(BOOL)editable required:(BOOL)required keyboardType:(UIKeyboardType)keyboardType images:(NSArray *)images showPlaceholder:(BOOL)showPlaceholder{
    self = [super init];
    if (self) {
        self.itemUnitType = SWFormItemUnitTypeNone;
        self.maxInputLength = SW_GlobalMaxInputLength;
        self.maxImageCount = SW_GlobalMaxImages;
        self.title = title;
        self.info = info;
        self.itemType = itemType;
        self.editable = editable;
        self.required = required;
        self.keyboardType = keyboardType;
        self.images = images;
        self.showPlaceholder = showPlaceholder;
        [self sw_setDefaultHeight:itemType];
        [self sw_setPlaceholderWithShow:showPlaceholder itemType:itemType];
        [self sw_setAttributedTitleWithRequired:required title:title itemType:itemType];
    }
    return self;
}

#pragma mark -- 根据表单条目类型设置条目缺省高度
- (void)sw_setDefaultHeight:(SWFormItemType)itemType {
    self.defaultHeight = itemType == SWFormItemTypeTextViewInput ? SW_DefaultTextViewItemHeight:SW_DefaultItemHeight;
}

#pragma mark -- 设置是否显示输入框占位字符
- (void)sw_setPlaceholderWithShow:(BOOL)show itemType:(SWFormItemType)itemType {
    if (!show) {
        self.placeholder = @"";
        return;
    }
    switch (itemType) {
        case SWFormItemTypeInput:
        case SWFormItemTypeTextViewInput:
        {
            self.placeholder = @"请输入";
        }
            break;
        case SWFormItemTypeSelect:
        {
            self.placeholder = @"请选择";
        }
            break;
        default:
            self.placeholder = @"";
            break;
    }
}

#pragma mark -- 设置标题显示
- (void)sw_setAttributedTitleWithRequired:(BOOL)required title:(NSString *)title itemType:(SWFormItemType)itemType{
    if (required) {
        if (SW_TitleShowType == SWTitleShowTypeDefault) {
            switch (self.itemType) {
                case SWFormItemTypeInput:
                case SWFormItemTypeTextViewInput:
                {
                    title = [NSString stringWithFormat:@"%@(必填)", title];
                }
                    break;
                case SWFormItemTypeSelect:
                case SWFormItemTypeImage:
                {
                    title = [NSString stringWithFormat:@"%@(必选)", title];
                }
                    break;
                default:
                    break;
            }
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarFront) {
            title = [NSString stringWithFormat:@"*%@", title];
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarBack) {
            title = [NSString stringWithFormat:@"%@*", title];
        }
    }
    
    NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc]initWithString:title attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:SW_TitleFont], NSForegroundColorAttributeName:SW_TITLECOLOR}];
    
    if (required) {
        if (SW_TitleShowType == SWTitleShowTypeRedStarFront) {
            [attributedTitle addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
        }
        else if (SW_TitleShowType == SWTitleShowTypeRedStarBack) {
            [attributedTitle addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(title.length - 1, 1)];
        }
    }
    _attributedTitle = attributedTitle;
}

#pragma mark -- 重写get方法
- (NSArray *)selectImages {
    NSMutableArray *tempImages = [NSMutableArray array];
    for (id temp in self.images) {
        if ([temp isKindOfClass:[UIImage class]]) {
            [tempImages addObject:temp];
        }
    }
    return tempImages;
}

#pragma mark -- 重写属性set方法,防止单独改变属性无响应效果
/**
 设置表单条目附带单位
 */
- (void)setItemUnitType:(SWFormItemUnitType)itemUnitType {
    NSString *tempUnit = self.unit ?: @"";
    switch (itemUnitType) {
        case SWFormItemUnitTypeNone:
        {
            tempUnit = @"";
        }
            break;
        case SWFormItemUnitTypeYuan:
        {
            tempUnit = SWUnitYuan;
        }
            break;
        case SWFormItemUnitTypeYear:
        {
            tempUnit = SWUnitYear;
        }
            break;
        case SWFormItemUnitTypeMillion:
        {
            tempUnit = SWUnitMillion;
        }
        default:
            break;
    }
    _unit = tempUnit;
}

/**
 根据单位设置单元格单位类别,防止单位与单元格式不一致
 */
- (void)setUnit:(NSString *)unit {
    _unit = unit;
    if ([unit isEqualToString:@""]) {
        _itemUnitType = SWFormItemUnitTypeNone;
    }
    else if (unit == SWUnitYuan) {
        _itemUnitType = SWFormItemUnitTypeYuan;
    }
    else if (unit == SWUnitYear) {
        _itemUnitType = SWFormItemUnitTypeYear;
    }
    else if (unit == SWUnitMillion) {
        _itemUnitType = SWFormItemUnitTypeMillion;
    }
    else {
        _itemUnitType = SWFormItemUnitTypeCustom;
    }
}

- (void)setImages:(NSArray *)images {
    _images = images;
    [self selectImages];
}

- (void)setTitle:(NSString *)title {
    _title = title;
    [self sw_setAttributedTitleWithRequired:self.required title:title itemType:self.itemType];
}

- (void)setRequired:(BOOL)required {
    _required = required;
    [self sw_setAttributedTitleWithRequired:required title:self.title itemType:self.itemType];
}

- (void)setItemType:(SWFormItemType)itemType {
    _itemType = itemType;
    [self sw_setDefaultHeight:itemType];
    [self sw_setAttributedTitleWithRequired:self.required title:self.title itemType:itemType];
    [self sw_setPlaceholderWithShow:self.showPlaceholder itemType:itemType];
}

- (void)setShowPlaceholder:(BOOL)showPlaceholder {
    _showPlaceholder = showPlaceholder;
    [self sw_setPlaceholderWithShow:showPlaceholder itemType:self.itemType];
}

- (void)setPlaceholder:(NSString *)placeholder {
    _placeholder = placeholder;
    NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc]initWithString:placeholder ?: @"" attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:SW_InfoFont],NSForegroundColorAttributeName:SW_PLACEHOLDERCOLOR}];
    _attributedPlaceholder = attributedPlaceholder;
}

- (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder {
    _attributedPlaceholder = attributedPlaceholder ?: [[NSAttributedString alloc]initWithString:@""];
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormItem/SWFormSectionItem.h
================================================
//
//  SWFormSectionItem.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**
 SWFormSectionItem 主要对表单section条目提供动态配置属性
 */
@interface SWFormSectionItem : NSObject

/**
 表单section包含的条目集合
 */
@property (nonatomic, strong, nonnull) NSArray *items;

/**
 表单section头部高度
 */
@property (nonatomic, assign) CGFloat headerHeight;

/**
 表单section尾部高度
 */
@property (nonatomic, assign) CGFloat footerHeight;

/**
 表单section头部视图
 */
@property (nonatomic, strong, nullable) UIView *headerView;

/**
 表单section尾部视图
 */
@property (nonatomic, strong, nullable) UIView *footerView;

@end

/**
 SWSectionItem 快捷构建表单section条目

 @param items 表单section包含的条目集合
 */
FOUNDATION_EXPORT SWFormSectionItem *SWSectionItem(NSArray * _Nonnull items);


================================================
FILE: SWFormExample/SWForm/SWFormItem/SWFormSectionItem.m
================================================
//
//  SWFormSectionItem.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormSectionItem.h"

@interface SWFormSectionItem()

+ (instancetype)sw_sectionItem:(NSArray *)items;

@end

inline SWFormSectionItem *SWSectionItem(NSArray * _Nonnull items) {
    return [SWFormSectionItem sw_sectionItem:items];
}

@implementation SWFormSectionItem

+ (instancetype)sw_sectionItem:(NSArray *)items {
    return [[self alloc]initWithItems:items];
}

- (instancetype)initWithItems:(NSArray *)items {
    self = [super init];
    if (self) {
        self.items = items;
    }
    return self;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/NSString+SWForm.h
================================================
//
//  NSString+SWForm.h
//  SWFormDemo
//
//  Created by zijin on 2018/6/26.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSString (SWForm)

/**
 字符串添加单位

 @param unit 单位
 */
- (NSString *)addUnit:(NSString *)unit;

/**
 获取字符串的Size大小

 @param fontSize 字体大小
 @param maxSize 最大显示Size
 */
- (CGSize)sizeWithFontSize:(CGFloat)fontSize maxSize:(CGSize)maxSize;

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/NSString+SWForm.m
================================================
//
//  NSString+SWForm.m
//  SWFormDemo
//
//  Created by zijin on 2018/6/26.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "NSString+SWForm.h"

@implementation NSString (SWForm)

- (NSString *)addUnit:(NSString *)unit {
    if ([self isEqualToString:@""] || [unit isEqualToString:@""]) {
        return self;
    }
    return [NSString stringWithFormat:@"%@ %@", self, unit];
}

- (CGSize)sizeWithFontSize:(CGFloat)fontSize maxSize:(CGSize)maxSize {
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size;
}

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/SWFormCompat.h
================================================
//
//  SWFormCompat.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

/**
 SWFormCompat 主要配置表单涉及的相关常量参数,可根据需求修改配置
 */
#import <UIKit/UIKit.h>

/**
 必选条目标题呈现形式类别
 */
typedef NS_ENUM(NSInteger, SWTitleShowType) {
    /**
     默认呈现形式,如: 标题(必填)
     */
    SWTitleShowTypeDefault,
    /**
     标题前部加红色*,如: *标题
     */
    SWTitleShowTypeRedStarFront,
    /**
     标题后部加红色*,如: 标题*
     */
    SWTitleShowTypeRedStarBack,
    /**
     仅显示标题
     */
    SWTitleShowTypeOnlyTitle,
};

/**
 表单标题字体大小,缺省为16
 */
extern CGFloat const SW_TitleFont;

/**
 表单详情字体大小,缺省为16
 */
extern CGFloat const SW_InfoFont;

/**
 表单条目边缘距离,缺省为10.0f
 */
extern CGFloat const SW_EdgeMargin;

/**
 表单标题宽度,缺省为100.0f
 */
extern CGFloat const SW_TitleWidth;

/**
 表单标题高度,缺省为24.0f
 */
extern CGFloat const SW_TitleHeight;

/**
 表单条目初始高度,缺省为44.0f,SWFormItemTypeTextViewInput 类型缺省高度为200,为确保显示正常,设置值>= 44
 */
extern CGFloat const SW_DefaultItemHeight;
extern CGFloat const SW_DefaultTextViewItemHeight;

/**
 表单标题显示类别,缺省为 SWTitleShowTypeRedStarFront
 */
extern NSInteger const SW_TitleShowType;

/**
 表单输入字数限制,缺省为200
 0 表示无限制
 */
extern NSUInteger const SW_GlobalMaxInputLength;

/**
 表单选择图片附件数,缺省为6
 */
extern NSUInteger const SW_GlobalMaxImages;

/**
 表单图片条目图片加载失败占位图
 */
extern NSString *const SW_PlaceholderImage;

/**
 表单附件删除图标
 */
extern NSString *const SW_DeleteIcon;

/**
 表单TextView字数提示文字大小
 */
extern CGFloat const SW_LengHintFont;

/**
 表单条目输入框占位符字体颜色
 */
#define SW_PLACEHOLDERCOLOR [UIColor colorWithRed:187/255.0 green:187/255.0 blue:187/255.0 alpha:1/1.0]

/**
 SWFormItemTypeTextViewInput 类别 TextView 背景颜色
 */
#define SW_TEXTVIEW_BACKGROUNDCOLOR [UIColor colorWithRed:250/255.0 green:250/255.0 blue:250/255.0 alpha:1/1.0]
/**
 表单条目标题颜色
 */
#define SW_TITLECOLOR [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1/1.0]

/**
 获取屏幕宽度
 */
#define SW_SCRREN_WIDTH [UIScreen mainScreen].bounds.size.width

/// 弱引用
#define SWWeakSelf __weak typeof(self) weakSelf = self;


================================================
FILE: SWFormExample/SWForm/SWFormManager/SWFormCompat.m
================================================
//
//  SWFormCompat.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormCompat.h"

// 表单标题字体大小
CGFloat const SW_TitleFont = 16.0f;

// 表单详情字体大小
CGFloat const SW_InfoFont = 16.0f;

// 表单条目边缘距离
CGFloat const SW_EdgeMargin = 10.0f;

// 表单标题宽度
CGFloat const SW_TitleWidth = 80.0f;

// 表单标题高度
CGFloat const SW_TitleHeight = 24.0f;

// 表单条目初始高度
CGFloat const SW_DefaultItemHeight = 44.0f;
CGFloat const SW_DefaultTextViewItemHeight = 200.0f;

// 表单标题显示类别
NSInteger const SW_TitleShowType = SWTitleShowTypeRedStarFront;

// 表单输入字数限制
NSUInteger const SW_GlobalMaxInputLength = 200;

// 表单选择图片附件数
NSUInteger const SW_GlobalMaxImages = 6;

// 表单TextView字数提示文字大小
CGFloat const SW_LengHintFont = 12;

// 表单图片条目图片加载失败占位图
NSString *const SW_PlaceholderImage = @"SWForm.bundle/SWPlaceholderIcon";

// 表单附件删除图标
NSString *const SW_DeleteIcon = @"SWForm.bundle/SWDeleteIcon";


================================================
FILE: SWFormExample/SWForm/SWFormManager/SelwynExpandableTextView.h
================================================
//
//  SelwynExpandableTextView.h
//  SelwynFormDemo
//
//  Created by BSW on 2017/6/24.
//  Copyright © 2017年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 SelwynExpandableTextView 可高度自适应的UITextView
 */
@interface SelwynExpandableTextView : UITextView

@property (nonatomic, assign) NSUInteger currentLength;
@property (nonatomic, assign) NSUInteger maxLength;
@property (nonatomic, assign) BOOL showLength;

@property (copy, nonatomic) IBInspectable NSString *placeholder;
@property (copy, nonatomic) NSAttributedString *attributedPlaceholder;

@property (nonatomic) IBInspectable double fadeTime;
@property (retain, nonatomic) UIColor *placeholderTextColor UI_APPEARANCE_SELECTOR;

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/SelwynExpandableTextView.m
================================================
//
//  SelwynExpandableTextView.m
//  SelwynFormDemo
//
//  Created by BSW on 2017/6/24.
//  Copyright © 2017年 selwyn. All rights reserved.
//

#import "SelwynExpandableTextView.h"
#import "SWFormCompat.h"

#define HAS_TEXT_CONTAINER [self respondsToSelector:@selector(textContainer)]
#define HAS_TEXT_CONTAINER_INSETS(x) [(x) respondsToSelector:@selector(textContainerInset)]

@interface SelwynExpandableTextView()
@property (strong, nonatomic) UITextView *_placeholderTextView;
@property (nonatomic, strong) UILabel *lenthLab;
@end

static NSString * const kAttributedPlaceholderKey = @"attributedPlaceholder";
static NSString * const kPlaceholderKey = @"placeholder";
static NSString * const kFontKey = @"font";
static NSString * const kAttributedTextKey = @"attributedText";
static NSString * const kTextKey = @"text";
static NSString * const kExclusionPathsKey = @"exclusionPaths";
static NSString * const kLineFragmentPaddingKey = @"lineFragmentPadding";
static NSString * const kTextContainerInsetKey = @"textContainerInset";
static NSString * const kTextAlignmentKey = @"textAlignment";

@implementation SelwynExpandableTextView

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer
{
    self = [super initWithFrame:frame textContainer:textContainer];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}
#else
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self preparePlaceholder];
    }
    return self;
}
#endif

- (void)preparePlaceholder
{
    NSAssert(!self._placeholderTextView, @"placeholder has been prepared already: %@", self._placeholderTextView);
    // the label which displays the placeholder
    // needs to inherit some properties from its parent text view
    
    // account for standard UITextViewPadding
    
    CGRect frame = self.bounds;
    self._placeholderTextView = [[UITextView alloc] initWithFrame:frame];
    self._placeholderTextView.opaque = NO;
    self._placeholderTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self._placeholderTextView.backgroundColor = [UIColor clearColor];
    self._placeholderTextView.textColor = [UIColor colorWithWhite:0.7f alpha:0.7f];
    self._placeholderTextView.editable = NO;
    self._placeholderTextView.scrollEnabled = YES;
    self._placeholderTextView.userInteractionEnabled = NO;
    self._placeholderTextView.font = self.font;
    self._placeholderTextView.isAccessibilityElement = NO;
    self._placeholderTextView.contentOffset = self.contentOffset;
    self._placeholderTextView.contentInset = self.contentInset;
    
    if ([self._placeholderTextView respondsToSelector:@selector(setSelectable:)]) {
        self._placeholderTextView.selectable = NO;
    }
    
    if (HAS_TEXT_CONTAINER) {
        self._placeholderTextView.textContainer.exclusionPaths = self.textContainer.exclusionPaths;
        self._placeholderTextView.textContainer.lineFragmentPadding = self.textContainer.lineFragmentPadding;
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        self._placeholderTextView.textContainerInset = self.textContainerInset;
    }
    
    if (_attributedPlaceholder) {
        self._placeholderTextView.attributedText = _attributedPlaceholder;
    } else if (_placeholder) {
        self._placeholderTextView.text = _placeholder;
    }
    
    [self setPlaceholderVisibleForText:self.text];
    
    self.clipsToBounds = YES;
    
    // some observations
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(textDidChange:)
                          name:UITextViewTextDidChangeNotification object:self];
    [defaultCenter addObserver:self selector:@selector(textDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:self];
    
    [self addObserver:self forKeyPath:kAttributedPlaceholderKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kPlaceholderKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kFontKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kAttributedTextKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kTextKey
              options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:kTextAlignmentKey
              options:NSKeyValueObservingOptionNew context:nil];
    
    if (HAS_TEXT_CONTAINER) {
        [self.textContainer addObserver:self forKeyPath:kExclusionPathsKey
                                options:NSKeyValueObservingOptionNew context:nil];
        [self.textContainer addObserver:self forKeyPath:kLineFragmentPaddingKey
                                options:NSKeyValueObservingOptionNew context:nil];
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        [self addObserver:self forKeyPath:kTextContainerInsetKey
                  options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)setPlaceholder:(NSString *)placeholderText
{
    _placeholder = [placeholderText copy];
    _attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholderText];
    
    [self resizePlaceholderFrame];
}

- (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholderText
{
    _placeholder = attributedPlaceholderText.string;
    _attributedPlaceholder = [attributedPlaceholderText copy];
    
    [self resizePlaceholderFrame];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    self._placeholderTextView.textAlignment = self.textAlignment;
    [self resizePlaceholderFrame];
    [self resizeLengthFrame];
}

- (void)setCurrentLength:(NSUInteger)currentLength {
    _currentLength = currentLength;
    [self resizeLengthFrame];
}

- (void)resizePlaceholderFrame
{
    CGRect frame = self._placeholderTextView.frame;
    frame.size = self.bounds.size;
    self._placeholderTextView.frame = frame;
}

- (void)resizeLengthFrame {
    if (self.showLength) {
        NSString *length = [NSString stringWithFormat:@"%lu", self.currentLength];
        if (self.maxLength > 0) {
            length = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)self.currentLength, (unsigned long)self.maxLength];
        }
        self.lenthLab.text = length;
        self.lenthLab.frame = CGRectMake(self.frame.size.width - 210, self.frame.size.height - 10 - 14, 200, 14);
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:kAttributedPlaceholderKey]) {
        self._placeholderTextView.attributedText = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kPlaceholderKey]) {
        self._placeholderTextView.text = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kFontKey]) {
        self._placeholderTextView.font = [change valueForKey:NSKeyValueChangeNewKey];
    }
    else if ([keyPath isEqualToString:kAttributedTextKey]) {
        NSAttributedString *newAttributedText = [change valueForKey:NSKeyValueChangeNewKey];
        [self setPlaceholderVisibleForText:newAttributedText.string];
    }
    else if ([keyPath isEqualToString:kTextKey]) {
        NSString *newText = [change valueForKey:NSKeyValueChangeNewKey];
        [self setPlaceholderVisibleForText:newText];
    }
    else if ([keyPath isEqualToString:kExclusionPathsKey]) {
        self._placeholderTextView.textContainer.exclusionPaths = [change objectForKey:NSKeyValueChangeNewKey];
        [self resizePlaceholderFrame];
    }
    else if ([keyPath isEqualToString:kLineFragmentPaddingKey]) {
        self._placeholderTextView.textContainer.lineFragmentPadding = [[change objectForKey:NSKeyValueChangeNewKey] floatValue];
        [self resizePlaceholderFrame];
    }
    else if ([keyPath isEqualToString:kTextContainerInsetKey]) {
        NSValue *value = [change objectForKey:NSKeyValueChangeNewKey];
        self._placeholderTextView.textContainerInset = value.UIEdgeInsetsValue;
    }
    else if ([keyPath isEqualToString:kTextAlignmentKey]) {
        NSNumber *alignment = [change objectForKey:NSKeyValueChangeNewKey];
        self._placeholderTextView.textAlignment = alignment.intValue;
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor
{
    self._placeholderTextView.textColor = placeholderTextColor;
}

- (UIColor *)placeholderTextColor
{
    return self._placeholderTextView.textColor;
}

- (void)textDidChange:(NSNotification *)aNotification
{
    [self setPlaceholderVisibleForText:self.text];
}

- (void)textDidBeginEditing:(NSNotification *)aNotification {
    [self setPlaceholderVisibleForText:self.text];
}

/**
- (BOOL)becomeFirstResponder
{
    [self setPlaceholderVisibleForText:self.text];
    
    return [super becomeFirstResponder];
}
 */

- (void)setPlaceholderVisibleForText:(NSString *)text
{
    if (text.length < 1) {
        if (self.fadeTime > 0.0) {
            if (![self._placeholderTextView isDescendantOfView:self]) {
                self._placeholderTextView.alpha = 0;
                [self addSubview:self._placeholderTextView];
                [self sendSubviewToBack:self._placeholderTextView];
            }
            [UIView animateWithDuration:_fadeTime animations:^{
                self._placeholderTextView.alpha = 1;
            }];
        }
        else {
            [self addSubview:self._placeholderTextView];
            [self sendSubviewToBack:self._placeholderTextView];
            self._placeholderTextView.alpha = 1;
        }
    }
    else {
        if (self.fadeTime > 0.0) {
            [UIView animateWithDuration:_fadeTime animations:^{
                self._placeholderTextView.alpha = 0;
            }];
        }
        else {
            [self._placeholderTextView removeFromSuperview];
        }
    }
}

- (UILabel *)lenthLab {
    if (!_lenthLab) {
        _lenthLab = [[UILabel alloc]init];
        _lenthLab.font = [UIFont systemFontOfSize:SW_LengHintFont];
        _lenthLab.backgroundColor = [UIColor clearColor];
        _lenthLab.textAlignment = NSTextAlignmentRight;
        _lenthLab.textColor = SW_PLACEHOLDERCOLOR;
        [self addSubview:_lenthLab];
    }
    return _lenthLab;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self removeObserver:self forKeyPath:kAttributedPlaceholderKey];
    [self removeObserver:self forKeyPath:kPlaceholderKey];
    [self removeObserver:self forKeyPath:kFontKey];
    [self removeObserver:self forKeyPath:kAttributedTextKey];
    [self removeObserver:self forKeyPath:kTextKey];
    [self removeObserver:self forKeyPath:kTextAlignmentKey];
    
    if (HAS_TEXT_CONTAINER) {
        [self.textContainer removeObserver:self forKeyPath:kExclusionPathsKey];
        [self.textContainer removeObserver:self forKeyPath:kLineFragmentPaddingKey];
    }
    
    if (HAS_TEXT_CONTAINER_INSETS(self)) {
        [self removeObserver:self forKeyPath:kTextContainerInsetKey];
    }
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/UITextView+TextLimit.h
================================================
//
//  UITextView+TextLimit.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UITextView (TextLimit)

/**
 TextView 添加字数限制

 @param maxLength 限制字数
 */
- (void)textLimitWithMaxLength:(NSInteger)maxLength;

@end


================================================
FILE: SWFormExample/SWForm/SWFormManager/UITextView+TextLimit.m
================================================
//
//  UITextView+TextLimit.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/29.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "UITextView+TextLimit.h"

@implementation UITextView (TextLimit)

- (void)textLimitWithMaxLength:(NSInteger)maxLength {
    NSString *toBeString = self.text;
    NSArray *inputModes = [UITextInputMode activeInputModes];
    UITextInputMode *currentMode = [inputModes firstObject];
    
    // 输入内容中文校验
    if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) {
        UITextRange *selectedRange = [self markedTextRange];
        UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
        if (!position) {
            if (toBeString.length > maxLength) {
                self.text = [toBeString substringToIndex:maxLength];
            }
        }
    }
    else{
        if (toBeString.length > maxLength) {
            self.text = [toBeString substringToIndex:maxLength];
        }
    }
}

@end


================================================
FILE: SWFormExample/SWForm/UIImageView+FormImage.h
================================================
//
//  UIImageView+FormImage.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 图片附件加载
 */
@interface UIImageView (FormImage)


/**
 图片附件条目图片加载
 可以在此使用 SDWebImage
 @param url 图片加载的url
 */
- (void)sw_setImageItemWithUrl:(NSURL *)url;

@end


================================================
FILE: SWFormExample/SWForm/UIImageView+FormImage.m
================================================
//
//  UIImageView+FormImage.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "UIImageView+FormImage.h"
#import "SWFormCompat.h"
#import "UIImageView+EMWebCache.h"

@implementation UIImageView (FormImage)


/**
 图片附件条目图片加载
 建议在此使用 SDWebImage
 */
- (void)sw_setImageItemWithUrl:(NSURL *)url {
    [self sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:SW_PlaceholderImage]];
}

@end


================================================
FILE: SWFormExample/SWFormExample/AppDelegate.h
================================================
//
//  AppDelegate.h
//  SWFormExample
//
//  Created by zijin on 2018/6/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


@end



================================================
FILE: SWFormExample/SWFormExample/AppDelegate.m
================================================
//
//  AppDelegate.m
//  SWFormExample
//
//  Created by zijin on 2018/6/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end


================================================
FILE: SWFormExample/SWFormExample/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "3x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "83.5x83.5",
      "scale" : "2x"
    },
    {
      "idiom" : "ios-marketing",
      "size" : "1024x1024",
      "scale" : "1x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: SWFormExample/SWFormExample/Assets.xcassets/Contents.json
================================================
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: SWFormExample/SWFormExample/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="iNf-F9-I3l"/>
                        <viewControllerLayoutGuide type="bottom" id="Yoo-8v-Ujb"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SWForm" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mjd-zo-M6o">
                                <rect key="frame" x="138" y="319" width="100.5" height="30"/>
                                <fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="Mjd-zo-M6o" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="oj0-rs-su8"/>
                            <constraint firstItem="Mjd-zo-M6o" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="z77-dd-XuM"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>


================================================
FILE: SWFormExample/SWFormExample/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="TIY-kA-ptf">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Navigation Controller-->
        <scene sceneID="24g-zl-CLI">
            <objects>
                <navigationController id="TIY-kA-ptf" sceneMemberID="viewController">
                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="ocr-tp-Shb">
                        <rect key="frame" x="0.0" y="20" width="375" height="44"/>
                        <autoresizingMask key="autoresizingMask"/>
                    </navigationBar>
                    <connections>
                        <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="4ch-h5-o2L"/>
                    </connections>
                </navigationController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="oAf-rR-uc0" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-775" y="34"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Zip-Vm-Clm"/>
                        <viewControllerLayoutGuide type="bottom" id="rHM-hs-HTH"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="yGi-di-zNn">
                                <rect key="frame" x="0.0" y="64" width="375" height="603"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <connections>
                                    <outlet property="dataSource" destination="BYZ-38-t0r" id="f56-fK-XdY"/>
                                    <outlet property="delegate" destination="BYZ-38-t0r" id="IuP-rP-kyA"/>
                                </connections>
                            </tableView>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="yGi-di-zNn" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="DoU-Gi-kv6"/>
                            <constraint firstItem="yGi-di-zNn" firstAttribute="top" secondItem="Zip-Vm-Clm" secondAttribute="bottom" id="Sbz-2s-YSe"/>
                            <constraint firstItem="rHM-hs-HTH" firstAttribute="top" secondItem="yGi-di-zNn" secondAttribute="bottom" id="XTr-t6-nSw"/>
                            <constraint firstAttribute="trailing" secondItem="yGi-di-zNn" secondAttribute="trailing" id="ypP-sU-7vL"/>
                        </constraints>
                    </view>
                    <navigationItem key="navigationItem" id="Yd0-Ab-3ZA"/>
                    <connections>
                        <outlet property="tableView" destination="yGi-di-zNn" id="eNJ-U9-qMi"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>
</document>


================================================
FILE: SWFormExample/SWFormExample/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSPhotoLibraryUsageDescription</key>
	<string>需要访问相册</string>
	<key>NSCameraUsageDescription</key>
	<string>需要使用相机</string>
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>


================================================
FILE: SWFormExample/SWFormExample/SWFormCommonController.h
================================================
//
//  SWFormCommonController.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseController.h"

@interface SWFormCommonController : SWFormBaseController

@end


================================================
FILE: SWFormExample/SWFormExample/SWFormCommonController.m
================================================
//
//  SWFormCommonController.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormCommonController.h"
#import "SWForm.h"
#import "SWFormHandler.h"

@interface SWFormCommonController ()<UIActionSheetDelegate>

@property (nonatomic, strong) NSArray *genders;
@property (nonatomic, strong) SWFormItem *name;
@property (nonatomic, strong) SWFormItem *age;
@property (nonatomic, strong) SWFormItem *price;
@property (nonatomic, strong) SWFormItem *gender;
@property (nonatomic, strong) SWFormItem *intro;
@property (nonatomic, strong) SWFormItem *image;

@end

@implementation SWFormCommonController

- (void)dealloc
{
    NSLog(@"dealloc");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.genders = @[@"男",@"女"];
    [self datas];
}

/**
 数据源处理
 */
- (void)datas {
    SWWeakSelf
    NSMutableArray *items = [NSMutableArray array];
    
    self.name = SWFormItem_Add(@"姓名", nil, SWFormItemTypeInput, YES, YES, UIKeyboardTypeDefault);
    self.name.showLength = YES;
    [items addObject:_name];
    
    self.age = SWFormItem_Add(@"年龄", nil, SWFormItemTypeInput, YES, YES, UIKeyboardTypeNumberPad);
    self.age.maxInputLength = 3;
    self.age.unit = @"岁";
    [items addObject:_age];
    
    self.price = SWFormItem_Add(@"价格", nil, SWFormItemTypeInput, YES, YES, UIKeyboardTypeNumberPad);
    self.price.maxInputLength = 5;
    self.price.itemUnitType = SWFormItemUnitTypeYuan;
    [items addObject:_price];
    
    self.gender = SWFormItem_Add(@"性别", nil, SWFormItemTypeSelect, NO, YES, UIKeyboardTypeDefault);
    self.gender.itemSelectCompletion = ^(SWFormItem *item) {
        UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:[NSString stringWithFormat:@"请选择%@",item.title] delegate:weakSelf cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:nil];
        for (int i = 0; i < weakSelf.genders.count; i++) {
            [actionSheet addButtonWithTitle:weakSelf.genders[i]];
        }
        actionSheet.tag = 10;
        [actionSheet showInView:weakSelf.view];
    };
    [items addObject:_gender];
    
    self.intro = SWFormItem_Add(@"个人简介", @"这是个人简介", SWFormItemTypeTextViewInput, YES, NO, UIKeyboardTypeDefault);
    self.intro.showLength = YES;
    [items addObject:_intro];
    
    self.image = SWFormItem_Add(@"附件", nil, SWFormItemTypeImage, YES, NO, UIKeyboardTypeDefault);
    self.image.images = @[@"http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=f04093d6da00baa1ae214ffb2e68dc7e/34fae6cd7b899e5160ce642e49a7d933c8950d43.jpg", @"http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=b360ab28790e0cf3b4fa46bb633e9773/e850352ac65c10387071c8f8b9119313b07e89f8.jpg", @""];
    [items addObject:_image];
    
    SWFormSectionItem *sectionItem = SWSectionItem(items);
    //    sectionItem.headerHeight = 10;
    //    sectionItem.footerView = [self footerView];
    //    sectionItem.footerHeight = 80;
    [self.mutableItems addObject:sectionItem];
    
    self.formTableView.tableFooterView = [self footerView];
}

/**
 创建footer
 */
- (UIView *)footerView {
    UIView *footer = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 80)];
    
    UIButton *submitBtn = [UIButton buttonWithType:UIButtonTypeSystem];
    submitBtn.bounds = CGRectMake(0, 0, 100, 40);
    submitBtn.center = footer.center;
    submitBtn.backgroundColor = [UIColor orangeColor];
    [submitBtn setTitle:@"提交" forState:UIControlStateNormal];
    [submitBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [submitBtn addTarget:self action:@selector(submitAction) forControlEvents:UIControlEventTouchUpInside];
    [footer addSubview:submitBtn];
    
    return footer;
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (actionSheet.tag == 10) {
        if (buttonIndex != 0) {
            self.gender.info = self.genders[buttonIndex-1];
            [self.formTableView reloadData];
        }
    }
}

- (void)submitAction {
    [SWFormHandler sw_checkFormNullDataWithWithDatas:self.mutableItems success:^{
        
        NSLog(@"selectImages === %@", self.image.selectImages);
        //NSLog(@"images === %@", image.images);
        NSLog(@"gender === %@", self.gender.info);
        NSLog(@"name === %@", self.name.info);
        
    } failure:^(NSString *error) {
        NSLog(@"error====%@",error);
    }];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


================================================
FILE: SWFormExample/SWFormExample/SWFormExample.pch
================================================
//
//  SWFormExample.pch
//  SWFormExample
//
//  Created by zijin on 2018/6/28.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#ifndef SWFormExample_pch
#define SWFormExample_pch

#import <UIKit/UIKit.h>
// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.

#endif /* SWFormExample_pch */


================================================
FILE: SWFormExample/SWFormExample/SWFormInfoController.h
================================================
//
//  SWFormInfoController.h
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormBaseController.h"

@interface SWFormInfoController : SWFormBaseController

@end


================================================
FILE: SWFormExample/SWFormExample/SWFormInfoController.m
================================================
//
//  SWFormInfoController.m
//  SWFormDemo
//
//  Created by zijin on 2018/5/31.
//  Copyright © 2018年 selwyn. All rights reserved.
//

#import "SWFormInfoController.h"
#import "SWForm.h"

typedef void(^EditCompletion)(void);

@interface SWFormInfoController ()

@property (nonatomic, strong) UIButton *editBtn;
@property (nonatomic, copy)EditCompletion editCompletion;
@property (nonatomic, assign) BOOL isEditing;

@end

@implementation SWFormInfoController

- (void)dealloc
{
    NSLog(@"dealloc");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.editBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.editBtn setTitle:@"编辑" forState:UIControlStateNormal];
    [self.editBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    self.editBtn.titleLabel.font = [UIFont systemFontOfSize:16];
    [self.editBtn sizeToFit];
    [self.editBtn addTarget:self action:@selector(editeAction) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *editItem = [[UIBarButtonItem alloc]initWithCustomView:self.editBtn];
    self.navigationItem.rightBarButtonItem = editItem;
    
    [self datas];
}

/**
 数据源处理
 */
- (void)datas {
    NSMutableArray *items = [NSMutableArray array];
    SWFormItem *name = SWFormItem_Info(@"姓名", @"selwyn", SWFormItemTypeInput);
    name.keyboardType = UIReturnKeyDefault;
    [items addObject:name];
    
    SWFormItem *age = SWFormItem_Info(@"年龄", @"14", SWFormItemTypeInput);
    age.keyboardType = UIKeyboardTypeNumberPad;
    [items addObject:age];
    
    SWFormItem *image = SWFormItem_Info(@"图片附件", nil, SWFormItemTypeImage);
    image.images = @[@"http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=f04093d6da00baa1ae214ffb2e68dc7e/34fae6cd7b899e5160ce642e49a7d933c8950d43.jpg", @"http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=b360ab28790e0cf3b4fa46bb633e9773/e850352ac65c10387071c8f8b9119313b07e89f8.jpg", @""];
    [items addObject:image];
    
    SWFormSectionItem *sectionItem = SWSectionItem(items);
    [self.mutableItems addObject:sectionItem];
    
    __weak typeof(self) weakSelf = self;
    
    // 编辑按钮点击事件回调
    self.editCompletion = ^{
        
        weakSelf.isEditing = !weakSelf.isEditing;
        name.editable = weakSelf.isEditing;
        age.editable = weakSelf.isEditing;
        image.editable = weakSelf.isEditing;
        
        if (weakSelf.isEditing) {
            NSLog(@"====编辑中====");
        }
        else {
            NSLog(@"====完成编辑====");
        }
        
        [weakSelf.formTableView reloadData];
    };
}

- (void)editeAction {
    self.editCompletion();
}

- (void)setIsEditing:(BOOL)isEditing {
    _isEditing = isEditing;
    [self.editBtn setTitle:isEditing ? @"完成":@"编辑" forState:UIControlStateNormal];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/all-wcprops
================================================
K 25
svn:wc:ra_dav:version-url
V 138
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD
END
MBProgressHUD.m
K 25
svn:wc:ra_dav:version-url
V 154
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/MBProgressHUD.m
END
Factory.m
K 25
svn:wc:ra_dav:version-url
V 148
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/Factory.m
END
MBProgressHUD+Add.m
K 25
svn:wc:ra_dav:version-url
V 158
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/MBProgressHUD+Add.m
END
MacroDef.h
K 25
svn:wc:ra_dav:version-url
V 149
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/MacroDef.h
END
MBProgressHUD.h
K 25
svn:wc:ra_dav:version-url
V 154
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/MBProgressHUD.h
END
Factory.h
K 25
svn:wc:ra_dav:version-url
V 148
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/Factory.h
END
MBProgressHUD+Add.h
K 25
svn:wc:ra_dav:version-url
V 158
/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD/MBProgressHUD+Add.h
END


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/entries
================================================
10

dir
4265
http://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo-UI3.0/ChatSDK/EaseUI/EMUIKit/3rdparty/MBProgressHUD
http://bishanwen@121.43.163.28:9090/zhuku/repo



2017-12-28T02:01:09.072372Z
4261
zhoujun














5738001b-f13b-4815-ac0f-2e2f54dd1d22

MBProgressHUD.m
file




2018-01-16T02:17:09.000000Z
12ee8d84563c68f1cae528ca2e5ea0e4
2017-12-28T02:01:09.072372Z
4261
zhoujun
has-props




















32691

Factory.m
file




2018-01-16T02:17:09.000000Z
ab116194093c76bfdc0d38fc131e8ff6
2017-12-28T02:01:09.072372Z
4261
zhoujun





















5537

MBProgressHUD+Add.m
file




2018-01-16T02:17:09.000000Z
237db6ed122879af9aae1098c88834ea
2017-12-28T02:01:09.072372Z
4261
zhoujun





















1660

MacroDef.h
file




2018-01-16T02:17:09.000000Z
8f92dd22bc0d8a9358b8564928ab03e1
2017-12-28T02:01:09.072372Z
4261
zhoujun





















4598

MBProgressHUD.h
file




2018-01-16T02:17:09.000000Z
8263e84d74c876541cc34ee6e55d5461
2017-12-28T02:01:09.072372Z
4261
zhoujun
has-props




















16269

Factory.h
file




2018-01-16T02:17:09.000000Z
c5c59e89c1da627eeb8e2cfa0aee584e
2017-12-28T02:01:09.072372Z
4261
zhoujun





















829

MBProgressHUD+Add.h
file




2018-01-16T02:17:09.000000Z
526d61b0b3d23cd979694b3d43b80003
2017-12-28T02:01:09.072372Z
4261
zhoujun





















398



================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/prop-base/MBProgressHUD.h.svn-base
================================================
K 14
svn:executable
V 0

END


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/prop-base/MBProgressHUD.m.svn-base
================================================
K 14
svn:executable
V 0

END


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/Factory.h.svn-base
================================================
//
//  Factory.h
//  DongDong
//
//  Created by jmsre on 15/11/25.
//  Copyright © 2015年 wangyang. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"

@interface Factory : NSObject


// 返回文本size
+ (CGSize)sizeForText:(NSString *)text withFont:(UIFont *)font contraint:(CGSize)constraint;


//提示:
+ (void)MBProgressHUD:(NSString *)text Time:(NSUInteger)time;
+ (void)MBProgressHUDUseblock:(void (^)(MBProgressHUD *hud))block;


// 校验手机号
+ (BOOL)isMobileNumber:(NSString *)mobileNum;
+ (BOOL)isChinaMobile:(NSString *)phoneNum;
+ (BOOL)isChinaUnicom:(NSString *)phoneNum;
+ (BOOL)isChinaTelecom:(NSString *)phoneNum;
+ (NSString *)getPhoneNumType:(NSString *)phoneNum;

//身份证号
+ (BOOL) validateIdentityCard: (NSString *)identityCard;

@end


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/Factory.m.svn-base
================================================
//
//  Factory.m
//  DongDong
//
//  Created by jmsre on 15/11/25.
//  Copyright © 2015年 wangyang. All rights reserved.
//

#import "Factory.h"
#import "MacroDef.h"

@implementation Factory


// 返回文本size
+ (CGSize)sizeForText:(NSString *)text withFont:(UIFont *)font contraint:(CGSize)constraint{
    CGSize size = CGSizeZero;
    if (IOS7_OR_LATER)
    {
        size = [text boundingRectWithSize:constraint
                                  options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                               attributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]
                                  context:nil].size;
    }
//    else
//    {
//        size = [text sizeWithFont:font constrainedToSize:constraint
//                    lineBreakMode:NSLineBreakByWordWrapping];
//    }
    return size;
}

//提示:
+ (void)MBProgressHUD:(NSString *)text Time:(NSUInteger)time{
    MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:[UIApplication sharedApplication].windows[0]];
    [[UIApplication sharedApplication].windows[0] addSubview:HUD];
    HUD.labelText = text;
    HUD.mode = MBProgressHUDModeText;
    
    //指定距离中心点的X轴和Y轴的偏移量,如果不指定则在屏幕中间显示
    //    HUD.yOffset = 150.0f;
    //    HUD.xOffset = 100.0f;
    
    __block unsigned int  tttt = (unsigned int)time;
    [HUD showAnimated:YES whileExecutingBlock:^{
        sleep(tttt);
    } completionBlock:^{
        [HUD removeFromSuperview];
    }];
}

+ (void)MBProgressHUDUseblock:(void (^)(MBProgressHUD *hud))block{
    MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:[UIApplication sharedApplication].windows[0]];
    [[UIApplication sharedApplication].windows[0] addSubview:HUD];
    HUD.labelText = @"正在加载...";
    HUD.mode = MBProgressHUDModeIndeterminate;
    
    //指定距离中心点的X轴和Y轴的偏移量,如果不指定则在屏幕中间显示
    //    HUD.yOffset = 150.0f;
    //    HUD.xOffset = 100.0f;
    
    [HUD showAnimated:YES whileExecutingBlock:^{
//        sleep(1);
        dispatch_sync(dispatch_get_main_queue(), ^{
            block(HUD);
        });
    } completionBlock:^{
        [HUD removeFromSuperview];
    }];
}


// 校验手机号
+ (BOOL)isMobileNumber:(NSString *)mobileNum
{
    if (mobileNum.length != 11)
    {
        return NO;
    }
    /**
     * 手机号码:
     * 13[0-9], 14[5,7], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[6, 7, 8], 18[0-9], 170[0-9]
     * 移动号段: 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
     * 联通号段: 130,131,132,155,156,185,186,145,176,1709
     * 电信号段: 133,153,180,181,189,177,1700
     */
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|70)\\d{8}$";
    /**
     * 中国移动:China Mobile
     * 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
     */
    NSString *CM = @"(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)";
    /**
     * 中国联通:China Unicom
     * 130,131,132,155,156,185,186,145,176,1709
     */
    NSString *CU = @"(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)";
    /**
     * 中国电信:China Telecom
     * 133,153,180,181,189,177,1700
     */
    NSString *CT = @"(^1(33|53|77|8[019])\\d{8}$)|(^1700\\d{7}$)";
    
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    
    if (([regextestmobile evaluateWithObject:mobileNum] == YES)
        || ([regextestcm evaluateWithObject:mobileNum] == YES)
        || ([regextestct evaluateWithObject:mobileNum] == YES)
        || ([regextestcu evaluateWithObject:mobileNum] == YES))
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

+ (BOOL)isChinaMobile:(NSString *)phoneNum
{
    NSString *CM = @"(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)";
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    return [regextestcm evaluateWithObject:phoneNum];
}

+ (BOOL)isChinaUnicom:(NSString *)phoneNum
{
    NSString *CU = @"(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)";
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    return [regextestcu evaluateWithObject:phoneNum];
}

+ (BOOL)isChinaTelecom:(NSString *)phoneNum
{
    NSString *CT = @"(^1(33|53|77|8[019])\\d{8}$)|(^1700\\d{7}$)";
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    return [regextestct evaluateWithObject:phoneNum];
}

+ (NSString *)getPhoneNumType:(NSString *)phoneNum
{
    return [self isChinaMobile:phoneNum]? @"中国移动": ([self isChinaUnicom:phoneNum]? @"中国联通":([self isChinaTelecom:phoneNum]? @"中国电信": @"未知"));
}


//身份证号
+ (BOOL) validateIdentityCard: (NSString *)identityCard
{
    BOOL flag;
    if (identityCard.length <= 0) {
        flag = NO;
        return flag;
    }
    NSString *regex2 = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    return [identityCardPredicate evaluateWithObject:identityCard];
}

@end


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD+Add.h.svn-base
================================================
//
//  MBProgressHUD+Add.h
//  视频客户端
//
//  Created by mj on 13-4-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "MBProgressHUD.h"

@interface MBProgressHUD (Add)
+ (void)showError:(NSString *)error toView:(UIView *)view;
+ (void)showSuccess:(NSString *)success toView:(UIView *)view;

+ (MBProgressHUD *)showMessag:(NSString *)message toView:(UIView *)view;
@end


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD+Add.m.svn-base
================================================
//
//  MBProgressHUD+Add.m
//  视频客户端
//
//  Created by mj on 13-4-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import "MBProgressHUD+Add.h"

@implementation MBProgressHUD (Add)

#pragma mark 显示信息
+ (void)show:(NSString *)text icon:(NSString *)icon view:(UIView *)view
{
    if (view == nil) view = [UIApplication sharedApplication].keyWindow;
    // 快速显示一个提示信息
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
    hud.labelText = text;
    // 设置图片
    hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"MBProgressHUD.bundle/%@", icon]]];
    // 再设置模式
    hud.mode = MBProgressHUDModeCustomView;
    
    // 隐藏时候从父控件中移除
    hud.removeFromSuperViewOnHide = YES;
    
    // 1秒之后再消失
    [hud hide:YES afterDelay:0.7];
}

#pragma mark 显示错误信息
+ (void)showError:(NSString *)error toView:(UIView *)view{
    [self show:error icon:@"error.png" view:view];
}

+ (void)showSuccess:(NSString *)success toView:(UIView *)view
{
    [self show:success icon:@"success.png" view:view];
}

#pragma mark 显示一些信息
+ (MBProgressHUD *)showMessag:(NSString *)message toView:(UIView *)view {
    if (view == nil) view = [UIApplication sharedApplication].keyWindow;
    // 快速显示一个提示信息
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
    hud.labelText = message;
    // 隐藏时候从父控件中移除
    hud.removeFromSuperViewOnHide = YES;
    // YES代表需要蒙版效果
    hud.dimBackground = YES;
    return hud;
}
@end


================================================
FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD.h.svn-base
================================================
//
//  MBProgressHUD.h
//  Version 0.8
//  Created by Matej Bukovinski on 2.4.09.
//

// This code is distributed under the terms and conditions of the MIT license.

// Copyright (c) 2013 Matej Bukovinski
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software withou
Download .txt
gitextract_fysrm9id/

├── README.md
├── SWForm/
│   ├── SWForm.bundle/
│   │   ├── Root.plist
│   │   └── en.lproj/
│   │       └── Root.strings
│   ├── SWForm.h
│   ├── SWFormBaseController.h
│   ├── SWFormBaseController.m
│   ├── SWFormCell/
│   │   ├── SWFormBaseCell.h
│   │   ├── SWFormBaseCell.m
│   │   ├── SWFormImageCell.h
│   │   ├── SWFormImageCell.m
│   │   ├── SWFormInputCell.h
│   │   ├── SWFormInputCell.m
│   │   ├── SWFormSelectCell.h
│   │   ├── SWFormSelectCell.m
│   │   ├── SWFormTextViewInputCell.h
│   │   ├── SWFormTextViewInputCell.m
│   │   ├── SWImageCollectionCell.h
│   │   └── SWImageCollectionCell.m
│   ├── SWFormHandler.h
│   ├── SWFormHandler.m
│   ├── SWFormImageCell+ImageHandle.h
│   ├── SWFormImageCell+ImageHandle.m
│   ├── SWFormItem/
│   │   ├── SWFormItem.h
│   │   ├── SWFormItem.m
│   │   ├── SWFormSectionItem.h
│   │   └── SWFormSectionItem.m
│   ├── SWFormManager/
│   │   ├── NSString+SWForm.h
│   │   ├── NSString+SWForm.m
│   │   ├── SWFormCompat.h
│   │   ├── SWFormCompat.m
│   │   ├── SelwynExpandableTextView.h
│   │   ├── SelwynExpandableTextView.m
│   │   ├── UITextView+TextLimit.h
│   │   └── UITextView+TextLimit.m
│   ├── UIImageView+FormImage.h
│   └── UIImageView+FormImage.m
└── SWFormExample/
    ├── SWForm/
    │   ├── SWForm.bundle/
    │   │   ├── Root.plist
    │   │   └── en.lproj/
    │   │       └── Root.strings
    │   ├── SWForm.h
    │   ├── SWFormBaseController.h
    │   ├── SWFormBaseController.m
    │   ├── SWFormCell/
    │   │   ├── SWFormBaseCell.h
    │   │   ├── SWFormBaseCell.m
    │   │   ├── SWFormImageCell.h
    │   │   ├── SWFormImageCell.m
    │   │   ├── SWFormInputCell.h
    │   │   ├── SWFormInputCell.m
    │   │   ├── SWFormSelectCell.h
    │   │   ├── SWFormSelectCell.m
    │   │   ├── SWFormTextViewInputCell.h
    │   │   ├── SWFormTextViewInputCell.m
    │   │   ├── SWImageCollectionCell.h
    │   │   └── SWImageCollectionCell.m
    │   ├── SWFormHandler.h
    │   ├── SWFormHandler.m
    │   ├── SWFormImageCell+ImageHandle.h
    │   ├── SWFormImageCell+ImageHandle.m
    │   ├── SWFormItem/
    │   │   ├── SWFormItem.h
    │   │   ├── SWFormItem.m
    │   │   ├── SWFormSectionItem.h
    │   │   └── SWFormSectionItem.m
    │   ├── SWFormManager/
    │   │   ├── NSString+SWForm.h
    │   │   ├── NSString+SWForm.m
    │   │   ├── SWFormCompat.h
    │   │   ├── SWFormCompat.m
    │   │   ├── SelwynExpandableTextView.h
    │   │   ├── SelwynExpandableTextView.m
    │   │   ├── UITextView+TextLimit.h
    │   │   └── UITextView+TextLimit.m
    │   ├── UIImageView+FormImage.h
    │   └── UIImageView+FormImage.m
    ├── SWFormExample/
    │   ├── AppDelegate.h
    │   ├── AppDelegate.m
    │   ├── Assets.xcassets/
    │   │   ├── AppIcon.appiconset/
    │   │   │   └── Contents.json
    │   │   └── Contents.json
    │   ├── Base.lproj/
    │   │   ├── LaunchScreen.storyboard
    │   │   └── Main.storyboard
    │   ├── Info.plist
    │   ├── SWFormCommonController.h
    │   ├── SWFormCommonController.m
    │   ├── SWFormExample.pch
    │   ├── SWFormInfoController.h
    │   ├── SWFormInfoController.m
    │   ├── Vendors/
    │   │   ├── MBProgressHUD/
    │   │   │   ├── .svn/
    │   │   │   │   ├── all-wcprops
    │   │   │   │   ├── entries
    │   │   │   │   ├── prop-base/
    │   │   │   │   │   ├── MBProgressHUD.h.svn-base
    │   │   │   │   │   └── MBProgressHUD.m.svn-base
    │   │   │   │   └── text-base/
    │   │   │   │       ├── Factory.h.svn-base
    │   │   │   │       ├── Factory.m.svn-base
    │   │   │   │       ├── MBProgressHUD+Add.h.svn-base
    │   │   │   │       ├── MBProgressHUD+Add.m.svn-base
    │   │   │   │       ├── MBProgressHUD.h.svn-base
    │   │   │   │       ├── MBProgressHUD.m.svn-base
    │   │   │   │       └── MacroDef.h.svn-base
    │   │   │   ├── Factory.h
    │   │   │   ├── Factory.m
    │   │   │   ├── MBProgressHUD+Add.h
    │   │   │   ├── MBProgressHUD+Add.m
    │   │   │   ├── MBProgressHUD.h
    │   │   │   ├── MBProgressHUD.m
    │   │   │   └── MacroDef.h
    │   │   ├── MWPhotoBrowser/
    │   │   │   ├── .svn/
    │   │   │   │   ├── all-wcprops
    │   │   │   │   └── entries
    │   │   │   ├── Classes/
    │   │   │   │   ├── .svn/
    │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   ├── entries
    │   │   │   │   │   └── text-base/
    │   │   │   │   │       ├── MWCaptionView.h.svn-base
    │   │   │   │   │       ├── MWCaptionView.m.svn-base
    │   │   │   │   │       ├── MWCommon.h.svn-base
    │   │   │   │   │       ├── MWGridCell.h.svn-base
    │   │   │   │   │       ├── MWGridCell.m.svn-base
    │   │   │   │   │       ├── MWGridViewController.h.svn-base
    │   │   │   │   │       ├── MWGridViewController.m.svn-base
    │   │   │   │   │       ├── MWPhoto.h.svn-base
    │   │   │   │   │       ├── MWPhoto.m.svn-base
    │   │   │   │   │       ├── MWPhotoBrowser.h.svn-base
    │   │   │   │   │       ├── MWPhotoBrowser.m.svn-base
    │   │   │   │   │       ├── MWPhotoBrowserPrivate.h.svn-base
    │   │   │   │   │       ├── MWPhotoProtocol.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingImageView.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingImageView.m.svn-base
    │   │   │   │   │       ├── MWTapDetectingView.h.svn-base
    │   │   │   │   │       ├── MWTapDetectingView.m.svn-base
    │   │   │   │   │       ├── MWZoomingScrollView.h.svn-base
    │   │   │   │   │       └── MWZoomingScrollView.m.svn-base
    │   │   │   │   ├── MWCaptionView.h
    │   │   │   │   ├── MWCaptionView.m
    │   │   │   │   ├── MWCommon.h
    │   │   │   │   ├── MWGridCell.h
    │   │   │   │   ├── MWGridCell.m
    │   │   │   │   ├── MWGridViewController.h
    │   │   │   │   ├── MWGridViewController.m
    │   │   │   │   ├── MWPhoto.h
    │   │   │   │   ├── MWPhoto.m
    │   │   │   │   ├── MWPhotoBrowser.h
    │   │   │   │   ├── MWPhotoBrowser.m
    │   │   │   │   ├── MWPhotoBrowserPrivate.h
    │   │   │   │   ├── MWPhotoProtocol.h
    │   │   │   │   ├── MWTapDetectingImageView.h
    │   │   │   │   ├── MWTapDetectingImageView.m
    │   │   │   │   ├── MWTapDetectingView.h
    │   │   │   │   ├── MWTapDetectingView.m
    │   │   │   │   ├── MWZoomingScrollView.h
    │   │   │   │   └── MWZoomingScrollView.m
    │   │   │   ├── Libraries/
    │   │   │   │   ├── .svn/
    │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   └── entries
    │   │   │   │   ├── DACircularProgress/
    │   │   │   │   │   ├── .svn/
    │   │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   │   ├── entries
    │   │   │   │   │   │   ├── prop-base/
    │   │   │   │   │   │   │   ├── DACircularProgressView.h.svn-base
    │   │   │   │   │   │   │   └── DACircularProgressView.m.svn-base
    │   │   │   │   │   │   └── text-base/
    │   │   │   │   │   │       ├── DACircularProgressView.h.svn-base
    │   │   │   │   │   │       └── DACircularProgressView.m.svn-base
    │   │   │   │   │   ├── DACircularProgressView.h
    │   │   │   │   │   └── DACircularProgressView.m
    │   │   │   │   ├── EMSDWebImage/
    │   │   │   │   │   ├── .svn/
    │   │   │   │   │   │   ├── all-wcprops
    │   │   │   │   │   │   ├── entries
    │   │   │   │   │   │   ├── prop-base/
    │   │   │   │   │   │   │   ├── EMSDImageCache.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDImageCache.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageCompat.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageCompat.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDecoder.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDecoder.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloader.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloader.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageManager.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageManager.m.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImageOperation.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImagePrefetcher.h.svn-base
    │   │   │   │   │   │   │   ├── EMSDWebImagePrefetcher.m.svn-base
    │   │   │   │   │   │   │   ├── MKAnnotationView+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── MKAnnotationView+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── NSData+EMImageContentType.h.svn-base
    │   │   │   │   │   │   │   ├── NSData+EMImageContentType.m.svn-base
    │   │   │   │   │   │   │   ├── UIButton+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIButton+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMGIF.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMGIF.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMMultiFormat.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMMultiFormat.m.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMWebP.h.svn-base
    │   │   │   │   │   │   │   ├── UIImage+EMWebP.m.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMWebCache.h.svn-base
    │   │   │   │   │   │   │   ├── UIImageView+EMWebCache.m.svn-base
    │   │   │   │   │   │   │   ├── UIView+EMWebCacheOperation.h.svn-base
    │   │   │   │   │   │   │   └── UIView+EMWebCacheOperation.m.svn-base
    │   │   │   │   │   │   └── text-base/
    │   │   │   │   │   │       ├── EMSDImageCache.h.svn-base
    │   │   │   │   │   │       ├── EMSDImageCache.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageCompat.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageCompat.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDecoder.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDecoder.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloader.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloader.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloaderOperation.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageDownloaderOperation.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageManager.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageManager.m.svn-base
    │   │   │   │   │   │       ├── EMSDWebImageOperation.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImagePrefetcher.h.svn-base
    │   │   │   │   │   │       ├── EMSDWebImagePrefetcher.m.svn-base
    │   │   │   │   │   │       ├── MKAnnotationView+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── MKAnnotationView+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── NSData+EMImageContentType.h.svn-base
    │   │   │   │   │   │       ├── NSData+EMImageContentType.m.svn-base
    │   │   │   │   │   │       ├── UIButton+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIButton+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMGIF.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMGIF.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMMultiFormat.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMMultiFormat.m.svn-base
    │   │   │   │   │   │       ├── UIImage+EMWebP.h.svn-base
    │   │   │   │   │   │       ├── UIImage+EMWebP.m.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMHighlightedWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMHighlightedWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMWebCache.h.svn-base
    │   │   │   │   │   │       ├── UIImageView+EMWebCache.m.svn-base
    │   │   │   │   │   │       ├── UIView+EMWebCacheOperation.h.svn-base
    │   │   │   │   │   │       └── UIView+EMWebCacheOperation.m.svn-base
    │   │   │   │   │   ├── EMSDImageCache.h
    │   │   │   │   │   ├── EMSDImageCache.m
    │   │   │   │   │   ├── EMSDWebImageCompat.h
    │   │   │   │   │   ├── EMSDWebImageCompat.m
    │   │   │   │   │   ├── EMSDWebImageDecoder.h
    │   │   │   │   │   ├── EMSDWebImageDecoder.m
    │   │   │   │   │   ├── EMSDWebImageDownloader.h
    │   │   │   │   │   ├── EMSDWebImageDownloader.m
    │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.h
    │   │   │   │   │   ├── EMSDWebImageDownloaderOperation.m
    │   │   │   │   │   ├── EMSDWebImageManager.h
    │   │   │   │   │   ├── EMSDWebImageManager.m
    │   │   │   │   │   ├── EMSDWebImageOperation.h
    │   │   │   │   │   ├── EMSDWebImagePrefetcher.h
    │   │   │   │   │   ├── EMSDWebImagePrefetcher.m
    │   │   │   │   │   ├── MKAnnotationView+EMWebCache.h
    │   │   │   │   │   ├── MKAnnotationView+EMWebCache.m
    │   │   │   │   │   ├── NSData+EMImageContentType.h
    │   │   │   │   │   ├── NSData+EMImageContentType.m
    │   │   │   │   │   ├── UIButton+EMWebCache.h
    │   │   │   │   │   ├── UIButton+EMWebCache.m
    │   │   │   │   │   ├── UIImage+EMGIF.h
    │   │   │   │   │   ├── UIImage+EMGIF.m
    │   │   │   │   │   ├── UIImage+EMMultiFormat.h
    │   │   │   │   │   ├── UIImage+EMMultiFormat.m
    │   │   │   │   │   ├── UIImage+EMWebP.h
    │   │   │   │   │   ├── UIImage+EMWebP.m
    │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.h
    │   │   │   │   │   ├── UIImageView+EMHighlightedWebCache.m
    │   │   │   │   │   ├── UIImageView+EMWebCache.h
    │   │   │   │   │   ├── UIImageView+EMWebCache.m
    │   │   │   │   │   ├── UIView+EMWebCacheOperation.h
    │   │   │   │   │   └── UIView+EMWebCacheOperation.m
    │   │   │   │   └── PSTCollectionView/
    │   │   │   │       ├── .svn/
    │   │   │   │       │   ├── all-wcprops
    │   │   │   │       │   ├── entries
    │   │   │   │       │   ├── prop-base/
    │   │   │   │       │   │   ├── NSIndexPath+PSTCollectionViewAdditions.h.svn-base
    │   │   │   │       │   │   ├── NSIndexPath+PSTCollectionViewAdditions.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionView.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionView.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCell.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCell.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewCommon.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewController.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewController.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewData.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewData.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewFlowLayout.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewFlowLayout.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewItemKey.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewItemKey.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout+Internals.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewLayout.m.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewUpdateItem.h.svn-base
    │   │   │   │       │   │   ├── PSTCollectionViewUpdateItem.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutInfo.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutInfo.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutItem.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutItem.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutRow.h.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutRow.m.svn-base
    │   │   │   │       │   │   ├── PSTGridLayoutSection.h.svn-base
    │   │   │   │       │   │   └── PSTGridLayoutSection.m.svn-base
    │   │   │   │       │   └── text-base/
    │   │   │   │       │       ├── NSIndexPath+PSTCollectionViewAdditions.h.svn-base
    │   │   │   │       │       ├── NSIndexPath+PSTCollectionViewAdditions.m.svn-base
    │   │   │   │       │       ├── PSTCollectionView.h.svn-base
    │   │   │   │       │       ├── PSTCollectionView.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCell.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCell.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewCommon.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewController.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewController.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewData.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewData.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewFlowLayout.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewFlowLayout.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewItemKey.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewItemKey.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout+Internals.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewLayout.m.svn-base
    │   │   │   │       │       ├── PSTCollectionViewUpdateItem.h.svn-base
    │   │   │   │       │       ├── PSTCollectionViewUpdateItem.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutInfo.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutInfo.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutItem.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutItem.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutRow.h.svn-base
    │   │   │   │       │       ├── PSTGridLayoutRow.m.svn-base
    │   │   │   │       │       ├── PSTGridLayoutSection.h.svn-base
    │   │   │   │       │       └── PSTGridLayoutSection.m.svn-base
    │   │   │   │       ├── NSIndexPath+PSTCollectionViewAdditions.h
    │   │   │   │       ├── NSIndexPath+PSTCollectionViewAdditions.m
    │   │   │   │       ├── PSTCollectionView.h
    │   │   │   │       ├── PSTCollectionView.m
    │   │   │   │       ├── PSTCollectionViewCell.h
    │   │   │   │       ├── PSTCollectionViewCell.m
    │   │   │   │       ├── PSTCollectionViewCommon.h
    │   │   │   │       ├── PSTCollectionViewController.h
    │   │   │   │       ├── PSTCollectionViewController.m
    │   │   │   │       ├── PSTCollectionViewData.h
    │   │   │   │       ├── PSTCollectionViewData.m
    │   │   │   │       ├── PSTCollectionViewFlowLayout.h
    │   │   │   │       ├── PSTCollectionViewFlowLayout.m
    │   │   │   │       ├── PSTCollectionViewItemKey.h
    │   │   │   │       ├── PSTCollectionViewItemKey.m
    │   │   │   │       ├── PSTCollectionViewLayout+Internals.h
    │   │   │   │       ├── PSTCollectionViewLayout.h
    │   │   │   │       ├── PSTCollectionViewLayout.m
    │   │   │   │       ├── PSTCollectionViewUpdateItem.h
    │   │   │   │       ├── PSTCollectionViewUpdateItem.m
    │   │   │   │       ├── PSTGridLayoutInfo.h
    │   │   │   │       ├── PSTGridLayoutInfo.m
    │   │   │   │       ├── PSTGridLayoutItem.h
    │   │   │   │       ├── PSTGridLayoutItem.m
    │   │   │   │       ├── PSTGridLayoutRow.h
    │   │   │   │       ├── PSTGridLayoutRow.m
    │   │   │   │       ├── PSTGridLayoutSection.h
    │   │   │   │       └── PSTGridLayoutSection.m
    │   │   │   └── MWPhotoBrowser.bundle/
    │   │   │       ├── .svn/
    │   │   │       │   ├── all-wcprops
    │   │   │       │   └── entries
    │   │   │       └── images/
    │   │   │           └── .svn/
    │   │   │               ├── all-wcprops
    │   │   │               ├── entries
    │   │   │               ├── prop-base/
    │   │   │               │   ├── Checkmark.png.svn-base
    │   │   │               │   ├── Checkmark@2x.png.svn-base
    │   │   │               │   ├── ImageError.png.svn-base
    │   │   │               │   ├── ImageError@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedOff.png.svn-base
    │   │   │               │   ├── ImageSelectedOff@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedOn.png.svn-base
    │   │   │               │   ├── ImageSelectedOn@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOff.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOff@2x.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOn.png.svn-base
    │   │   │               │   ├── ImageSelectedSmallOn@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowLeft.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowLeft@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineLeft.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineLeft@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineRight.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowOutlineRight@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowRight.png.svn-base
    │   │   │               │   ├── UIBarButtonItemArrowRight@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGrid.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGrid@2x.png.svn-base
    │   │   │               │   ├── UIBarButtonItemGridiOS6.png.svn-base
    │   │   │               │   └── UIBarButtonItemGridiOS6@2x.png.svn-base
    │   │   │               └── text-base/
    │   │   │                   ├── Checkmark.png.svn-base
    │   │   │                   ├── Checkmark@2x.png.svn-base
    │   │   │                   ├── ImageError.png.svn-base
    │   │   │                   ├── ImageError@2x.png.svn-base
    │   │   │                   ├── ImageSelectedOff.png.svn-base
    │   │   │                   ├── ImageSelectedOff@2x.png.svn-base
    │   │   │                   ├── ImageSelectedOn.png.svn-base
    │   │   │                   ├── ImageSelectedOn@2x.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOff.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOff@2x.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOn.png.svn-base
    │   │   │                   ├── ImageSelectedSmallOn@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowLeft.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowLeft@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineLeft.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineLeft@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineRight.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowOutlineRight@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowRight.png.svn-base
    │   │   │                   ├── UIBarButtonItemArrowRight@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemGrid.png.svn-base
    │   │   │                   ├── UIBarButtonItemGrid@2x.png.svn-base
    │   │   │                   ├── UIBarButtonItemGridiOS6.png.svn-base
    │   │   │                   └── UIBarButtonItemGridiOS6@2x.png.svn-base
    │   │   └── TZImagePickerController/
    │   │       ├── .svn/
    │   │       │   ├── all-wcprops
    │   │       │   ├── entries
    │   │       │   ├── prop-base/
    │   │       │   │   ├── UIView+Layout.h.svn-base
    │   │       │   │   └── UIView+Layout.m.svn-base
    │   │       │   └── text-base/
    │   │       │       ├── TZAssetCell.h.svn-base
    │   │       │       ├── TZAssetCell.m.svn-base
    │   │       │       ├── TZAssetModel.h.svn-base
    │   │       │       ├── TZAssetModel.m.svn-base
    │   │       │       ├── TZImageManager.h.svn-base
    │   │       │       ├── TZImageManager.m.svn-base
    │   │       │       ├── TZImagePickerController.h.svn-base
    │   │       │       ├── TZImagePickerController.m.svn-base
    │   │       │       ├── TZPhotoPickerController.h.svn-base
    │   │       │       ├── TZPhotoPickerController.m.svn-base
    │   │       │       ├── TZPhotoPreviewCell.h.svn-base
    │   │       │       ├── TZPhotoPreviewCell.m.svn-base
    │   │       │       ├── TZPhotoPreviewController.h.svn-base
    │   │       │       ├── TZPhotoPreviewController.m.svn-base
    │   │       │       ├── TZVideoPlayerController.h.svn-base
    │   │       │       ├── TZVideoPlayerController.m.svn-base
    │   │       │       ├── UIView+Layout.h.svn-base
    │   │       │       └── UIView+Layout.m.svn-base
    │   │       ├── TZAssetCell.h
    │   │       ├── TZAssetCell.m
    │   │       ├── TZAssetModel.h
    │   │       ├── TZAssetModel.m
    │   │       ├── TZImageManager.h
    │   │       ├── TZImageManager.m
    │   │       ├── TZImagePickerController.bundle/
    │   │       │   ├── .svn/
    │   │       │   │   ├── all-wcprops
    │   │       │   │   ├── entries
    │   │       │   │   ├── prop-base/
    │   │       │   │   │   ├── MMVideoPreviewPlay@2x.png.svn-base
    │   │       │   │   │   ├── MMVideoPreviewPlayHL@2x.png.svn-base
    │   │       │   │   │   ├── TableViewArrow@2x.png.svn-base
    │   │       │   │   │   ├── VideoSendIcon@2x.png.svn-base
    │   │       │   │   │   ├── navi_back@2x.png.svn-base
    │   │       │   │   │   ├── photo_def_photoPickerVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_def_previewVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_number_icon@2x.png.svn-base
    │   │       │   │   │   ├── photo_original_def@2x.png.svn-base
    │   │       │   │   │   ├── photo_original_sel@2x.png.svn-base
    │   │       │   │   │   ├── photo_sel_photoPickerVc@2x.png.svn-base
    │   │       │   │   │   ├── photo_sel_previewVc@2x.png.svn-base
    │   │       │   │   │   ├── preview_number_icon@2x.png.svn-base
    │   │       │   │   │   ├── preview_original_def@2x.png.svn-base
    │   │       │   │   │   └── takePicture@2x.png.svn-base
    │   │       │   │   └── text-base/
    │   │       │   │       ├── MMVideoPreviewPlay@2x.png.svn-base
    │   │       │   │       ├── MMVideoPreviewPlayHL@2x.png.svn-base
    │   │       │   │       ├── Root.plist.svn-base
    │   │       │   │       ├── TZAlbumCell.xib.svn-base
    │   │       │   │       ├── TZAssetCell.xib.svn-base
    │   │       │   │       ├── TableViewArrow@2x.png.svn-base
    │   │       │   │       ├── VideoSendIcon@2x.png.svn-base
    │   │       │   │       ├── navi_back@2x.png.svn-base
    │   │       │   │       ├── photo_def_photoPickerVc@2x.png.svn-base
    │   │       │   │       ├── photo_def_previewVc@2x.png.svn-base
    │   │       │   │       ├── photo_number_icon@2x.png.svn-base
    │   │       │   │       ├── photo_original_def@2x.png.svn-base
    │   │       │   │       ├── photo_original_sel@2x.png.svn-base
    │   │       │   │       ├── photo_sel_photoPickerVc@2x.png.svn-base
    │   │       │   │       ├── photo_sel_previewVc@2x.png.svn-base
    │   │       │   │       ├── preview_number_icon@2x.png.svn-base
    │   │       │   │       ├── preview_original_def@2x.png.svn-base
    │   │       │   │       └── takePicture@2x.png.svn-base
    │   │       │   ├── Root.plist
    │   │       │   ├── TZAlbumCell.xib
    │   │       │   └── TZAssetCell.xib
    │   │       ├── TZImagePickerController.h
    │   │       ├── TZImagePickerController.m
    │   │       ├── TZPhotoPickerController.h
    │   │       ├── TZPhotoPickerController.m
    │   │       ├── TZPhotoPreviewCell.h
    │   │       ├── TZPhotoPreviewCell.m
    │   │       ├── TZPhotoPreviewController.h
    │   │       ├── TZPhotoPreviewController.m
    │   │       ├── TZVideoPlayerController.h
    │   │       ├── TZVideoPlayerController.m
    │   │       ├── UIView+Layout.h
    │   │       └── UIView+Layout.m
    │   ├── ViewController.h
    │   ├── ViewController.m
    │   └── main.m
    └── SWFormExample.xcodeproj/
        ├── project.pbxproj
        └── project.xcworkspace/
            ├── contents.xcworkspacedata
            └── xcshareddata/
                └── IDEWorkspaceChecks.plist
Download .txt
SYMBOL INDEX (20 symbols across 18 files)

FILE: SWForm/SWFormManager/SWFormCompat.h
  type SWTitleShowTypeDefault (line 17) | typedef NS_ENUM(NSInteger, SWTitleShowType) {

FILE: SWFormExample/SWForm/SWFormManager/SWFormCompat.h
  type SWTitleShowTypeDefault (line 17) | typedef NS_ENUM(NSInteger, SWTitleShowType) {

FILE: SWFormExample/SWFormExample/Vendors/MBProgressHUD/MBProgressHUD.h
  type MBProgressHUDMode (line 36) | typedef enum {
  type MBProgressHUDAnimation (line 51) | typedef enum {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridCell.h
  function interface (line 14) | interface MWGridCell : PSTCollectionViewCell {}

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridViewController.h
  function interface (line 13) | interface MWGridViewController : PSTCollectionViewController {}

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhotoBrowserPrivate.h
  function interface (line 15) | interface MWPhotoBrowser () {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingImageView.h
  function interface (line 13) | interface MWTapDetectingImageView : UIImageView {}

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingView.h
  function interface (line 14) | interface MWTapDetectingView : UIView {}

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/EMSDImageCache.h
  type EMSDImageCacheTypeNone (line 12) | typedef NS_ENUM(NSInteger, EMSDImageCacheType) {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/EMSDWebImageDownloader.h
  type EMSDWebImageDownloaderFIFOExecutionOrder (line 56) | typedef NS_ENUM(NSInteger, EMSDWebImageDownloaderExecutionOrder) {
  type NSDictionary (line 75) | typedef NSDictionary *(^EMSDWebImageDownloaderHeadersFilterBlock)(NSURL ...

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/EMSDWebImageManager.h
  type NSString (line 84) | typedef NSString *(^EMSDWebImageCacheKeyFilterBlock)(NSURL *url);

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/PSTCollectionView/PSTCollectionView.h
  type PSTCollectionElementCategoryCell (line 31) | typedef NS_ENUM(NSUInteger, PSTCollectionElementCategory) {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/PSTCollectionView/PSTCollectionViewFlowLayout.h
  type PSTCollectionViewScrollDirectionVertical (line 13) | typedef NS_ENUM(NSInteger, PSTCollectionViewScrollDirection) {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/PSTCollectionView/PSTCollectionViewLayout.h
  type PSTCollectionViewItemTypeCell (line 12) | typedef NS_ENUM(NSUInteger, PSTCollectionViewItemType) {

FILE: SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/PSTCollectionView/PSTCollectionViewUpdateItem.h
  type PSTCollectionUpdateActionInsert (line 11) | typedef NS_ENUM(NSInteger, PSTCollectionUpdateAction) {

FILE: SWFormExample/SWFormExample/Vendors/TZImagePickerController/TZAssetCell.h
  type TZAssetCellType (line 11) | typedef enum : NSUInteger {

FILE: SWFormExample/SWFormExample/Vendors/TZImagePickerController/TZAssetModel.h
  type TZAssetModelMediaType (line 12) | typedef enum : NSUInteger {

FILE: SWFormExample/SWFormExample/Vendors/TZImagePickerController/UIView+Layout.h
  type TZOscillatoryAnimationType (line 10) | typedef enum : NSUInteger {
Condensed preview — 476 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,953K chars).
[
  {
    "path": "README.md",
    "chars": 1944,
    "preview": "# SWForm\n\n>详细说明戳这里:[iOS 高度封装自适应表单(重构版)](https://www.jianshu.com/p/2d2f742622fa)\n\n![image](https://github.com/RockChanel/"
  },
  {
    "path": "SWForm/SWForm.bundle/Root.plist",
    "chars": 1456,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "SWForm/SWForm.h",
    "chars": 286,
    "preview": "//\n//  SWForm.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserved.\n"
  },
  {
    "path": "SWForm/SWFormBaseController.h",
    "chars": 587,
    "preview": "//\n//  SWFormBaseController.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWForm/SWFormBaseController.m",
    "chars": 7569,
    "preview": "//\n//  SWFormBaseController.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWForm/SWFormCell/SWFormBaseCell.h",
    "chars": 523,
    "preview": "//\n//  SWFormBaseCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWForm/SWFormCell/SWFormBaseCell.m",
    "chars": 1806,
    "preview": "//\n//  SWFormBaseCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWForm/SWFormCell/SWFormImageCell.h",
    "chars": 631,
    "preview": "//\n//  SWFormImageCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormCell/SWFormImageCell.m",
    "chars": 6698,
    "preview": "//\n//  SWFormImageCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormCell/SWFormInputCell.h",
    "chars": 736,
    "preview": "//\n//  SWFormInputCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormCell/SWFormInputCell.m",
    "chars": 2841,
    "preview": "//\n//  SWFormInputCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormCell/SWFormSelectCell.h",
    "chars": 472,
    "preview": "//\n//  SWFormSelectCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights "
  },
  {
    "path": "SWForm/SWFormCell/SWFormSelectCell.m",
    "chars": 2102,
    "preview": "//\n//  SWFormSelectCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights "
  },
  {
    "path": "SWForm/SWFormCell/SWFormTextViewInputCell.h",
    "chars": 672,
    "preview": "//\n//  SWFormTextViewInputCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All "
  },
  {
    "path": "SWForm/SWFormCell/SWFormTextViewInputCell.m",
    "chars": 3603,
    "preview": "//\n//  SWFormTextViewInputCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All "
  },
  {
    "path": "SWForm/SWFormCell/SWImageCollectionCell.h",
    "chars": 552,
    "preview": "//\n//  SWImageCollectionCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWForm/SWFormCell/SWImageCollectionCell.m",
    "chars": 2655,
    "preview": "//\n//  SWImageCollectionCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWForm/SWFormHandler.h",
    "chars": 733,
    "preview": "//\n//  SWFormHandler.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights res"
  },
  {
    "path": "SWForm/SWFormHandler.m",
    "chars": 3958,
    "preview": "//\n//  SWFormHandler.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights res"
  },
  {
    "path": "SWForm/SWFormImageCell+ImageHandle.h",
    "chars": 636,
    "preview": "//\n//  SWFormImageCell+ImageHandle.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/1.\n//  Copyright © 2018年 selwyn. A"
  },
  {
    "path": "SWForm/SWFormImageCell+ImageHandle.m",
    "chars": 2403,
    "preview": "//\n//  SWFormImageCell+ImageHandle.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/1.\n//  Copyright © 2018年 selwyn. A"
  },
  {
    "path": "SWForm/SWFormItem/SWFormItem.h",
    "chars": 3240,
    "preview": "//\n//  SWFormItem.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserv"
  },
  {
    "path": "SWForm/SWFormItem/SWFormItem.m",
    "chars": 8251,
    "preview": "//\n//  SWFormItem.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserv"
  },
  {
    "path": "SWForm/SWFormItem/SWFormSectionItem.h",
    "chars": 842,
    "preview": "//\n//  SWFormSectionItem.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights"
  },
  {
    "path": "SWForm/SWFormItem/SWFormSectionItem.m",
    "chars": 661,
    "preview": "//\n//  SWFormSectionItem.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights"
  },
  {
    "path": "SWForm/SWFormManager/NSString+SWForm.h",
    "chars": 419,
    "preview": "//\n//  NSString+SWForm.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/26.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormManager/NSString+SWForm.m",
    "chars": 689,
    "preview": "//\n//  NSString+SWForm.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/26.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWForm/SWFormManager/SWFormCompat.h",
    "chars": 2017,
    "preview": "//\n//  SWFormCompat.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights rese"
  },
  {
    "path": "SWForm/SWFormManager/SWFormCompat.m",
    "chars": 931,
    "preview": "//\n//  SWFormCompat.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights rese"
  },
  {
    "path": "SWForm/SWFormManager/SelwynExpandableTextView.h",
    "chars": 707,
    "preview": "//\n//  SelwynExpandableTextView.h\n//  SelwynFormDemo\n//\n//  Created by BSW on 2017/6/24.\n//  Copyright © 2017年 selwyn. A"
  },
  {
    "path": "SWForm/SWFormManager/SelwynExpandableTextView.m",
    "chars": 11744,
    "preview": "//\n//  SelwynExpandableTextView.m\n//  SelwynFormDemo\n//\n//  Created by BSW on 2017/6/24.\n//  Copyright © 2017年 selwyn. A"
  },
  {
    "path": "SWForm/SWFormManager/UITextView+TextLimit.h",
    "chars": 306,
    "preview": "//\n//  UITextView+TextLimit.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWForm/SWFormManager/UITextView+TextLimit.m",
    "chars": 987,
    "preview": "//\n//  UITextView+TextLimit.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWForm/UIImageView+FormImage.h",
    "chars": 328,
    "preview": "//\n//  UIImageView+FormImage.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWForm/UIImageView+FormImage.m",
    "chars": 389,
    "preview": "//\n//  UIImageView+FormImage.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWFormExample/SWForm/SWForm.bundle/Root.plist",
    "chars": 1456,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "SWFormExample/SWForm/SWForm.h",
    "chars": 286,
    "preview": "//\n//  SWForm.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserved.\n"
  },
  {
    "path": "SWFormExample/SWForm/SWFormBaseController.h",
    "chars": 586,
    "preview": "//\n//  SWFormBaseController.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWForm/SWFormBaseController.m",
    "chars": 7569,
    "preview": "//\n//  SWFormBaseController.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormBaseCell.h",
    "chars": 523,
    "preview": "//\n//  SWFormBaseCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormBaseCell.m",
    "chars": 1806,
    "preview": "//\n//  SWFormBaseCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormImageCell.h",
    "chars": 631,
    "preview": "//\n//  SWFormImageCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormImageCell.m",
    "chars": 6698,
    "preview": "//\n//  SWFormImageCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormInputCell.h",
    "chars": 736,
    "preview": "//\n//  SWFormInputCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormInputCell.m",
    "chars": 2841,
    "preview": "//\n//  SWFormInputCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormSelectCell.h",
    "chars": 472,
    "preview": "//\n//  SWFormSelectCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights "
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormSelectCell.m",
    "chars": 2102,
    "preview": "//\n//  SWFormSelectCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights "
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormTextViewInputCell.h",
    "chars": 672,
    "preview": "//\n//  SWFormTextViewInputCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All "
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWFormTextViewInputCell.m",
    "chars": 3603,
    "preview": "//\n//  SWFormTextViewInputCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All "
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWImageCollectionCell.h",
    "chars": 552,
    "preview": "//\n//  SWImageCollectionCell.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWFormExample/SWForm/SWFormCell/SWImageCollectionCell.m",
    "chars": 2655,
    "preview": "//\n//  SWImageCollectionCell.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWFormExample/SWForm/SWFormHandler.h",
    "chars": 733,
    "preview": "//\n//  SWFormHandler.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights res"
  },
  {
    "path": "SWFormExample/SWForm/SWFormHandler.m",
    "chars": 3958,
    "preview": "//\n//  SWFormHandler.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/30.\n//  Copyright © 2018年 selwyn. All rights res"
  },
  {
    "path": "SWFormExample/SWForm/SWFormImageCell+ImageHandle.h",
    "chars": 636,
    "preview": "//\n//  SWFormImageCell+ImageHandle.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/1.\n//  Copyright © 2018年 selwyn. A"
  },
  {
    "path": "SWFormExample/SWForm/SWFormImageCell+ImageHandle.m",
    "chars": 7656,
    "preview": "//\n//  SWFormImageCell+ImageHandle.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/1.\n//  Copyright © 2018年 selwyn. A"
  },
  {
    "path": "SWFormExample/SWForm/SWFormItem/SWFormItem.h",
    "chars": 3240,
    "preview": "//\n//  SWFormItem.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserv"
  },
  {
    "path": "SWFormExample/SWForm/SWFormItem/SWFormItem.m",
    "chars": 8251,
    "preview": "//\n//  SWFormItem.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All rights reserv"
  },
  {
    "path": "SWFormExample/SWForm/SWFormItem/SWFormSectionItem.h",
    "chars": 842,
    "preview": "//\n//  SWFormSectionItem.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights"
  },
  {
    "path": "SWFormExample/SWForm/SWFormItem/SWFormSectionItem.m",
    "chars": 661,
    "preview": "//\n//  SWFormSectionItem.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/NSString+SWForm.h",
    "chars": 419,
    "preview": "//\n//  NSString+SWForm.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/26.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/NSString+SWForm.m",
    "chars": 689,
    "preview": "//\n//  NSString+SWForm.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/6/26.\n//  Copyright © 2018年 selwyn. All rights r"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/SWFormCompat.h",
    "chars": 2017,
    "preview": "//\n//  SWFormCompat.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights rese"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/SWFormCompat.m",
    "chars": 931,
    "preview": "//\n//  SWFormCompat.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rights rese"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/SelwynExpandableTextView.h",
    "chars": 707,
    "preview": "//\n//  SelwynExpandableTextView.h\n//  SelwynFormDemo\n//\n//  Created by BSW on 2017/6/24.\n//  Copyright © 2017年 selwyn. A"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/SelwynExpandableTextView.m",
    "chars": 11748,
    "preview": "//\n//  SelwynExpandableTextView.m\n//  SelwynFormDemo\n//\n//  Created by BSW on 2017/6/24.\n//  Copyright © 2017年 selwyn. A"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/UITextView+TextLimit.h",
    "chars": 306,
    "preview": "//\n//  UITextView+TextLimit.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWForm/SWFormManager/UITextView+TextLimit.m",
    "chars": 987,
    "preview": "//\n//  UITextView+TextLimit.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/29.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWForm/UIImageView+FormImage.h",
    "chars": 328,
    "preview": "//\n//  UIImageView+FormImage.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWFormExample/SWForm/UIImageView+FormImage.m",
    "chars": 462,
    "preview": "//\n//  UIImageView+FormImage.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All ri"
  },
  {
    "path": "SWFormExample/SWFormExample/AppDelegate.h",
    "chars": 275,
    "preview": "//\n//  AppDelegate.h\n//  SWFormExample\n//\n//  Created by zijin on 2018/6/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWFormExample/SWFormExample/AppDelegate.m",
    "chars": 2037,
    "preview": "//\n//  AppDelegate.m\n//  SWFormExample\n//\n//  Created by zijin on 2018/6/28.\n//  Copyright © 2018年 selwyn. All rights re"
  },
  {
    "path": "SWFormExample/SWFormExample/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1590,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\""
  },
  {
    "path": "SWFormExample/SWFormExample/Assets.xcassets/Contents.json",
    "chars": 62,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "SWFormExample/SWFormExample/Base.lproj/LaunchScreen.storyboard",
    "chars": 3009,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "SWFormExample/SWFormExample/Base.lproj/Main.storyboard",
    "chars": 4655,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "SWFormExample/SWFormExample/Info.plist",
    "chars": 1691,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "SWFormExample/SWFormExample/SWFormCommonController.h",
    "chars": 237,
    "preview": "//\n//  SWFormCommonController.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All r"
  },
  {
    "path": "SWFormExample/SWFormExample/SWFormCommonController.m",
    "chars": 5011,
    "preview": "//\n//  SWFormCommonController.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/28.\n//  Copyright © 2018年 selwyn. All r"
  },
  {
    "path": "SWFormExample/SWFormExample/SWFormExample.pch",
    "chars": 468,
    "preview": "//\n//  SWFormExample.pch\n//  SWFormExample\n//\n//  Created by zijin on 2018/6/28.\n//  Copyright © 2018年 selwyn. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/SWFormInfoController.h",
    "chars": 233,
    "preview": "//\n//  SWFormInfoController.h\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWFormExample/SWFormInfoController.m",
    "chars": 3278,
    "preview": "//\n//  SWFormInfoController.m\n//  SWFormDemo\n//\n//  Created by zijin on 2018/5/31.\n//  Copyright © 2018年 selwyn. All rig"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/all-wcprops",
    "chars": 1646,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 138\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/entries",
    "chars": 1411,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/prop-base/MBProgressHUD.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/prop-base/MBProgressHUD.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/Factory.h.svn-base",
    "chars": 796,
    "preview": "//\n//  Factory.h\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved.\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/Factory.m.svn-base",
    "chars": 5290,
    "preview": "//\n//  Factory.m\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved.\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD+Add.h.svn-base",
    "chars": 386,
    "preview": "//\n//  MBProgressHUD+Add.h\n//  视频客户端\n//\n//  Created by mj on 13-4-18.\n//  Copyright (c) 2013年 itcast. All rights reserve"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD+Add.m.svn-base",
    "chars": 1486,
    "preview": "//\n//  MBProgressHUD+Add.m\n//  视频客户端\n//\n//  Created by mj on 13-4-18.\n//  Copyright (c) 2013年 itcast. All rights reserve"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD.h.svn-base",
    "chars": 16269,
    "preview": "//\n//  MBProgressHUD.h\n//  Version 0.8\n//  Created by Matej Bukovinski on 2.4.09.\n//\n\n// This code is distributed under "
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MBProgressHUD.m.svn-base",
    "chars": 32691,
    "preview": "//\n// MBProgressHUD.m\n// Version 0.8\n// Created by Matej Bukovinski on 2.4.09.\n//\n\n#import \"MBProgressHUD.h\"\n\n\n#if __has"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/.svn/text-base/MacroDef.h.svn-base",
    "chars": 4503,
    "preview": "//\n//  MacroDef.h\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/Factory.h",
    "chars": 796,
    "preview": "//\n//  Factory.h\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved.\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/Factory.m",
    "chars": 5290,
    "preview": "//\n//  Factory.m\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved.\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/MBProgressHUD+Add.h",
    "chars": 386,
    "preview": "//\n//  MBProgressHUD+Add.h\n//  视频客户端\n//\n//  Created by mj on 13-4-18.\n//  Copyright (c) 2013年 itcast. All rights reserve"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/MBProgressHUD+Add.m",
    "chars": 1486,
    "preview": "//\n//  MBProgressHUD+Add.m\n//  视频客户端\n//\n//  Created by mj on 13-4-18.\n//  Copyright (c) 2013年 itcast. All rights reserve"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/MBProgressHUD.h",
    "chars": 16269,
    "preview": "//\n//  MBProgressHUD.h\n//  Version 0.8\n//  Created by Matej Bukovinski on 2.4.09.\n//\n\n// This code is distributed under "
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/MBProgressHUD.m",
    "chars": 32691,
    "preview": "//\n// MBProgressHUD.m\n// Version 0.8\n// Created by Matej Bukovinski on 2.4.09.\n//\n\n#import \"MBProgressHUD.h\"\n\n\n#if __has"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MBProgressHUD/MacroDef.h",
    "chars": 4503,
    "preview": "//\n//  MacroDef.h\n//  DongDong\n//\n//  Created by jmsre on 15/11/25.\n//  Copyright © 2015年 wangyang. All rights reserved."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/.svn/all-wcprops",
    "chars": 181,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 139\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/.svn/entries",
    "chars": 376,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/all-wcprops",
    "chars": 4478,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 147\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/entries",
    "chars": 3312,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWCaptionView.h.svn-base",
    "chars": 1049,
    "preview": "//\n//  MWCaptionView.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 30/12/2011.\n//  Copyright (c) 2011 __My"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWCaptionView.m.svn-base",
    "chars": 4261,
    "preview": "//\n//  MWCaptionView.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 30/12/2011.\n//  Copyright (c) 2011 __My"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWCommon.h.svn-base",
    "chars": 860,
    "preview": "//\n//  MWPreprocessor.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 01/10/2013.\n//\n\n#define SYSTEM_VERSION"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWGridCell.h.svn-base",
    "chars": 513,
    "preview": "//\n//  MWGridCell.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UIKit/UIKit.h>"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWGridCell.m.svn-base",
    "chars": 7473,
    "preview": "//\n//  MWGridCell.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import \"MWGridCell.h\"\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWGridViewController.h.svn-base",
    "chars": 410,
    "preview": "//\n//  MWGridViewController.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UIKi"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWGridViewController.m.svn-base",
    "chars": 6860,
    "preview": "//\n//  MWGridViewController.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import \"MWGr"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhoto.h.svn-base",
    "chars": 1115,
    "preview": "//\n//  MWPhoto.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 17/10/2010.\n//  Copyright 2010 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhoto.m.svn-base",
    "chars": 8171,
    "preview": "//\n//  MWPhoto.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 17/10/2010.\n//  Copyright 2010 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhotoBrowser.h.svn-base",
    "chars": 2740,
    "preview": "//\n//  MWPhotoBrowser.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i. Al"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhotoBrowser.m.svn-base",
    "chars": 65007,
    "preview": "//\n//  MWPhotoBrowser.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i. Al"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhotoBrowserPrivate.h.svn-base",
    "chars": 4124,
    "preview": "//\n//  MWPhotoBrowser_Private.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UI"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWPhotoProtocol.h.svn-base",
    "chars": 2545,
    "preview": "//\n//  MWPhotoProtocol.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 02/01/2012.\n//  Copyright (c) 2012 __"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWTapDetectingImageView.h.svn-base",
    "chars": 660,
    "preview": "//\n//  UIImageViewTap.h\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWTapDetectingImageView.m.svn-base",
    "chars": 1681,
    "preview": "//\n//  UIImageViewTap.m\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWTapDetectingView.h.svn-base",
    "chars": 585,
    "preview": "//\n//  UIViewTap.h\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All rights res"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWTapDetectingView.m.svn-base",
    "chars": 1375,
    "preview": "//\n//  UIViewTap.m\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All rights res"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWZoomingScrollView.h.svn-base",
    "chars": 825,
    "preview": "//\n//  ZoomingScrollView.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/.svn/text-base/MWZoomingScrollView.m.svn-base",
    "chars": 13890,
    "preview": "//\n//  ZoomingScrollView.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWCaptionView.h",
    "chars": 1049,
    "preview": "//\n//  MWCaptionView.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 30/12/2011.\n//  Copyright (c) 2011 __My"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWCaptionView.m",
    "chars": 4261,
    "preview": "//\n//  MWCaptionView.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 30/12/2011.\n//  Copyright (c) 2011 __My"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWCommon.h",
    "chars": 860,
    "preview": "//\n//  MWPreprocessor.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 01/10/2013.\n//\n\n#define SYSTEM_VERSION"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridCell.h",
    "chars": 513,
    "preview": "//\n//  MWGridCell.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UIKit/UIKit.h>"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridCell.m",
    "chars": 7473,
    "preview": "//\n//  MWGridCell.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import \"MWGridCell.h\"\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridViewController.h",
    "chars": 410,
    "preview": "//\n//  MWGridViewController.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UIKi"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWGridViewController.m",
    "chars": 6860,
    "preview": "//\n//  MWGridViewController.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import \"MWGr"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhoto.h",
    "chars": 1115,
    "preview": "//\n//  MWPhoto.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 17/10/2010.\n//  Copyright 2010 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhoto.m",
    "chars": 8171,
    "preview": "//\n//  MWPhoto.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 17/10/2010.\n//  Copyright 2010 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhotoBrowser.h",
    "chars": 2740,
    "preview": "//\n//  MWPhotoBrowser.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i. Al"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhotoBrowser.m",
    "chars": 65118,
    "preview": "//\n//  MWPhotoBrowser.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i. Al"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhotoBrowserPrivate.h",
    "chars": 4124,
    "preview": "//\n//  MWPhotoBrowser_Private.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 08/10/2013.\n//\n//\n\n#import <UI"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWPhotoProtocol.h",
    "chars": 2545,
    "preview": "//\n//  MWPhotoProtocol.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 02/01/2012.\n//  Copyright (c) 2012 __"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingImageView.h",
    "chars": 660,
    "preview": "//\n//  UIImageViewTap.h\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingImageView.m",
    "chars": 1681,
    "preview": "//\n//  UIImageViewTap.m\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All right"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingView.h",
    "chars": 610,
    "preview": "//\n//  UIViewTap.h\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All rights res"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWTapDetectingView.m",
    "chars": 1375,
    "preview": "//\n//  UIViewTap.m\n//  Momento\n//\n//  Created by Michael Waterfall on 04/11/2009.\n//  Copyright 2009 d3i. All rights res"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWZoomingScrollView.h",
    "chars": 825,
    "preview": "//\n//  ZoomingScrollView.h\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Classes/MWZoomingScrollView.m",
    "chars": 13890,
    "preview": "//\n//  ZoomingScrollView.m\n//  MWPhotoBrowser\n//\n//  Created by Michael Waterfall on 14/10/2010.\n//  Copyright 2010 d3i."
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/.svn/all-wcprops",
    "chars": 191,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 149\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/.svn/entries",
    "chars": 396,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/all-wcprops",
    "chars": 730,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 168\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/entries",
    "chars": 692,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/prop-base/DACircularProgressView.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/prop-base/DACircularProgressView.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/text-base/DACircularProgressView.h.svn-base",
    "chars": 883,
    "preview": "//\n//  DACircularProgressView.h\n//  DACircularProgress\n//\n//  Created by Daniel Amitay on 2/6/12.\n//  Copyright (c) 2012"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/.svn/text-base/DACircularProgressView.m.svn-base",
    "chars": 7307,
    "preview": "//\n//  DACircularProgressView.m\n//  DACircularProgress\n//\n//  Created by Daniel Amitay on 2/6/12.\n//  Copyright (c) 2012"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/DACircularProgressView.h",
    "chars": 883,
    "preview": "//\n//  DACircularProgressView.h\n//  DACircularProgress\n//\n//  Created by Daniel Amitay on 2/6/12.\n//  Copyright (c) 2012"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/DACircularProgress/DACircularProgressView.m",
    "chars": 7307,
    "preview": "//\n//  DACircularProgressView.m\n//  DACircularProgress\n//\n//  Created by Daniel Amitay on 2/6/12.\n//  Copyright (c) 2012"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/all-wcprops",
    "chars": 8556,
    "preview": "K 25\nsvn:wc:ra_dav:version-url\nV 162\n/zhuku/repo/!svn/ver/4261/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatD"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/entries",
    "chars": 6035,
    "preview": "10\n\ndir\n4265\nhttp://bishanwen@121.43.163.28:9090/zhuku/repo/zhuku-ios/trunk/zhuku-iOS/trunk/ios-zhuku2017.12.28/ChatDemo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDImageCache.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDImageCache.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageCompat.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageCompat.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDecoder.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDecoder.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDownloader.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDownloader.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDownloaderOperation.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageDownloaderOperation.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageManager.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageManager.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImageOperation.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImagePrefetcher.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/EMSDWebImagePrefetcher.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/MKAnnotationView+EMWebCache.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/MKAnnotationView+EMWebCache.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/NSData+EMImageContentType.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/NSData+EMImageContentType.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIButton+EMWebCache.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIButton+EMWebCache.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMGIF.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMGIF.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMMultiFormat.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMMultiFormat.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMWebP.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImage+EMWebP.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImageView+EMHighlightedWebCache.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImageView+EMHighlightedWebCache.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImageView+EMWebCache.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIImageView+EMWebCache.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIView+EMWebCacheOperation.h.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/prop-base/UIView+EMWebCacheOperation.m.svn-base",
    "chars": 29,
    "preview": "K 14\nsvn:executable\nV 0\n\nEND\n"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDImageCache.h.svn-base",
    "chars": 7555,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDImageCache.m.svn-base",
    "chars": 19401,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageCompat.h.svn-base",
    "chars": 1735,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n * (c) Jamie Pinkham\n *\n "
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageCompat.m.svn-base",
    "chars": 1482,
    "preview": "//\n//  EMSDWebImageCompat.m\n//  SDWebImage\n//\n//  Created by Olivier Poitrey on 11/12/12.\n//  Copyright (c) 2012 Dailymo"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDecoder.h.svn-base",
    "chars": 455,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * Created by james <h"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDecoder.m.svn-base",
    "chars": 2598,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * Created by james <h"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDownloader.h.svn-base",
    "chars": 6103,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDownloader.m.svn-base",
    "chars": 11105,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDownloaderOperation.h.svn-base",
    "chars": 2371,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageDownloaderOperation.m.svn-base",
    "chars": 15894,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageManager.h.svn-base",
    "chars": 10641,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageManager.m.svn-base",
    "chars": 14560,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImageOperation.h.svn-base",
    "chars": 331,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  },
  {
    "path": "SWFormExample/SWFormExample/Vendors/MWPhotoBrowser/Libraries/EMSDWebImage/.svn/text-base/EMSDWebImagePrefetcher.h.svn-base",
    "chars": 3623,
    "preview": "/*\n * This file is part of the SDWebImage package.\n * (c) Olivier Poitrey <rs@dailymotion.com>\n *\n * For the full copyri"
  }
]

// ... and 276 more files (download for full content)

About this extraction

This page contains the full source code of the RockChanel/SWForm GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 476 files (1.7 MB), approximately 463.8k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!