├── LICENSE ├── README.md ├── ZJPasswordStyle.podspec ├── ZJPasswordStyle └── 1.2.5 │ └── ZJPasswordStyle.podspec ├── ZJPasswordStyleView ├── .DS_Store ├── ZJPasswordFile │ ├── Base │ │ ├── ZJKeyboardHelperView.h │ │ ├── ZJKeyboardHelperView.m │ │ ├── ZJPSWBaseTextField.h │ │ ├── ZJPSWBaseTextField.m │ │ ├── ZJPSWBaseView.h │ │ ├── ZJPSWBaseView.m │ │ └── ZJUIHeader.h │ ├── Lib │ │ ├── .DS_Store │ │ ├── Category │ │ │ ├── NSString+ZJTools.h │ │ │ └── NSString+ZJTools.m │ │ └── Masonry │ │ │ ├── MASCompositeConstraint.h │ │ │ ├── MASCompositeConstraint.m │ │ │ ├── MASConstraint+Private.h │ │ │ ├── MASConstraint.h │ │ │ ├── MASConstraint.m │ │ │ ├── MASConstraintMaker.h │ │ │ ├── MASConstraintMaker.m │ │ │ ├── MASLayoutConstraint.h │ │ │ ├── MASLayoutConstraint.m │ │ │ ├── MASUtilities.h │ │ │ ├── MASViewAttribute.h │ │ │ ├── MASViewAttribute.m │ │ │ ├── MASViewConstraint.h │ │ │ ├── MASViewConstraint.m │ │ │ ├── Masonry.h │ │ │ ├── NSArray+MASAdditions.h │ │ │ ├── NSArray+MASAdditions.m │ │ │ ├── NSArray+MASShorthandAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.m │ │ │ ├── View+MASAdditions.h │ │ │ ├── View+MASAdditions.m │ │ │ ├── View+MASShorthandAdditions.h │ │ │ ├── ViewController+MASAdditions.h │ │ │ └── ViewController+MASAdditions.m │ └── TextfiledView │ │ ├── AnimatedView │ │ ├── ZJCircleAnimatedView.h │ │ ├── ZJCircleAnimatedView.m │ │ ├── ZJSuccessLoadingView.h │ │ └── ZJSuccessLoadingView.m │ │ ├── TestViewController │ │ ├── ZJModel.h │ │ ├── ZJModel.m │ │ ├── ZJPasswordStyleViewController.h │ │ └── ZJPasswordStyleViewController.m │ │ ├── TextfiledViewElement │ │ ├── ZJPSWRectEncryptView.h │ │ └── ZJPSWRectEncryptView.m │ │ ├── ZJDotView │ │ ├── ZJMaskView.h │ │ ├── ZJMaskView.m │ │ ├── ZJPSWLineDotEncryptionView.h │ │ ├── ZJPSWLineDotEncryptionView.m │ │ ├── ZJPSWLineDotNormalView.h │ │ ├── ZJPSWLineDotNormalView.m │ │ ├── ZJPSWRectDotEncryptionView.h │ │ ├── ZJPSWRectDotEncryptionView.m │ │ ├── ZJPSWRectDotNormalView.h │ │ ├── ZJPSWRectDotNormalView.m │ │ ├── ZJPasswordDotView.h │ │ └── ZJPasswordDotView.m │ │ ├── ZJPasswordViewHeader.h │ │ ├── ZJPasswordViewProtocol.h │ │ └── ZJTextfieldView │ │ ├── ZJPSWLineEncryptTextfiledView.h │ │ ├── ZJPSWLineEncryptTextfiledView.m │ │ ├── ZJPSWLineNormalTextfiledView.h │ │ ├── ZJPSWLineNormalTextfiledView.m │ │ ├── ZJPSWRectAnimateTextfieldView.h │ │ ├── ZJPSWRectAnimateTextfieldView.m │ │ ├── ZJPSWRectEncryptTextfiledView.h │ │ ├── ZJPSWRectEncryptTextfiledView.m │ │ ├── ZJPSWRectNormalTextfieldView.h │ │ ├── ZJPSWRectNormalTextfieldView.m │ │ ├── ZJPSWTextfieldContext.h │ │ └── ZJPSWTextfieldContext.m ├── ZJPasswordStyleView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcuserdata │ │ │ └── ZhangJunjun.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── ZhangJunjun.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── ZJPasswordStyleView │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── wx_Back_icon_normal.imageset │ │ ├── Contents.json │ │ └── wx_Back_icon_normal@3x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── 样式截图 ├── PasswordAnimated.gif ├── 下划线高亮密文.png ├── 下划线高亮明文.png ├── 矩形框密文.png ├── 矩形框密文密码长度达到6位.png ├── 矩形框明文6位密码.png └── 矩形框明文输入密码.png /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 FreshManCode <649283213@qq.com> 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZJPasswordStyle 2 | 3 | 用于平时开发过程中用到的密码输入框的样式问题,本案例提供了四中样式,案例中有些写法使用了继承有些使用了协议,如有需要可以自行修改或者再次封装处理,如果发现有问题,请issue,谢谢. 4 | 5 | --- 6 | ## 安装方式 7 | * 1.正常的方式,git clone之后,把相关文件资源拉入到自己的项目中 8 | * 2.使用*pod*安装,**pod search ZJPasswordStyle** ,之后会出现相关的说明 9 | * 3.在iOS14上,当已经输入1-2位验证码时,此时收到了短信验证码,然后用工具栏来输入短信验证码时,会出现的相关issue在1.2.5版本已经修复. 10 | 11 | --- 12 | 13 | #### 下面样式是目前使用比较多的样式: 14 | 15 | * 下划线高亮明文输入框样式,如下图 16 | 17 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E4%B8%8B%E5%88%92%E7%BA%BF%E9%AB%98%E4%BA%AE%E6%98%8E%E6%96%87.png) 18 | 19 | 20 | * 下划线高亮密文样式,如下图: 21 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E4%B8%8B%E5%88%92%E7%BA%BF%E9%AB%98%E4%BA%AE%E5%AF%86%E6%96%87.png) 22 | 23 | * 矩形框明文样式,如下图: 24 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E7%9F%A9%E5%BD%A2%E6%A1%86%E6%98%8E%E6%96%87%E8%BE%93%E5%85%A5%E5%AF%86%E7%A0%81.png) 25 | 26 | * 矩形框密文样式,如下图: 27 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E7%9F%A9%E5%BD%A2%E6%A1%86%E5%AF%86%E6%96%87.png) 28 | 29 | 30 | 输入到指定位数(目前设定的是6位,项目中有对应的回调,本例使用了Alert提示如下图:) 31 | 32 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E7%9F%A9%E5%BD%A2%E6%A1%86%E5%AF%86%E6%96%87%E5%AF%86%E7%A0%81%E9%95%BF%E5%BA%A6%E8%BE%BE%E5%88%B06%E4%BD%8D.png) 33 | 34 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/%E7%9F%A9%E5%BD%A2%E6%A1%86%E6%98%8E%E6%96%876%E4%BD%8D%E5%AF%86%E7%A0%81.png) 35 | 36 | * 输入密码之后,具有类似于支付宝提交支付密码的一个过渡提交动画.具体样式如下gif展示: 37 | 38 | ![](https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/PasswordAnimated.gif) 39 | 40 | *注: *动画的实现参考了这篇博主的实现思路,起初我还以为是图片,后来看到了这个思路恍然大悟.原文的链接如下:[原文地址](https://blog.csdn.net/u013282507/article/details/70208141) 41 | 42 | 如需要自行修改回调逻辑以及相关样式可以参照对应的子类以及**ZJPasswordViewProtocol**这个协议类中,包含了回调的委托方法,以及可以自定义相关样式或者逻辑的TextfieldView应该事先的协议方法. 43 | 44 | 下述则是委托方法,包含了目前定义的几种事件类型,以及输入达到6位密码之后的通知. 45 | /** 46 | 对应的代理事件 47 | 48 | @param textfieldView 响应的包含Textfield 的view 49 | @param result 加密后的结果(有些情况下可能为空) 50 | @param type 事件类型 51 | */ 52 | - (void)textfieldView:(UIView *)textfieldView 53 | result:(NSString *)result 54 | eventType:(ZJPasswordViewEventType)type; 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ZJPasswordStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint ZJPasswordStyle.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # pod trunk push ZJPasswordStyle.podspec --use-libraries --allow-warnings 8 | 9 | Pod::Spec.new do |spec| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | spec.name = "ZJPasswordStyle" 19 | spec.version = "1.2.5" 20 | spec.summary = "常用的密码输入框样式" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = "用于平时开发过程中用到的密码输入框的样式问题,本案例提供了四中样式,案例中有些写法使用了继承有些使用了协议,如有需要可以自行修改或者再次封装处理" 28 | 29 | spec.homepage = "https://github.com/FreshManCode/ZJPasswordStyle" 30 | spec.screenshots = "https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/PasswordAnimated.gif" 31 | 32 | 33 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 34 | # 35 | # Licensing your code is important. See https://choosealicense.com for more info. 36 | # CocoaPods will detect a license file if there is a named LICENSE* 37 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 38 | # 39 | 40 | spec.license = { :type => "MIT", :file => "LICENSE" } 41 | 42 | 43 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 44 | # 45 | # Specify the authors of the library, with email addresses. Email addresses 46 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 47 | # accepts just a name if you'd rather not provide an email address. 48 | # 49 | # Specify a social_media_url where others can refer to, for example a twitter 50 | # profile URL. 51 | # 52 | 53 | spec.author = { "张君君" => "649283213@qq.com" } 54 | # Or just: spec.author = "张君君" 55 | # spec.authors = { "张君君" => "649283213@qq.com" } 56 | # spec.social_media_url = "https://twitter.com/张君君" 57 | 58 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 59 | # 60 | # If this Pod runs only on iOS or OS X, then specify the platform and 61 | # the deployment target. You can optionally include the target after the platform. 62 | # 63 | 64 | # When using multiple platforms 65 | spec.ios.deployment_target = "9.0" 66 | # spec.osx.deployment_target = "10.7" 67 | # spec.watchos.deployment_target = "2.0" 68 | # spec.tvos.deployment_target = "9.0" 69 | 70 | 71 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 72 | # 73 | # Specify the location from where the source should be retrieved. 74 | # Supports git, hg, bzr, svn and HTTP. 75 | # 76 | 77 | spec.source = { :git => "https://github.com/FreshManCode/ZJPasswordStyle.git", :tag => spec.version } 78 | 79 | 80 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 81 | # 82 | # CocoaPods is smart about how it includes source code. For source files 83 | # giving a folder will include any swift, h, m, mm, c & cpp files. 84 | # For header files it will include any header in the folder. 85 | # Not including the public_header_files will make all headers public. 86 | # 87 | 88 | spec.source_files = "ZJPasswordStyleView/ZJPasswordFile/Base/*","ZJPasswordStyleView/ZJPasswordFile/Lib/**/*.{h,m}","ZJPasswordStyleView/ZJPasswordFile/TextfiledView/*.{h,m}","ZJPasswordStyleView/ZJPasswordFile/TextfiledView/**/*.{h,m}" 89 | 90 | 91 | #spec.exclude_files = "Classes/Exclude" 92 | 93 | #spec.public_header_files = "ZJPasswordStyleView/ZJPasswordStyleView/Base/*.h" 94 | #spec.public_header_files = "ZJPasswordStyleView/ZJPasswordStyleView/TextfiledView/**/*.h" 95 | 96 | 97 | 98 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 99 | # 100 | # A list of resources included with the Pod. These are copied into the 101 | # target bundle with a build phase script. Anything else will be cleaned. 102 | # You can preserve files from being cleaned, please don't preserve 103 | # non-essential files like tests, examples and documentation. 104 | # 105 | 106 | # spec.resource = "icon.png" 107 | # spec.resources = "Resources/*.png" 108 | 109 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 110 | 111 | 112 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 113 | # 114 | # Link your library with frameworks, or libraries. Libraries do not include 115 | # the lib prefix of their name. 116 | # 117 | 118 | # spec.framework = "SomeFramework" 119 | # spec.frameworks = "SomeFramework", "AnotherFramework" 120 | 121 | # spec.library = "iconv" 122 | # spec.libraries = "iconv", "xml2" 123 | 124 | 125 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 126 | # 127 | # If your library depends on compiler flags you can set them in the xcconfig hash 128 | # where they will only apply to your library. If you depend on other Podspecs 129 | # you can include multiple dependencies to ensure it works. 130 | 131 | # spec.requires_arc = true 132 | 133 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 134 | # spec.dependency "JSONKit", "~> 1.4" 135 | 136 | end 137 | -------------------------------------------------------------------------------- /ZJPasswordStyle/1.2.5/ZJPasswordStyle.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint ZJPasswordStyle.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # pod trunk push ZJPasswordStyle.podspec --use-libraries --allow-warnings 8 | 9 | Pod::Spec.new do |spec| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | spec.name = "ZJPasswordStyle" 19 | spec.version = "1.2.5" 20 | spec.summary = "常用的密码输入框样式" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = "用于平时开发过程中用到的密码输入框的样式问题,本案例提供了四中样式,案例中有些写法使用了继承有些使用了协议,如有需要可以自行修改或者再次封装处理" 28 | 29 | spec.homepage = "https://github.com/FreshManCode/ZJPasswordStyle" 30 | spec.screenshots = "https://xunpizhangjj.coding.net/p/CodingImageURL/d/CodingImageURL/git/raw/master/PasswordStyle/PasswordAnimated.gif" 31 | 32 | 33 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 34 | # 35 | # Licensing your code is important. See https://choosealicense.com for more info. 36 | # CocoaPods will detect a license file if there is a named LICENSE* 37 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 38 | # 39 | 40 | spec.license = { :type => "MIT", :file => "LICENSE" } 41 | 42 | 43 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 44 | # 45 | # Specify the authors of the library, with email addresses. Email addresses 46 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 47 | # accepts just a name if you'd rather not provide an email address. 48 | # 49 | # Specify a social_media_url where others can refer to, for example a twitter 50 | # profile URL. 51 | # 52 | 53 | spec.author = { "张君君" => "649283213@qq.com" } 54 | # Or just: spec.author = "张君君" 55 | # spec.authors = { "张君君" => "649283213@qq.com" } 56 | # spec.social_media_url = "https://twitter.com/张君君" 57 | 58 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 59 | # 60 | # If this Pod runs only on iOS or OS X, then specify the platform and 61 | # the deployment target. You can optionally include the target after the platform. 62 | # 63 | 64 | # When using multiple platforms 65 | spec.ios.deployment_target = "9.0" 66 | # spec.osx.deployment_target = "10.7" 67 | # spec.watchos.deployment_target = "2.0" 68 | # spec.tvos.deployment_target = "9.0" 69 | 70 | 71 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 72 | # 73 | # Specify the location from where the source should be retrieved. 74 | # Supports git, hg, bzr, svn and HTTP. 75 | # 76 | 77 | spec.source = { :git => "https://github.com/FreshManCode/ZJPasswordStyle.git", :tag => spec.version } 78 | 79 | 80 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 81 | # 82 | # CocoaPods is smart about how it includes source code. For source files 83 | # giving a folder will include any swift, h, m, mm, c & cpp files. 84 | # For header files it will include any header in the folder. 85 | # Not including the public_header_files will make all headers public. 86 | # 87 | 88 | spec.source_files = "ZJPasswordStyleView/ZJPasswordFile/Base/*","ZJPasswordStyleView/ZJPasswordFile/Lib/**/*.{h,m}","ZJPasswordStyleView/ZJPasswordFile/TextfiledView/*.{h,m}","ZJPasswordStyleView/ZJPasswordFile/TextfiledView/**/*.{h,m}" 89 | 90 | 91 | #spec.exclude_files = "Classes/Exclude" 92 | 93 | #spec.public_header_files = "ZJPasswordStyleView/ZJPasswordStyleView/Base/*.h" 94 | #spec.public_header_files = "ZJPasswordStyleView/ZJPasswordStyleView/TextfiledView/**/*.h" 95 | 96 | 97 | 98 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 99 | # 100 | # A list of resources included with the Pod. These are copied into the 101 | # target bundle with a build phase script. Anything else will be cleaned. 102 | # You can preserve files from being cleaned, please don't preserve 103 | # non-essential files like tests, examples and documentation. 104 | # 105 | 106 | # spec.resource = "icon.png" 107 | # spec.resources = "Resources/*.png" 108 | 109 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 110 | 111 | 112 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 113 | # 114 | # Link your library with frameworks, or libraries. Libraries do not include 115 | # the lib prefix of their name. 116 | # 117 | 118 | # spec.framework = "SomeFramework" 119 | # spec.frameworks = "SomeFramework", "AnotherFramework" 120 | 121 | # spec.library = "iconv" 122 | # spec.libraries = "iconv", "xml2" 123 | 124 | 125 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 126 | # 127 | # If your library depends on compiler flags you can set them in the xcconfig hash 128 | # where they will only apply to your library. If you depend on other Podspecs 129 | # you can include multiple dependencies to ensure it works. 130 | 131 | # spec.requires_arc = true 132 | 133 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 134 | # spec.dependency "JSONKit", "~> 1.4" 135 | 136 | end 137 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/ZJPasswordStyleView/.DS_Store -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJKeyboardHelperView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJKeyboardHelperView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJKeyboardHelperView : ZJPSWBaseView 14 | 15 | + (instancetype)createHelerViewWithFrame:(CGRect)frame 16 | keyboardDismiss:(void(^)(void))dismiss; 17 | 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJKeyboardHelperView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJKeyboardHelperView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJKeyboardHelperView.h" 10 | 11 | @interface ZJKeyboardHelperView () 12 | 13 | @property (nonatomic, strong) UIButton *downButton; 14 | @property (nonatomic, strong) UIView *sepratorLine; 15 | @property (nonatomic, strong) UIView *bottomSepratorLine; 16 | @property (nonatomic,copy) void (^DismissEvent)(void); 17 | 18 | 19 | @end 20 | 21 | @implementation ZJKeyboardHelperView 22 | 23 | static CGFloat const kButtonW = 40.f; 24 | 25 | + (instancetype)createHelerViewWithFrame:(CGRect)frame 26 | keyboardDismiss:(void(^)(void))dismiss { 27 | ZJKeyboardHelperView *helerView = [[ZJKeyboardHelperView alloc] initWithFrame:frame]; 28 | helerView.DismissEvent = dismiss; 29 | return helerView; 30 | } 31 | - (id)initWithFrame:(CGRect)frame { 32 | if (self = [super initWithFrame:frame]) { 33 | 34 | _downButton = [UIButton buttonWithType:UIButtonTypeCustom]; 35 | UIImage *image = ZJImage(@"wx_Back_icon_normal"); 36 | [_downButton setBackgroundImage:image forState:UIControlStateNormal]; 37 | [_downButton setBackgroundImage:image forState:UIControlStateSelected]; 38 | [_downButton setBackgroundImage:image forState:UIControlStateHighlighted]; 39 | _downButton.transform = [self rotateTransform]; 40 | CGFloat w = CGRectGetWidth(frame); 41 | CGFloat h = CGRectGetHeight(frame); 42 | _downButton.frame = CGRectMake((w - kButtonW)/2.0, ( h - kButtonW )/2.0, kButtonW, kButtonW); 43 | [_downButton addTarget:self action:@selector(downEvent:) forControlEvents:UIControlEventTouchUpInside]; 44 | [self addSubview:_downButton]; 45 | 46 | _sepratorLine = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 1.f)]; 47 | [_sepratorLine setBackgroundColor:ZJColorWithHex(0xF4F4F4)]; 48 | [self addSubview:_sepratorLine]; 49 | 50 | _bottomSepratorLine = [[UIView alloc] initWithFrame:CGRectMake(0, h - 1, w, 1.f)]; 51 | [_bottomSepratorLine setBackgroundColor:ZJColorWithHex(0xF4F4F4)]; 52 | [self addSubview:_bottomSepratorLine]; 53 | } 54 | return self; 55 | } 56 | 57 | - (CGAffineTransform)rotateTransform { 58 | CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_2 + M_PI); 59 | return transform; 60 | } 61 | 62 | - (void)downEvent:(UIButton *)sender { 63 | !self.DismissEvent ? : self.DismissEvent(); 64 | } 65 | 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJPSWBaseTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJBaseTextField.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2018/12/20. 6 | // Copyright © 2018年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface ZJPSWBaseTextField : UITextField 13 | 14 | @property (nonatomic,weak) id pDelegate; 15 | @property (nonatomic, assign) NSInteger maxCount; 16 | /// 是否过滤空格,默认为true 17 | @property (nonatomic, assign) BOOL filterSpace; 18 | 19 | /// 输入框内容发生了变化回调 20 | @property (nonatomic,copy) void (^TextFieldDidChange)(UITextField *textField); 21 | 22 | /** 23 | 是否允许长按弹出 Copy等相关选择框 (YES/NO) 24 | */ 25 | @property (nonatomic, assign) BOOL allowCopyMenu; 26 | 27 | 28 | /** 29 | 是否允许显示键盘上方的工具条 30 | */ 31 | @property (nonatomic, assign) BOOL showToolbarView; 32 | 33 | 34 | /** 35 | 工具条事件回调 36 | */ 37 | @property (nonatomic,copy) void (^ToolBarViewEvent)(void); 38 | 39 | 40 | 41 | - (BOOL)isReachMaxCountCharacterRange:(NSRange)range replacmentString:(NSString *)string; 42 | 43 | 44 | @end 45 | 46 | 47 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJPSWBaseTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJBaseTextField.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2018/12/20. 6 | // Copyright © 2018年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseTextField.h" 10 | #import "ZJKeyboardHelperView.h" 11 | #import "NSString+ZJTools.h" 12 | 13 | @interface ZJTextFieldHelper : NSObject 14 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 15 | 16 | @end 17 | 18 | @implementation ZJTextFieldHelper 19 | 20 | - (instancetype)initWithTextField:(ZJPSWBaseTextField *)textField { 21 | if (self = [super init]) { 22 | self.textField = textField; 23 | self.textField.delegate = self; 24 | } 25 | return self; 26 | } 27 | 28 | // MARK: - UITextFieldDelegate 29 | 30 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 31 | id pDelegate = [(ZJPSWBaseTextField *)textField pDelegate]; 32 | if ([pDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { 33 | [pDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string]; 34 | } 35 | 36 | ZJPSWBaseTextField *p_textField = (ZJPSWBaseTextField *)textField; 37 | // 判断是否达到设定的最大值 38 | if ([p_textField isReachMaxCountCharacterRange:range replacmentString:string ]) { 39 | return NO; 40 | } 41 | return true; 42 | } 43 | 44 | - (BOOL)textFieldShouldClear:(UITextField *)textField { 45 | id pDelegate = [(ZJPSWBaseTextField *)textField pDelegate]; 46 | if ([pDelegate respondsToSelector:@selector(textFieldShouldClear:)]) { 47 | return [pDelegate textFieldShouldClear:textField]; 48 | } 49 | return true; 50 | } 51 | 52 | - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { 53 | id pDelegate = [(ZJPSWBaseTextField *)textField pDelegate]; 54 | if ([pDelegate respondsToSelector:@selector(textFieldShouldBeginEditing:)]) { 55 | return [pDelegate textFieldShouldBeginEditing:textField]; 56 | } 57 | return true; 58 | } 59 | 60 | - (BOOL)textFieldShouldEndEditing:(UITextField *)textField { 61 | id pDelegate = [(ZJPSWBaseTextField *)textField pDelegate]; 62 | if ([pDelegate respondsToSelector:@selector(textFieldShouldEndEditing:)]) { 63 | return [pDelegate textFieldShouldEndEditing:textField]; 64 | } 65 | return true; 66 | } 67 | 68 | - (void)textFieldDidBeginEditing:(UITextField *)textField { 69 | id pDelegate = ((ZJPSWBaseTextField*)textField).pDelegate; 70 | if([pDelegate respondsToSelector:@selector(textFieldDidBeginEditing:)]) { 71 | [pDelegate textFieldDidBeginEditing:textField]; 72 | } 73 | } 74 | 75 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 76 | id pDelegate = ((ZJPSWBaseTextField*)textField).pDelegate; 77 | if([pDelegate respondsToSelector:@selector(textFieldShouldReturn:)]) { 78 | return [pDelegate textFieldShouldReturn:textField]; 79 | } 80 | return YES; 81 | } 82 | 83 | 84 | @end 85 | 86 | @interface ZJPSWBaseTextField () 87 | 88 | @property (nonatomic, strong) ZJTextFieldHelper *fieldHelper; 89 | @property (nonatomic, strong) ZJKeyboardHelperView *helperView; 90 | 91 | 92 | @end 93 | 94 | 95 | @implementation ZJPSWBaseTextField 96 | 97 | 98 | - (instancetype)init { 99 | if (self = [super init]) { 100 | [self p_defaultInit]; 101 | } 102 | return self; 103 | } 104 | 105 | - (void)p_defaultInit { 106 | self.translatesAutoresizingMaskIntoConstraints = NO; 107 | self.borderStyle = UITextBorderStyleNone; 108 | self.clearButtonMode = UITextFieldViewModeWhileEditing; 109 | self.autocorrectionType = UITextAutocorrectionTypeNo; 110 | self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 111 | [self addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged]; 112 | _maxCount = 0; 113 | _fieldHelper = [[ZJTextFieldHelper alloc] initWithTextField:self]; 114 | self.filterSpace = true; 115 | } 116 | 117 | - (void)setShowToolbarView:(BOOL)showToolbarView { 118 | if (showToolbarView) { 119 | [self setInputAccessoryView:self.helperView]; 120 | } 121 | } 122 | 123 | - (BOOL)isReachMaxCountCharacterRange:(NSRange)range replacmentString:(NSString *)string { 124 | if (self.maxCount < 1) { 125 | return false; 126 | } 127 | NSString *new_string = [self.text stringByReplacingCharactersInRange:range withString:string]; 128 | if (new_string.length > _maxCount) { 129 | return YES; 130 | } 131 | return false; 132 | } 133 | 134 | - (void)textFieldChanged:(UITextField *)textField { 135 | __weak typeof(textField) weakTextField = textField; 136 | if (self.filterSpace) { 137 | NSString *tempText = textField.text; 138 | if ([tempText containsString:@" "]) { 139 | tempText = [tempText filterSpaceChar]; 140 | textField.text = tempText; 141 | } 142 | } 143 | !self.TextFieldDidChange? : self.TextFieldDidChange(weakTextField); 144 | } 145 | 146 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 147 | if (self.allowCopyMenu) { 148 | return [super canPerformAction:action withSender:sender]; 149 | } 150 | UIMenuController *menuController = [UIMenuController sharedMenuController]; 151 | if (menuController) { 152 | menuController.menuVisible = NO; 153 | } 154 | return false; 155 | } 156 | 157 | 158 | 159 | - (ZJKeyboardHelperView *)helperView{ 160 | if(!_helperView){ 161 | __weak typeof(self) weakSelf = self; 162 | _helperView = [ZJKeyboardHelperView createHelerViewWithFrame:CGRectMake(0, 0, ZJWinodwWidth, 45) keyboardDismiss:^{ 163 | !weakSelf.ToolBarViewEvent ? : weakSelf.ToolBarViewEvent (); 164 | }]; 165 | } 166 | return _helperView; 167 | } 168 | 169 | 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJPSWBaseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWBaseView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Masonry.h" 11 | #import "ZJUIHeader.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface ZJPSWBaseView : UIView 16 | 17 | - (void)zj_addSubviews; 18 | 19 | - (void)zj_addConstraints; 20 | 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJPSWBaseView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJBaseView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | 11 | 12 | @implementation ZJPSWBaseView 13 | 14 | - (void)awakeFromNib { 15 | [super awakeFromNib]; 16 | [self zj_addSubviews]; 17 | [self zj_addConstraints]; 18 | } 19 | 20 | - (id)initWithFrame:(CGRect)frame { 21 | if (self = [super initWithFrame:frame]) { 22 | [self zj_addSubviews]; 23 | [self zj_addConstraints]; 24 | } 25 | return self; 26 | } 27 | 28 | 29 | - (void)zj_addSubviews { 30 | 31 | } 32 | 33 | - (void)zj_addConstraints { 34 | 35 | } 36 | @end 37 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Base/ZJUIHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJUIHeader.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/1/22. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define Font(a) [UIFont systemFontOfSize:a] 12 | #define BFont(a) [UIFont boldSystemFontOfSize:a] 13 | #define ZJImage(name) [UIImage imageNamed:name] 14 | 15 | #define ZJWinodwWidth [UIScreen mainScreen].bounds.size.width 16 | #define ZJWinodwHeight [UIScreen mainScreen].bounds.size.height 17 | 18 | 19 | 20 | #define ZJColorWithHex(value) [UIColor \ 21 | colorWithRed:((float)((value & 0xFF0000) >> 16))/255.0 \ 22 | green:((float)((value & 0xFF00) >> 8))/255.0 \ 23 | blue:((float)(value & 0xFF))/255.0 alpha:1.0] 24 | 25 | #define ZJAfter(timer,block) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timer * NSEC_PER_SEC)), dispatch_get_main_queue(),block) 26 | 27 | 28 | static inline UILabel * CreateLeftAlignmentLabel(UIFont *font,UIColor *textColor) { 29 | UILabel *leftLabel = [UILabel new]; 30 | leftLabel.font = font; 31 | leftLabel.textColor = textColor; 32 | leftLabel.textAlignment = NSTextAlignmentLeft; 33 | leftLabel.adjustsFontSizeToFitWidth = true; 34 | //宽度不够狗时压缩 35 | [leftLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 36 | //宽度够时正常显示 37 | [leftLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 38 | return leftLabel; 39 | } 40 | 41 | static inline UILabel * CreateCenterAlignmentLabel(UIFont *font,UIColor *textColor) { 42 | UILabel *leftLabel = [UILabel new]; 43 | leftLabel.font = font; 44 | leftLabel.textColor = textColor; 45 | leftLabel.textAlignment = NSTextAlignmentCenter; 46 | leftLabel.adjustsFontSizeToFitWidth = true; 47 | //宽度不够狗时压缩 48 | [leftLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 49 | //宽度够时正常显示 50 | [leftLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 51 | return leftLabel; 52 | } 53 | 54 | static inline UILabel * CreateRightAlignmentLabel(UIFont *font,UIColor *textColor) { 55 | UILabel *leftLabel = [UILabel new]; 56 | leftLabel.font = font; 57 | leftLabel.textColor = textColor; 58 | leftLabel.textAlignment = NSTextAlignmentRight; 59 | leftLabel.adjustsFontSizeToFitWidth = true; 60 | //宽度不够狗时压缩 61 | [leftLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 62 | //宽度够时正常显示 63 | [leftLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; 64 | return leftLabel; 65 | } 66 | 67 | NS_ASSUME_NONNULL_BEGIN 68 | 69 | @interface ZJUIHeader : NSObject 70 | 71 | @end 72 | 73 | NS_ASSUME_NONNULL_END 74 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/ZJPasswordStyleView/ZJPasswordFile/Lib/.DS_Store -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Category/NSString+ZJTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ZJTools.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2020/12/2. 6 | // Copyright © 2020 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (ZJTools) 14 | 15 | 16 | /// 过滤空格 17 | - (NSString *)filterSpaceChar; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Category/NSString+ZJTools.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ZJTools.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2020/12/2. 6 | // Copyright © 2020 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "NSString+ZJTools.h" 10 | 11 | @implementation NSString (ZJTools) 12 | 13 | - (BOOL)isNull { 14 | if ( [self isKindOfClass:[NSNull class]] ||self.length < 1 ) { 15 | return true; 16 | } 17 | return false; 18 | } 19 | 20 | /// 过滤空格 21 | - (NSString *)filterSpaceChar { 22 | if ([self isNull]) { 23 | return self; 24 | } 25 | if ([self containsString:@" "]) { 26 | return [self stringByReplacingOccurrencesOfString:@" " withString:@""]; 27 | } 28 | return self; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | /** 13 | * A group of MASConstraint objects 14 | */ 15 | @interface MASCompositeConstraint : MASConstraint 16 | 17 | /** 18 | * Creates a composite with a predefined array of children 19 | * 20 | * @param children child MASConstraints 21 | * 22 | * @return a composite constraint 23 | */ 24 | - (id)initWithChildren:(NSArray *)children; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASCompositeConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASCompositeConstraint.h" 10 | #import "MASConstraint+Private.h" 11 | 12 | @interface MASCompositeConstraint () 13 | 14 | @property (nonatomic, strong) id mas_key; 15 | @property (nonatomic, strong) NSMutableArray *childConstraints; 16 | 17 | @end 18 | 19 | @implementation MASCompositeConstraint 20 | 21 | - (id)initWithChildren:(NSArray *)children { 22 | self = [super init]; 23 | if (!self) return nil; 24 | 25 | _childConstraints = [children mutableCopy]; 26 | for (MASConstraint *constraint in _childConstraints) { 27 | constraint.delegate = self; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - MASConstraintDelegate 34 | 35 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint { 36 | NSUInteger index = [self.childConstraints indexOfObject:constraint]; 37 | NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint); 38 | [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint]; 39 | } 40 | 41 | - (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 42 | id strongDelegate = self.delegate; 43 | MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 44 | newConstraint.delegate = self; 45 | [self.childConstraints addObject:newConstraint]; 46 | return newConstraint; 47 | } 48 | 49 | #pragma mark - NSLayoutConstraint multiplier proxies 50 | 51 | - (MASConstraint * (^)(CGFloat))multipliedBy { 52 | return ^id(CGFloat multiplier) { 53 | for (MASConstraint *constraint in self.childConstraints) { 54 | constraint.multipliedBy(multiplier); 55 | } 56 | return self; 57 | }; 58 | } 59 | 60 | - (MASConstraint * (^)(CGFloat))dividedBy { 61 | return ^id(CGFloat divider) { 62 | for (MASConstraint *constraint in self.childConstraints) { 63 | constraint.dividedBy(divider); 64 | } 65 | return self; 66 | }; 67 | } 68 | 69 | #pragma mark - MASLayoutPriority proxy 70 | 71 | - (MASConstraint * (^)(MASLayoutPriority))priority { 72 | return ^id(MASLayoutPriority priority) { 73 | for (MASConstraint *constraint in self.childConstraints) { 74 | constraint.priority(priority); 75 | } 76 | return self; 77 | }; 78 | } 79 | 80 | #pragma mark - NSLayoutRelation proxy 81 | 82 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { 83 | return ^id(id attr, NSLayoutRelation relation) { 84 | for (MASConstraint *constraint in self.childConstraints.copy) { 85 | constraint.equalToWithRelation(attr, relation); 86 | } 87 | return self; 88 | }; 89 | } 90 | 91 | #pragma mark - attribute chaining 92 | 93 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute { 94 | [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute]; 95 | return self; 96 | } 97 | 98 | #pragma mark - Animator proxy 99 | 100 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 101 | 102 | - (MASConstraint *)animator { 103 | for (MASConstraint *constraint in self.childConstraints) { 104 | [constraint animator]; 105 | } 106 | return self; 107 | } 108 | 109 | #endif 110 | 111 | #pragma mark - debug helpers 112 | 113 | - (MASConstraint * (^)(id))key { 114 | return ^id(id key) { 115 | self.mas_key = key; 116 | int i = 0; 117 | for (MASConstraint *constraint in self.childConstraints) { 118 | constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]); 119 | } 120 | return self; 121 | }; 122 | } 123 | 124 | #pragma mark - NSLayoutConstraint constant setters 125 | 126 | - (void)setInsets:(MASEdgeInsets)insets { 127 | for (MASConstraint *constraint in self.childConstraints) { 128 | constraint.insets = insets; 129 | } 130 | } 131 | 132 | - (void)setInset:(CGFloat)inset { 133 | for (MASConstraint *constraint in self.childConstraints) { 134 | constraint.inset = inset; 135 | } 136 | } 137 | 138 | - (void)setOffset:(CGFloat)offset { 139 | for (MASConstraint *constraint in self.childConstraints) { 140 | constraint.offset = offset; 141 | } 142 | } 143 | 144 | - (void)setSizeOffset:(CGSize)sizeOffset { 145 | for (MASConstraint *constraint in self.childConstraints) { 146 | constraint.sizeOffset = sizeOffset; 147 | } 148 | } 149 | 150 | - (void)setCenterOffset:(CGPoint)centerOffset { 151 | for (MASConstraint *constraint in self.childConstraints) { 152 | constraint.centerOffset = centerOffset; 153 | } 154 | } 155 | 156 | #pragma mark - MASConstraint 157 | 158 | - (void)activate { 159 | for (MASConstraint *constraint in self.childConstraints) { 160 | [constraint activate]; 161 | } 162 | } 163 | 164 | - (void)deactivate { 165 | for (MASConstraint *constraint in self.childConstraints) { 166 | [constraint deactivate]; 167 | } 168 | } 169 | 170 | - (void)install { 171 | for (MASConstraint *constraint in self.childConstraints) { 172 | constraint.updateExisting = self.updateExisting; 173 | [constraint install]; 174 | } 175 | } 176 | 177 | - (void)uninstall { 178 | for (MASConstraint *constraint in self.childConstraints) { 179 | [constraint uninstall]; 180 | } 181 | } 182 | 183 | @end 184 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint+Private.h 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 29/04/14. 6 | // Copyright (c) 2014 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | 11 | @protocol MASConstraintDelegate; 12 | 13 | 14 | @interface MASConstraint () 15 | 16 | /** 17 | * Whether or not to check for an existing constraint instead of adding constraint 18 | */ 19 | @property (nonatomic, assign) BOOL updateExisting; 20 | 21 | /** 22 | * Usually MASConstraintMaker but could be a parent MASConstraint 23 | */ 24 | @property (nonatomic, weak) id delegate; 25 | 26 | /** 27 | * Based on a provided value type, is equal to calling: 28 | * NSNumber - setOffset: 29 | * NSValue with CGPoint - setPointOffset: 30 | * NSValue with CGSize - setSizeOffset: 31 | * NSValue with MASEdgeInsets - setInsets: 32 | */ 33 | - (void)setLayoutConstantWithValue:(NSValue *)value; 34 | 35 | @end 36 | 37 | 38 | @interface MASConstraint (Abstract) 39 | 40 | /** 41 | * Sets the constraint relation to given NSLayoutRelation 42 | * returns a block which accepts one of the following: 43 | * MASViewAttribute, UIView, NSValue, NSArray 44 | * see readme for more details. 45 | */ 46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 47 | 48 | /** 49 | * Override to set a custom chaining behaviour 50 | */ 51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 52 | 53 | @end 54 | 55 | 56 | @protocol MASConstraintDelegate 57 | 58 | /** 59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example 60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks 61 | */ 62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; 63 | 64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * Enables Constraints to be created with chainable syntax 13 | * Constraint can represent single NSLayoutConstraint (MASViewConstraint) 14 | * or a group of NSLayoutConstraints (MASComposisteConstraint) 15 | */ 16 | @interface MASConstraint : NSObject 17 | 18 | // Chaining Support 19 | 20 | /** 21 | * Modifies the NSLayoutConstraint constant, 22 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 23 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 24 | */ 25 | - (MASConstraint * (^)(MASEdgeInsets insets))insets; 26 | 27 | /** 28 | * Modifies the NSLayoutConstraint constant, 29 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 30 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 31 | */ 32 | - (MASConstraint * (^)(CGFloat inset))inset; 33 | 34 | /** 35 | * Modifies the NSLayoutConstraint constant, 36 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 37 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight 38 | */ 39 | - (MASConstraint * (^)(CGSize offset))sizeOffset; 40 | 41 | /** 42 | * Modifies the NSLayoutConstraint constant, 43 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 44 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY 45 | */ 46 | - (MASConstraint * (^)(CGPoint offset))centerOffset; 47 | 48 | /** 49 | * Modifies the NSLayoutConstraint constant 50 | */ 51 | - (MASConstraint * (^)(CGFloat offset))offset; 52 | 53 | /** 54 | * Modifies the NSLayoutConstraint constant based on a value type 55 | */ 56 | - (MASConstraint * (^)(NSValue *value))valueOffset; 57 | 58 | /** 59 | * Sets the NSLayoutConstraint multiplier property 60 | */ 61 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy; 62 | 63 | /** 64 | * Sets the NSLayoutConstraint multiplier to 1.0/dividedBy 65 | */ 66 | - (MASConstraint * (^)(CGFloat divider))dividedBy; 67 | 68 | /** 69 | * Sets the NSLayoutConstraint priority to a float or MASLayoutPriority 70 | */ 71 | - (MASConstraint * (^)(MASLayoutPriority priority))priority; 72 | 73 | /** 74 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityLow 75 | */ 76 | - (MASConstraint * (^)(void))priorityLow; 77 | 78 | /** 79 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium 80 | */ 81 | - (MASConstraint * (^)(void))priorityMedium; 82 | 83 | /** 84 | * Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh 85 | */ 86 | - (MASConstraint * (^)(void))priorityHigh; 87 | 88 | /** 89 | * Sets the constraint relation to NSLayoutRelationEqual 90 | * returns a block which accepts one of the following: 91 | * MASViewAttribute, UIView, NSValue, NSArray 92 | * see readme for more details. 93 | */ 94 | - (MASConstraint * (^)(id attr))equalTo; 95 | 96 | /** 97 | * Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual 98 | * returns a block which accepts one of the following: 99 | * MASViewAttribute, UIView, NSValue, NSArray 100 | * see readme for more details. 101 | */ 102 | - (MASConstraint * (^)(id attr))greaterThanOrEqualTo; 103 | 104 | /** 105 | * Sets the constraint relation to NSLayoutRelationLessThanOrEqual 106 | * returns a block which accepts one of the following: 107 | * MASViewAttribute, UIView, NSValue, NSArray 108 | * see readme for more details. 109 | */ 110 | - (MASConstraint * (^)(id attr))lessThanOrEqualTo; 111 | 112 | /** 113 | * Optional semantic property which has no effect but improves the readability of constraint 114 | */ 115 | - (MASConstraint *)with; 116 | 117 | /** 118 | * Optional semantic property which has no effect but improves the readability of constraint 119 | */ 120 | - (MASConstraint *)and; 121 | 122 | /** 123 | * Creates a new MASCompositeConstraint with the called attribute and reciever 124 | */ 125 | - (MASConstraint *)left; 126 | - (MASConstraint *)top; 127 | - (MASConstraint *)right; 128 | - (MASConstraint *)bottom; 129 | - (MASConstraint *)leading; 130 | - (MASConstraint *)trailing; 131 | - (MASConstraint *)width; 132 | - (MASConstraint *)height; 133 | - (MASConstraint *)centerX; 134 | - (MASConstraint *)centerY; 135 | - (MASConstraint *)baseline; 136 | 137 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 138 | 139 | - (MASConstraint *)firstBaseline; 140 | - (MASConstraint *)lastBaseline; 141 | 142 | #endif 143 | 144 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 145 | 146 | - (MASConstraint *)leftMargin; 147 | - (MASConstraint *)rightMargin; 148 | - (MASConstraint *)topMargin; 149 | - (MASConstraint *)bottomMargin; 150 | - (MASConstraint *)leadingMargin; 151 | - (MASConstraint *)trailingMargin; 152 | - (MASConstraint *)centerXWithinMargins; 153 | - (MASConstraint *)centerYWithinMargins; 154 | 155 | #endif 156 | 157 | 158 | /** 159 | * Sets the constraint debug name 160 | */ 161 | - (MASConstraint * (^)(id key))key; 162 | 163 | // NSLayoutConstraint constant Setters 164 | // for use outside of mas_updateConstraints/mas_makeConstraints blocks 165 | 166 | /** 167 | * Modifies the NSLayoutConstraint constant, 168 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 169 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 170 | */ 171 | - (void)setInsets:(MASEdgeInsets)insets; 172 | 173 | /** 174 | * Modifies the NSLayoutConstraint constant, 175 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 176 | * NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight 177 | */ 178 | - (void)setInset:(CGFloat)inset; 179 | 180 | /** 181 | * Modifies the NSLayoutConstraint constant, 182 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 183 | * NSLayoutAttributeWidth, NSLayoutAttributeHeight 184 | */ 185 | - (void)setSizeOffset:(CGSize)sizeOffset; 186 | 187 | /** 188 | * Modifies the NSLayoutConstraint constant, 189 | * only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following 190 | * NSLayoutAttributeCenterX, NSLayoutAttributeCenterY 191 | */ 192 | - (void)setCenterOffset:(CGPoint)centerOffset; 193 | 194 | /** 195 | * Modifies the NSLayoutConstraint constant 196 | */ 197 | - (void)setOffset:(CGFloat)offset; 198 | 199 | 200 | // NSLayoutConstraint Installation support 201 | 202 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 203 | /** 204 | * Whether or not to go through the animator proxy when modifying the constraint 205 | */ 206 | @property (nonatomic, copy, readonly) MASConstraint *animator; 207 | #endif 208 | 209 | /** 210 | * Activates an NSLayoutConstraint if it's supported by an OS. 211 | * Invokes install otherwise. 212 | */ 213 | - (void)activate; 214 | 215 | /** 216 | * Deactivates previously installed/activated NSLayoutConstraint. 217 | */ 218 | - (void)deactivate; 219 | 220 | /** 221 | * Creates a NSLayoutConstraint and adds it to the appropriate view. 222 | */ 223 | - (void)install; 224 | 225 | /** 226 | * Removes previously installed NSLayoutConstraint 227 | */ 228 | - (void)uninstall; 229 | 230 | @end 231 | 232 | 233 | /** 234 | * Convenience auto-boxing macros for MASConstraint methods. 235 | * 236 | * Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax. 237 | * A potential drawback of this is that the unprefixed macros will appear in global scope. 238 | */ 239 | #define mas_equalTo(...) equalTo(MASBoxValue((__VA_ARGS__))) 240 | #define mas_greaterThanOrEqualTo(...) greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__))) 241 | #define mas_lessThanOrEqualTo(...) lessThanOrEqualTo(MASBoxValue((__VA_ARGS__))) 242 | 243 | #define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__))) 244 | 245 | 246 | #ifdef MAS_SHORTHAND_GLOBALS 247 | 248 | #define equalTo(...) mas_equalTo(__VA_ARGS__) 249 | #define greaterThanOrEqualTo(...) mas_greaterThanOrEqualTo(__VA_ARGS__) 250 | #define lessThanOrEqualTo(...) mas_lessThanOrEqualTo(__VA_ARGS__) 251 | 252 | #define offset(...) mas_offset(__VA_ARGS__) 253 | 254 | #endif 255 | 256 | 257 | @interface MASConstraint (AutoboxingSupport) 258 | 259 | /** 260 | * Aliases to corresponding relation methods (for shorthand macros) 261 | * Also needed to aid autocompletion 262 | */ 263 | - (MASConstraint * (^)(id attr))mas_equalTo; 264 | - (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo; 265 | - (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo; 266 | 267 | /** 268 | * A dummy method to aid autocompletion 269 | */ 270 | - (MASConstraint * (^)(id offset))mas_offset; 271 | 272 | @end 273 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint.m 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 1/20/14. 6 | // 7 | 8 | #import "MASConstraint.h" 9 | #import "MASConstraint+Private.h" 10 | 11 | #define MASMethodNotImplemented() \ 12 | @throw [NSException exceptionWithName:NSInternalInconsistencyException \ 13 | reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \ 14 | userInfo:nil] 15 | 16 | @implementation MASConstraint 17 | 18 | #pragma mark - Init 19 | 20 | - (id)init { 21 | NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly."); 22 | return [super init]; 23 | } 24 | 25 | #pragma mark - NSLayoutRelation proxies 26 | 27 | - (MASConstraint * (^)(id))equalTo { 28 | return ^id(id attribute) { 29 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); 30 | }; 31 | } 32 | 33 | - (MASConstraint * (^)(id))mas_equalTo { 34 | return ^id(id attribute) { 35 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); 36 | }; 37 | } 38 | 39 | - (MASConstraint * (^)(id))greaterThanOrEqualTo { 40 | return ^id(id attribute) { 41 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); 42 | }; 43 | } 44 | 45 | - (MASConstraint * (^)(id))mas_greaterThanOrEqualTo { 46 | return ^id(id attribute) { 47 | return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual); 48 | }; 49 | } 50 | 51 | - (MASConstraint * (^)(id))lessThanOrEqualTo { 52 | return ^id(id attribute) { 53 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); 54 | }; 55 | } 56 | 57 | - (MASConstraint * (^)(id))mas_lessThanOrEqualTo { 58 | return ^id(id attribute) { 59 | return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual); 60 | }; 61 | } 62 | 63 | #pragma mark - MASLayoutPriority proxies 64 | 65 | - (MASConstraint * (^)(void))priorityLow { 66 | return ^id{ 67 | self.priority(MASLayoutPriorityDefaultLow); 68 | return self; 69 | }; 70 | } 71 | 72 | - (MASConstraint * (^)(void))priorityMedium { 73 | return ^id{ 74 | self.priority(MASLayoutPriorityDefaultMedium); 75 | return self; 76 | }; 77 | } 78 | 79 | - (MASConstraint * (^)(void))priorityHigh { 80 | return ^id{ 81 | self.priority(MASLayoutPriorityDefaultHigh); 82 | return self; 83 | }; 84 | } 85 | 86 | #pragma mark - NSLayoutConstraint constant proxies 87 | 88 | - (MASConstraint * (^)(MASEdgeInsets))insets { 89 | return ^id(MASEdgeInsets insets){ 90 | self.insets = insets; 91 | return self; 92 | }; 93 | } 94 | 95 | - (MASConstraint * (^)(CGFloat))inset { 96 | return ^id(CGFloat inset){ 97 | self.inset = inset; 98 | return self; 99 | }; 100 | } 101 | 102 | - (MASConstraint * (^)(CGSize))sizeOffset { 103 | return ^id(CGSize offset) { 104 | self.sizeOffset = offset; 105 | return self; 106 | }; 107 | } 108 | 109 | - (MASConstraint * (^)(CGPoint))centerOffset { 110 | return ^id(CGPoint offset) { 111 | self.centerOffset = offset; 112 | return self; 113 | }; 114 | } 115 | 116 | - (MASConstraint * (^)(CGFloat))offset { 117 | return ^id(CGFloat offset){ 118 | self.offset = offset; 119 | return self; 120 | }; 121 | } 122 | 123 | - (MASConstraint * (^)(NSValue *value))valueOffset { 124 | return ^id(NSValue *offset) { 125 | NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset); 126 | [self setLayoutConstantWithValue:offset]; 127 | return self; 128 | }; 129 | } 130 | 131 | - (MASConstraint * (^)(id offset))mas_offset { 132 | // Will never be called due to macro 133 | return nil; 134 | } 135 | 136 | #pragma mark - NSLayoutConstraint constant setter 137 | 138 | - (void)setLayoutConstantWithValue:(NSValue *)value { 139 | if ([value isKindOfClass:NSNumber.class]) { 140 | self.offset = [(NSNumber *)value doubleValue]; 141 | } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) { 142 | CGPoint point; 143 | [value getValue:&point]; 144 | self.centerOffset = point; 145 | } else if (strcmp(value.objCType, @encode(CGSize)) == 0) { 146 | CGSize size; 147 | [value getValue:&size]; 148 | self.sizeOffset = size; 149 | } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) { 150 | MASEdgeInsets insets; 151 | [value getValue:&insets]; 152 | self.insets = insets; 153 | } else { 154 | NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value); 155 | } 156 | } 157 | 158 | #pragma mark - Semantic properties 159 | 160 | - (MASConstraint *)with { 161 | return self; 162 | } 163 | 164 | - (MASConstraint *)and { 165 | return self; 166 | } 167 | 168 | #pragma mark - Chaining 169 | 170 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute { 171 | MASMethodNotImplemented(); 172 | } 173 | 174 | - (MASConstraint *)left { 175 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft]; 176 | } 177 | 178 | - (MASConstraint *)top { 179 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop]; 180 | } 181 | 182 | - (MASConstraint *)right { 183 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight]; 184 | } 185 | 186 | - (MASConstraint *)bottom { 187 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom]; 188 | } 189 | 190 | - (MASConstraint *)leading { 191 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading]; 192 | } 193 | 194 | - (MASConstraint *)trailing { 195 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing]; 196 | } 197 | 198 | - (MASConstraint *)width { 199 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth]; 200 | } 201 | 202 | - (MASConstraint *)height { 203 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; 204 | } 205 | 206 | - (MASConstraint *)centerX { 207 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX]; 208 | } 209 | 210 | - (MASConstraint *)centerY { 211 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY]; 212 | } 213 | 214 | - (MASConstraint *)baseline { 215 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline]; 216 | } 217 | 218 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 219 | 220 | - (MASConstraint *)firstBaseline { 221 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline]; 222 | } 223 | - (MASConstraint *)lastBaseline { 224 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline]; 225 | } 226 | 227 | #endif 228 | 229 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 230 | 231 | - (MASConstraint *)leftMargin { 232 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin]; 233 | } 234 | 235 | - (MASConstraint *)rightMargin { 236 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin]; 237 | } 238 | 239 | - (MASConstraint *)topMargin { 240 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin]; 241 | } 242 | 243 | - (MASConstraint *)bottomMargin { 244 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin]; 245 | } 246 | 247 | - (MASConstraint *)leadingMargin { 248 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin]; 249 | } 250 | 251 | - (MASConstraint *)trailingMargin { 252 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin]; 253 | } 254 | 255 | - (MASConstraint *)centerXWithinMargins { 256 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins]; 257 | } 258 | 259 | - (MASConstraint *)centerYWithinMargins { 260 | return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins]; 261 | } 262 | 263 | #endif 264 | 265 | #pragma mark - Abstract 266 | 267 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); } 268 | 269 | - (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); } 270 | 271 | - (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); } 272 | 273 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); } 274 | 275 | - (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); } 276 | 277 | - (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); } 278 | 279 | - (void)setInset:(CGFloat __unused)inset { MASMethodNotImplemented(); } 280 | 281 | - (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); } 282 | 283 | - (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); } 284 | 285 | - (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); } 286 | 287 | #if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV) 288 | 289 | - (MASConstraint *)animator { MASMethodNotImplemented(); } 290 | 291 | #endif 292 | 293 | - (void)activate { MASMethodNotImplemented(); } 294 | 295 | - (void)deactivate { MASMethodNotImplemented(); } 296 | 297 | - (void)install { MASMethodNotImplemented(); } 298 | 299 | - (void)uninstall { MASMethodNotImplemented(); } 300 | 301 | @end 302 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASConstraintMaker.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraintMaker.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | typedef NS_OPTIONS(NSInteger, MASAttribute) { 13 | MASAttributeLeft = 1 << NSLayoutAttributeLeft, 14 | MASAttributeRight = 1 << NSLayoutAttributeRight, 15 | MASAttributeTop = 1 << NSLayoutAttributeTop, 16 | MASAttributeBottom = 1 << NSLayoutAttributeBottom, 17 | MASAttributeLeading = 1 << NSLayoutAttributeLeading, 18 | MASAttributeTrailing = 1 << NSLayoutAttributeTrailing, 19 | MASAttributeWidth = 1 << NSLayoutAttributeWidth, 20 | MASAttributeHeight = 1 << NSLayoutAttributeHeight, 21 | MASAttributeCenterX = 1 << NSLayoutAttributeCenterX, 22 | MASAttributeCenterY = 1 << NSLayoutAttributeCenterY, 23 | MASAttributeBaseline = 1 << NSLayoutAttributeBaseline, 24 | 25 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 26 | 27 | MASAttributeFirstBaseline = 1 << NSLayoutAttributeFirstBaseline, 28 | MASAttributeLastBaseline = 1 << NSLayoutAttributeLastBaseline, 29 | 30 | #endif 31 | 32 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 33 | 34 | MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin, 35 | MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin, 36 | MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin, 37 | MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin, 38 | MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin, 39 | MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin, 40 | MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins, 41 | MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins, 42 | 43 | #endif 44 | 45 | }; 46 | 47 | /** 48 | * Provides factory methods for creating MASConstraints. 49 | * Constraints are collected until they are ready to be installed 50 | * 51 | */ 52 | @interface MASConstraintMaker : NSObject 53 | 54 | /** 55 | * The following properties return a new MASViewConstraint 56 | * with the first item set to the makers associated view and the appropriate MASViewAttribute 57 | */ 58 | @property (nonatomic, strong, readonly) MASConstraint *left; 59 | @property (nonatomic, strong, readonly) MASConstraint *top; 60 | @property (nonatomic, strong, readonly) MASConstraint *right; 61 | @property (nonatomic, strong, readonly) MASConstraint *bottom; 62 | @property (nonatomic, strong, readonly) MASConstraint *leading; 63 | @property (nonatomic, strong, readonly) MASConstraint *trailing; 64 | @property (nonatomic, strong, readonly) MASConstraint *width; 65 | @property (nonatomic, strong, readonly) MASConstraint *height; 66 | @property (nonatomic, strong, readonly) MASConstraint *centerX; 67 | @property (nonatomic, strong, readonly) MASConstraint *centerY; 68 | @property (nonatomic, strong, readonly) MASConstraint *baseline; 69 | 70 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 71 | 72 | @property (nonatomic, strong, readonly) MASConstraint *firstBaseline; 73 | @property (nonatomic, strong, readonly) MASConstraint *lastBaseline; 74 | 75 | #endif 76 | 77 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 78 | 79 | @property (nonatomic, strong, readonly) MASConstraint *leftMargin; 80 | @property (nonatomic, strong, readonly) MASConstraint *rightMargin; 81 | @property (nonatomic, strong, readonly) MASConstraint *topMargin; 82 | @property (nonatomic, strong, readonly) MASConstraint *bottomMargin; 83 | @property (nonatomic, strong, readonly) MASConstraint *leadingMargin; 84 | @property (nonatomic, strong, readonly) MASConstraint *trailingMargin; 85 | @property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins; 86 | @property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins; 87 | 88 | #endif 89 | 90 | /** 91 | * Returns a block which creates a new MASCompositeConstraint with the first item set 92 | * to the makers associated view and children corresponding to the set bits in the 93 | * MASAttribute parameter. Combine multiple attributes via binary-or. 94 | */ 95 | @property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs); 96 | 97 | /** 98 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges 99 | * which generates the appropriate MASViewConstraint children (top, left, bottom, right) 100 | * with the first item set to the makers associated view 101 | */ 102 | @property (nonatomic, strong, readonly) MASConstraint *edges; 103 | 104 | /** 105 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize 106 | * which generates the appropriate MASViewConstraint children (width, height) 107 | * with the first item set to the makers associated view 108 | */ 109 | @property (nonatomic, strong, readonly) MASConstraint *size; 110 | 111 | /** 112 | * Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter 113 | * which generates the appropriate MASViewConstraint children (centerX, centerY) 114 | * with the first item set to the makers associated view 115 | */ 116 | @property (nonatomic, strong, readonly) MASConstraint *center; 117 | 118 | /** 119 | * Whether or not to check for an existing constraint instead of adding constraint 120 | */ 121 | @property (nonatomic, assign) BOOL updateExisting; 122 | 123 | /** 124 | * Whether or not to remove existing constraints prior to installing 125 | */ 126 | @property (nonatomic, assign) BOOL removeExisting; 127 | 128 | /** 129 | * initialises the maker with a default view 130 | * 131 | * @param view any MASConstraint are created with this view as the first item 132 | * 133 | * @return a new MASConstraintMaker 134 | */ 135 | - (id)initWithView:(MAS_VIEW *)view; 136 | 137 | /** 138 | * Calls install method on any MASConstraints which have been created by this maker 139 | * 140 | * @return an array of all the installed MASConstraints 141 | */ 142 | - (NSArray *)install; 143 | 144 | - (MASConstraint * (^)(dispatch_block_t))group; 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * When you are debugging or printing the constraints attached to a view this subclass 13 | * makes it easier to identify which constraints have been created via Masonry 14 | */ 15 | @interface MASLayoutConstraint : NSLayoutConstraint 16 | 17 | /** 18 | * a key to associate with this constraint 19 | */ 20 | @property (nonatomic, strong) id mas_key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASLayoutConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASLayoutConstraint.h" 10 | 11 | @implementation MASLayoutConstraint 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASUtilities.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 19/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | #if TARGET_OS_IPHONE || TARGET_OS_TV 14 | 15 | #import 16 | #define MAS_VIEW UIView 17 | #define MAS_VIEW_CONTROLLER UIViewController 18 | #define MASEdgeInsets UIEdgeInsets 19 | 20 | typedef UILayoutPriority MASLayoutPriority; 21 | static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired; 22 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh; 23 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500; 24 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow; 25 | static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel; 26 | 27 | #elif TARGET_OS_MAC 28 | 29 | #import 30 | #define MAS_VIEW NSView 31 | #define MASEdgeInsets NSEdgeInsets 32 | 33 | typedef NSLayoutPriority MASLayoutPriority; 34 | static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired; 35 | static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh; 36 | static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow; 37 | static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501; 38 | static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut; 39 | static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow; 40 | static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow; 41 | static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression; 42 | 43 | #endif 44 | 45 | /** 46 | * Allows you to attach keys to objects matching the variable names passed. 47 | * 48 | * view1.mas_key = @"view1", view2.mas_key = @"view2"; 49 | * 50 | * is equivalent to: 51 | * 52 | * MASAttachKeys(view1, view2); 53 | */ 54 | #define MASAttachKeys(...) \ 55 | { \ 56 | NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__); \ 57 | for (id key in keyPairs.allKeys) { \ 58 | id obj = keyPairs[key]; \ 59 | NSAssert([obj respondsToSelector:@selector(setMas_key:)], \ 60 | @"Cannot attach mas_key to %@", obj); \ 61 | [obj setMas_key:key]; \ 62 | } \ 63 | } 64 | 65 | /** 66 | * Used to create object hashes 67 | * Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html 68 | */ 69 | #define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger)) 70 | #define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch))) 71 | 72 | /** 73 | * Given a scalar or struct value, wraps it in NSValue 74 | * Based on EXPObjectify: https://github.com/specta/expecta 75 | */ 76 | static inline id _MASBoxValue(const char *type, ...) { 77 | va_list v; 78 | va_start(v, type); 79 | id obj = nil; 80 | if (strcmp(type, @encode(id)) == 0) { 81 | id actual = va_arg(v, id); 82 | obj = actual; 83 | } else if (strcmp(type, @encode(CGPoint)) == 0) { 84 | CGPoint actual = (CGPoint)va_arg(v, CGPoint); 85 | obj = [NSValue value:&actual withObjCType:type]; 86 | } else if (strcmp(type, @encode(CGSize)) == 0) { 87 | CGSize actual = (CGSize)va_arg(v, CGSize); 88 | obj = [NSValue value:&actual withObjCType:type]; 89 | } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) { 90 | MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets); 91 | obj = [NSValue value:&actual withObjCType:type]; 92 | } else if (strcmp(type, @encode(double)) == 0) { 93 | double actual = (double)va_arg(v, double); 94 | obj = [NSNumber numberWithDouble:actual]; 95 | } else if (strcmp(type, @encode(float)) == 0) { 96 | float actual = (float)va_arg(v, double); 97 | obj = [NSNumber numberWithFloat:actual]; 98 | } else if (strcmp(type, @encode(int)) == 0) { 99 | int actual = (int)va_arg(v, int); 100 | obj = [NSNumber numberWithInt:actual]; 101 | } else if (strcmp(type, @encode(long)) == 0) { 102 | long actual = (long)va_arg(v, long); 103 | obj = [NSNumber numberWithLong:actual]; 104 | } else if (strcmp(type, @encode(long long)) == 0) { 105 | long long actual = (long long)va_arg(v, long long); 106 | obj = [NSNumber numberWithLongLong:actual]; 107 | } else if (strcmp(type, @encode(short)) == 0) { 108 | short actual = (short)va_arg(v, int); 109 | obj = [NSNumber numberWithShort:actual]; 110 | } else if (strcmp(type, @encode(char)) == 0) { 111 | char actual = (char)va_arg(v, int); 112 | obj = [NSNumber numberWithChar:actual]; 113 | } else if (strcmp(type, @encode(bool)) == 0) { 114 | bool actual = (bool)va_arg(v, int); 115 | obj = [NSNumber numberWithBool:actual]; 116 | } else if (strcmp(type, @encode(unsigned char)) == 0) { 117 | unsigned char actual = (unsigned char)va_arg(v, unsigned int); 118 | obj = [NSNumber numberWithUnsignedChar:actual]; 119 | } else if (strcmp(type, @encode(unsigned int)) == 0) { 120 | unsigned int actual = (unsigned int)va_arg(v, unsigned int); 121 | obj = [NSNumber numberWithUnsignedInt:actual]; 122 | } else if (strcmp(type, @encode(unsigned long)) == 0) { 123 | unsigned long actual = (unsigned long)va_arg(v, unsigned long); 124 | obj = [NSNumber numberWithUnsignedLong:actual]; 125 | } else if (strcmp(type, @encode(unsigned long long)) == 0) { 126 | unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long); 127 | obj = [NSNumber numberWithUnsignedLongLong:actual]; 128 | } else if (strcmp(type, @encode(unsigned short)) == 0) { 129 | unsigned short actual = (unsigned short)va_arg(v, unsigned int); 130 | obj = [NSNumber numberWithUnsignedShort:actual]; 131 | } 132 | va_end(v); 133 | return obj; 134 | } 135 | 136 | #define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value)) 137 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * An immutable tuple which stores the view and the related NSLayoutAttribute. 13 | * Describes part of either the left or right hand side of a constraint equation 14 | */ 15 | @interface MASViewAttribute : NSObject 16 | 17 | /** 18 | * The view which the reciever relates to. Can be nil if item is not a view. 19 | */ 20 | @property (nonatomic, weak, readonly) MAS_VIEW *view; 21 | 22 | /** 23 | * The item which the reciever relates to. 24 | */ 25 | @property (nonatomic, weak, readonly) id item; 26 | 27 | /** 28 | * The attribute which the reciever relates to 29 | */ 30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 31 | 32 | /** 33 | * Convenience initializer. 34 | */ 35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 36 | 37 | /** 38 | * The designated initializer. 39 | */ 40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; 41 | 42 | /** 43 | * Determine whether the layoutAttribute is a size attribute 44 | * 45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight 46 | */ 47 | - (BOOL)isSizeAttribute; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASViewAttribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | 11 | @implementation MASViewAttribute 12 | 13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { 14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; 15 | return self; 16 | } 17 | 18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { 19 | self = [super init]; 20 | if (!self) return nil; 21 | 22 | _view = view; 23 | _item = item; 24 | _layoutAttribute = layoutAttribute; 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)isSizeAttribute { 30 | return self.layoutAttribute == NSLayoutAttributeWidth 31 | || self.layoutAttribute == NSLayoutAttributeHeight; 32 | } 33 | 34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute { 35 | if ([viewAttribute isKindOfClass:self.class]) { 36 | return self.view == viewAttribute.view 37 | && self.layoutAttribute == viewAttribute.layoutAttribute; 38 | } 39 | return [super isEqual:viewAttribute]; 40 | } 41 | 42 | - (NSUInteger)hash { 43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | #import "MASUtilities.h" 13 | 14 | /** 15 | * A single constraint. 16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view 17 | */ 18 | @interface MASViewConstraint : MASConstraint 19 | 20 | /** 21 | * First item/view and first attribute of the NSLayoutConstraint 22 | */ 23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; 24 | 25 | /** 26 | * Second item/view and second attribute of the NSLayoutConstraint 27 | */ 28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; 29 | 30 | /** 31 | * initialises the MASViewConstraint with the first part of the equation 32 | * 33 | * @param firstViewAttribute view.mas_left, view.mas_width etc. 34 | * 35 | * @return a new view constraint 36 | */ 37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; 38 | 39 | /** 40 | * Returns all MASViewConstraints installed with this view as a first item. 41 | * 42 | * @param view A view to retrieve constraints for. 43 | * 44 | * @return An array of MASViewConstraints. 45 | */ 46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Masonry.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Masonry. 12 | FOUNDATION_EXPORT double MasonryVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 16 | 17 | #import "MASUtilities.h" 18 | #import "View+MASAdditions.h" 19 | #import "View+MASShorthandAdditions.h" 20 | #import "ViewController+MASAdditions.h" 21 | #import "NSArray+MASAdditions.h" 22 | #import "NSArray+MASShorthandAdditions.h" 23 | #import "MASConstraint.h" 24 | #import "MASCompositeConstraint.h" 25 | #import "MASViewAttribute.h" 26 | #import "MASViewConstraint.h" 27 | #import "MASConstraintMaker.h" 28 | #import "MASLayoutConstraint.h" 29 | #import "NSLayoutConstraint+MASDebugAdditions.h" 30 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.h 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | typedef NS_ENUM(NSUInteger, MASAxisType) { 14 | MASAxisTypeHorizontal, 15 | MASAxisTypeVertical 16 | }; 17 | 18 | @interface NSArray (MASAdditions) 19 | 20 | /** 21 | * Creates a MASConstraintMaker with each view in the callee. 22 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view 23 | * 24 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 25 | * 26 | * @return Array of created MASConstraints 27 | */ 28 | - (NSArray *)mas_makeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 29 | 30 | /** 31 | * Creates a MASConstraintMaker with each view in the callee. 32 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 33 | * If an existing constraint exists then it will be updated instead. 34 | * 35 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 36 | * 37 | * @return Array of created/updated MASConstraints 38 | */ 39 | - (NSArray *)mas_updateConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 40 | 41 | /** 42 | * Creates a MASConstraintMaker with each view in the callee. 43 | * Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view. 44 | * All constraints previously installed for the views will be removed. 45 | * 46 | * @param block scope within which you can build up the constraints which you wish to apply to each view. 47 | * 48 | * @return Array of created/updated MASConstraints 49 | */ 50 | - (NSArray *)mas_remakeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block; 51 | 52 | /** 53 | * distribute with fixed spacing 54 | * 55 | * @param axisType which axis to distribute items along 56 | * @param fixedSpacing the spacing between each item 57 | * @param leadSpacing the spacing before the first item and the container 58 | * @param tailSpacing the spacing after the last item and the container 59 | */ 60 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 61 | 62 | /** 63 | * distribute with fixed item size 64 | * 65 | * @param axisType which axis to distribute items along 66 | * @param fixedItemLength the fixed length of each item 67 | * @param leadSpacing the spacing before the first item and the container 68 | * @param tailSpacing the spacing after the last item and the container 69 | */ 70 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/NSArray+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASAdditions.m 3 | // 4 | // 5 | // Created by Daniel Hammond on 11/26/13. 6 | // 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | #import "View+MASAdditions.h" 11 | 12 | @implementation NSArray (MASAdditions) 13 | 14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block { 15 | NSMutableArray *constraints = [NSMutableArray array]; 16 | for (MAS_VIEW *view in self) { 17 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 18 | [constraints addObjectsFromArray:[view mas_makeConstraints:block]]; 19 | } 20 | return constraints; 21 | } 22 | 23 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block { 24 | NSMutableArray *constraints = [NSMutableArray array]; 25 | for (MAS_VIEW *view in self) { 26 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 27 | [constraints addObjectsFromArray:[view mas_updateConstraints:block]]; 28 | } 29 | return constraints; 30 | } 31 | 32 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { 33 | NSMutableArray *constraints = [NSMutableArray array]; 34 | for (MAS_VIEW *view in self) { 35 | NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views"); 36 | [constraints addObjectsFromArray:[view mas_remakeConstraints:block]]; 37 | } 38 | return constraints; 39 | } 40 | 41 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { 42 | if (self.count < 2) { 43 | NSAssert(self.count>1,@"views to distribute need to bigger than one"); 44 | return; 45 | } 46 | 47 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; 48 | if (axisType == MASAxisTypeHorizontal) { 49 | MAS_VIEW *prev; 50 | for (int i = 0; i < self.count; i++) { 51 | MAS_VIEW *v = self[i]; 52 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 53 | if (prev) { 54 | make.width.equalTo(prev); 55 | make.left.equalTo(prev.mas_right).offset(fixedSpacing); 56 | if (i == self.count - 1) {//last one 57 | make.right.equalTo(tempSuperView).offset(-tailSpacing); 58 | } 59 | } 60 | else {//first one 61 | make.left.equalTo(tempSuperView).offset(leadSpacing); 62 | } 63 | 64 | }]; 65 | prev = v; 66 | } 67 | } 68 | else { 69 | MAS_VIEW *prev; 70 | for (int i = 0; i < self.count; i++) { 71 | MAS_VIEW *v = self[i]; 72 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 73 | if (prev) { 74 | make.height.equalTo(prev); 75 | make.top.equalTo(prev.mas_bottom).offset(fixedSpacing); 76 | if (i == self.count - 1) {//last one 77 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing); 78 | } 79 | } 80 | else {//first one 81 | make.top.equalTo(tempSuperView).offset(leadSpacing); 82 | } 83 | 84 | }]; 85 | prev = v; 86 | } 87 | } 88 | } 89 | 90 | - (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { 91 | if (self.count < 2) { 92 | NSAssert(self.count>1,@"views to distribute need to bigger than one"); 93 | return; 94 | } 95 | 96 | MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews]; 97 | if (axisType == MASAxisTypeHorizontal) { 98 | MAS_VIEW *prev; 99 | for (int i = 0; i < self.count; i++) { 100 | MAS_VIEW *v = self[i]; 101 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 102 | make.width.equalTo(@(fixedItemLength)); 103 | if (prev) { 104 | if (i == self.count - 1) {//last one 105 | make.right.equalTo(tempSuperView).offset(-tailSpacing); 106 | } 107 | else { 108 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); 109 | make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); 110 | } 111 | } 112 | else {//first one 113 | make.left.equalTo(tempSuperView).offset(leadSpacing); 114 | } 115 | }]; 116 | prev = v; 117 | } 118 | } 119 | else { 120 | MAS_VIEW *prev; 121 | for (int i = 0; i < self.count; i++) { 122 | MAS_VIEW *v = self[i]; 123 | [v mas_makeConstraints:^(MASConstraintMaker *make) { 124 | make.height.equalTo(@(fixedItemLength)); 125 | if (prev) { 126 | if (i == self.count - 1) {//last one 127 | make.bottom.equalTo(tempSuperView).offset(-tailSpacing); 128 | } 129 | else { 130 | CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1)); 131 | make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset); 132 | } 133 | } 134 | else {//first one 135 | make.top.equalTo(tempSuperView).offset(leadSpacing); 136 | } 137 | }]; 138 | prev = v; 139 | } 140 | } 141 | } 142 | 143 | - (MAS_VIEW *)mas_commonSuperviewOfViews 144 | { 145 | MAS_VIEW *commonSuperview = nil; 146 | MAS_VIEW *previousView = nil; 147 | for (id object in self) { 148 | if ([object isKindOfClass:[MAS_VIEW class]]) { 149 | MAS_VIEW *view = (MAS_VIEW *)object; 150 | if (previousView) { 151 | commonSuperview = [view mas_closestCommonSuperview:commonSuperview]; 152 | } else { 153 | commonSuperview = view; 154 | } 155 | previousView = view; 156 | } 157 | } 158 | NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy."); 159 | return commonSuperview; 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand array additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface NSArray (MASShorthandAdditions) 18 | 19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 22 | 23 | @end 24 | 25 | @implementation NSArray (MASShorthandAdditions) 26 | 27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 28 | return [self mas_makeConstraints:block]; 29 | } 30 | 31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 32 | return [self mas_updateConstraints:block]; 33 | } 34 | 35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 36 | return [self mas_remakeConstraints:block]; 37 | } 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * makes debug and log output of NSLayoutConstraints more readable 13 | */ 14 | @interface NSLayoutConstraint (MASDebugAdditions) 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/NSLayoutConstraint+MASDebugAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSLayoutConstraint+MASDebugAdditions.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | 13 | @implementation NSLayoutConstraint (MASDebugAdditions) 14 | 15 | #pragma mark - description maps 16 | 17 | + (NSDictionary *)layoutRelationDescriptionsByValue { 18 | static dispatch_once_t once; 19 | static NSDictionary *descriptionMap; 20 | dispatch_once(&once, ^{ 21 | descriptionMap = @{ 22 | @(NSLayoutRelationEqual) : @"==", 23 | @(NSLayoutRelationGreaterThanOrEqual) : @">=", 24 | @(NSLayoutRelationLessThanOrEqual) : @"<=", 25 | }; 26 | }); 27 | return descriptionMap; 28 | } 29 | 30 | + (NSDictionary *)layoutAttributeDescriptionsByValue { 31 | static dispatch_once_t once; 32 | static NSDictionary *descriptionMap; 33 | dispatch_once(&once, ^{ 34 | descriptionMap = @{ 35 | @(NSLayoutAttributeTop) : @"top", 36 | @(NSLayoutAttributeLeft) : @"left", 37 | @(NSLayoutAttributeBottom) : @"bottom", 38 | @(NSLayoutAttributeRight) : @"right", 39 | @(NSLayoutAttributeLeading) : @"leading", 40 | @(NSLayoutAttributeTrailing) : @"trailing", 41 | @(NSLayoutAttributeWidth) : @"width", 42 | @(NSLayoutAttributeHeight) : @"height", 43 | @(NSLayoutAttributeCenterX) : @"centerX", 44 | @(NSLayoutAttributeCenterY) : @"centerY", 45 | @(NSLayoutAttributeBaseline) : @"baseline", 46 | 47 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 48 | @(NSLayoutAttributeFirstBaseline) : @"firstBaseline", 49 | @(NSLayoutAttributeLastBaseline) : @"lastBaseline", 50 | #endif 51 | 52 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 53 | @(NSLayoutAttributeLeftMargin) : @"leftMargin", 54 | @(NSLayoutAttributeRightMargin) : @"rightMargin", 55 | @(NSLayoutAttributeTopMargin) : @"topMargin", 56 | @(NSLayoutAttributeBottomMargin) : @"bottomMargin", 57 | @(NSLayoutAttributeLeadingMargin) : @"leadingMargin", 58 | @(NSLayoutAttributeTrailingMargin) : @"trailingMargin", 59 | @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins", 60 | @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins", 61 | #endif 62 | 63 | }; 64 | 65 | }); 66 | return descriptionMap; 67 | } 68 | 69 | 70 | + (NSDictionary *)layoutPriorityDescriptionsByValue { 71 | static dispatch_once_t once; 72 | static NSDictionary *descriptionMap; 73 | dispatch_once(&once, ^{ 74 | #if TARGET_OS_IPHONE || TARGET_OS_TV 75 | descriptionMap = @{ 76 | @(MASLayoutPriorityDefaultHigh) : @"high", 77 | @(MASLayoutPriorityDefaultLow) : @"low", 78 | @(MASLayoutPriorityDefaultMedium) : @"medium", 79 | @(MASLayoutPriorityRequired) : @"required", 80 | @(MASLayoutPriorityFittingSizeLevel) : @"fitting size", 81 | }; 82 | #elif TARGET_OS_MAC 83 | descriptionMap = @{ 84 | @(MASLayoutPriorityDefaultHigh) : @"high", 85 | @(MASLayoutPriorityDragThatCanResizeWindow) : @"drag can resize window", 86 | @(MASLayoutPriorityDefaultMedium) : @"medium", 87 | @(MASLayoutPriorityWindowSizeStayPut) : @"window size stay put", 88 | @(MASLayoutPriorityDragThatCannotResizeWindow) : @"drag cannot resize window", 89 | @(MASLayoutPriorityDefaultLow) : @"low", 90 | @(MASLayoutPriorityFittingSizeCompression) : @"fitting size", 91 | @(MASLayoutPriorityRequired) : @"required", 92 | }; 93 | #endif 94 | }); 95 | return descriptionMap; 96 | } 97 | 98 | #pragma mark - description override 99 | 100 | + (NSString *)descriptionForObject:(id)obj { 101 | if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) { 102 | return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]]; 103 | } 104 | return [NSString stringWithFormat:@"%@:%p", [obj class], obj]; 105 | } 106 | 107 | - (NSString *)description { 108 | NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"]; 109 | 110 | [description appendString:[self.class descriptionForObject:self]]; 111 | 112 | [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]]; 113 | if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) { 114 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]]; 115 | } 116 | 117 | [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]]; 118 | 119 | if (self.secondItem) { 120 | [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]]; 121 | } 122 | if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) { 123 | [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]]; 124 | } 125 | 126 | if (self.multiplier != 1) { 127 | [description appendFormat:@" * %g", self.multiplier]; 128 | } 129 | 130 | if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) { 131 | [description appendFormat:@" %g", self.constant]; 132 | } else { 133 | if (self.constant) { 134 | [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)]; 135 | } 136 | } 137 | 138 | if (self.priority != MASLayoutPriorityRequired) { 139 | [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]]; 140 | } 141 | 142 | [description appendString:@">"]; 143 | return description; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | /** 14 | * Provides constraint maker block 15 | * and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs 16 | */ 17 | @interface MAS_VIEW (MASAdditions) 18 | 19 | /** 20 | * following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute 21 | */ 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leading; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_width; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_height; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; 31 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; 32 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; 33 | @property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr); 34 | 35 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 36 | 37 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline; 38 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline; 39 | 40 | #endif 41 | 42 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 43 | 44 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin; 49 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin; 50 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins; 51 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins; 52 | 53 | #endif 54 | 55 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 56 | 57 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuide API_AVAILABLE(ios(11.0),tvos(11.0)); 58 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0)); 59 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0)); 60 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0)); 61 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0)); 62 | 63 | #endif 64 | 65 | /** 66 | * a key to associate with this view 67 | */ 68 | @property (nonatomic, strong) id mas_key; 69 | 70 | /** 71 | * Finds the closest common superview between this view and another view 72 | * 73 | * @param view other view 74 | * 75 | * @return returns nil if common superview could not be found 76 | */ 77 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view; 78 | 79 | /** 80 | * Creates a MASConstraintMaker with the callee view. 81 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing 82 | * 83 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 84 | * 85 | * @return Array of created MASConstraints 86 | */ 87 | - (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 88 | 89 | /** 90 | * Creates a MASConstraintMaker with the callee view. 91 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 92 | * If an existing constraint exists then it will be updated instead. 93 | * 94 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 95 | * 96 | * @return Array of created/updated MASConstraints 97 | */ 98 | - (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 99 | 100 | /** 101 | * Creates a MASConstraintMaker with the callee view. 102 | * Any constraints defined are added to the view or the appropriate superview once the block has finished executing. 103 | * All constraints previously installed for the view will be removed. 104 | * 105 | * @param block scope within which you can build up the constraints which you wish to apply to the view. 106 | * 107 | * @return Array of created/updated MASConstraints 108 | */ 109 | - (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block; 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/View+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | #import 11 | 12 | @implementation MAS_VIEW (MASAdditions) 13 | 14 | - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block { 15 | self.translatesAutoresizingMaskIntoConstraints = NO; 16 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 17 | block(constraintMaker); 18 | return [constraintMaker install]; 19 | } 20 | 21 | - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block { 22 | self.translatesAutoresizingMaskIntoConstraints = NO; 23 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 24 | constraintMaker.updateExisting = YES; 25 | block(constraintMaker); 26 | return [constraintMaker install]; 27 | } 28 | 29 | - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block { 30 | self.translatesAutoresizingMaskIntoConstraints = NO; 31 | MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; 32 | constraintMaker.removeExisting = YES; 33 | block(constraintMaker); 34 | return [constraintMaker install]; 35 | } 36 | 37 | #pragma mark - NSLayoutAttribute properties 38 | 39 | - (MASViewAttribute *)mas_left { 40 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft]; 41 | } 42 | 43 | - (MASViewAttribute *)mas_top { 44 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop]; 45 | } 46 | 47 | - (MASViewAttribute *)mas_right { 48 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight]; 49 | } 50 | 51 | - (MASViewAttribute *)mas_bottom { 52 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom]; 53 | } 54 | 55 | - (MASViewAttribute *)mas_leading { 56 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading]; 57 | } 58 | 59 | - (MASViewAttribute *)mas_trailing { 60 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing]; 61 | } 62 | 63 | - (MASViewAttribute *)mas_width { 64 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth]; 65 | } 66 | 67 | - (MASViewAttribute *)mas_height { 68 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight]; 69 | } 70 | 71 | - (MASViewAttribute *)mas_centerX { 72 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX]; 73 | } 74 | 75 | - (MASViewAttribute *)mas_centerY { 76 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY]; 77 | } 78 | 79 | - (MASViewAttribute *)mas_baseline { 80 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline]; 81 | } 82 | 83 | - (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute 84 | { 85 | return ^(NSLayoutAttribute attr) { 86 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr]; 87 | }; 88 | } 89 | 90 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 91 | 92 | - (MASViewAttribute *)mas_firstBaseline { 93 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeFirstBaseline]; 94 | } 95 | - (MASViewAttribute *)mas_lastBaseline { 96 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLastBaseline]; 97 | } 98 | 99 | #endif 100 | 101 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 102 | 103 | - (MASViewAttribute *)mas_leftMargin { 104 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin]; 105 | } 106 | 107 | - (MASViewAttribute *)mas_rightMargin { 108 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin]; 109 | } 110 | 111 | - (MASViewAttribute *)mas_topMargin { 112 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin]; 113 | } 114 | 115 | - (MASViewAttribute *)mas_bottomMargin { 116 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin]; 117 | } 118 | 119 | - (MASViewAttribute *)mas_leadingMargin { 120 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin]; 121 | } 122 | 123 | - (MASViewAttribute *)mas_trailingMargin { 124 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin]; 125 | } 126 | 127 | - (MASViewAttribute *)mas_centerXWithinMargins { 128 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins]; 129 | } 130 | 131 | - (MASViewAttribute *)mas_centerYWithinMargins { 132 | return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins]; 133 | } 134 | 135 | #endif 136 | 137 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 138 | 139 | - (MASViewAttribute *)mas_safeAreaLayoutGuide { 140 | return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 141 | } 142 | - (MASViewAttribute *)mas_safeAreaLayoutGuideTop { 143 | return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 144 | } 145 | - (MASViewAttribute *)mas_safeAreaLayoutGuideBottom { 146 | return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 147 | } 148 | - (MASViewAttribute *)mas_safeAreaLayoutGuideLeft { 149 | return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeLeft]; 150 | } 151 | - (MASViewAttribute *)mas_safeAreaLayoutGuideRight { 152 | return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeRight]; 153 | } 154 | 155 | #endif 156 | 157 | #pragma mark - associated properties 158 | 159 | - (id)mas_key { 160 | return objc_getAssociatedObject(self, @selector(mas_key)); 161 | } 162 | 163 | - (void)setMas_key:(id)key { 164 | objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 165 | } 166 | 167 | #pragma mark - heirachy 168 | 169 | - (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view { 170 | MAS_VIEW *closestCommonSuperview = nil; 171 | 172 | MAS_VIEW *secondViewSuperview = view; 173 | while (!closestCommonSuperview && secondViewSuperview) { 174 | MAS_VIEW *firstViewSuperview = self; 175 | while (!closestCommonSuperview && firstViewSuperview) { 176 | if (secondViewSuperview == firstViewSuperview) { 177 | closestCommonSuperview = secondViewSuperview; 178 | } 179 | firstViewSuperview = firstViewSuperview.superview; 180 | } 181 | secondViewSuperview = secondViewSuperview.superview; 182 | } 183 | return closestCommonSuperview; 184 | } 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "View+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand view additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface MAS_VIEW (MASShorthandAdditions) 18 | 19 | @property (nonatomic, strong, readonly) MASViewAttribute *left; 20 | @property (nonatomic, strong, readonly) MASViewAttribute *top; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *right; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *bottom; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *leading; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *trailing; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *width; 26 | @property (nonatomic, strong, readonly) MASViewAttribute *height; 27 | @property (nonatomic, strong, readonly) MASViewAttribute *centerX; 28 | @property (nonatomic, strong, readonly) MASViewAttribute *centerY; 29 | @property (nonatomic, strong, readonly) MASViewAttribute *baseline; 30 | @property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr); 31 | 32 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 33 | 34 | @property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline; 35 | @property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline; 36 | 37 | #endif 38 | 39 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 40 | 41 | @property (nonatomic, strong, readonly) MASViewAttribute *leftMargin; 42 | @property (nonatomic, strong, readonly) MASViewAttribute *rightMargin; 43 | @property (nonatomic, strong, readonly) MASViewAttribute *topMargin; 44 | @property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin; 45 | @property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin; 46 | @property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin; 47 | @property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins; 48 | @property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins; 49 | 50 | #endif 51 | 52 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 53 | 54 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0)); 55 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0)); 56 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0)); 57 | @property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0)); 58 | 59 | #endif 60 | 61 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 62 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 63 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 64 | 65 | @end 66 | 67 | #define MAS_ATTR_FORWARD(attr) \ 68 | - (MASViewAttribute *)attr { \ 69 | return [self mas_##attr]; \ 70 | } 71 | 72 | @implementation MAS_VIEW (MASShorthandAdditions) 73 | 74 | MAS_ATTR_FORWARD(top); 75 | MAS_ATTR_FORWARD(left); 76 | MAS_ATTR_FORWARD(bottom); 77 | MAS_ATTR_FORWARD(right); 78 | MAS_ATTR_FORWARD(leading); 79 | MAS_ATTR_FORWARD(trailing); 80 | MAS_ATTR_FORWARD(width); 81 | MAS_ATTR_FORWARD(height); 82 | MAS_ATTR_FORWARD(centerX); 83 | MAS_ATTR_FORWARD(centerY); 84 | MAS_ATTR_FORWARD(baseline); 85 | 86 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 87 | 88 | MAS_ATTR_FORWARD(firstBaseline); 89 | MAS_ATTR_FORWARD(lastBaseline); 90 | 91 | #endif 92 | 93 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) 94 | 95 | MAS_ATTR_FORWARD(leftMargin); 96 | MAS_ATTR_FORWARD(rightMargin); 97 | MAS_ATTR_FORWARD(topMargin); 98 | MAS_ATTR_FORWARD(bottomMargin); 99 | MAS_ATTR_FORWARD(leadingMargin); 100 | MAS_ATTR_FORWARD(trailingMargin); 101 | MAS_ATTR_FORWARD(centerXWithinMargins); 102 | MAS_ATTR_FORWARD(centerYWithinMargins); 103 | 104 | #endif 105 | 106 | #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000) 107 | 108 | MAS_ATTR_FORWARD(safeAreaLayoutGuideTop); 109 | MAS_ATTR_FORWARD(safeAreaLayoutGuideBottom); 110 | MAS_ATTR_FORWARD(safeAreaLayoutGuideLeft); 111 | MAS_ATTR_FORWARD(safeAreaLayoutGuideRight); 112 | 113 | #endif 114 | 115 | - (MASViewAttribute *(^)(NSLayoutAttribute))attribute { 116 | return [self mas_attribute]; 117 | } 118 | 119 | - (NSArray *)makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 120 | return [self mas_makeConstraints:block]; 121 | } 122 | 123 | - (NSArray *)updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 124 | return [self mas_updateConstraints:block]; 125 | } 126 | 127 | - (NSArray *)remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block { 128 | return [self mas_remakeConstraints:block]; 129 | } 130 | 131 | @end 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | #ifdef MAS_VIEW_CONTROLLER 14 | 15 | @interface MAS_VIEW_CONTROLLER (MASAdditions) 16 | 17 | /** 18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute 19 | */ 20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; 26 | 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/Lib/Masonry/ViewController+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "ViewController+MASAdditions.h" 10 | 11 | #ifdef MAS_VIEW_CONTROLLER 12 | 13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions) 14 | 15 | - (MASViewAttribute *)mas_topLayoutGuide { 16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 17 | } 18 | - (MASViewAttribute *)mas_topLayoutGuideTop { 19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 20 | } 21 | - (MASViewAttribute *)mas_topLayoutGuideBottom { 22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 23 | } 24 | 25 | - (MASViewAttribute *)mas_bottomLayoutGuide { 26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 27 | } 28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop { 29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 30 | } 31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom { 32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 33 | } 34 | 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/AnimatedView/ZJCircleAnimatedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJCircleAnimatedView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 参考了 https://blog.csdn.net/u013282507/article/details/70208141 作者的实现思路 8 | 9 | #import "ZJPSWBaseView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJCircleAnimatedView : ZJPSWBaseView 14 | 15 | - (void)beginAnimating; 16 | 17 | - (void)endAnimating; 18 | 19 | 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/AnimatedView/ZJCircleAnimatedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJCircleAnimatedView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJCircleAnimatedView.h" 10 | 11 | @interface ZJCircleAnimatedView () 12 | 13 | @property (nonatomic, strong) CAShapeLayer *circleLayer; 14 | 15 | @property (nonatomic, strong) CADisplayLink *displayLink; 16 | 17 | @property (nonatomic, assign) CGFloat lineWidth; 18 | 19 | @property (nonatomic, assign) CGFloat startAngle; 20 | 21 | @property (nonatomic, assign) CGFloat endAngle; 22 | 23 | @property (nonatomic, assign) CGFloat progress; 24 | 25 | @property (nonatomic, assign) CGFloat speed; 26 | 27 | @property (nonatomic, assign) CGPoint arcCenter; 28 | 29 | 30 | @end 31 | 32 | @implementation ZJCircleAnimatedView 33 | 34 | static CGFloat const kRadius = 60; 35 | 36 | - (id)initWithFrame:(CGRect)frame { 37 | if (self = [super initWithFrame:frame]) { 38 | self.circleLayer = [CAShapeLayer layer]; 39 | [self initUpUI]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)initUpUI { 45 | self.lineWidth = 4.f; 46 | self.startAngle = - M_PI_2; 47 | self.arcCenter = CGPointMake(kRadius/2.0,kRadius / 2.0); 48 | 49 | self.circleLayer = [CAShapeLayer layer]; 50 | self.circleLayer.frame = CGRectMake((CGRectGetWidth(self.frame ) - kRadius ) / 2.0, (CGRectGetHeight(self.frame ) - kRadius ) / 2.0, kRadius, kRadius); 51 | self.circleLayer.strokeColor = [UIColor blueColor].CGColor; 52 | self.circleLayer.lineWidth = self.lineWidth; 53 | self.circleLayer.fillColor = [UIColor clearColor].CGColor; 54 | self.circleLayer.lineCap = kCALineCapRound; 55 | [self.layer addSublayer:self.circleLayer]; 56 | 57 | } 58 | 59 | - (void)beginAnimating { 60 | self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(targetEvent:)]; 61 | [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 62 | } 63 | 64 | - (void)targetEvent:(CADisplayLink *)link { 65 | self.progress += self.speed; 66 | self.startAngle = - M_PI_2; 67 | if (_progress >= 1) { 68 | self.progress = 0; 69 | } 70 | _endAngle = _startAngle + _progress * M_PI * 2; 71 | 72 | if (_endAngle > M_PI) { 73 | //大于180度时,速度变慢 74 | CGFloat progress = 1 - (1 - _progress) * 4; 75 | _startAngle = -M_PI_2 + progress * M_PI * 2; 76 | } 77 | 78 | CGFloat radius = kRadius/2.0f - _lineWidth/2.0f; 79 | UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.arcCenter 80 | radius:radius 81 | startAngle:_startAngle 82 | endAngle:_endAngle 83 | clockwise:true]; 84 | self.circleLayer.path = path.CGPath; 85 | } 86 | 87 | //有种先快后慢的感觉 88 | -(CGFloat)speed{ 89 | if (_endAngle > M_PI) { 90 | return 0.3 / 60.f; 91 | } 92 | return 3 / 60.f; 93 | } 94 | 95 | 96 | - (void)endAnimating { 97 | self.displayLink.paused = true; 98 | [self.circleLayer removeFromSuperlayer]; 99 | } 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/AnimatedView/ZJSuccessLoadingView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJSuccessLoadingView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJSuccessLoadingView : ZJPSWBaseView 14 | 15 | @property (nonatomic,copy) void (^ZJSuccessLoadEnd)(void); 16 | 17 | 18 | - (void)beginAnimating; 19 | 20 | - (void)stopAnimating; 21 | 22 | 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/AnimatedView/ZJSuccessLoadingView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJSuccessLoadingView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJSuccessLoadingView.h" 10 | 11 | @interface ZJSuccessLoadingView () 12 | 13 | @property (nonatomic, strong) CAShapeLayer *circleLayer; 14 | 15 | @property (nonatomic, strong) CAShapeLayer *markLayer; 16 | 17 | @property (nonatomic, assign) CGFloat lineWidth; 18 | 19 | @property (nonatomic, assign) CGFloat startAngle; 20 | 21 | @property (nonatomic, assign) CGFloat endAngle; 22 | 23 | @property (nonatomic, assign) CGPoint arcCenter; 24 | 25 | 26 | @end 27 | 28 | @implementation ZJSuccessLoadingView 29 | 30 | static CGFloat const kRadius = 60.f; 31 | 32 | static NSString * const kAnimationKey = @"AnimationKey"; 33 | static NSString * const kCircleAnimation = @"kCircleAnimationValue"; 34 | static NSString * const kMarkAnimation = @"kMarkAnimationValue"; 35 | 36 | - (id)initWithFrame:(CGRect)frame { 37 | if (self = [super initWithFrame:frame]) { 38 | [self initUI]; 39 | } 40 | return self; 41 | } 42 | 43 | - (void)initUI { 44 | self.lineWidth = 4.f; 45 | self.startAngle = - M_PI_2; 46 | self.endAngle = - M_PI_2 + M_PI * 2; 47 | self.arcCenter = CGPointMake(kRadius/2.0,kRadius / 2.0); 48 | 49 | self.circleLayer = [CAShapeLayer layer]; 50 | self.circleLayer.frame = CGRectMake((CGRectGetWidth(self.frame ) - kRadius ) / 2.0, (CGRectGetHeight(self.frame ) - kRadius ) / 2.0, kRadius, kRadius); 51 | self.circleLayer.strokeColor = [UIColor blueColor].CGColor; 52 | self.circleLayer.lineWidth = self.lineWidth; 53 | self.circleLayer.fillColor = [UIColor clearColor].CGColor; 54 | self.circleLayer.lineCap = kCALineCapRound; 55 | [self.layer addSublayer:self.circleLayer]; 56 | } 57 | 58 | - (void)beginAnimating { 59 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:self.arcCenter 60 | radius:kRadius / 2.0 61 | startAngle:self.startAngle 62 | endAngle:self.endAngle 63 | clockwise:true]; 64 | self.circleLayer.path = bezierPath.CGPath; 65 | 66 | CABasicAnimation *aniamtion = [self anitionWithDuration:0.8f]; 67 | [aniamtion setValue:kCircleAnimation forKey:kAnimationKey]; 68 | [self.circleLayer addAnimation:aniamtion forKey:kAnimationKey]; 69 | } 70 | 71 | - (void)stopAnimating { 72 | if (self.circleLayer) { 73 | [self.circleLayer removeFromSuperlayer]; 74 | } 75 | if (self.markLayer) { 76 | [self.markLayer removeFromSuperlayer]; 77 | } 78 | } 79 | 80 | - (void)addSuccessMarkView { 81 | UIBezierPath *bezierPath = [UIBezierPath bezierPath]; 82 | CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 83 | shapeLayer.lineWidth = self.lineWidth; 84 | [bezierPath moveToPoint:CGPointMake(self.arcCenter.x - 20, self.arcCenter.y + 10)]; 85 | [bezierPath addLineToPoint:CGPointMake(self.arcCenter.x - 5, self.arcCenter.y + 15)]; 86 | [bezierPath addLineToPoint:CGPointMake(self.arcCenter.x + 20, self.arcCenter.y - 15)]; 87 | shapeLayer.fillColor = [UIColor clearColor].CGColor; 88 | shapeLayer.strokeColor = [UIColor blueColor].CGColor; 89 | shapeLayer.path = bezierPath.CGPath; 90 | CABasicAnimation *animaion = [self anitionWithDuration:0.4]; 91 | [animaion setValue:kMarkAnimation forKey:kAnimationKey]; 92 | [shapeLayer addAnimation:animaion forKey:kAnimationKey]; 93 | self.markLayer = shapeLayer; 94 | [self.circleLayer addSublayer:self.markLayer]; 95 | } 96 | 97 | - (CABasicAnimation *)anitionWithDuration:(NSTimeInterval)duration { 98 | CABasicAnimation *aniamtion = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 99 | aniamtion.fromValue = @(0); 100 | aniamtion.toValue = @(1); 101 | aniamtion.removedOnCompletion = false; 102 | aniamtion.duration = duration; 103 | aniamtion.repeatCount = 1; 104 | aniamtion.delegate = self; 105 | return aniamtion; 106 | } 107 | 108 | - (void)animationDidStop:(CAAnimation *)anim 109 | finished:(BOOL)flag { 110 | if ([[anim valueForKey:kAnimationKey] isEqualToString:kCircleAnimation]) { 111 | [self addSuccessMarkView]; 112 | } 113 | else if ([[anim valueForKey:kAnimationKey] isEqualToString:kMarkAnimation]) { 114 | ZJAfter(0.2, ^{ 115 | [self stopAnimating]; 116 | !self.ZJSuccessLoadEnd ? : self.ZJSuccessLoadEnd(); 117 | }); 118 | } 119 | } 120 | 121 | 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TestViewController/ZJModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJModel.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | typedef NS_ENUM(NSInteger,ZJPasswordStyleType) { 13 | ZJPasswordStyleBottomLineNormal = 0, //下划线高亮样式明文 14 | ZJPasswordStyleBottomLineEncrypt = 1, //下划线高亮样式密文 15 | ZJPasswordStyleRectangleNormal = 2, //矩形框样式明文 16 | ZJPasswordStyleRectangleEncrypt = 3, //矩形框样式密文 17 | ZJPasswordStyleWithAnimating = 4, //带动画的 18 | 19 | }; 20 | 21 | @interface ZJModel : NSObject 22 | 23 | @property (nonatomic, copy) NSString *name; 24 | @property (nonatomic, assign) ZJPasswordStyleType styleType; 25 | 26 | @end 27 | 28 | @interface ZJViewModel : NSObject 29 | 30 | - (NSInteger)numberOfSections; 31 | 32 | - (NSInteger)numberOfRowInSection:(NSInteger)setion; 33 | 34 | - (ZJModel *)rowModelOfIndexPath:(NSIndexPath *)indexPath; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TestViewController/ZJModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJModel.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJModel.h" 10 | #import 11 | 12 | @implementation ZJModel 13 | 14 | @end 15 | 16 | @interface ZJViewModel () 17 | 18 | @property (nonatomic, strong) NSMutableArray *rows; 19 | 20 | 21 | @end 22 | 23 | @implementation ZJViewModel 24 | 25 | - (id)init { 26 | if (self = [super init]) { 27 | [self configureDefaultData]; 28 | } 29 | return self; 30 | } 31 | 32 | - (NSInteger)numberOfSections { 33 | return 1; 34 | } 35 | 36 | - (NSInteger)numberOfRowInSection:(NSInteger)setion { 37 | 38 | 39 | 40 | return self.rows.count; 41 | } 42 | 43 | - (ZJModel *)rowModelOfIndexPath:(NSIndexPath *)indexPath { 44 | if (indexPath.row >= self.rows.count) { 45 | return nil; 46 | } 47 | return self.rows[indexPath.row]; 48 | } 49 | 50 | - (void)configureDefaultData { 51 | for (int i = 0 ; i < 5; i++) { 52 | ZJModel *model = [ZJModel new]; 53 | if (i == 0) { 54 | model.name = @"下划线高亮明文密码输入框样式"; 55 | model.styleType = ZJPasswordStyleBottomLineNormal; 56 | } 57 | else if (i == 1) { 58 | model.name = @"下划线安全密码输入框样式"; 59 | model.styleType = ZJPasswordStyleBottomLineEncrypt; 60 | } 61 | else if (i == 2) { 62 | model.name = @"矩形框明文密码输入框样式"; 63 | model.styleType = ZJPasswordStyleRectangleNormal; 64 | } 65 | else if (i == 3) { 66 | model.name = @"矩形框安全密码输入框样式"; 67 | model.styleType = ZJPasswordStyleRectangleEncrypt; 68 | } 69 | else if (i == 4) { 70 | model.name = @"密码密码框带完成动画"; 71 | model.styleType = ZJPasswordStyleWithAnimating; 72 | } 73 | [self.rows addObject:model]; 74 | } 75 | } 76 | 77 | 78 | - (NSMutableArray *)rows{ 79 | if(!_rows){ 80 | _rows = [NSMutableArray new]; 81 | } 82 | return _rows; 83 | } 84 | 85 | 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TestViewController/ZJPasswordStyleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordStyleViewController.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ZJModel; 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPasswordStyleViewController : UIViewController 15 | 16 | @property (nonatomic, strong) ZJModel *dataModel; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TestViewController/ZJPasswordStyleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordStyleViewController.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordStyleViewController.h" 10 | #import "ZJModel.h" 11 | 12 | #import "ZJPSWTextfieldContext.h" 13 | #import "ZJUIHeader.h" 14 | 15 | 16 | @interface ZJPasswordStyleViewController () 17 | 18 | @property (nonatomic, strong) UIView *textfieldView; 19 | 20 | @property (nonatomic, strong) UIView *backView; 21 | 22 | @end 23 | 24 | @implementation ZJPasswordStyleViewController 25 | 26 | - (void)viewWillAppear:(BOOL)animated { 27 | [super viewWillAppear:animated]; 28 | [self.view setBackgroundColor:[UIColor whiteColor]]; 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | self.title = @"输入密码"; 34 | [self initUI]; 35 | } 36 | 37 | - (void)initUI { 38 | ZJPSWTextfieldViewType viewType = ZJPSWTextfieldViewLineNormal; 39 | switch (_dataModel.styleType) { 40 | case ZJPasswordStyleBottomLineNormal: { 41 | viewType = ZJPSWTextfieldViewLineNormal; 42 | [self setUpTextfieldViewWithType:viewType]; 43 | } 44 | break; 45 | case ZJPasswordStyleBottomLineEncrypt: { 46 | viewType = ZJPSWTextfieldViewLineEncryption; 47 | [self setUpTextfieldViewWithType:viewType]; 48 | } 49 | break; 50 | case ZJPasswordStyleRectangleNormal: { 51 | viewType = ZJPSWTextfieldViewRectNormal; 52 | [self setUpTextfieldViewWithType:viewType]; 53 | } 54 | break; 55 | case ZJPasswordStyleRectangleEncrypt: { 56 | viewType = ZJPSWTextfieldViewRectEncryption; 57 | [self setUpTextfieldViewWithType:viewType]; 58 | } 59 | break; 60 | case ZJPasswordStyleWithAnimating: { 61 | viewType = ZJPSWTextfieldViewWithAnimating; 62 | [self setUpTextfieldViewWithType:viewType]; 63 | } 64 | } 65 | 66 | } 67 | 68 | - (void)setUpTextfieldViewWithType:(ZJPSWTextfieldViewType)type { 69 | self.textfieldView = [ZJPSWTextfieldContext configureTextfieldView:type frame:CGRectMake(0, 110, ZJWinodwWidth, ZJWinodwHeight - 100)]; 70 | [self.textfieldView setDelegate:self]; 71 | [self.view addSubview:self.textfieldView]; 72 | } 73 | 74 | - (void)setUpAnimatedView { 75 | self.backView = [[UIView alloc] initWithFrame:CGRectMake(0, ZJWinodwHeight - 400, ZJWinodwWidth, 400)]; 76 | [self.backView setBackgroundColor:[UIColor whiteColor]]; 77 | [self.view addSubview:self.backView]; 78 | 79 | } 80 | 81 | - (void)textfieldView:(UIView *)textfieldView 82 | result:(NSString *)result 83 | eventType:(ZJPasswordViewEventType)type { 84 | switch (type) { 85 | case ZJPasswordViewEventAutoDone: { 86 | NSLog(@"输入6位密码完成,<<%@>>",result); 87 | if (_dataModel.styleType == ZJPSWTextfieldViewWithAnimating) { 88 | [textfieldView showCircleAnimating]; 89 | ZJAfter(2.f, ^{ 90 | [textfieldView stopCircleAnimating]; 91 | [textfieldView showCheckAnimation]; 92 | }); 93 | } 94 | else { 95 | [self showAlertTitle:@"输入密码完成" message:result okTitle:@"确定" okEvent:^{ 96 | [self.textfieldView clearAllInputChars]; 97 | [self.textfieldView makeTextfieldBecomeFirstResponder]; 98 | }]; 99 | } 100 | } 101 | break; 102 | case ZJPasswordViewEventOKButton: { 103 | NSLog(@"点击ToolBarView 使键盘下落"); 104 | } 105 | break; 106 | case ZJPasswordViewEventLengthUpdate: { 107 | NSLog(@"输入变化"); 108 | } 109 | break; 110 | case ZJPasswordViewAnimateViewFinish: { 111 | NSLog(@"支付完成,回到上一页"); 112 | [self.navigationController popViewControllerAnimated:true]; 113 | } 114 | break; 115 | default: 116 | break; 117 | } 118 | } 119 | 120 | 121 | 122 | - (void)showAlertTitle:(NSString *)title 123 | message:(NSString *)message 124 | okTitle:(NSString *)okTitle 125 | okEvent:(void(^)(void))okEvet{ 126 | 127 | message = [NSString stringWithFormat:@"\n%@\n",message]; 128 | UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; 129 | if ([okTitle length] >0) { 130 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:okTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 131 | !okEvet ? : okEvet(); 132 | }]; 133 | [alertVC addAction:okAction]; 134 | } 135 | 136 | [self.navigationController presentViewController:alertVC animated:true completion:nil]; 137 | } 138 | 139 | 140 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 141 | 142 | 143 | 144 | 145 | } 146 | 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TextfiledViewElement/ZJPSWRectEncryptView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectEncryptView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2020/6/3. 6 | // Copyright © 2020 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWRectEncryptView : ZJPSWBaseView 15 | 16 | @property (nonatomic,weak) id delegate; 17 | 18 | 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/TextfiledViewElement/ZJPSWRectEncryptView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectEncryptView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2020/6/3. 6 | // Copyright © 2020 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectEncryptView.h" 10 | #import "ZJPasswordDotView.h" 11 | #import "ZJPSWBaseTextField.h" 12 | 13 | static CGFloat const kDotViewRadius = 6.f; 14 | static NSInteger const kNormalMaxCount = 6; 15 | static CGFloat const kLineGap = 7.f; 16 | static CGFloat const kLineHeight = 1.f; 17 | 18 | @interface ZJPSWRectEncryptView () 19 | 20 | @property (nonatomic, strong) NSMutableArray *dotViews; 21 | @property (nonatomic, strong) ZJMaskView *maskView; 22 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 23 | 24 | 25 | @end 26 | 27 | @implementation ZJPSWRectEncryptView 28 | 29 | - (void)zj_addSubviews { 30 | 31 | _textField = [ZJPSWBaseTextField new]; 32 | _textField.textColor = [UIColor whiteColor]; 33 | _textField.tintColor = [UIColor whiteColor]; 34 | _textField.secureTextEntry = true; 35 | _textField.maxCount = kMaxCount; 36 | _textField.allowCopyMenu = false; 37 | _textField.keyboardType = UIKeyboardTypeNumberPad; 38 | [_textField addTarget:self action:@selector(textfieldDidChanged:) forControlEvents:UIControlEventEditingChanged]; 39 | __weak typeof(self) weakSelf = self; 40 | _textField.showToolbarView = true; 41 | _textField.ToolBarViewEvent = ^{ 42 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 43 | }; 44 | [self addSubview:_textField]; 45 | 46 | _maskView = [[ZJMaskView alloc] init]; 47 | _maskView.layer.cornerRadius = 8.f; 48 | _maskView.layer.borderColor = ZJBorderLayerCorlor.CGColor; 49 | _maskView.layer.borderWidth = 1.f; 50 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 51 | [self addSubview:_maskView]; 52 | } 53 | 54 | - (void)zj_addConstraints { 55 | [_maskView mas_makeConstraints:^(MASConstraintMaker *make) { 56 | make.left.mas_equalTo(15); 57 | make.centerY.mas_equalTo(0).priorityHigh(); 58 | make.right.mas_equalTo(-15); 59 | make.height.mas_equalTo(40); 60 | }]; 61 | 62 | [_textField mas_makeConstraints:^(MASConstraintMaker *make) { 63 | make.left.mas_equalTo(15); 64 | make.centerY.mas_equalTo(0); 65 | make.right.mas_equalTo(-15); 66 | make.height.mas_equalTo(44); 67 | }]; 68 | 69 | [_textField layoutIfNeeded]; 70 | [_maskView layoutIfNeeded]; 71 | [self p_initDotViewWithFrame:_maskView.bounds]; 72 | } 73 | - (void)p_initDotViewWithFrame:(CGRect)frame { 74 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 75 | CGFloat viewW = frame.size.width / kMaxCount; 76 | CGFloat viewH = frame.size.height; 77 | for (int i = 0; i < kMaxCount; i ++) { 78 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 79 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordRectangleEncryption 80 | frame:frame]; 81 | [dotView.verticalLineView setHidden:i == kMaxCount - 1]; 82 | [self.maskView addSubview:dotView]; 83 | [self.dotViews addObject:dotView]; 84 | } 85 | [self updateInputNumWithText:_textField.text]; 86 | } 87 | 88 | - (void)textfieldDidChanged:(UITextField *)textfiled { 89 | [self updateInputNumWithText:textfiled.text]; 90 | } 91 | 92 | - (void)updateInputNumWithText:(NSString *)text { 93 | NSInteger length = text.length; 94 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 95 | if (length < kMaxCount) { 96 | [obj setDotBottomLineHightlight:idx == length]; 97 | } 98 | [obj setDotPointHide:!(idx < length)]; 99 | }]; 100 | if (length == kMaxCount) { 101 | [self callBackAutoDoneFunnctionWithText:text]; 102 | } 103 | else { 104 | [self callBackInpuTextLengthUpdateWithText:text]; 105 | } 106 | } 107 | 108 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 109 | [self makeTextfieldResignFirstResponder]; 110 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 111 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 112 | } 113 | } 114 | 115 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 116 | [self makeTextfieldResignFirstResponder]; 117 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 118 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 119 | } 120 | } 121 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 122 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 123 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 124 | } 125 | } 126 | 127 | - (void)makeTextfieldBecomeFirstResponder { 128 | [_textField becomeFirstResponder]; 129 | } 130 | 131 | - (void)makeTextfieldResignFirstResponder { 132 | [_textField resignFirstResponder]; 133 | } 134 | 135 | - (void)clearAllInputChars { 136 | [self.textField setText:@""]; 137 | [self updateInputNumWithText:@""]; 138 | } 139 | 140 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 141 | ZJAfter(delay, ^{ 142 | [self->_textField becomeFirstResponder]; 143 | }); 144 | } 145 | 146 | - (NSInteger)textLength { 147 | return _textField.text.length; 148 | } 149 | 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJMaskView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJMaskView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class ZJMaskView; 14 | @protocol ZJMaskViewDelegate 15 | @optional; 16 | - (void)maskViewDidClick:(ZJMaskView *)maskView; 17 | 18 | @end 19 | 20 | @interface ZJMaskView : ZJPSWBaseView 21 | 22 | { 23 | struct { 24 | unsigned int ClickMaskView : 1; 25 | }_DelegateFlags; 26 | } 27 | 28 | @property (nonatomic,weak) id delegate; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJMaskView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJMaskView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJMaskView.h" 10 | 11 | @implementation ZJMaskView 12 | 13 | - (void)setDelegate:(id)delegate { 14 | _delegate = delegate; 15 | _DelegateFlags.ClickMaskView = [_delegate respondsToSelector:@selector(maskViewDidClick:)]; 16 | } 17 | 18 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 19 | static BOOL first = true; 20 | UIView *hitView = [super hitTest:point withEvent:event]; 21 | if (hitView == self) { 22 | if (first) { 23 | first = NO; 24 | if (_DelegateFlags.ClickMaskView) { 25 | [_delegate maskViewDidClick:self]; 26 | } 27 | } 28 | return nil; 29 | } 30 | return hitView; 31 | } 32 | 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWLineDotEncryptionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineDotEncryptionView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordDotView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJPSWLineDotEncryptionView : ZJPasswordDotView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWLineDotEncryptionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineDotEncryptionView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWLineDotEncryptionView.h" 10 | 11 | @implementation ZJPSWLineDotEncryptionView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | if (self = [super initWithFrame:frame]) { 15 | [self p_initUIWithFrame:frame]; 16 | } 17 | return self; 18 | } 19 | - (void)p_initUIWithFrame:(CGRect)frame { 20 | [self.verticalLineView setHidden:true]; 21 | [self.titleLab setHidden:true]; 22 | 23 | self.bottomLineView.frame = CGRectMake(self.kLineLeftGap, frame.size.height - 5.f, frame.size.width - 2 * self.kLineLeftGap, 1.f); 24 | 25 | [self.dotView mas_makeConstraints:^(MASConstraintMaker *make) { 26 | make.centerX.mas_equalTo(0); 27 | make.centerY.mas_equalTo(0); 28 | make.size.mas_equalTo(CGSizeMake(self.dotViewRaduis * 2, self.dotViewRaduis * 2)); 29 | }]; 30 | } 31 | 32 | 33 | 34 | - (void)zj_addSubviews { 35 | [super zj_addSubviews]; 36 | [self.titleLab setHidden:true]; 37 | [self.verticalLineView setHidden:true]; 38 | } 39 | 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWLineDotNormalView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineDotNormalView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordDotView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJPSWLineDotNormalView : ZJPasswordDotView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWLineDotNormalView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineDotNormalView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWLineDotNormalView.h" 10 | 11 | @implementation ZJPSWLineDotNormalView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | if (self = [super initWithFrame:frame]) { 15 | [self p_initUIWithFrame:frame]; 16 | } 17 | return self; 18 | } 19 | - (void)p_initUIWithFrame:(CGRect)frame { 20 | [self.dotView setHidden:true]; 21 | [self.verticalLineView setHidden:true]; 22 | 23 | self.bottomLineView.frame = CGRectMake(self.kLineLeftGap, frame.size.height - 5.f, frame.size.width - 2 * self.kLineLeftGap, 1.f); 24 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 25 | make.centerX.mas_equalTo(0); 26 | make.centerY.mas_equalTo(0); 27 | }]; 28 | } 29 | 30 | 31 | 32 | 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWRectDotEncryptionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectDotEncryptionView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordDotView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJPSWRectDotEncryptionView : ZJPasswordDotView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWRectDotEncryptionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectDotEncryptionView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectDotEncryptionView.h" 10 | 11 | @implementation ZJPSWRectDotEncryptionView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | if (self = [super initWithFrame:frame]) { 15 | [self p_initUIWithFrame:frame]; 16 | } 17 | return self; 18 | } 19 | - (void)p_initUIWithFrame:(CGRect)frame { 20 | [self.titleLab setHidden:true]; 21 | [self.bottomLineView setHidden:true]; 22 | 23 | self.verticalLineView.frame = CGRectMake(frame.size.width - 1, 0, 1.f, frame.size.height); 24 | 25 | [self.dotView mas_makeConstraints:^(MASConstraintMaker *make) { 26 | make.centerX.mas_equalTo(0); 27 | make.centerY.mas_equalTo(0); 28 | make.size.mas_equalTo(CGSizeMake(self.dotViewRaduis * 2, self.dotViewRaduis * 2)); 29 | }]; 30 | } 31 | 32 | 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWRectDotNormalView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectDotNormalView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordDotView.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZJPSWRectDotNormalView : ZJPasswordDotView 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPSWRectDotNormalView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectDotNormalView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectDotNormalView.h" 10 | 11 | @implementation ZJPSWRectDotNormalView 12 | 13 | - (id)initWithFrame:(CGRect)frame { 14 | if (self = [super initWithFrame:frame]) { 15 | [self p_initUIWithFrame:frame]; 16 | } 17 | return self; 18 | } 19 | 20 | - (void)p_initUIWithFrame:(CGRect)frame { 21 | [self.dotView setHidden:true]; 22 | [self.bottomLineView setHidden:true]; 23 | 24 | self.verticalLineView.frame = CGRectMake(frame.size.width - 1, 0, 1.f, frame.size.height); 25 | 26 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 27 | make.centerX.mas_equalTo(0); 28 | make.centerY.mas_equalTo(0); 29 | }]; 30 | } 31 | 32 | 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPasswordDotView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordDotView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJMaskView.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef NS_ENUM(NSInteger,ZJPasswordType) { 15 | ZJPasswordBottomLineNormal = 0, //下划线正常样式 16 | ZJPasswordBottomLineEncrytion = 1, //下划线加密样式 17 | ZJPasswordRectangleNormal = 2, //矩形框正常样式 18 | ZJPasswordRectangleEncryption = 3, //矩形框加密样式 19 | }; 20 | 21 | @interface ZJPasswordDotView : ZJPSWBaseView 22 | 23 | @property (nonatomic, strong) UILabel *titleLab; 24 | @property (nonatomic, strong) UIView *bottomLineView; 25 | @property (nonatomic, strong) UIView *verticalLineView; 26 | @property (nonatomic, strong) ZJMaskView *dotView; 27 | 28 | //实心圆点半径 29 | @property (nonatomic, assign) CGFloat dotViewRaduis; 30 | //底部分割线与view的gap 31 | @property (nonatomic, assign) CGFloat kLineLeftGap; 32 | //垂直分割线与View的gap 33 | @property (nonatomic, assign) CGFloat kLineTopGap; 34 | 35 | 36 | 37 | + (instancetype)createDotViewWithType:(ZJPasswordType)type 38 | frame:(CGRect)frame; 39 | 40 | 41 | /** 42 | 设置 bottomLine 是否高亮 43 | 44 | @param isHightlight YES/NO 45 | */ 46 | - (void)setDotBottomLineHightlight:(BOOL)isHightlight; 47 | 48 | /** 49 | 设置Title 50 | 51 | @param aTitle title 52 | */ 53 | - (void)setDotTitle:(NSString *)aTitle; 54 | 55 | 56 | /** 57 | 设置实心圆点是否显示 58 | 59 | @param isHide yes/no 60 | */ 61 | - (void)setDotPointHide:(BOOL)isHide; 62 | 63 | @end 64 | 65 | NS_ASSUME_NONNULL_END 66 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJDotView/ZJPasswordDotView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordDotView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPasswordDotView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | #import "ZJPSWLineDotNormalView.h" 13 | #import "ZJPSWLineDotEncryptionView.h" 14 | #import "ZJPSWRectDotNormalView.h" 15 | #import "ZJPSWRectDotEncryptionView.h" 16 | 17 | 18 | @interface ZJPasswordDotView () 19 | 20 | @property (nonatomic, strong) ZJPasswordDotView *currentDotView; 21 | 22 | @end 23 | 24 | 25 | @implementation ZJPasswordDotView 26 | 27 | + (instancetype)createDotViewWithType:(ZJPasswordType)type 28 | frame:(CGRect)frame { 29 | ZJPasswordDotView *dotView = [[ZJPasswordDotView alloc] initWithFrame:frame type:type]; 30 | return dotView; 31 | } 32 | 33 | - (id)initWithFrame:(CGRect)frame type:(ZJPasswordType)type { 34 | ZJPasswordDotView *currentDotView = nil; 35 | switch (type) { 36 | case ZJPasswordBottomLineNormal: { 37 | currentDotView = [[ZJPSWLineDotNormalView alloc] initWithFrame:frame]; 38 | } 39 | break; 40 | case ZJPasswordBottomLineEncrytion: { 41 | currentDotView = [[ZJPSWLineDotEncryptionView alloc] initWithFrame:frame]; 42 | } 43 | break; 44 | case ZJPasswordRectangleNormal: { 45 | currentDotView = [[ZJPSWRectDotNormalView alloc] initWithFrame:frame]; 46 | } 47 | break; 48 | case ZJPasswordRectangleEncryption: { 49 | currentDotView = [[ZJPSWRectDotEncryptionView alloc] initWithFrame:frame]; 50 | } 51 | break; 52 | 53 | default: { 54 | currentDotView = [[ZJPSWLineDotNormalView alloc] initWithFrame:frame]; 55 | } 56 | break; 57 | } 58 | [self setCurrentDotView:currentDotView]; 59 | return currentDotView; 60 | } 61 | 62 | - (void)zj_addConstraints { 63 | self.dotViewRaduis = 6.f; 64 | self.kLineLeftGap = 8.f; 65 | self.kLineTopGap = 0.f; 66 | 67 | self.titleLab = CreateCenterAlignmentLabel(BFont(25), ZJColorWithHex(0x333333)); 68 | self.titleLab.userInteractionEnabled = true; 69 | [self addSubview:self.titleLab]; 70 | 71 | self.dotView = [[ZJMaskView alloc] init]; 72 | self.dotView.backgroundColor = ZJColorWithHex(0x333333); 73 | self.dotView.layer.cornerRadius = self.dotViewRaduis; 74 | self.dotView.clipsToBounds = true; 75 | [self addSubview:self.dotView]; 76 | 77 | self.bottomLineView = [UIView new]; 78 | [self.bottomLineView setBackgroundColor:kNormarLineColor]; 79 | [self addSubview:self.bottomLineView]; 80 | 81 | self.verticalLineView = [UIView new]; 82 | [self.verticalLineView setBackgroundColor:ZJBorderLayerCorlor]; 83 | [self addSubview:self.verticalLineView]; 84 | } 85 | 86 | 87 | /** 88 | 设置 bottomLine 是否高亮 89 | 90 | @param isHightlight YES/NO 91 | */ 92 | - (void)setDotBottomLineHightlight:(BOOL)isHightlight { 93 | [self.bottomLineView setBackgroundColor:isHightlight ? 94 | kHightlightLineColor : kNormarLineColor ]; 95 | } 96 | 97 | /** 98 | 设置Title 99 | 100 | @param aTitle title 101 | */ 102 | - (void)setDotTitle:(NSString *)aTitle { 103 | [self.titleLab setText:aTitle]; 104 | } 105 | 106 | 107 | /** 108 | 设置实心圆点是否显示 109 | 110 | @param isHide yes/no 111 | */ 112 | - (void)setDotPointHide:(BOOL)isHide { 113 | [self.dotView setHidden:isHide]; 114 | } 115 | 116 | 117 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 118 | UIView *pointView = [super hitTest:point withEvent:event]; 119 | if ([pointView isKindOfClass:self.class]) { 120 | return nil; 121 | } 122 | return pointView; 123 | } 124 | 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJPasswordViewHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordViewHeader.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2020/10/12. 6 | // Copyright © 2020 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ZJPasswordViewProtocol.h" 12 | #import "ZJPasswordStyleViewController.h" 13 | #import "ZJPSWLineNormalTextfiledView.h" 14 | #import "ZJPSWLineEncryptTextfiledView.h" 15 | #import "ZJPSWRectAnimateTextfieldView.h" 16 | #import "ZJPSWRectNormalTextfieldView.h" 17 | #import "ZJPSWRectEncryptTextfiledView.h" 18 | #import "ZJPSWRectEncryptView.h" 19 | 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @interface ZJPasswordViewHeader : NSObject 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJPasswordViewProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPasswordViewProtocol.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | #define ZJBorderLayerCorlor ZJColorWithHex(0xDEE2EC) 14 | 15 | #define kNormarLineColor ZJColorWithHex(0xE4E4E4) 16 | 17 | #define kHightlightLineColor ZJColorWithHex(0x3773FF) 18 | 19 | 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | //最大密码长度 23 | #define kMaxCount 6 24 | 25 | typedef NS_ENUM(NSInteger,ZJPasswordViewEventType) { 26 | ZJPasswordViewEventAutoDone = 1, //输入密码达到6位 27 | ZJPasswordViewEventLengthUpdate = 2, //输入密码长度变化 28 | ZJPasswordViewEventOKButton = 3, //点击了键盘工具条,使键盘下落 29 | ZJPasswordViewAnimateViewFinish = 4, //输入密码动画完成了 30 | }; 31 | 32 | 33 | @protocol ZJPasswordViewDelegate; 34 | 35 | @protocol ZJPasswordViewProtocol 36 | 37 | 38 | /** 39 | 用户回调对应事件的委托 40 | */ 41 | @property (nonatomic, weak) id delegate; 42 | 43 | 44 | /** 45 | 使键盘弹出 46 | */ 47 | - (void)makeTextfieldBecomeFirstResponder; 48 | 49 | 50 | /** 51 | 使键盘关闭 52 | */ 53 | - (void)makeTextfieldResignFirstResponder; 54 | 55 | 56 | /** 57 | 自动显示键盘 58 | 59 | @param delay 延迟多久 60 | */ 61 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay; 62 | 63 | 64 | /** 65 | 清除已经输入的全部字符 66 | */ 67 | - (void)clearAllInputChars; 68 | 69 | 70 | /** 71 | 当前输入的字符长度 72 | 73 | @return length 74 | */ 75 | - (NSInteger)textLength; 76 | 77 | 78 | @optional; 79 | 80 | - (void)showCircleAnimating; 81 | 82 | - (void)stopCircleAnimating; 83 | 84 | - (void)showCheckAnimation; 85 | 86 | 87 | @end 88 | 89 | @protocol ZJPasswordViewDelegate 90 | 91 | /** 92 | 对应的代理事件 93 | 94 | @param textfieldView 响应的包含Textfield 的view 95 | @param result 加密后的结果(有些情况下可能为空) 96 | @param type 事件类型 97 | */ 98 | - (void)textfieldView:(UIView *)textfieldView 99 | result:(NSString *)result 100 | eventType:(ZJPasswordViewEventType)type; 101 | 102 | 103 | @optional 104 | 105 | /** 106 | 点击了Textfiled 107 | 108 | @param textfieldView 包含Textfield的view 109 | */ 110 | - (void)textfieldViewDidClicked:(UIView *)textfieldView; 111 | 112 | 113 | 114 | @end 115 | 116 | 117 | NS_ASSUME_NONNULL_END 118 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWLineEncryptTextfiledView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineEncryptTextfiledView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWLineEncryptTextfiledView : ZJPSWBaseView 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWLineEncryptTextfiledView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineEncryptTextfiledView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWLineEncryptTextfiledView.h" 10 | 11 | #import "ZJPasswordDotView.h" 12 | #import "ZJMaskView.h" 13 | #import "ZJPSWBaseTextField.h" 14 | #import "ZJPasswordViewProtocol.h" 15 | 16 | @interface ZJPSWLineEncryptTextfiledView () 17 | 18 | @property (nonatomic, strong) UILabel *titleLab; 19 | @property (nonatomic, strong) ZJPasswordDotView *dotView; 20 | @property (nonatomic, strong) ZJMaskView *maskView; 21 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 22 | @property (nonatomic, strong) NSMutableArray *dotViews; 23 | 24 | @end 25 | 26 | @implementation ZJPSWLineEncryptTextfiledView 27 | 28 | @synthesize delegate = _delegate; 29 | 30 | - (void)zj_addSubviews { 31 | __weak typeof(self) weakSelf = self; 32 | 33 | self.titleLab = CreateCenterAlignmentLabel(Font(16.f), ZJColorWithHex(0x333333)); 34 | [self addSubview:self.titleLab]; 35 | [self.titleLab setText:@"请输入密码"]; 36 | 37 | _textField = [ZJPSWBaseTextField new]; 38 | _textField.textColor = [UIColor whiteColor]; 39 | _textField.tintColor = [UIColor whiteColor]; 40 | _textField.maxCount = kMaxCount; 41 | _textField.allowCopyMenu = false; 42 | _textField.keyboardType = UIKeyboardTypeNumberPad; 43 | _textField.TextFieldDidChange = ^(UITextField *textField) { 44 | [weakSelf updateInputNumWithText:textField.text]; 45 | }; 46 | 47 | _textField.showToolbarView = true; 48 | _textField.ToolBarViewEvent = ^{ 49 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 50 | }; 51 | 52 | [self addSubview:_textField]; 53 | 54 | _maskView = [[ZJMaskView alloc] init]; 55 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 56 | [self addSubview:_maskView]; 57 | } 58 | 59 | - (void)zj_addConstraints { 60 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 61 | make.centerX.mas_equalTo(0); 62 | make.top.mas_equalTo(60); 63 | }]; 64 | 65 | [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { 66 | make.left.mas_equalTo(15); 67 | make.right.mas_equalTo(-15); 68 | make.top.mas_equalTo(self.titleLab.mas_bottom).offset(60); 69 | make.height.mas_equalTo(50); 70 | }]; 71 | [self.maskView mas_makeConstraints:^(MASConstraintMaker *make) { 72 | make.left.mas_equalTo(15); 73 | make.top.equalTo(self.textField); 74 | make.right.mas_equalTo(-15); 75 | make.height.mas_equalTo(50); 76 | }]; 77 | [_textField layoutIfNeeded]; 78 | [_maskView layoutIfNeeded]; 79 | [self p_initDotViewWithFrame:_maskView.bounds]; 80 | } 81 | - (void)p_initDotViewWithFrame:(CGRect)frame { 82 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 83 | CGFloat viewW = frame.size.width / kMaxCount; 84 | CGFloat viewH = frame.size.height; 85 | for (int i = 0; i < 6; i ++) { 86 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 87 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordBottomLineEncrytion 88 | frame:frame]; 89 | [self.maskView addSubview:dotView]; 90 | [self.dotViews addObject:dotView]; 91 | } 92 | [self updateInputNumWithText:_textField.text]; 93 | } 94 | 95 | - (void)updateInputNumWithText:(NSString *)text { 96 | NSInteger length = text.length; 97 | //更新下划线状态 98 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 99 | if (length < kMaxCount) { 100 | [obj setDotBottomLineHightlight:idx == length]; 101 | } 102 | [obj setDotPointHide:!(idx < length)]; 103 | }]; 104 | if (length == kMaxCount) { 105 | [self callBackAutoDoneFunnctionWithText:text]; 106 | } 107 | else { 108 | [self callBackInpuTextLengthUpdateWithText:text]; 109 | } 110 | } 111 | 112 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 113 | [self makeTextfieldResignFirstResponder]; 114 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 115 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 116 | } 117 | } 118 | 119 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 120 | [self makeTextfieldResignFirstResponder]; 121 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 122 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 123 | } 124 | } 125 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 126 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 127 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 128 | } 129 | } 130 | 131 | - (void)makeTextfieldBecomeFirstResponder { 132 | [_textField becomeFirstResponder]; 133 | } 134 | 135 | - (void)makeTextfieldResignFirstResponder { 136 | [_textField resignFirstResponder]; 137 | } 138 | 139 | - (void)clearAllInputChars { 140 | [self.textField setText:@""]; 141 | [self updateInputNumWithText:@""]; 142 | } 143 | 144 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 145 | ZJAfter(delay, ^{ 146 | [self->_textField becomeFirstResponder]; 147 | }); 148 | } 149 | 150 | - (NSInteger)textLength { 151 | return _textField.text.length; 152 | } 153 | 154 | 155 | 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWLineNormalTextfiledView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineNormalTextfiledView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWLineNormalTextfiledView : ZJPSWBaseView 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWLineNormalTextfiledView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWLineNormalTextfiledView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWLineNormalTextfiledView.h" 10 | #import "ZJPasswordDotView.h" 11 | #import "ZJMaskView.h" 12 | #import "ZJPSWBaseTextField.h" 13 | #import "ZJPasswordViewProtocol.h" 14 | 15 | @interface ZJPSWLineNormalTextfiledView () 16 | 17 | @property (nonatomic, strong) UILabel *titleLab; 18 | @property (nonatomic, strong) ZJPasswordDotView *dotView; 19 | @property (nonatomic, strong) ZJMaskView *maskView; 20 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 21 | @property (nonatomic, strong) NSMutableArray *dotViews; 22 | 23 | @end 24 | 25 | @implementation ZJPSWLineNormalTextfiledView 26 | 27 | @synthesize delegate = _delegate; 28 | 29 | - (void)zj_addSubviews { 30 | 31 | self.titleLab = CreateCenterAlignmentLabel(Font(16.f), ZJColorWithHex(0x333333)); 32 | [self addSubview:self.titleLab]; 33 | [self.titleLab setText:@"请输入密码"]; 34 | 35 | _textField = [ZJPSWBaseTextField new]; 36 | _textField.textColor = [UIColor whiteColor]; 37 | _textField.tintColor = [UIColor whiteColor]; 38 | _textField.maxCount = kMaxCount; 39 | _textField.allowCopyMenu = false; 40 | _textField.keyboardType = UIKeyboardTypeNumberPad; 41 | 42 | __weak typeof(self) weakSelf = self; 43 | _textField.showToolbarView = true; 44 | _textField.ToolBarViewEvent = ^{ 45 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 46 | }; 47 | 48 | _textField.TextFieldDidChange = ^(UITextField *textField) { 49 | [weakSelf updateInputNumWithText:textField.text]; 50 | }; 51 | 52 | [self addSubview:_textField]; 53 | 54 | _maskView = [[ZJMaskView alloc] init]; 55 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 56 | [self addSubview:_maskView]; 57 | } 58 | 59 | - (void)zj_addConstraints { 60 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 61 | make.centerX.mas_equalTo(0); 62 | make.top.mas_equalTo(60); 63 | }]; 64 | 65 | [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { 66 | make.left.mas_equalTo(15); 67 | make.right.mas_equalTo(-15); 68 | make.top.mas_equalTo(self.titleLab.mas_bottom).offset(60); 69 | make.height.mas_equalTo(50); 70 | }]; 71 | [self.maskView mas_makeConstraints:^(MASConstraintMaker *make) { 72 | make.left.mas_equalTo(15); 73 | make.top.equalTo(self.textField); 74 | make.right.mas_equalTo(-15); 75 | make.height.mas_equalTo(50); 76 | }]; 77 | [_textField layoutIfNeeded]; 78 | [_maskView layoutIfNeeded]; 79 | [self p_initDotViewWithFrame:_maskView.bounds]; 80 | } 81 | - (void)p_initDotViewWithFrame:(CGRect)frame { 82 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 83 | CGFloat viewW = frame.size.width / kMaxCount; 84 | CGFloat viewH = frame.size.height; 85 | for (int i = 0; i < 6; i ++) { 86 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 87 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordBottomLineNormal 88 | frame:frame]; 89 | [self.maskView addSubview:dotView]; 90 | [self.dotViews addObject:dotView]; 91 | } 92 | [self updateInputNumWithText:_textField.text]; 93 | } 94 | 95 | - (void)updateInputNumWithText:(NSString *)text { 96 | NSInteger length = text.length; 97 | const char *textChar = text.UTF8String; 98 | //更新下划线状态 99 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 100 | if (length < kMaxCount) { 101 | [obj setDotBottomLineHightlight:idx == length]; 102 | } 103 | //更新输入的内容 104 | if (idx < length) { 105 | NSString *text_string = [NSString stringWithFormat:@"%c",textChar[idx]]; 106 | [obj setDotTitle:text_string]; 107 | } else { 108 | [obj setDotTitle:@""]; 109 | } 110 | }]; 111 | if (length == kMaxCount) { 112 | [self callBackAutoDoneFunnctionWithText:text]; 113 | } 114 | else { 115 | [self callBackInpuTextLengthUpdateWithText:text]; 116 | } 117 | } 118 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 119 | [self makeTextfieldResignFirstResponder]; 120 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 121 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 122 | } 123 | } 124 | 125 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 126 | [self makeTextfieldResignFirstResponder]; 127 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 128 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 129 | } 130 | } 131 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 132 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 133 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 134 | } 135 | } 136 | 137 | - (void)makeTextfieldBecomeFirstResponder { 138 | [_textField becomeFirstResponder]; 139 | } 140 | 141 | - (void)makeTextfieldResignFirstResponder { 142 | [_textField resignFirstResponder]; 143 | } 144 | 145 | - (void)clearAllInputChars { 146 | [self.textField setText:@""]; 147 | [self updateInputNumWithText:@""]; 148 | } 149 | 150 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 151 | ZJAfter(delay, ^{ 152 | [self.textField becomeFirstResponder]; 153 | }); 154 | } 155 | 156 | 157 | 158 | - (NSInteger)textLength { 159 | return _textField.text.length; 160 | } 161 | 162 | 163 | 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectAnimateTextfieldView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectAnimateTextfieldView.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWRectAnimateTextfieldView : ZJPSWBaseView 15 | 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectAnimateTextfieldView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectAnimateTextfieldView.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/7/4. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectAnimateTextfieldView.h" 10 | 11 | #import "ZJPasswordDotView.h" 12 | #import "ZJMaskView.h" 13 | #import "ZJPSWBaseTextField.h" 14 | #import "ZJPasswordViewProtocol.h" 15 | 16 | #import "ZJCircleAnimatedView.h" 17 | #import "ZJSuccessLoadingView.h" 18 | 19 | @interface ZJPSWRectAnimateTextfieldView () 20 | 21 | @property (nonatomic, strong) UILabel *titleLab; 22 | @property (nonatomic, strong) ZJPasswordDotView *dotView; 23 | @property (nonatomic, strong) ZJMaskView *maskView; 24 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 25 | @property (nonatomic, strong) NSMutableArray *dotViews; 26 | 27 | @property (nonatomic, strong) ZJCircleAnimatedView *circleAnimatedView; 28 | @property (nonatomic, strong) ZJSuccessLoadingView *successCheckView; 29 | 30 | @end 31 | 32 | @implementation ZJPSWRectAnimateTextfieldView 33 | 34 | @synthesize delegate = _delegate; 35 | 36 | - (void)zj_addSubviews { 37 | 38 | self.titleLab = CreateCenterAlignmentLabel(Font(16.f), ZJColorWithHex(0x333333)); 39 | [self addSubview:self.titleLab]; 40 | [self.titleLab setText:@"请输入密码"]; 41 | 42 | _textField = [ZJPSWBaseTextField new]; 43 | _textField.textColor = [UIColor whiteColor]; 44 | _textField.tintColor = [UIColor whiteColor]; 45 | _textField.secureTextEntry = true; 46 | _textField.maxCount = kMaxCount; 47 | _textField.allowCopyMenu = false; 48 | _textField.keyboardType = UIKeyboardTypeNumberPad; 49 | __weak typeof(self) weakSelf = self; 50 | _textField.showToolbarView = true; 51 | _textField.ToolBarViewEvent = ^{ 52 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 53 | }; 54 | 55 | _textField.TextFieldDidChange = ^(UITextField *textField) { 56 | [weakSelf updateInputNumWithText:textField.text]; 57 | }; 58 | 59 | [self addSubview:_textField]; 60 | 61 | _maskView = [[ZJMaskView alloc] init]; 62 | _maskView.layer.cornerRadius = 8.f; 63 | _maskView.layer.borderColor = ZJBorderLayerCorlor.CGColor; 64 | _maskView.layer.borderWidth = 1.f; 65 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 66 | [self addSubview:_maskView]; 67 | } 68 | 69 | - (void)zj_addConstraints { 70 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 71 | make.centerX.mas_equalTo(0); 72 | make.top.mas_equalTo(60); 73 | }]; 74 | 75 | [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { 76 | make.left.mas_equalTo(15); 77 | make.right.mas_equalTo(-15); 78 | make.top.mas_equalTo(self.titleLab.mas_bottom).offset(60); 79 | make.height.mas_equalTo(50); 80 | }]; 81 | [self.maskView mas_makeConstraints:^(MASConstraintMaker *make) { 82 | make.left.mas_equalTo(15); 83 | make.top.equalTo(self.textField); 84 | make.right.mas_equalTo(-15); 85 | make.height.mas_equalTo(50); 86 | }]; 87 | [_textField layoutIfNeeded]; 88 | [_maskView layoutIfNeeded]; 89 | [self p_initDotViewWithFrame:_maskView.bounds]; 90 | } 91 | - (void)p_initDotViewWithFrame:(CGRect)frame { 92 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 93 | CGFloat viewW = frame.size.width / kMaxCount; 94 | CGFloat viewH = frame.size.height; 95 | for (int i = 0; i < kMaxCount; i ++) { 96 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 97 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordRectangleEncryption 98 | frame:frame]; 99 | [dotView.verticalLineView setHidden:i == kMaxCount - 1]; 100 | [self.maskView addSubview:dotView]; 101 | [self.dotViews addObject:dotView]; 102 | } 103 | [self updateInputNumWithText:_textField.text]; 104 | 105 | [self addAnimatedView]; 106 | } 107 | 108 | - (void)addAnimatedView { 109 | [self layoutIfNeeded]; 110 | 111 | __weak typeof(self) weakSelf = self; 112 | 113 | self.circleAnimatedView = [[ZJCircleAnimatedView alloc] initWithFrame:self.bounds]; 114 | [self.circleAnimatedView setHidden:true]; 115 | 116 | self.successCheckView = [[ZJSuccessLoadingView alloc] initWithFrame:self.bounds]; 117 | //动画完成了 118 | self.successCheckView.ZJSuccessLoadEnd = ^{ 119 | if (weakSelf.delegate && [weakSelf.delegate 120 | respondsToSelector:@selector(textfieldView:result:eventType:)]) { 121 | [weakSelf.delegate textfieldView:weakSelf 122 | result:@"" 123 | eventType:ZJPasswordViewAnimateViewFinish]; 124 | } 125 | [weakSelf.circleAnimatedView setHidden:true]; 126 | [weakSelf.successCheckView setHidden:true]; 127 | }; 128 | [self.successCheckView setHidden:true]; 129 | 130 | [self addSubview:self.circleAnimatedView]; 131 | [self addSubview:self.successCheckView]; 132 | } 133 | 134 | 135 | - (void)updateInputNumWithText:(NSString *)text { 136 | NSInteger length = text.length; 137 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 138 | if (length < kMaxCount) { 139 | [obj setDotBottomLineHightlight:idx == length]; 140 | } 141 | [obj setDotPointHide:!(idx < length)]; 142 | }]; 143 | if (length == kMaxCount) { 144 | [self callBackAutoDoneFunnctionWithText:text]; 145 | } 146 | else { 147 | [self callBackInpuTextLengthUpdateWithText:text]; 148 | } 149 | } 150 | 151 | 152 | - (void)showCircleAnimating { 153 | [self.circleAnimatedView setHidden:false]; 154 | [self.circleAnimatedView beginAnimating]; 155 | } 156 | 157 | - (void)stopCircleAnimating { 158 | [self.circleAnimatedView endAnimating]; 159 | [self.circleAnimatedView setHidden:true]; 160 | } 161 | 162 | - (void)showCheckAnimation { 163 | [self.successCheckView setHidden:false]; 164 | [self.successCheckView beginAnimating]; 165 | } 166 | 167 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 168 | [self makeTextfieldResignFirstResponder]; 169 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 170 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 171 | } 172 | } 173 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 174 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 175 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 176 | } 177 | } 178 | 179 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 180 | [self makeTextfieldResignFirstResponder]; 181 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 182 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 183 | } 184 | } 185 | 186 | - (void)makeTextfieldBecomeFirstResponder { 187 | [_textField becomeFirstResponder]; 188 | } 189 | 190 | - (void)makeTextfieldResignFirstResponder { 191 | [_textField resignFirstResponder]; 192 | } 193 | 194 | - (void)clearAllInputChars { 195 | [self.textField setText:@""]; 196 | [self updateInputNumWithText:@""]; 197 | } 198 | 199 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 200 | ZJAfter(delay, ^{ 201 | [_textField becomeFirstResponder]; 202 | }); 203 | } 204 | - (NSInteger)textLength { 205 | return _textField.text.length; 206 | } 207 | 208 | @end 209 | 210 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectEncryptTextfiledView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectEncryptTextfiledView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWRectEncryptTextfiledView : ZJPSWBaseView 15 | 16 | @end 17 | 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectEncryptTextfiledView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectEncryptTextfiledView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectEncryptTextfiledView.h" 10 | #import "ZJPasswordDotView.h" 11 | #import "ZJMaskView.h" 12 | #import "ZJPSWBaseTextField.h" 13 | #import "ZJPasswordViewProtocol.h" 14 | 15 | @interface ZJPSWRectEncryptTextfiledView () 16 | 17 | @property (nonatomic, strong) UILabel *titleLab; 18 | @property (nonatomic, strong) ZJPasswordDotView *dotView; 19 | @property (nonatomic, strong) ZJMaskView *maskView; 20 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 21 | @property (nonatomic, strong) NSMutableArray *dotViews; 22 | 23 | @end 24 | 25 | @implementation ZJPSWRectEncryptTextfiledView 26 | 27 | @synthesize delegate = _delegate; 28 | 29 | - (void)zj_addSubviews { 30 | 31 | self.titleLab = CreateCenterAlignmentLabel(Font(16.f), ZJColorWithHex(0x333333)); 32 | [self addSubview:self.titleLab]; 33 | [self.titleLab setText:@"请输入密码"]; 34 | 35 | 36 | _textField = [ZJPSWBaseTextField new]; 37 | _textField.textColor = [UIColor whiteColor]; 38 | _textField.tintColor = [UIColor whiteColor]; 39 | _textField.secureTextEntry = true; 40 | _textField.maxCount = kMaxCount; 41 | _textField.allowCopyMenu = false; 42 | _textField.keyboardType = UIKeyboardTypeNumberPad; 43 | __weak typeof(self) weakSelf = self; 44 | _textField.showToolbarView = true; 45 | _textField.ToolBarViewEvent = ^{ 46 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 47 | }; 48 | 49 | _textField.TextFieldDidChange = ^(UITextField *textField) { 50 | [weakSelf updateInputNumWithText:textField.text]; 51 | }; 52 | 53 | [self addSubview:_textField]; 54 | 55 | 56 | 57 | _maskView = [[ZJMaskView alloc] init]; 58 | _maskView.layer.cornerRadius = 8.f; 59 | _maskView.layer.borderColor = ZJBorderLayerCorlor.CGColor; 60 | _maskView.layer.borderWidth = 1.f; 61 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 62 | [self addSubview:_maskView]; 63 | } 64 | 65 | - (void)zj_addConstraints { 66 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 67 | make.centerX.mas_equalTo(0); 68 | make.top.mas_equalTo(60); 69 | }]; 70 | 71 | [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { 72 | make.left.mas_equalTo(15); 73 | make.right.mas_equalTo(-15); 74 | make.top.mas_equalTo(self.titleLab.mas_bottom).offset(60); 75 | make.height.mas_equalTo(50); 76 | }]; 77 | [self.maskView mas_makeConstraints:^(MASConstraintMaker *make) { 78 | make.left.mas_equalTo(15); 79 | make.top.equalTo(self.textField); 80 | make.right.mas_equalTo(-15); 81 | make.height.mas_equalTo(50); 82 | }]; 83 | [_textField layoutIfNeeded]; 84 | [_maskView layoutIfNeeded]; 85 | [self p_initDotViewWithFrame:_maskView.bounds]; 86 | } 87 | - (void)p_initDotViewWithFrame:(CGRect)frame { 88 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 89 | CGFloat viewW = frame.size.width / kMaxCount; 90 | CGFloat viewH = frame.size.height; 91 | for (int i = 0; i < kMaxCount; i ++) { 92 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 93 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordRectangleEncryption 94 | frame:frame]; 95 | [dotView.verticalLineView setHidden:i == kMaxCount - 1]; 96 | [self.maskView addSubview:dotView]; 97 | [self.dotViews addObject:dotView]; 98 | } 99 | [self updateInputNumWithText:_textField.text]; 100 | } 101 | 102 | 103 | 104 | - (void)updateInputNumWithText:(NSString *)text { 105 | NSInteger length = text.length; 106 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 107 | if (length < kMaxCount) { 108 | [obj setDotBottomLineHightlight:idx == length]; 109 | } 110 | [obj setDotPointHide:!(idx < length)]; 111 | }]; 112 | if (length == kMaxCount) { 113 | [self callBackAutoDoneFunnctionWithText:text]; 114 | } 115 | else { 116 | [self callBackInpuTextLengthUpdateWithText:text]; 117 | } 118 | } 119 | 120 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 121 | [self makeTextfieldResignFirstResponder]; 122 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 123 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 124 | } 125 | } 126 | 127 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 128 | [self makeTextfieldResignFirstResponder]; 129 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 130 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 131 | } 132 | } 133 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 134 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 135 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 136 | } 137 | } 138 | 139 | - (void)makeTextfieldBecomeFirstResponder { 140 | [_textField becomeFirstResponder]; 141 | } 142 | 143 | - (void)makeTextfieldResignFirstResponder { 144 | [_textField resignFirstResponder]; 145 | } 146 | 147 | - (void)clearAllInputChars { 148 | [self.textField setText:@""]; 149 | [self updateInputNumWithText:@""]; 150 | } 151 | 152 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 153 | ZJAfter(delay, ^{ 154 | [self->_textField becomeFirstResponder]; 155 | }); 156 | } 157 | 158 | - (NSInteger)textLength { 159 | return _textField.text.length; 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectNormalTextfieldView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectNormalTextfieldView.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWBaseView.h" 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface ZJPSWRectNormalTextfieldView : ZJPSWBaseView 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWRectNormalTextfieldView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWRectNormalTextfieldView.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWRectNormalTextfieldView.h" 10 | 11 | #import "ZJPasswordDotView.h" 12 | #import "ZJMaskView.h" 13 | #import "ZJPSWBaseTextField.h" 14 | #import "ZJPasswordViewProtocol.h" 15 | 16 | @interface ZJPSWRectNormalTextfieldView () 17 | 18 | @property (nonatomic, strong) UILabel *titleLab; 19 | @property (nonatomic, strong) ZJPasswordDotView *dotView; 20 | @property (nonatomic, strong) ZJMaskView *maskView; 21 | @property (nonatomic, strong) ZJPSWBaseTextField *textField; 22 | @property (nonatomic, strong) NSMutableArray *dotViews; 23 | 24 | @end 25 | 26 | @implementation ZJPSWRectNormalTextfieldView 27 | 28 | @synthesize delegate = _delegate; 29 | 30 | - (void)zj_addSubviews { 31 | 32 | self.titleLab = CreateCenterAlignmentLabel(Font(16.f), ZJColorWithHex(0x333333)); 33 | [self addSubview:self.titleLab]; 34 | [self.titleLab setText:@"请输入密码"]; 35 | 36 | _textField = [ZJPSWBaseTextField new]; 37 | _textField.textColor = [UIColor whiteColor]; 38 | _textField.tintColor = [UIColor whiteColor]; 39 | _textField.secureTextEntry = true; 40 | _textField.maxCount = kMaxCount; 41 | _textField.allowCopyMenu = false; 42 | _textField.keyboardType = UIKeyboardTypeNumberPad; 43 | __weak typeof(self) weakSelf = self; 44 | _textField.showToolbarView = true; 45 | _textField.ToolBarViewEvent = ^{ 46 | [weakSelf callOkButtonFunnctionWithText:weakSelf.textField.text]; 47 | }; 48 | 49 | _textField.TextFieldDidChange = ^(UITextField *textField) { 50 | [weakSelf updateInputNumWithText:textField.text]; 51 | }; 52 | 53 | [self addSubview:_textField]; 54 | 55 | _maskView = [[ZJMaskView alloc] init]; 56 | _maskView.layer.cornerRadius = 8.f; 57 | _maskView.layer.borderColor = ZJBorderLayerCorlor.CGColor; 58 | _maskView.layer.borderWidth = 1.f; 59 | [_maskView setBackgroundColor:[UIColor whiteColor]]; 60 | [self addSubview:_maskView]; 61 | } 62 | 63 | - (void)zj_addConstraints { 64 | [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { 65 | make.centerX.mas_equalTo(0); 66 | make.top.mas_equalTo(60); 67 | }]; 68 | 69 | [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { 70 | make.left.mas_equalTo(15); 71 | make.right.mas_equalTo(-15); 72 | make.top.mas_equalTo(self.titleLab.mas_bottom).offset(60); 73 | make.height.mas_equalTo(50); 74 | }]; 75 | [self.maskView mas_makeConstraints:^(MASConstraintMaker *make) { 76 | make.left.mas_equalTo(15); 77 | make.top.equalTo(self.textField); 78 | make.right.mas_equalTo(-15); 79 | make.height.mas_equalTo(50); 80 | }]; 81 | [_textField layoutIfNeeded]; 82 | [_maskView layoutIfNeeded]; 83 | [self p_initDotViewWithFrame:_maskView.bounds]; 84 | } 85 | - (void)p_initDotViewWithFrame:(CGRect)frame { 86 | self.dotViews = [[NSMutableArray alloc] initWithCapacity:6]; 87 | CGFloat viewW = frame.size.width / kMaxCount; 88 | CGFloat viewH = frame.size.height; 89 | for (int i = 0; i < kMaxCount; i ++) { 90 | CGRect frame = CGRectMake(viewW * i , 0, viewW , viewH ); 91 | ZJPasswordDotView *dotView = [ZJPasswordDotView createDotViewWithType:ZJPasswordRectangleNormal 92 | frame:frame]; 93 | [dotView.verticalLineView setHidden:i == kMaxCount - 1]; 94 | [self.maskView addSubview:dotView]; 95 | [self.dotViews addObject:dotView]; 96 | } 97 | [self updateInputNumWithText:_textField.text]; 98 | } 99 | 100 | - (void)updateInputNumWithText:(NSString *)text { 101 | NSInteger length = text.length; 102 | const char *textChar = text.UTF8String; 103 | //更新输入框内容 104 | [self.dotViews enumerateObjectsUsingBlock:^(ZJPasswordDotView * obj, NSUInteger idx, BOOL * stop) { 105 | //更新输入的内容 106 | if (idx < length) { 107 | NSString *text_string = [NSString stringWithFormat:@"%c",textChar[idx]]; 108 | [obj setDotTitle:text_string]; 109 | } else { 110 | [obj setDotTitle:@""]; 111 | } 112 | }]; 113 | 114 | if (length == kMaxCount) { 115 | [self callBackAutoDoneFunnctionWithText:text]; 116 | } 117 | else { 118 | [self callBackInpuTextLengthUpdateWithText:text]; 119 | } 120 | } 121 | 122 | - (void)callBackAutoDoneFunnctionWithText:(NSString *)text { 123 | [self makeTextfieldResignFirstResponder]; 124 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 125 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventAutoDone]; 126 | } 127 | } 128 | - (void)callBackInpuTextLengthUpdateWithText:(NSString *)text { 129 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 130 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventLengthUpdate]; 131 | } 132 | } 133 | 134 | - (void)callOkButtonFunnctionWithText:(NSString *)text { 135 | [self makeTextfieldResignFirstResponder]; 136 | if (_delegate && [_delegate respondsToSelector:@selector(textfieldView:result:eventType:)]) { 137 | [_delegate textfieldView:self result:text eventType:ZJPasswordViewEventOKButton]; 138 | } 139 | } 140 | 141 | - (void)makeTextfieldBecomeFirstResponder { 142 | [_textField becomeFirstResponder]; 143 | } 144 | 145 | - (void)makeTextfieldResignFirstResponder { 146 | [_textField resignFirstResponder]; 147 | } 148 | 149 | - (void)clearAllInputChars { 150 | [self.textField setText:@""]; 151 | [self updateInputNumWithText:@""]; 152 | } 153 | 154 | - (void)autoShowKeyboardDelay:(NSTimeInterval)delay { 155 | ZJAfter(delay, ^{ 156 | [_textField becomeFirstResponder]; 157 | }); 158 | } 159 | - (NSInteger)textLength { 160 | return _textField.text.length; 161 | } 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWTextfieldContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWTextfieldContext.h 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ZJPasswordViewProtocol.h" 11 | 12 | typedef NS_ENUM(NSInteger,ZJPSWTextfieldViewType) { 13 | ZJPSWTextfieldViewLineNormal = 0, 14 | ZJPSWTextfieldViewLineEncryption = 1, 15 | ZJPSWTextfieldViewRectNormal = 2, 16 | ZJPSWTextfieldViewRectEncryption = 3, 17 | ZJPSWTextfieldViewWithAnimating = 4, 18 | }; 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | @interface ZJPSWTextfieldContext : NSObject 23 | 24 | + (UIView *)configureTextfieldView:(ZJPSWTextfieldViewType)viewType 25 | frame:(CGRect)frame; 26 | 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordFile/TextfiledView/ZJTextfieldView/ZJPSWTextfieldContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZJPSWTextfieldContext.m 3 | // ImitateBaiduCourse 4 | // 5 | // Created by 张君君 on 2019/6/21. 6 | // Copyright © 2019年 ZhangJunJun. All rights reserved. 7 | // 8 | 9 | #import "ZJPSWTextfieldContext.h" 10 | #import "ZJPSWLineNormalTextfiledView.h" 11 | #import "ZJPSWLineEncryptTextfiledView.h" 12 | #import "ZJPSWRectEncryptTextfiledView.h" 13 | #import "ZJPSWRectNormalTextfieldView.h" 14 | #import "ZJPSWRectAnimateTextfieldView.h" 15 | 16 | 17 | @interface ZJPSWTextfieldContext () 18 | 19 | @property (nonatomic, strong) UIView * textfiledView; 20 | 21 | 22 | @end 23 | 24 | @implementation ZJPSWTextfieldContext 25 | 26 | 27 | + (UIView *)configureTextfieldView:(ZJPSWTextfieldViewType)viewType 28 | frame:(CGRect)frame { 29 | return [[self alloc] configureWithType:viewType frame:frame]; 30 | } 31 | 32 | - (UIView *)configureWithType:(ZJPSWTextfieldViewType)type 33 | frame:(CGRect)frame { 34 | switch (type) { 35 | case ZJPSWTextfieldViewLineNormal: { 36 | self.textfiledView = [[ZJPSWLineNormalTextfiledView alloc] initWithFrame:frame]; 37 | } 38 | break; 39 | case ZJPSWTextfieldViewLineEncryption: { 40 | self.textfiledView = [[ZJPSWLineEncryptTextfiledView alloc] initWithFrame:frame]; 41 | } 42 | break; 43 | case ZJPSWTextfieldViewRectNormal: { 44 | self.textfiledView = [[ZJPSWRectNormalTextfieldView alloc]initWithFrame:frame]; 45 | } 46 | break; 47 | case ZJPSWTextfieldViewRectEncryption: { 48 | self.textfiledView = [[ZJPSWRectEncryptTextfiledView alloc] initWithFrame:frame]; 49 | } 50 | break; 51 | case ZJPSWTextfieldViewWithAnimating: { 52 | self.textfiledView = [[ZJPSWRectAnimateTextfieldView alloc] initWithFrame:frame]; 53 | } 54 | break; 55 | 56 | default: 57 | break; 58 | } 59 | [self.textfiledView autoShowKeyboardDelay:0.5f]; 60 | return self.textfiledView; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/xcuserdata/ZhangJunjun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/xcuserdata/ZhangJunjun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/project.xcworkspace/xcuserdata/ZhangJunjun.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | EnabledFullIndexStoreVisibility 12 | 13 | IssueFilterStyle 14 | ShowActiveSchemeOnly 15 | LiveSourceIssuesEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/xcuserdata/ZhangJunjun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView.xcodeproj/xcuserdata/ZhangJunjun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ZJPasswordStyleView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | ZJPasswordStyleView.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (readonly, strong) NSPersistentContainer *persistentContainer; 17 | 18 | - (void)saveContext; 19 | 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | 21 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 22 | [self.window setBackgroundColor:[UIColor whiteColor]]; 23 | 24 | UINavigationController *navRoot = [[UINavigationController alloc] initWithRootViewController:[ViewController new]]; 25 | [self.window setRootViewController:navRoot]; 26 | 27 | [self.window makeKeyAndVisible]; 28 | 29 | return YES; 30 | } 31 | 32 | 33 | - (void)applicationWillResignActive:(UIApplication *)application { 34 | // 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. 35 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 36 | } 37 | 38 | 39 | - (void)applicationDidEnterBackground:(UIApplication *)application { 40 | // 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. 41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | } 43 | 44 | 45 | - (void)applicationWillEnterForeground:(UIApplication *)application { 46 | // 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. 47 | } 48 | 49 | 50 | - (void)applicationDidBecomeActive:(UIApplication *)application { 51 | // 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. 52 | } 53 | 54 | 55 | - (void)applicationWillTerminate:(UIApplication *)application { 56 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 57 | // Saves changes in the application's managed object context before the application terminates. 58 | [self saveContext]; 59 | } 60 | 61 | 62 | #pragma mark - Core Data stack 63 | 64 | @synthesize persistentContainer = _persistentContainer; 65 | 66 | - (NSPersistentContainer *)persistentContainer { 67 | // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. 68 | @synchronized (self) { 69 | if (_persistentContainer == nil) { 70 | _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"ZJPasswordStyleView"]; 71 | [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { 72 | if (error != nil) { 73 | // Replace this implementation with code to handle the error appropriately. 74 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 75 | 76 | /* 77 | Typical reasons for an error here include: 78 | * The parent directory does not exist, cannot be created, or disallows writing. 79 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 80 | * The device is out of space. 81 | * The store could not be migrated to the current model version. 82 | Check the error message to determine what the actual problem was. 83 | */ 84 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 85 | abort(); 86 | } 87 | }]; 88 | } 89 | } 90 | 91 | return _persistentContainer; 92 | } 93 | 94 | #pragma mark - Core Data Saving support 95 | 96 | - (void)saveContext { 97 | NSManagedObjectContext *context = self.persistentContainer.viewContext; 98 | NSError *error = nil; 99 | if ([context hasChanges] && ![context save:&error]) { 100 | // Replace this implementation with code to handle the error appropriately. 101 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 102 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 103 | abort(); 104 | } 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Assets.xcassets/wx_Back_icon_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "wx_Back_icon_normal@3x.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Assets.xcassets/wx_Back_icon_normal.imageset/wx_Back_icon_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/ZJPasswordStyleView/ZJPasswordStyleView/Assets.xcassets/wx_Back_icon_normal.imageset/wx_Back_icon_normal@3x.png -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ZJPasswordStyleViewController.h" 11 | #import "ZJUIHeader.h" 12 | #import "Masonry.h" 13 | #import "ZJModel.h" 14 | 15 | @interface ViewController () 16 | 17 | @property (nonatomic, strong) UITableView *tableView; 18 | 19 | @property (nonatomic, strong) ZJViewModel *dataModel; 20 | 21 | @end 22 | 23 | @implementation ViewController 24 | 25 | static NSString * const kCellID = @"UITableViewCellID"; 26 | 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | self.title = @"支付密码框样式列表"; 31 | [self initUI]; 32 | } 33 | 34 | - (void)initUI { 35 | self.dataModel = [ZJViewModel new]; 36 | [self.view addSubview:self.tableView]; 37 | [self.tableView reloadData]; 38 | } 39 | 40 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 41 | return [self.dataModel numberOfSections]; 42 | } 43 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 44 | return [self.dataModel numberOfRowInSection:section]; 45 | } 46 | 47 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 48 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID forIndexPath:indexPath]; 49 | [cell.textLabel setText:[self.dataModel rowModelOfIndexPath:indexPath].name]; 50 | return cell; 51 | } 52 | 53 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 54 | ZJPasswordStyleViewController *passwordStyleVC = [ZJPasswordStyleViewController new]; 55 | passwordStyleVC.dataModel = [self.dataModel rowModelOfIndexPath:indexPath]; 56 | [self.navigationController pushViewController:passwordStyleVC animated:true]; 57 | } 58 | 59 | 60 | - (UITableView *)tableView{ 61 | if(!_tableView){ 62 | _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 100, ZJWinodwWidth, ZJWinodwHeight - 100) style:UITableViewStyleGrouped]; 63 | _tableView.delegate = self; 64 | _tableView.dataSource = self; 65 | _tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; 66 | 67 | _tableView.estimatedRowHeight = 44; 68 | _tableView.rowHeight = 44; 69 | _tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, ZJWinodwWidth, 0.01)]; 70 | [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kCellID]; 71 | if (@available(iOS 11.0,*)) { 72 | _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; 73 | } else { 74 | self.automaticallyAdjustsScrollViewInsets = false; 75 | } 76 | } 77 | return _tableView; 78 | } 79 | 80 | 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /ZJPasswordStyleView/ZJPasswordStyleView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZJPasswordStyleView 4 | // 5 | // Created by 张君君 on 2019/6/24. 6 | // Copyright © 2019年 com.zhangjunjun.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /样式截图/PasswordAnimated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/PasswordAnimated.gif -------------------------------------------------------------------------------- /样式截图/下划线高亮密文.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/下划线高亮密文.png -------------------------------------------------------------------------------- /样式截图/下划线高亮明文.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/下划线高亮明文.png -------------------------------------------------------------------------------- /样式截图/矩形框密文.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/矩形框密文.png -------------------------------------------------------------------------------- /样式截图/矩形框密文密码长度达到6位.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/矩形框密文密码长度达到6位.png -------------------------------------------------------------------------------- /样式截图/矩形框明文6位密码.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/矩形框明文6位密码.png -------------------------------------------------------------------------------- /样式截图/矩形框明文输入密码.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreshManCode/ZJPasswordStyle/974f2667436550b8a96b67a6e6f72119f8407cb7/样式截图/矩形框明文输入密码.png --------------------------------------------------------------------------------