Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
637703bd5e | |
![]() |
ad85f71bd2 | |
![]() |
0e89b0c162 | |
![]() |
344eab8512 | |
![]() |
35523f5ec7 | |
![]() |
8981182b38 | |
![]() |
7e5864260b | |
![]() |
c47631f3e7 |
|
@ -1,3 +1,5 @@
|
|||
DSFFloatLabelledTextControls.xcodeproj/xcuserdata
|
||||
xcschememanagement.plist
|
||||
.swiftpm
|
||||
Demos/DSFFloatLabelledTextControls.xcodeproj/xcuserdata
|
||||
gyb.cpython-310.pyc
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "DSFFloatLabelledTextControl"
|
||||
s.version = "1.7.0"
|
||||
s.summary = "A macOS Cocoa single-line NSTextField that implements the Float Label Pattern"
|
||||
s.version = "2.0.0"
|
||||
s.summary = "A macOS Cocoa single-line NSTextField/NSSecureTextField that implements the Float Label Pattern"
|
||||
s.description = <<-DESC
|
||||
A macOS Cocoa single-line NSTextField that implements the Float Label Pattern.
|
||||
A macOS Cocoa single-line NSTextField/NSSecureTextField that implements the Float Label Pattern.
|
||||
DESC
|
||||
s.homepage = "https://github.com/dagronf/DSFFloatLabelledTextControl"
|
||||
s.license = { :type => "MIT", :file => "LICENSE" }
|
||||
|
@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
|||
s.social_media_url = ""
|
||||
s.osx.deployment_target = "10.11"
|
||||
s.source = { :git => ".git", :tag => s.version.to_s }
|
||||
s.source_files = "DSFFloatLabelledTextControl/DSFFloatLabelledTextField.swift"
|
||||
s.source_files = "Sources/DSFFloatLabelledTextField/**/*.{swift}"
|
||||
s.frameworks = "Cocoa"
|
||||
s.swift_version = "5.0"
|
||||
s.swift_version = "5.4"
|
||||
end
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>DSFFloatLabelledTextControl.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>DSFFloatLabelledTextControls Demo objc.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>DSFFloatLabelledTextControls RTL.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>DSFFloatLabelledTextControls.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>DSFFloatLabelledTextField.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>2351F84A2207D15C00EFA4F7</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>23A2B7E8220792FE00B2FC77</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>23C3AB9923FBCFA30079D9C3</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -3,41 +3,50 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objectVersion = 52;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
23E825612575D1760023A3C7 /* All */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = 23E825642575D1760023A3C7 /* Build configuration list for PBXAggregateTarget "All" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
23E825682575D17E0023A3C7 /* PBXTargetDependency */,
|
||||
23E8256A2575D17E0023A3C7 /* PBXTargetDependency */,
|
||||
);
|
||||
name = All;
|
||||
productName = All;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2351F84F2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 2351F84D2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
2351F8522207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */; };
|
||||
2351F8532207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
2351F8582207D16100EFA4F7 /* DSFFloatLabelledTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A2B7FA2207931500B2FC77 /* DSFFloatLabelledTextField.swift */; };
|
||||
2351F85B22082AD800EFA4F7 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 2351F85922082AD800EFA4F7 /* LICENSE */; };
|
||||
2351F85C22082AD800EFA4F7 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 2351F85A22082AD800EFA4F7 /* README.md */; };
|
||||
23A2B7ED220792FE00B2FC77 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A2B7EC220792FE00B2FC77 /* AppDelegate.swift */; };
|
||||
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23A2B7EE220792FF00B2FC77 /* Assets.xcassets */; };
|
||||
23A2B7F2220792FF00B2FC77 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 23A2B7F0220792FF00B2FC77 /* MainMenu.xib */; };
|
||||
23A3061C29C12CB200BEC98A /* DSFFloatLabelledTextField in Frameworks */ = {isa = PBXBuildFile; productRef = 23A3061B29C12CB200BEC98A /* DSFFloatLabelledTextField */; };
|
||||
23A3061E29C12CB800BEC98A /* DSFFloatLabelledTextField in Frameworks */ = {isa = PBXBuildFile; productRef = 23A3061D29C12CB800BEC98A /* DSFFloatLabelledTextField */; };
|
||||
23C3AB9E23FBCFA30079D9C3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 23C3AB9D23FBCFA30079D9C3 /* AppDelegate.m */; };
|
||||
23C3ABA023FBCFA40079D9C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23C3AB9F23FBCFA40079D9C3 /* Assets.xcassets */; };
|
||||
23C3ABA323FBCFA40079D9C3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 23C3ABA123FBCFA40079D9C3 /* MainMenu.xib */; };
|
||||
23C3ABA623FBCFA40079D9C3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 23C3ABA523FBCFA40079D9C3 /* main.m */; };
|
||||
23C3ABAC23FBCFDE0079D9C3 /* DSFFloatLabelledTextField.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */; };
|
||||
23C3ABB023FBD0F80079D9C3 /* DSFFloatLabelledTextField.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
2351F8502207D15C00EFA4F7 /* PBXContainerItemProxy */ = {
|
||||
23E825672575D17E0023A3C7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2351F84A2207D15C00EFA4F7;
|
||||
remoteInfo = DSFFloatLabelledTextControl;
|
||||
remoteGlobalIDString = 23A2B7E8220792FE00B2FC77;
|
||||
remoteInfo = DSFFloatLabelledTextControls;
|
||||
};
|
||||
23C3ABAD23FBCFE40079D9C3 /* PBXContainerItemProxy */ = {
|
||||
23E825692575D17E0023A3C7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2351F84A2207D15C00EFA4F7;
|
||||
remoteInfo = DSFFloatLabelledTextField;
|
||||
remoteGlobalIDString = 23C3AB9923FBCFA30079D9C3;
|
||||
remoteInfo = "DSFFloatLabelledTextControls Demo objc";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
|
@ -48,7 +57,6 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
2351F8532207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -59,26 +67,19 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
23C3ABB023FBD0F80079D9C3 /* DSFFloatLabelledTextField.framework in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DSFFloatLabelledTextField.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2351F84D2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSFFloatLabelledTextControl.h; sourceTree = "<group>"; };
|
||||
2351F84E2207D15C00EFA4F7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
2351F85922082AD800EFA4F7 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||
2351F85A22082AD800EFA4F7 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DSFFloatLabelledTextControls.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
23A2B7EC220792FE00B2FC77 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
23A2B7EE220792FF00B2FC77 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
23A2B7F1220792FF00B2FC77 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
23A2B7F3220792FF00B2FC77 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
23A2B7F4220792FF00B2FC77 /* DSFFloatLabelledTextControls.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DSFFloatLabelledTextControls.entitlements; sourceTree = "<group>"; };
|
||||
23A2B7FA2207931500B2FC77 /* DSFFloatLabelledTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSFFloatLabelledTextField.swift; sourceTree = "<group>"; };
|
||||
23ACF96D228A3F6600FF6594 /* DSFFloatLabelledTextControl.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = DSFFloatLabelledTextControl.podspec; sourceTree = "<group>"; };
|
||||
23A3061A29C12C9C00BEC98A /* DSFFloatLabelledTextControls */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DSFFloatLabelledTextControls; path = ..; sourceTree = "<group>"; };
|
||||
23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DSFFloatLabelledTextControls Demo objc.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
23C3AB9C23FBCFA30079D9C3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
23C3AB9D23FBCFA30079D9C3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
|
@ -87,22 +88,15 @@
|
|||
23C3ABA423FBCFA40079D9C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
23C3ABA523FBCFA40079D9C3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
23C3ABA723FBCFA40079D9C3 /* DSFFloatLabelledTextControls_Demo_objc.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DSFFloatLabelledTextControls_Demo_objc.entitlements; sourceTree = "<group>"; };
|
||||
23FFF1CD23BD490F008FA55A /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||
23E8256D2575D28A0023A3C7 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
2351F8482207D15C00EFA4F7 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
23A2B7E6220792FE00B2FC77 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2351F8522207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Frameworks */,
|
||||
23A3061C29C12CB200BEC98A /* DSFFloatLabelledTextField in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -110,32 +104,18 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
23C3ABAC23FBCFDE0079D9C3 /* DSFFloatLabelledTextField.framework in Frameworks */,
|
||||
23A3061E29C12CB800BEC98A /* DSFFloatLabelledTextField in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2351F84C2207D15C00EFA4F7 /* DSFFloatLabelledTextField */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
23A2B7FA2207931500B2FC77 /* DSFFloatLabelledTextField.swift */,
|
||||
2351F84D2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h */,
|
||||
2351F84E2207D15C00EFA4F7 /* Info.plist */,
|
||||
);
|
||||
path = DSFFloatLabelledTextField;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
23A2B7E0220792FE00B2FC77 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
23A3061A29C12C9C00BEC98A /* DSFFloatLabelledTextControls */,
|
||||
23FFF1CF23BD4982008FA55A /* Demos */,
|
||||
23FFF1CE23BD496A008FA55A /* Sources */,
|
||||
23ACF96D228A3F6600FF6594 /* DSFFloatLabelledTextControl.podspec */,
|
||||
2351F85922082AD800EFA4F7 /* LICENSE */,
|
||||
2351F85A22082AD800EFA4F7 /* README.md */,
|
||||
23FFF1CD23BD490F008FA55A /* Package.swift */,
|
||||
23A2B7EA220792FE00B2FC77 /* Products */,
|
||||
23C3ABAB23FBCFDE0079D9C3 /* Frameworks */,
|
||||
);
|
||||
|
@ -145,7 +125,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */,
|
||||
2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */,
|
||||
23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */,
|
||||
);
|
||||
name = Products;
|
||||
|
@ -184,14 +163,6 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
23FFF1CE23BD496A008FA55A /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2351F84C2207D15C00EFA4F7 /* DSFFloatLabelledTextField */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
23FFF1CF23BD4982008FA55A /* Demos */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -203,36 +174,7 @@
|
|||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
2351F8462207D15C00EFA4F7 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2351F84F2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2351F8542207D15C00EFA4F7 /* Build configuration list for PBXNativeTarget "DSFFloatLabelledTextField" */;
|
||||
buildPhases = (
|
||||
2351F8462207D15C00EFA4F7 /* Headers */,
|
||||
2351F8472207D15C00EFA4F7 /* Sources */,
|
||||
2351F8482207D15C00EFA4F7 /* Frameworks */,
|
||||
2351F8492207D15C00EFA4F7 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = DSFFloatLabelledTextField;
|
||||
productName = DSFFloatLabelledTextControl;
|
||||
productReference = 2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 23A2B7F7220792FF00B2FC77 /* Build configuration list for PBXNativeTarget "DSFFloatLabelledTextControls" */;
|
||||
|
@ -245,9 +187,11 @@
|
|||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
2351F8512207D15C00EFA4F7 /* PBXTargetDependency */,
|
||||
);
|
||||
name = DSFFloatLabelledTextControls;
|
||||
packageProductDependencies = (
|
||||
23A3061B29C12CB200BEC98A /* DSFFloatLabelledTextField */,
|
||||
);
|
||||
productName = DSFFloatLabelledTextControls;
|
||||
productReference = 23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
|
@ -264,9 +208,11 @@
|
|||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
23C3ABAE23FBCFE40079D9C3 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "DSFFloatLabelledTextControls Demo objc";
|
||||
packageProductDependencies = (
|
||||
23A3061D29C12CB800BEC98A /* DSFFloatLabelledTextField */,
|
||||
);
|
||||
productName = "DSFFloatLabelledTextControls Demo objc";
|
||||
productReference = 23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
|
@ -281,15 +227,15 @@
|
|||
LastUpgradeCheck = 1010;
|
||||
ORGANIZATIONNAME = "Darren Ford";
|
||||
TargetAttributes = {
|
||||
2351F84A2207D15C00EFA4F7 = {
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
};
|
||||
23A2B7E8220792FE00B2FC77 = {
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
};
|
||||
23C3AB9923FBCFA30079D9C3 = {
|
||||
CreatedOnToolsVersion = 11.3.1;
|
||||
};
|
||||
23E825612575D1760023A3C7 = {
|
||||
CreatedOnToolsVersion = 12.2;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 23A2B7E4220792FE00B2FC77 /* Build configuration list for PBXProject "DSFFloatLabelledTextControls" */;
|
||||
|
@ -299,34 +245,26 @@
|
|||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
ar,
|
||||
);
|
||||
mainGroup = 23A2B7E0220792FE00B2FC77;
|
||||
productRefGroup = 23A2B7EA220792FE00B2FC77 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */,
|
||||
23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */,
|
||||
23C3AB9923FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc */,
|
||||
23E825612575D1760023A3C7 /* All */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
2351F8492207D15C00EFA4F7 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
23A2B7E7220792FE00B2FC77 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2351F85B22082AD800EFA4F7 /* LICENSE in Resources */,
|
||||
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */,
|
||||
2351F85C22082AD800EFA4F7 /* README.md in Resources */,
|
||||
23A2B7F2220792FF00B2FC77 /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -343,14 +281,6 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
2351F8472207D15C00EFA4F7 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2351F8582207D16100EFA4F7 /* DSFFloatLabelledTextField.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
23A2B7E5220792FE00B2FC77 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -371,15 +301,15 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
2351F8512207D15C00EFA4F7 /* PBXTargetDependency */ = {
|
||||
23E825682575D17E0023A3C7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */;
|
||||
targetProxy = 2351F8502207D15C00EFA4F7 /* PBXContainerItemProxy */;
|
||||
target = 23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */;
|
||||
targetProxy = 23E825672575D17E0023A3C7 /* PBXContainerItemProxy */;
|
||||
};
|
||||
23C3ABAE23FBCFE40079D9C3 /* PBXTargetDependency */ = {
|
||||
23E8256A2575D17E0023A3C7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */;
|
||||
targetProxy = 23C3ABAD23FBCFE40079D9C3 /* PBXContainerItemProxy */;
|
||||
target = 23C3AB9923FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc */;
|
||||
targetProxy = 23E825692575D17E0023A3C7 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
|
@ -388,6 +318,7 @@
|
|||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
23A2B7F1220792FF00B2FC77 /* Base */,
|
||||
23E8256D2575D28A0023A3C7 /* ar */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
|
@ -403,70 +334,11 @@
|
|||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
2351F8552207D15C00EFA4F7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = Sources/DSFFloatLabelledTextField/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControl;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.2;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2351F8562207D15C00EFA4F7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = Sources/DSFFloatLabelledTextField/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControl;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.2;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
23A2B7F5220792FF00B2FC77 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
|
@ -528,6 +400,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
|
@ -581,8 +454,8 @@
|
|||
23A2B7F8220792FF00B2FC77 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
||||
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -593,6 +466,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 1.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -604,8 +478,8 @@
|
|||
23A2B7F9220792FF00B2FC77 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
||||
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -616,6 +490,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 1.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -627,19 +502,20 @@
|
|||
23C3ABA823FBCFA40079D9C3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
@ -648,36 +524,46 @@
|
|||
23C3ABA923FBCFA40079D9C3 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
23E825622575D1760023A3C7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
23E825632575D1760023A3C7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2351F8542207D15C00EFA4F7 /* Build configuration list for PBXNativeTarget "DSFFloatLabelledTextField" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2351F8552207D15C00EFA4F7 /* Debug */,
|
||||
2351F8562207D15C00EFA4F7 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
23A2B7E4220792FE00B2FC77 /* Build configuration list for PBXProject "DSFFloatLabelledTextControls" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
@ -705,7 +591,27 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
23E825642575D1760023A3C7 /* Build configuration list for PBXAggregateTarget "All" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
23E825622575D1760023A3C7 /* Debug */,
|
||||
23E825632575D1760023A3C7 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
23A3061B29C12CB200BEC98A /* DSFFloatLabelledTextField */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = DSFFloatLabelledTextField;
|
||||
};
|
||||
23A3061D29C12CB800BEC98A /* DSFFloatLabelledTextField */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = DSFFloatLabelledTextField;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
||||
}
|
|
@ -34,13 +34,14 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = "IDELaunchSchemeLanguageRLO"
|
||||
language = "ar"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
allowLocationSimulation = "YES"
|
||||
showNonLocalizedStrings = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
|
@ -27,8 +27,6 @@
|
|||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
|
@ -38,8 +36,8 @@
|
|||
ReferencedContainer = "container:DSFFloatLabelledTextControls.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
|
@ -61,8 +59,6 @@
|
|||
ReferencedContainer = "container:DSFFloatLabelledTextControls.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@import DSFFloatLabelledTextField;
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate, DSFFloatLabelledTextFieldDelegate>
|
||||
|
||||
|
||||
@end
|
|
@ -24,5 +24,8 @@
|
|||
// Insert code here to tear down your application
|
||||
}
|
||||
|
||||
- (void)floatLabelledTextFieldContentChanged:(DSFFloatLabelledSecureTextField *)field {
|
||||
NSLog(@"Password is now `%@`", field.stringValue);
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -684,50 +684,77 @@
|
|||
<window title="DSFFloatLabelledTextControls Demo objc" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="107"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="107"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="145"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||
<view key="contentView" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="138"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="XPK-cR-iSb" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="20" y="55" width="440" height="32"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="left" placeholderString="Title" id="PFO-GA-4nl">
|
||||
<font key="font" metaFont="system" size="24"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="16"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="257-gt-5Ui" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="20" y="20" width="440" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="left" placeholderString="Subtitle text goes here" id="Msd-kf-k0Q">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="13"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<stackView distribution="fill" orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="249.99998474121094" ambiguous="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Xn-w2-ecV">
|
||||
<rect key="frame" x="20" y="27" width="440" height="98"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="XPK-cR-iSb" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="66" width="440" height="32"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="left" placeholderString="Title" id="PFO-GA-4nl">
|
||||
<font key="font" metaFont="system" size="24"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="16"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="5uu-Hi-xn8" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="33" width="440" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="left" placeholderString="Subtitle text goes here" id="Uic-HN-dxQ">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="13"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="257-gt-5Ui" userLabel="Title Field" customClass="DSFFloatLabelledSecureTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="0.0" width="440" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="left" placeholderString="My Secret Password" id="Msd-kf-k0Q">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="13"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="fDf-Y2-VaF"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="257-gt-5Ui" firstAttribute="trailing" secondItem="XPK-cR-iSb" secondAttribute="trailing" id="6wQ-8C-VXo"/>
|
||||
<constraint firstItem="XPK-cR-iSb" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="Dfi-58-3cv"/>
|
||||
<constraint firstItem="257-gt-5Ui" firstAttribute="leading" secondItem="XPK-cR-iSb" secondAttribute="leading" id="Pf1-5G-WVc"/>
|
||||
<constraint firstItem="XPK-cR-iSb" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="mRz-gB-T7B"/>
|
||||
<constraint firstAttribute="trailing" secondItem="XPK-cR-iSb" secondAttribute="trailing" constant="20" symbolic="YES" id="pRo-7r-rd2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="257-gt-5Ui" secondAttribute="bottom" constant="20" id="pct-fO-Xxt"/>
|
||||
<constraint firstItem="257-gt-5Ui" firstAttribute="top" secondItem="XPK-cR-iSb" secondAttribute="bottom" constant="10" id="wMY-qA-eat"/>
|
||||
<constraint firstAttribute="trailing" secondItem="5Xn-w2-ecV" secondAttribute="trailing" constant="20" symbolic="YES" id="FBf-0I-IIa"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="5Xn-w2-ecV" secondAttribute="bottom" constant="20" symbolic="YES" id="Sdh-oS-cCe"/>
|
||||
<constraint firstItem="5Xn-w2-ecV" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="wLY-Yu-p9z"/>
|
||||
<constraint firstItem="5Xn-w2-ecV" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="ztN-wM-TMN"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="139" y="-246.5"/>
|
||||
<point key="canvasLocation" x="139" y="-227.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -35,6 +35,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
@IBOutlet weak var window: NSWindow!
|
||||
@IBOutlet weak var topFloatingLabel: DSFFloatLabelledTextField!
|
||||
|
||||
@IBOutlet weak var secureTextField: DSFFloatLabelledSecureTextField!
|
||||
@IBOutlet weak var passwordFloatingLabel: DSFFloatLabelledTextField!
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
// Insert code here to initialize your application
|
||||
|
||||
|
@ -45,27 +48,36 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
|
||||
let cv = self.window.contentView!
|
||||
|
||||
let x = NSLayoutConstraint(item: ft, attribute: .width,
|
||||
relatedBy: .equal,
|
||||
toItem: nil, attribute: .notAnAttribute,
|
||||
multiplier: 1, constant: 300)
|
||||
let x = NSLayoutConstraint(
|
||||
item: ft, attribute: .width,
|
||||
relatedBy: .equal,
|
||||
toItem: nil, attribute: .notAnAttribute,
|
||||
multiplier: 1, constant: 300
|
||||
)
|
||||
ft.addConstraint(x)
|
||||
cv.addSubview(ft)
|
||||
|
||||
|
||||
|
||||
let x1 = NSLayoutConstraint(item: ft, attribute: .left,
|
||||
relatedBy: .equal,
|
||||
toItem: cv, attribute: .left,
|
||||
multiplier: 1, constant: 20)
|
||||
let x1 = NSLayoutConstraint(
|
||||
item: ft, attribute: .leading,
|
||||
relatedBy: .equal,
|
||||
toItem: cv, attribute: .leading,
|
||||
multiplier: 1, constant: 20
|
||||
)
|
||||
cv.addConstraint(x1)
|
||||
|
||||
let x2 = NSLayoutConstraint(item: ft, attribute: .bottom,
|
||||
relatedBy: .equal,
|
||||
toItem: cv, attribute: .bottom,
|
||||
multiplier: 1, constant: -20)
|
||||
let x2 = NSLayoutConstraint(
|
||||
item: ft, attribute: .bottom,
|
||||
relatedBy: .equal,
|
||||
toItem: cv, attribute: .bottom,
|
||||
multiplier: 1, constant: -20
|
||||
)
|
||||
cv.addConstraint(x2)
|
||||
|
||||
self.secureTextField.stringValue = "caterpillar"
|
||||
}
|
||||
|
||||
@IBAction func resetPressed(_ sender: Any) {
|
||||
// Verify that when we programatically change the string value the control updates accordingly
|
||||
self.topFloatingLabel.stringValue = "Reset the content"
|
||||
|
@ -75,6 +87,34 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension AppDelegate: DSFFloatLabelledTextFieldDelegate {
|
||||
func floatLabelledTextField(_ field: DSFFloatLabelledTextField, didShowFloatingLabel didShow: Bool) {
|
||||
if field === topFloatingLabel {
|
||||
if didShow {
|
||||
Swift.print("Title Field floating label is now visible")
|
||||
}
|
||||
else {
|
||||
Swift.print("Title Field floating label is no longer visible")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func floatLabelledTextField(_ field: DSFFloatLabelledTextField, didFocus: Bool) {
|
||||
if field === topFloatingLabel {
|
||||
if didFocus {
|
||||
Swift.print("Title Field did focus")
|
||||
}
|
||||
else {
|
||||
Swift.print("Title Field lost focus")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func floatLabelledTextFieldContentChanged(_ field: DSFFloatLabelledTextField) {
|
||||
if field === passwordFloatingLabel {
|
||||
Swift.print("Password is now '\(self.passwordFloatingLabel.stringValue)'")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17154"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -15,6 +15,8 @@
|
|||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="DSFFloatLabelledTextControls" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="passwordFloatingLabel" destination="VLP-0u-Kf3" id="9Lw-el-n78"/>
|
||||
<outlet property="secureTextField" destination="VLP-0u-Kf3" id="uDf-HC-5AQ"/>
|
||||
<outlet property="topFloatingLabel" destination="tnz-85-NdV" id="Pyt-zO-up9"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
|
@ -685,21 +687,21 @@
|
|||
<window title="Floating Labels Test" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="497" height="441"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<rect key="contentRect" x="335" y="390" width="497" height="592"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="497" height="461"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="497" height="592"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<box boxType="secondary" title="Purchase Form" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="pnz-8U-z2F">
|
||||
<rect key="frame" x="17" y="303" width="463" height="140"/>
|
||||
<view key="contentView" id="fUJ-lp-O9s">
|
||||
<rect key="frame" x="3" y="3" width="457" height="134"/>
|
||||
<rect key="frame" x="17" y="432" width="463" height="142"/>
|
||||
<view key="contentView" ambiguous="YES" id="fUJ-lp-O9s">
|
||||
<rect key="frame" x="4" y="5" width="455" height="134"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="tnz-85-NdV" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="12" y="97" width="366" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" title="This is a fusdfjk" placeholderString="Title" id="ETD-Tb-a7N">
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tnz-85-NdV" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="12" y="97" width="374" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" title="Groovy Software v1" placeholderString="Title" id="ETD-Tb-a7N">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -709,9 +711,12 @@
|
|||
<real key="value" value="13"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="62z-Xl-apm"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<button toolTip="Check for programattic changing of stringValue" horizontalHuggingPriority="999" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nTi-Ym-3BC">
|
||||
<rect key="frame" x="380" y="92" width="75" height="32"/>
|
||||
<button toolTip="Check for programattic changing of stringValue" horizontalHuggingPriority="999" verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nTi-Ym-3BC">
|
||||
<rect key="frame" x="387" y="93" width="69" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="pTp-yr-DKx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -720,7 +725,7 @@
|
|||
<action selector="resetPressed:" target="Voe-Tx-rLC" id="keN-c6-1wD"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="pyP-dk-pAy">
|
||||
<box verticalHuggingPriority="750" ambiguous="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="pyP-dk-pAy">
|
||||
<rect key="frame" x="12" y="86" width="437" height="5"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="zbB-HI-AVu" userLabel="Price Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
|
@ -742,7 +747,7 @@
|
|||
<box horizontalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Mrp-MT-gGa">
|
||||
<rect key="frame" x="117" y="46" width="5" height="43"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="SAo-aL-Ofe" userLabel="Location Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SAo-aL-Ofe" userLabel="Location Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="128" y="55" width="321" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" placeholderString="Specific Location (Optional)" id="BHQ-MA-tIJ">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
|
@ -755,10 +760,10 @@
|
|||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="YiQ-45-hxx">
|
||||
<box verticalHuggingPriority="750" ambiguous="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="YiQ-45-hxx">
|
||||
<rect key="frame" x="12" y="44" width="437" height="5"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" translatesAutoresizingMaskIntoConstraints="NO" id="h8z-Ku-xLD" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="h8z-Ku-xLD" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="12" y="13" width="437" height="25"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="border" placeholderString="Description" id="XtC-Dr-5RL">
|
||||
<font key="font" metaFont="system" size="18"/>
|
||||
|
@ -800,10 +805,10 @@
|
|||
</view>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="CVr-p8-VOx">
|
||||
<rect key="frame" x="20" y="273" width="457" height="5"/>
|
||||
<rect key="frame" x="20" y="402" width="457" height="5"/>
|
||||
</box>
|
||||
<stackView distribution="fillEqually" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="waN-7O-qLn">
|
||||
<rect key="frame" x="20" y="212" width="457" height="33"/>
|
||||
<rect key="frame" x="20" y="341" width="457" height="33"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="oU9-jl-8Ow" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="0.0" width="50" height="33"/>
|
||||
|
@ -848,13 +853,13 @@
|
|||
</customSpacing>
|
||||
</stackView>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="QuB-jf-wmu">
|
||||
<rect key="frame" x="20" y="176" width="457" height="5"/>
|
||||
<rect key="frame" x="20" y="305" width="457" height="5"/>
|
||||
</box>
|
||||
<stackView distribution="fillEqually" orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CBs-1o-JjM">
|
||||
<rect key="frame" x="20" y="80" width="250" height="82"/>
|
||||
<rect key="frame" x="20" y="179" width="250" height="112"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3hp-BV-Ls3" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="60" width="250" height="22"/>
|
||||
<rect key="frame" x="0.0" y="90" width="250" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="Billy Snedden" placeholderString="Licensee Name" drawsBackground="YES" id="I01-Tl-E8r">
|
||||
<font key="font" metaFont="system" size="14"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -869,6 +874,25 @@
|
|||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VLP-0u-Kf3" customClass="DSFFloatLabelledSecureTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="60" width="250" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="caterpillar" placeholderString="Password" drawsBackground="YES" id="2oD-a4-pQh">
|
||||
<font key="font" metaFont="system" size="14"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||
<real key="value" value="12"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderSpacing">
|
||||
<real key="value" value="1"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="IaQ-aC-gRR"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="100" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MfQ-T7-eym" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||
<rect key="frame" x="0.0" y="30" width="250" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="1DRF-1X" placeholderString="Serial Number" drawsBackground="YES" id="3Xv-o0-6Io">
|
||||
|
@ -903,23 +927,27 @@
|
|||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="VLP-0u-Kf3" firstAttribute="leading" secondItem="3hp-BV-Ls3" secondAttribute="leading" id="1tz-ab-IsB"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3hp-BV-Ls3" secondAttribute="trailing" id="Cxv-bf-SFN"/>
|
||||
<constraint firstItem="ueu-5M-hVI" firstAttribute="leading" secondItem="3hp-BV-Ls3" secondAttribute="leading" id="HGs-7T-sEb"/>
|
||||
<constraint firstAttribute="width" constant="250" id="SfX-Wt-05r"/>
|
||||
<constraint firstItem="MfQ-T7-eym" firstAttribute="leading" secondItem="3hp-BV-Ls3" secondAttribute="leading" id="Xpi-7I-DrD"/>
|
||||
<constraint firstItem="MfQ-T7-eym" firstAttribute="trailing" secondItem="3hp-BV-Ls3" secondAttribute="trailing" id="YEC-So-F7G"/>
|
||||
<constraint firstItem="ueu-5M-hVI" firstAttribute="trailing" secondItem="3hp-BV-Ls3" secondAttribute="trailing" id="gq8-B3-sya"/>
|
||||
<constraint firstItem="VLP-0u-Kf3" firstAttribute="trailing" secondItem="3hp-BV-Ls3" secondAttribute="trailing" id="lxu-7C-U86"/>
|
||||
<constraint firstItem="3hp-BV-Ls3" firstAttribute="leading" secondItem="CBs-1o-JjM" secondAttribute="leading" id="w8m-Ox-vCH"/>
|
||||
</constraints>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
</subviews>
|
||||
|
@ -943,7 +971,7 @@
|
|||
<constraint firstItem="pnz-8U-z2F" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="zgF-Fx-OjE"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-163.5" y="191.5"/>
|
||||
<point key="canvasLocation" x="-480.5" y="144"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -0,0 +1,456 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Customize Toolbar…"; ObjectID = "1UK-8n-QPP"; */
|
||||
"1UK-8n-QPP.title" = "Customize Toolbar…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "DSFFloatLabelledTextControls"; ObjectID = "1Xt-HY-uBw"; */
|
||||
"1Xt-HY-uBw.title" = "DSFFloatLabelledTextControls";
|
||||
|
||||
/* Class = "NSMenu"; title = "Find"; ObjectID = "1b7-l0-nxx"; */
|
||||
"1b7-l0-nxx.title" = "Find";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Lower"; ObjectID = "1tx-W0-xDw"; */
|
||||
"1tx-W0-xDw.title" = "Lower";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Raise"; ObjectID = "2h7-ER-AoG"; */
|
||||
"2h7-ER-AoG.title" = "Raise";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Password"; ObjectID = "2oD-a4-pQh"; */
|
||||
"2oD-a4-pQh.placeholderString" = "كلمه السر";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "caterpillar"; ObjectID = "2oD-a4-pQh"; */
|
||||
"2oD-a4-pQh.title" = "caterpillar";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Transformations"; ObjectID = "2oI-Rn-ZJC"; */
|
||||
"2oI-Rn-ZJC.title" = "Transformations";
|
||||
|
||||
/* Class = "NSMenu"; title = "Spelling"; ObjectID = "3IN-sU-3Bg"; */
|
||||
"3IN-sU-3Bg.title" = "Spelling";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "3Om-Ey-2VK"; */
|
||||
"3Om-Ey-2VK.title" = "Use Default";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Serial Number"; ObjectID = "3Xv-o0-6Io"; */
|
||||
"3Xv-o0-6Io.placeholderString" = "رقم سري";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "1DRF-1X"; ObjectID = "3Xv-o0-6Io"; */
|
||||
"3Xv-o0-6Io.title" = "1DRF-1X";
|
||||
|
||||
/* Class = "NSMenu"; title = "Speech"; ObjectID = "3rS-ZA-NoH"; */
|
||||
"3rS-ZA-NoH.title" = "Speech";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Tighten"; ObjectID = "46P-cB-AYj"; */
|
||||
"46P-cB-AYj.title" = "Tighten";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Find"; ObjectID = "4EN-yA-p0u"; */
|
||||
"4EN-yA-p0u.title" = "Find";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */
|
||||
"4J7-dP-txa.title" = "Enter Full Screen";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Quit DSFFloatLabelledTextControls"; ObjectID = "4sb-4s-VLi"; */
|
||||
"4sb-4s-VLi.title" = "Quit DSFFloatLabelledTextControls";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
|
||||
"5QF-Oa-p0T.title" = "Edit";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Copy Style"; ObjectID = "5Vv-lz-BsD"; */
|
||||
"5Vv-lz-BsD.title" = "Copy Style";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "First Name"; ObjectID = "5Wb-1R-5YV"; */
|
||||
"5Wb-1R-5YV.placeholderString" = "الاسم الاول";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Billy"; ObjectID = "5Wb-1R-5YV"; */
|
||||
"5Wb-1R-5YV.title" = "Billy";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "About DSFFloatLabelledTextControls"; ObjectID = "5kV-Vb-QxS"; */
|
||||
"5kV-Vb-QxS.title" = "About DSFFloatLabelledTextControls";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Redo"; ObjectID = "6dh-zS-Vam"; */
|
||||
"6dh-zS-Vam.title" = "Redo";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Last Name"; ObjectID = "74P-hN-0Vg"; */
|
||||
"74P-hN-0Vg.placeholderString" = "الكنية";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Snedden"; ObjectID = "74P-hN-0Vg"; */
|
||||
"74P-hN-0Vg.title" = "Snedden";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Correct Spelling Automatically"; ObjectID = "78Y-hA-62v"; */
|
||||
"78Y-hA-62v.title" = "Correct Spelling Automatically";
|
||||
|
||||
/* Class = "NSMenu"; title = "Writing Direction"; ObjectID = "8mr-sm-Yjd"; */
|
||||
"8mr-sm-Yjd.title" = "Writing Direction";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Substitutions"; ObjectID = "9ic-FL-obx"; */
|
||||
"9ic-FL-obx.title" = "Substitutions";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Smart Copy/Paste"; ObjectID = "9yt-4B-nSM"; */
|
||||
"9yt-4B-nSM.title" = "Smart Copy/Paste";
|
||||
|
||||
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
|
||||
"AYu-sK-qS6.title" = "Main Menu";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Specific Location (Optional)"; ObjectID = "BHQ-MA-tIJ"; */
|
||||
"BHQ-MA-tIJ.placeholderString" = "موقع محدد (اختياري)";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
|
||||
"BOF-NM-1cW.title" = "Preferences…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "BgM-ve-c93"; */
|
||||
"BgM-ve-c93.title" = "\tLeft to Right";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Save As…"; ObjectID = "Bw7-FT-i3A"; */
|
||||
"Bw7-FT-i3A.title" = "Save As…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */
|
||||
"DVo-aG-piG.title" = "Close";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Spelling and Grammar"; ObjectID = "Dv1-io-Yv7"; */
|
||||
"Dv1-io-Yv7.title" = "Spelling and Grammar";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Title"; ObjectID = "ETD-Tb-a7N"; */
|
||||
"ETD-Tb-a7N.placeholderString" = "لقب";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Groovy Software v1"; ObjectID = "ETD-Tb-a7N"; */
|
||||
"ETD-Tb-a7N.title" = "Groovy Software v1";
|
||||
|
||||
/* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */
|
||||
"F2S-fz-NVQ.title" = "Help";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "DSFFloatLabelledTextControls Help"; ObjectID = "FKE-Sm-Kum"; */
|
||||
"FKE-Sm-Kum.title" = "DSFFloatLabelledTextControls Help";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Text"; ObjectID = "Fal-I4-PZk"; */
|
||||
"Fal-I4-PZk.title" = "Text";
|
||||
|
||||
/* Class = "NSMenu"; title = "Substitutions"; ObjectID = "FeM-D8-WVr"; */
|
||||
"FeM-D8-WVr.title" = "Substitutions";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Bold"; ObjectID = "GB9-OM-e27"; */
|
||||
"GB9-OM-e27.title" = "Bold";
|
||||
|
||||
/* Class = "NSMenu"; title = "Format"; ObjectID = "GEO-Iw-cKr"; */
|
||||
"GEO-Iw-cKr.title" = "Format";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "GUa-eO-cwY"; */
|
||||
"GUa-eO-cwY.title" = "Use Default";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Font"; ObjectID = "Gi5-1S-RQB"; */
|
||||
"Gi5-1S-RQB.title" = "Font";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Writing Direction"; ObjectID = "H1b-Si-o9J"; */
|
||||
"H1b-Si-o9J.title" = "Writing Direction";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
|
||||
"H8h-7b-M4v.title" = "View";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Text Replacement"; ObjectID = "HFQ-gK-NFA"; */
|
||||
"HFQ-gK-NFA.title" = "Text Replacement";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Spelling and Grammar"; ObjectID = "HFo-cy-zxI"; */
|
||||
"HFo-cy-zxI.title" = "Show Spelling and Grammar";
|
||||
|
||||
/* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */
|
||||
"HyV-fh-RgO.title" = "View";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Licensee Name"; ObjectID = "I01-Tl-E8r"; */
|
||||
"I01-Tl-E8r.placeholderString" = "اسم المرخص له";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Billy Snedden"; ObjectID = "I01-Tl-E8r"; */
|
||||
"I01-Tl-E8r.title" = "Billy Snedden";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Subscript"; ObjectID = "I0S-gh-46l"; */
|
||||
"I0S-gh-46l.title" = "Subscript";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Open…"; ObjectID = "IAo-SY-fd9"; */
|
||||
"IAo-SY-fd9.title" = "Open…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Justify"; ObjectID = "J5U-5w-g23"; */
|
||||
"J5U-5w-g23.title" = "Justify";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use None"; ObjectID = "J7y-lM-qPV"; */
|
||||
"J7y-lM-qPV.title" = "Use None";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Revert to Saved"; ObjectID = "KaW-ft-85H"; */
|
||||
"KaW-ft-85H.title" = "Revert to Saved";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
|
||||
"Kd2-mp-pUS.title" = "Show All";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */
|
||||
"LE2-aR-0XJ.title" = "Bring All to Front";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Paste Ruler"; ObjectID = "LVM-kO-fVI"; */
|
||||
"LVM-kO-fVI.title" = "Paste Ruler";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "Lbh-J2-qVU"; */
|
||||
"Lbh-J2-qVU.title" = "\tLeft to Right";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Copy Ruler"; ObjectID = "MkV-Pr-PK5"; */
|
||||
"MkV-Pr-PK5.title" = "Copy Ruler";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
|
||||
"NMo-om-nkz.title" = "Services";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "Nop-cj-93Q"; */
|
||||
"Nop-cj-93Q.title" = "\tDefault";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */
|
||||
"OY7-WF-poV.title" = "Minimize";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Baseline"; ObjectID = "OaQ-X3-Vso"; */
|
||||
"OaQ-X3-Vso.title" = "Baseline";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Hide DSFFloatLabelledTextControls"; ObjectID = "Olw-nP-bQN"; */
|
||||
"Olw-nP-bQN.title" = "Hide DSFFloatLabelledTextControls";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Find Previous"; ObjectID = "OwM-mh-QMV"; */
|
||||
"OwM-mh-QMV.title" = "Find Previous";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Stop Speaking"; ObjectID = "Oyz-dy-DGm"; */
|
||||
"Oyz-dy-DGm.title" = "Stop Speaking";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Bigger"; ObjectID = "Ptp-SP-VEL"; */
|
||||
"Ptp-SP-VEL.title" = "Bigger";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Fonts"; ObjectID = "Q5e-8K-NDq"; */
|
||||
"Q5e-8K-NDq.title" = "Show Fonts";
|
||||
|
||||
/* Class = "NSWindow"; title = "Floating Labels Test"; ObjectID = "QvC-M9-y7g"; */
|
||||
"QvC-M9-y7g.title" = "Floating Labels Test";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */
|
||||
"R4o-n2-Eq4.title" = "Zoom";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "RB4-Sm-HuC"; */
|
||||
"RB4-Sm-HuC.title" = "\tRight to Left";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Superscript"; ObjectID = "Rqc-34-cIF"; */
|
||||
"Rqc-34-cIF.title" = "Superscript";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Select All"; ObjectID = "Ruw-6m-B2m"; */
|
||||
"Ruw-6m-B2m.title" = "Select All";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Jump to Selection"; ObjectID = "S0p-oC-mLd"; */
|
||||
"S0p-oC-mLd.title" = "Jump to Selection";
|
||||
|
||||
/* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */
|
||||
"Td7-aD-5lo.title" = "Window";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Capitalize"; ObjectID = "UEZ-Bs-lqG"; */
|
||||
"UEZ-Bs-lqG.title" = "Capitalize";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Center"; ObjectID = "VIY-Ag-zcb"; */
|
||||
"VIY-Ag-zcb.title" = "Center";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
|
||||
"Vdr-fp-XzO.title" = "Hide Others";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Italic"; ObjectID = "Vjx-xi-njq"; */
|
||||
"Vjx-xi-njq.title" = "Italic";
|
||||
|
||||
/* Class = "NSMenu"; title = "Edit"; ObjectID = "W48-6f-4Dl"; */
|
||||
"W48-6f-4Dl.title" = "Edit";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Underline"; ObjectID = "WRG-CD-K1S"; */
|
||||
"WRG-CD-K1S.title" = "Underline";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "New"; ObjectID = "Was-JA-tGl"; */
|
||||
"Was-JA-tGl.title" = "New";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Paste and Match Style"; ObjectID = "WeT-3V-zwk"; */
|
||||
"WeT-3V-zwk.title" = "Paste and Match Style";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Description"; ObjectID = "XtC-Dr-5RL"; */
|
||||
"XtC-Dr-5RL.placeholderString" = "وصف";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Find…"; ObjectID = "Xz5-n4-O0W"; */
|
||||
"Xz5-n4-O0W.title" = "Find…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Find and Replace…"; ObjectID = "YEy-JH-Tfz"; */
|
||||
"YEy-JH-Tfz.title" = "Find and Replace…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "YGs-j5-SAR"; */
|
||||
"YGs-j5-SAR.title" = "\tDefault";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Start Speaking"; ObjectID = "Ynk-f8-cLZ"; */
|
||||
"Ynk-f8-cLZ.title" = "Start Speaking";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Align Left"; ObjectID = "ZM1-6Q-yy1"; */
|
||||
"ZM1-6Q-yy1.title" = "Align Left";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Paragraph"; ObjectID = "ZvO-Gk-QUH"; */
|
||||
"ZvO-Gk-QUH.title" = "Paragraph";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */
|
||||
"aTl-1u-JFS.title" = "Print…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
|
||||
"aUF-d1-5bR.title" = "Window";
|
||||
|
||||
/* Class = "NSMenu"; title = "Font"; ObjectID = "aXa-aM-Jaq"; */
|
||||
"aXa-aM-Jaq.title" = "Font";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "agt-UL-0e3"; */
|
||||
"agt-UL-0e3.title" = "Use Default";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Colors"; ObjectID = "bgn-CT-cEk"; */
|
||||
"bgn-CT-cEk.title" = "Show Colors";
|
||||
|
||||
/* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */
|
||||
"bib-Uj-vzu.title" = "File";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use Selection for Find"; ObjectID = "buJ-ug-pKt"; */
|
||||
"buJ-ug-pKt.title" = "Use Selection for Find";
|
||||
|
||||
/* Class = "NSMenu"; title = "Transformations"; ObjectID = "c8a-y6-VQd"; */
|
||||
"c8a-y6-VQd.title" = "Transformations";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use None"; ObjectID = "cDB-IK-hbR"; */
|
||||
"cDB-IK-hbR.title" = "Use None";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Selection"; ObjectID = "cqv-fj-IhA"; */
|
||||
"cqv-fj-IhA.title" = "Selection";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Smart Links"; ObjectID = "cwL-P1-jid"; */
|
||||
"cwL-P1-jid.title" = "Smart Links";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Make Lower Case"; ObjectID = "d9M-CD-aMd"; */
|
||||
"d9M-CD-aMd.title" = "Make Lower Case";
|
||||
|
||||
/* Class = "NSMenu"; title = "Text"; ObjectID = "d9c-me-L2H"; */
|
||||
"d9c-me-L2H.title" = "Text";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
|
||||
"dMs-cI-mzQ.title" = "File";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Undo"; ObjectID = "dRJ-4n-Yzg"; */
|
||||
"dRJ-4n-Yzg.title" = "Undo";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Price"; ObjectID = "doO-uJ-2o2"; */
|
||||
"doO-uJ-2o2.placeholderString" = "السعر";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Paste"; ObjectID = "gVA-U4-sdL"; */
|
||||
"gVA-U4-sdL.title" = "Paste";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Smart Quotes"; ObjectID = "hQb-2v-fYv"; */
|
||||
"hQb-2v-fYv.title" = "Smart Quotes";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Check Document Now"; ObjectID = "hz2-CU-CR7"; */
|
||||
"hz2-CU-CR7.title" = "Check Document Now";
|
||||
|
||||
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
|
||||
"hz9-B4-Xy5.title" = "Services";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Smaller"; ObjectID = "i1d-Er-qST"; */
|
||||
"i1d-Er-qST.title" = "Smaller";
|
||||
|
||||
/* Class = "NSMenu"; title = "Baseline"; ObjectID = "ijk-EB-dga"; */
|
||||
"ijk-EB-dga.title" = "Baseline";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Kern"; ObjectID = "jBQ-r6-VK2"; */
|
||||
"jBQ-r6-VK2.title" = "Kern";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "jFq-tB-4Kx"; */
|
||||
"jFq-tB-4Kx.title" = "\tRight to Left";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
|
||||
"jxT-CU-nIS.title" = "Format";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Sidebar"; ObjectID = "kIP-vf-haE"; */
|
||||
"kIP-vf-haE.title" = "Show Sidebar";
|
||||
|
||||
/* Class = "NSTextFieldCell"; placeholderString = "Maximum Clients"; ObjectID = "l0d-Jv-tQ6"; */
|
||||
"l0d-Jv-tQ6.placeholderString" = "أقصى عدد من العملاء";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "2"; ObjectID = "l0d-Jv-tQ6"; */
|
||||
"l0d-Jv-tQ6.title" = "2";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Check Grammar With Spelling"; ObjectID = "mK6-2p-4JG"; */
|
||||
"mK6-2p-4JG.title" = "Check Grammar With Spelling";
|
||||
|
||||
/* Class = "NSButton"; ibShadowedToolTip = "Check for programattic changing of stringValue"; ObjectID = "nTi-Ym-3BC"; */
|
||||
"nTi-Ym-3BC.ibShadowedToolTip" = "Check for programattic changing of stringValue";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Ligatures"; ObjectID = "o6e-r0-MWq"; */
|
||||
"o6e-r0-MWq.title" = "Ligatures";
|
||||
|
||||
/* Class = "NSMenu"; title = "Open Recent"; ObjectID = "oas-Oc-fiZ"; */
|
||||
"oas-Oc-fiZ.title" = "Open Recent";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Loosen"; ObjectID = "ogc-rX-tC1"; */
|
||||
"ogc-rX-tC1.title" = "Loosen";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Reset"; ObjectID = "pTp-yr-DKx"; */
|
||||
"pTp-yr-DKx.title" = "أعاد التشغيل";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Delete"; ObjectID = "pa3-QI-u2k"; */
|
||||
"pa3-QI-u2k.title" = "Delete";
|
||||
|
||||
/* Class = "NSBox"; title = "Purchase Form"; ObjectID = "pnz-8U-z2F"; */
|
||||
"pnz-8U-z2F.title" = "Purchase Form";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Save…"; ObjectID = "pxx-59-PXV"; */
|
||||
"pxx-59-PXV.title" = "Save…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Find Next"; ObjectID = "q09-fT-Sye"; */
|
||||
"q09-fT-Sye.title" = "Find Next";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */
|
||||
"qIS-W8-SiK.title" = "Page Setup…";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Check Spelling While Typing"; ObjectID = "rbD-Rh-wIN"; */
|
||||
"rbD-Rh-wIN.title" = "Check Spelling While Typing";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Smart Dashes"; ObjectID = "rgM-f4-ycn"; */
|
||||
"rgM-f4-ycn.title" = "Smart Dashes";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Toolbar"; ObjectID = "snW-S8-Cw5"; */
|
||||
"snW-S8-Cw5.title" = "Show Toolbar";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Data Detectors"; ObjectID = "tRr-pd-1PS"; */
|
||||
"tRr-pd-1PS.title" = "Data Detectors";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Open Recent"; ObjectID = "tXI-mr-wws"; */
|
||||
"tXI-mr-wws.title" = "Open Recent";
|
||||
|
||||
/* Class = "NSMenu"; title = "Kern"; ObjectID = "tlD-Oa-oAM"; */
|
||||
"tlD-Oa-oAM.title" = "Kern";
|
||||
|
||||
/* Class = "NSMenu"; title = "DSFFloatLabelledTextControls"; ObjectID = "uQy-DD-JDr"; */
|
||||
"uQy-DD-JDr.title" = "DSFFloatLabelledTextControls";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Cut"; ObjectID = "uRl-iY-unG"; */
|
||||
"uRl-iY-unG.title" = "Cut";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Paste Style"; ObjectID = "vKC-jM-MkH"; */
|
||||
"vKC-jM-MkH.title" = "Paste Style";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Ruler"; ObjectID = "vLm-3I-IUL"; */
|
||||
"vLm-3I-IUL.title" = "Show Ruler";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Clear Menu"; ObjectID = "vNY-rz-j42"; */
|
||||
"vNY-rz-j42.title" = "Clear Menu";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Make Upper Case"; ObjectID = "vmV-6d-7jI"; */
|
||||
"vmV-6d-7jI.title" = "Make Upper Case";
|
||||
|
||||
/* Class = "NSMenu"; title = "Ligatures"; ObjectID = "w0m-vy-SC9"; */
|
||||
"w0m-vy-SC9.title" = "Ligatures";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Align Right"; ObjectID = "wb2-vD-lq4"; */
|
||||
"wb2-vD-lq4.title" = "Align Right";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
|
||||
"wpr-3q-Mcd.title" = "Help";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Copy"; ObjectID = "x3v-GG-iWU"; */
|
||||
"x3v-GG-iWU.title" = "Copy";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Use All"; ObjectID = "xQD-1f-W4t"; */
|
||||
"xQD-1f-W4t.title" = "Use All";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Speech"; ObjectID = "xrE-MZ-jX0"; */
|
||||
"xrE-MZ-jX0.title" = "Speech";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Show Substitutions"; ObjectID = "z6F-FW-3nz"; */
|
||||
"z6F-FW-3nz.title" = "Show Substitutions";
|
|
@ -1,29 +1,23 @@
|
|||
// swift-tools-version:5.1
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
// swift-tools-version: 5.4
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "DSFFloatLabelledTextField",
|
||||
platforms: [
|
||||
.macOS(.v10_11)
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
||||
.library(
|
||||
name: "DSFFloatLabelledTextField",
|
||||
targets: ["DSFFloatLabelledTextField"]),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
// .package(url: /* package url */, from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||
.target(
|
||||
name: "DSFFloatLabelledTextField",
|
||||
dependencies: [])
|
||||
],
|
||||
swiftLanguageVersions: [.v5]
|
||||
name: "DSFFloatLabelledTextField",
|
||||
platforms: [
|
||||
.macOS(.v10_11)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "DSFFloatLabelledTextField",
|
||||
targets: ["DSFFloatLabelledTextField"]
|
||||
),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "DSFFloatLabelledTextField",
|
||||
dependencies: []
|
||||
)
|
||||
],
|
||||
swiftLanguageVersions: [.v5]
|
||||
)
|
||||
|
|
31
README.md
31
README.md
|
@ -1,8 +1,9 @@
|
|||
# macOS Float Label Pattern Text Field
|
||||
|
||||
A macOS Cocoa single-line NSTextField that implements the Float Label Pattern. You can read about the float pattern [here](http://mds.is/float-label-pattern/). Usable in Swift and Objective-C projects.
|
||||
A macOS Cocoa single-line NSTextField/NSSecureTextField that implements the Float Label Pattern.
|
||||
You can read about the float pattern [here](http://mds.is/float-label-pattern/).
|
||||
|
||||
  
|
||||
   
|
||||
 [](https://cocoapods.org) [](https://swift.org/package-manager)
|
||||
|
||||
## Screenshot
|
||||
|
@ -23,14 +24,12 @@ Add `https://github.com/dagronf/DSFFloatLabelledTextControl` to your project.
|
|||
|
||||
Add `pod 'DSFFloatLabelledTextControl', :git => 'https://github.com/dagronf/DSFFloatLabelledTextControl'` to your podfile.
|
||||
|
||||
### Directly
|
||||
Copy the `DSFFloatLabelledTextField.swift` into your project. This class inherits directly from `NSTextField` so all settings that you make on a text field (eg. alignment) should also apply here.
|
||||
|
||||
## Usage
|
||||
|
||||
### Interface builder
|
||||
|
||||
* Drop in a new Text Field into your canvas and set its class to `DSFFloatLabelledTextField`
|
||||
* Drop in a new Text Field into your canvas and set its class to `DSFFloatLabelledTextField` or
|
||||
`DSFFloatLabelledSecureTextControl` depending on whether you need a secure field
|
||||
* Set the size and style of your primary font as you would a regular text field
|
||||
* Set the size of the secondary font via the attributes inspector for the control
|
||||
|
||||
|
@ -47,11 +46,18 @@ parentView.addSubview(field)
|
|||
|
||||
## Custom Properties
|
||||
|
||||
This control inherits from `NSTextField`, so all `NSTextField` functionalities (like cocoa binding and Interface Builder settings) are available. If you can use an NSTextField, you can use this control.
|
||||
These controls inherit from `NSTextField`, so all `NSTextField` functionalities (like cocoa binding and Interface Builder settings) are available. If you can use an NSTextField, you can use this control.
|
||||
|
||||
`placeholderTextSize` - the size of the text used in the floating label (in pt)
|
||||
* `placeholderTextSize` - the size of the text used in the floating label (in pt)
|
||||
* `placeholderSpacing` - the distance between the text field text and the floating label (in px)
|
||||
|
||||
`placeholderSpacing` - the distance between the text field text and the floating label (in px)
|
||||
## Delegate Handling
|
||||
|
||||
You can specify a delegate (`floatLabelDelegate`), either programatically or via Interface Builder, to receive additional information regarding the actions of the control.
|
||||
|
||||
## Screenshot
|
||||
|
||||
<img src="https://github.com/dagronf/dagronf.github.io/blob/master/art/projects/DSFFloatingLabel/light-mode-secure-field.png?raw=true" alt="drawing" width="265"/>
|
||||
|
||||
## Credits
|
||||
|
||||
|
@ -59,12 +65,17 @@ This control inherits from `NSTextField`, so all `NSTextField` functionalities (
|
|||
* Read about the pattern [here](http://mds.is/float-label-pattern/)
|
||||
* [UITextField implementation](https://github.com/jverdi/JVFloatLabeledTextField)
|
||||
|
||||
## Versions
|
||||
|
||||
* `2.0.0`: Moved secure text field into separate class (fixing security warnings in modern Xcode)
|
||||
* `1.8.0`: Added secure text field support, delegate support
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Darren Ford
|
||||
Copyright (c) 2023 Darren Ford
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
// ** Automatically generated from DSFFloatLabelledTextField.swift.gyb **
|
||||
//
|
||||
// DSFFloatLabelledSecureTextField.swift
|
||||
// (generated using tools/regenerate-sources.sh)
|
||||
//
|
||||
// Copyright © 2023 Darren Ford. All rights reserved.
|
||||
//
|
||||
// MIT license
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
||||
/// DSFFloatLabelledTextField delegate protocol
|
||||
@objc public protocol DSFFloatLabelledSecureTextFieldDelegate: NSObjectProtocol {
|
||||
/// Called when the label is shown or hidden
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelledSecureTextField, didShowFloatingLabel didShow: Bool)
|
||||
/// Called when the field becomes or loses first responder status
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelledSecureTextField, didFocus: Bool)
|
||||
/// Called when the content of the field changes
|
||||
@objc optional func floatLabelledTextFieldContentChanged(_ field: DSFFloatLabelledSecureTextField)
|
||||
}
|
||||
|
||||
/// An NSSecureTextField that implements the Float Label Pattern
|
||||
@IBDesignable open class DSFFloatLabelledSecureTextField: NSSecureTextField {
|
||||
|
||||
/// Optional delegate to provide callbacks for the floating label state.
|
||||
///
|
||||
/// This delegate can be set via Interface Builder or programatically
|
||||
@IBOutlet @objc public weak var floatLabelDelegate: DSFFloatLabelledSecureTextFieldDelegate?
|
||||
|
||||
/// The size (in pt) of the floating label text
|
||||
@IBInspectable public var placeholderTextSize: CGFloat = NSFont.smallSystemFontSize {
|
||||
didSet {
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
/// Spacing between the floating label and the text field text
|
||||
@IBInspectable public var placeholderSpacing: CGFloat = 0.0 {
|
||||
didSet {
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
// Override so that we can notify when the developer changes the text programatically too
|
||||
open override var stringValue: String {
|
||||
get {
|
||||
return super.stringValue
|
||||
}
|
||||
set {
|
||||
super.stringValue = newValue
|
||||
NotificationCenter.default.post(name: NSControl.textDidChangeNotification, object: self)
|
||||
}
|
||||
}
|
||||
|
||||
// Override so that we can update when the developer changes the placeholder string
|
||||
open override var placeholderString: String? {
|
||||
get {
|
||||
return super.placeholderString
|
||||
}
|
||||
set {
|
||||
super.placeholderString = newValue
|
||||
self.floatingLabel.stringValue = newValue ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
/// Floating label
|
||||
private let floatingLabel = NSTextField()
|
||||
|
||||
/// Is the label currently showing
|
||||
private var isShowing: Bool = false {
|
||||
didSet {
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didShowFloatingLabel: self.isShowing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Constraint to tie the label to the top of the control
|
||||
private var floatingTop: NSLayoutConstraint?
|
||||
|
||||
/// Height of the control
|
||||
private var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
/// Observers for the font and placeholder text
|
||||
private var fontObserver: NSKeyValueObservation?
|
||||
private var placeholderObserver: NSKeyValueObservation?
|
||||
|
||||
/// Returns the height of the placeholder text
|
||||
var placeholderHeight: CGFloat {
|
||||
let layoutManager = NSLayoutManager()
|
||||
return layoutManager.defaultLineHeight(for: self.floatingLabel.font!) + 1
|
||||
}
|
||||
|
||||
/// Returns the height of the primary (editable) text
|
||||
private var textHeight: CGFloat {
|
||||
let layoutManager = NSLayoutManager()
|
||||
return layoutManager.defaultLineHeight(for: self.font!) + 1
|
||||
}
|
||||
|
||||
/// Returns the total height of the control given the font settings
|
||||
private var controlHeight: CGFloat {
|
||||
return self.textHeight + self.placeholderSpacing + self.placeholderHeight
|
||||
}
|
||||
|
||||
open override var intrinsicContentSize: NSSize {
|
||||
var sz = super.intrinsicContentSize
|
||||
sz.height = self.controlHeight
|
||||
return sz
|
||||
}
|
||||
|
||||
func configureCell() {
|
||||
let customCell = DSFFloatLabelledSecureTextFieldCell()
|
||||
customCell.isEditable = true
|
||||
customCell.wraps = false
|
||||
customCell.usesSingleLineMode = true
|
||||
customCell.placeholderString = self.placeholderString
|
||||
customCell.title = self.stringValue
|
||||
customCell.font = self.font
|
||||
customCell.isBordered = self.isBordered
|
||||
customCell.isBezeled = self.isBezeled
|
||||
customCell.bezelStyle = self.bezelStyle
|
||||
customCell.isScrollable = true
|
||||
customCell.isContinuous = self.isContinuous
|
||||
customCell.alignment = self.alignment
|
||||
customCell.formatter = self.formatter
|
||||
customCell.topOffset = self.placeholderHeight
|
||||
self.cell = customCell
|
||||
}
|
||||
|
||||
func setTopOffset(_ value: CGFloat) {
|
||||
guard var f = self.cell as? DSFFloatLabelledTextFieldCellProtocol else {
|
||||
return
|
||||
}
|
||||
f.topOffset = value
|
||||
}
|
||||
|
||||
/// Set the fonts to be used in the control
|
||||
open func setFonts(primary: NSFont, secondary: NSFont) {
|
||||
self.floatingLabel.font = secondary
|
||||
self.font = primary
|
||||
}
|
||||
|
||||
public override init(frame frameRect: NSRect) {
|
||||
super.init(frame: frameRect)
|
||||
self.setup()
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
self.setup()
|
||||
}
|
||||
|
||||
open override func viewDidMoveToWindow() {
|
||||
super.viewDidMoveToWindow()
|
||||
|
||||
// When we're added to the view, make sure that the floating label alignment matches us
|
||||
// (as the user might have changed the alignment BEFORE adding to the superview
|
||||
self.floatingLabel.alignment = self.alignment
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
// Setup the common elements of the control
|
||||
self.commonSetup()
|
||||
|
||||
// Configure a default text cell
|
||||
self.configureCell()
|
||||
|
||||
// Listen to changes in the primary font so we can reconfigure to match
|
||||
self.fontObserver = self.observe(\.font, options: [.new]) { [weak self] _, _ in
|
||||
self?.reconfigureControl()
|
||||
}
|
||||
|
||||
// Listen to changes in the placeholder text so we can reflect it in the floater
|
||||
self.placeholderObserver = self.observe(\.placeholderString, options: [.new]) { [weak self] _, _ in
|
||||
guard let `self` = self else { return }
|
||||
self.floatingLabel.stringValue = self.placeholderString!
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the floating label
|
||||
private func createFloatingLabel() {
|
||||
if self.floatingLabel.superview == nil {
|
||||
self.addSubview(self.floatingLabel)
|
||||
}
|
||||
|
||||
self.floatingLabel.wantsLayer = true
|
||||
self.floatingLabel.isEditable = false
|
||||
self.floatingLabel.isSelectable = false
|
||||
self.floatingLabel.isEnabled = true
|
||||
self.floatingLabel.isBezeled = false
|
||||
self.floatingLabel.isBordered = false
|
||||
self.floatingLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
self.floatingLabel.stringValue = self.placeholderString ?? ""
|
||||
self.floatingLabel.alphaValue = 0.0
|
||||
self.floatingLabel.alignment = self.alignment
|
||||
self.floatingLabel.drawsBackground = false
|
||||
|
||||
self.floatingTop = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .top,
|
||||
multiplier: 1.0, constant: 10
|
||||
)
|
||||
self.addConstraint(self.floatingTop!)
|
||||
|
||||
var x = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .leading,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .leading,
|
||||
multiplier: 1.0, constant: self.isBezeled ? 4 : 0
|
||||
)
|
||||
self.addConstraint(x)
|
||||
|
||||
x = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .trailing,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .trailing,
|
||||
multiplier: 1.0, constant: self.isBezeled ? -4 : 0
|
||||
)
|
||||
self.addConstraint(x)
|
||||
|
||||
self.floatingLabel.setContentHuggingPriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
self.floatingLabel.setContentCompressionResistancePriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
}
|
||||
|
||||
private func commonSetup() {
|
||||
self.wantsLayer = true
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.usesSingleLineMode = true
|
||||
self.delegate = self
|
||||
|
||||
// Default to natural layout
|
||||
self.alignment = .natural
|
||||
|
||||
self.createFloatingLabel()
|
||||
|
||||
self.heightConstraint = NSLayoutConstraint(
|
||||
item: self, attribute: .height,
|
||||
relatedBy: .equal,
|
||||
toItem: nil, attribute: .notAnAttribute,
|
||||
multiplier: 1.0, constant: self.controlHeight
|
||||
)
|
||||
self.addConstraint(self.heightConstraint!)
|
||||
|
||||
// If the field already has text, make sure the placeholder is shown
|
||||
if self.stringValue.count > 0 {
|
||||
self.showPlaceholder(animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Change the layout if any changes occur
|
||||
private func reconfigureControl() {
|
||||
if self.isCurrentFocus() {
|
||||
/// If we are currently editing, then finish before changing.
|
||||
self.window?.endEditing(for: nil)
|
||||
}
|
||||
self.expandFrame()
|
||||
}
|
||||
|
||||
/// Rebuild the frame of the text field to match the new settings
|
||||
private func expandFrame() {
|
||||
self.heightConstraint?.constant = self.controlHeight
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
open override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Focus and editing
|
||||
|
||||
extension DSFFloatLabelledSecureTextField: NSTextFieldDelegate {
|
||||
|
||||
// Change the floating label color to represent active state
|
||||
private func setFloatingLabelActive(_ active: Bool) {
|
||||
if active {
|
||||
self.floatingLabel.textColor = NSColor.simulatedAccentColor
|
||||
}
|
||||
else {
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didFocus: active)
|
||||
}
|
||||
|
||||
public func controlTextDidChange(_ obj: Notification) {
|
||||
guard let field = obj.object as? NSTextField else {
|
||||
return
|
||||
}
|
||||
|
||||
if field.stringValue.count > 0, !self.isShowing {
|
||||
self.showPlaceholder(animated: true)
|
||||
}
|
||||
else if field.stringValue.count == 0, self.isShowing {
|
||||
self.hidePlaceholder()
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextFieldContentChanged?(self)
|
||||
}
|
||||
|
||||
open override func becomeFirstResponder() -> Bool {
|
||||
let becomeResult = super.becomeFirstResponder()
|
||||
if becomeResult, self.isCurrentFocus() {
|
||||
// Set the color of the 'label' to match the current focus color.
|
||||
// We need to perform this on the main thread after the current set of notifications are processed
|
||||
// Why? We (occasionally) receive a 'controlTextDidEndEditing' message AFTER we receive a
|
||||
// 'becomeFirstResponder'. I've read that this is related to the text field automatically selecting
|
||||
// text when taking focus, but I haven't been able to verify this in any useful manner.
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
if let `self` = self {
|
||||
self.setFloatingLabelActive(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return becomeResult
|
||||
}
|
||||
|
||||
open func controlTextDidEndEditing(_: Notification) {
|
||||
// When we lose focus, set the label color back to the placeholder color
|
||||
self.setFloatingLabelActive(false)
|
||||
}
|
||||
|
||||
/// Does our text field currently have input focus?
|
||||
private func isCurrentFocus() -> Bool {
|
||||
// 1. Get the window's first responder
|
||||
// 2. Check is has an active field editor
|
||||
// 3. Is the delegate of the field editor us?
|
||||
if let fr = self.window?.firstResponder as? NSTextView,
|
||||
self.window?.fieldEditor(false, for: nil) != nil,
|
||||
fr.delegate === self {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Animations
|
||||
|
||||
extension DSFFloatLabelledSecureTextField {
|
||||
|
||||
/// Duration of the fade in/out of the secondary label
|
||||
private var animationDuration: TimeInterval {
|
||||
return shouldAnimate() ? 0.4 : 0.0
|
||||
}
|
||||
|
||||
/// Returns true if the system is NOT set to reduce motion (accessibility settings)
|
||||
private func shouldAnimate() -> Bool {
|
||||
if #available(OSX 10.12, *) {
|
||||
return !NSWorkspace.shared.accessibilityDisplayShouldReduceMotion
|
||||
} else {
|
||||
// Fallback on earlier versions. Just animate
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private func showPlaceholder(animated: Bool) {
|
||||
self.isShowing = true
|
||||
if animated {
|
||||
NSAnimationContext.runAnimationGroup({ [weak self] context in
|
||||
guard let `self` = self else { return }
|
||||
context.allowsImplicitAnimation = true
|
||||
context.duration = self.animationDuration
|
||||
self.floatingTop?.constant = 0
|
||||
self.floatingLabel.alphaValue = 1.0
|
||||
self.layoutSubtreeIfNeeded()
|
||||
}, completionHandler: {
|
||||
//
|
||||
})
|
||||
}
|
||||
else {
|
||||
self.setFloatingLabelActive(false)
|
||||
self.floatingTop?.constant = 0
|
||||
self.floatingLabel.alphaValue = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
private func hidePlaceholder() {
|
||||
self.isShowing = false
|
||||
let duration = self.animationDuration
|
||||
NSAnimationContext.runAnimationGroup({ [weak self] context in
|
||||
guard let `self` = self else { return }
|
||||
context.allowsImplicitAnimation = true
|
||||
context.duration = duration
|
||||
self.floatingTop?.constant = self.textHeight / 1.5
|
||||
self.floatingLabel.alphaValue = 0.0
|
||||
self.layoutSubtreeIfNeeded()
|
||||
}, completionHandler: {
|
||||
//
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Cell definition
|
||||
|
||||
private class DSFFloatLabelledSecureTextFieldCell: NSSecureTextFieldCell, DSFFloatLabelledTextFieldCellProtocol {
|
||||
var topOffset: CGFloat = 0
|
||||
|
||||
private func offset() -> CGFloat {
|
||||
return self.topOffset - (self.isBezeled ? 5 : 1)
|
||||
}
|
||||
|
||||
override func titleRect(forBounds rect: NSRect) -> NSRect {
|
||||
return NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
}
|
||||
|
||||
override func edit(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) {
|
||||
let insetRect = NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
super.edit(withFrame: insetRect, in: controlView, editor: textObj, delegate: delegate, event: event)
|
||||
}
|
||||
|
||||
override func select(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) {
|
||||
let insetRect = NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
super.select(withFrame: insetRect, in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
|
||||
}
|
||||
|
||||
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
|
||||
let insetRect = NSRect(x: cellFrame.origin.x, y: cellFrame.origin.y + self.offset(), width: cellFrame.width, height: cellFrame.height)
|
||||
super.drawInterior(withFrame: insetRect, in: controlView)
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// DSFFloatLabelledTextControl.h
|
||||
// DSFFloatLabelledTextControl
|
||||
//
|
||||
// Created by Darren Ford on 4/2/19.
|
||||
// Copyright © 2020 Darren Ford. All rights reserved.
|
||||
//
|
||||
// MIT License
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
//! Project version number for DSFFloatLabelledTextControl.
|
||||
FOUNDATION_EXPORT double DSFFloatLabelledTextControlVersionNumber;
|
||||
|
||||
//! Project version string for DSFFloatLabelledTextControl.
|
||||
FOUNDATION_EXPORT const unsigned char DSFFloatLabelledTextControlVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <DSFFloatLabelledTextControl/PublicHeader.h>
|
||||
|
||||
|
|
@ -1,34 +1,51 @@
|
|||
// ** Automatically generated from DSFFloatLabelledTextField.swift.gyb **
|
||||
//
|
||||
// DSFFloatLabelledTextField.swift
|
||||
// DSFFloatLabelledTextControls
|
||||
// (generated using tools/regenerate-sources.sh)
|
||||
//
|
||||
// Created by Darren Ford on 4/2/19.
|
||||
// Copyright © 2020 Darren Ford. All rights reserved.
|
||||
// Copyright © 2023 Darren Ford. All rights reserved.
|
||||
//
|
||||
// MIT License
|
||||
// MIT license
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import Cocoa
|
||||
import AppKit
|
||||
|
||||
/// DSFFloatLabelledTextField delegate protocol
|
||||
@objc public protocol DSFFloatLabelledTextFieldDelegate: NSObjectProtocol {
|
||||
/// Called when the label is shown or hidden
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelledTextField, didShowFloatingLabel didShow: Bool)
|
||||
/// Called when the field becomes or loses first responder status
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelledTextField, didFocus: Bool)
|
||||
/// Called when the content of the field changes
|
||||
@objc optional func floatLabelledTextFieldContentChanged(_ field: DSFFloatLabelledTextField)
|
||||
}
|
||||
|
||||
/// An NSTextField that implements the Float Label Pattern
|
||||
@IBDesignable open class DSFFloatLabelledTextField: NSTextField {
|
||||
|
||||
/// Optional delegate to provide callbacks for the floating label state.
|
||||
///
|
||||
/// This delegate can be set via Interface Builder or programatically
|
||||
@IBOutlet @objc public weak var floatLabelDelegate: DSFFloatLabelledTextFieldDelegate?
|
||||
|
||||
/// The size (in pt) of the floating label text
|
||||
@IBInspectable public var placeholderTextSize: CGFloat = NSFont.smallSystemFontSize {
|
||||
didSet {
|
||||
|
@ -71,7 +88,11 @@ import Cocoa
|
|||
private let floatingLabel = NSTextField()
|
||||
|
||||
/// Is the label currently showing
|
||||
private var isShowing: Bool = false
|
||||
private var isShowing: Bool = false {
|
||||
didSet {
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didShowFloatingLabel: self.isShowing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Constraint to tie the label to the top of the control
|
||||
private var floatingTop: NSLayoutConstraint?
|
||||
|
@ -100,27 +121,14 @@ import Cocoa
|
|||
return self.textHeight + self.placeholderSpacing + self.placeholderHeight
|
||||
}
|
||||
|
||||
/// Returns of the color for the floating text
|
||||
private var floatTextColor: NSColor {
|
||||
if #available(macOS 10.14, *) {
|
||||
return NSColor.controlAccentColor
|
||||
}
|
||||
else {
|
||||
return NSColor.headerTextColor
|
||||
}
|
||||
}
|
||||
|
||||
open override var intrinsicContentSize: NSSize {
|
||||
var sz = super.intrinsicContentSize
|
||||
sz.height = self.controlHeight
|
||||
return sz
|
||||
}
|
||||
|
||||
/// Return the custom cell type
|
||||
fileprivate lazy var fieldCell: DSFFloatLabelledTextFieldCell = {
|
||||
func configureCell() {
|
||||
let customCell = DSFFloatLabelledTextFieldCell()
|
||||
customCell.topOffset = self.placeholderHeight
|
||||
|
||||
customCell.isEditable = true
|
||||
customCell.wraps = false
|
||||
customCell.usesSingleLineMode = true
|
||||
|
@ -134,11 +142,16 @@ import Cocoa
|
|||
customCell.isContinuous = self.isContinuous
|
||||
customCell.alignment = self.alignment
|
||||
customCell.formatter = self.formatter
|
||||
|
||||
customCell.topOffset = self.placeholderHeight
|
||||
self.cell = customCell
|
||||
}
|
||||
|
||||
return customCell
|
||||
}()
|
||||
func setTopOffset(_ value: CGFloat) {
|
||||
guard var f = self.cell as? DSFFloatLabelledTextFieldCellProtocol else {
|
||||
return
|
||||
}
|
||||
f.topOffset = value
|
||||
}
|
||||
|
||||
/// Set the fonts to be used in the control
|
||||
open func setFonts(primary: NSFont, secondary: NSFont) {
|
||||
|
@ -168,6 +181,9 @@ import Cocoa
|
|||
// Setup the common elements of the control
|
||||
self.commonSetup()
|
||||
|
||||
// Configure a default text cell
|
||||
self.configureCell()
|
||||
|
||||
// Listen to changes in the primary font so we can reconfigure to match
|
||||
self.fontObserver = self.observe(\.font, options: [.new]) { [weak self] _, _ in
|
||||
self?.reconfigureControl()
|
||||
|
@ -195,7 +211,7 @@ import Cocoa
|
|||
self.floatingLabel.isBordered = false
|
||||
self.floatingLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.floatingLabel.textColor = self.floatTextColor
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
self.floatingLabel.stringValue = self.placeholderString ?? ""
|
||||
self.floatingLabel.alphaValue = 0.0
|
||||
self.floatingLabel.alignment = self.alignment
|
||||
|
@ -224,6 +240,9 @@ import Cocoa
|
|||
multiplier: 1.0, constant: self.isBezeled ? -4 : 0
|
||||
)
|
||||
self.addConstraint(x)
|
||||
|
||||
self.floatingLabel.setContentHuggingPriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
self.floatingLabel.setContentCompressionResistancePriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
}
|
||||
|
||||
private func commonSetup() {
|
||||
|
@ -257,17 +276,23 @@ import Cocoa
|
|||
/// If we are currently editing, then finish before changing.
|
||||
self.window?.endEditing(for: nil)
|
||||
}
|
||||
self.fieldCell.topOffset = self.placeholderHeight + self.placeholderSpacing
|
||||
|
||||
self.expandFrame()
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
/// Rebuild the frame of the text field to match the new settings
|
||||
private func expandFrame() {
|
||||
self.heightConstraint?.constant = self.controlHeight
|
||||
self.fieldCell.topOffset = self.placeholderHeight + self.placeholderSpacing
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
open override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Focus and editing
|
||||
|
@ -277,11 +302,13 @@ extension DSFFloatLabelledTextField: NSTextFieldDelegate {
|
|||
// Change the floating label color to represent active state
|
||||
private func setFloatingLabelActive(_ active: Bool) {
|
||||
if active {
|
||||
self.floatingLabel.textColor = self.floatTextColor
|
||||
self.floatingLabel.textColor = NSColor.simulatedAccentColor
|
||||
}
|
||||
else {
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didFocus: active)
|
||||
}
|
||||
|
||||
public func controlTextDidChange(_ obj: Notification) {
|
||||
|
@ -295,6 +322,8 @@ extension DSFFloatLabelledTextField: NSTextFieldDelegate {
|
|||
else if field.stringValue.count == 0, self.isShowing {
|
||||
self.hidePlaceholder()
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextFieldContentChanged?(self)
|
||||
}
|
||||
|
||||
open override func becomeFirstResponder() -> Bool {
|
||||
|
@ -391,7 +420,7 @@ extension DSFFloatLabelledTextField {
|
|||
|
||||
// MARK: - Cell definition
|
||||
|
||||
private class DSFFloatLabelledTextFieldCell: NSTextFieldCell {
|
||||
private class DSFFloatLabelledTextFieldCell: NSTextFieldCell, DSFFloatLabelledTextFieldCellProtocol {
|
||||
var topOffset: CGFloat = 0
|
||||
|
||||
private func offset() -> CGFloat {
|
||||
|
@ -417,4 +446,3 @@ private class DSFFloatLabelledTextFieldCell: NSTextFieldCell {
|
|||
super.drawInterior(withFrame: insetRect, in: controlView)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
// ** Automatically generated from DSFFloatLabelledTextField.swift.gyb **
|
||||
//
|
||||
// DSFFloatLabelled${field_type}Field.swift
|
||||
// (generated using tools/regenerate-sources.sh)
|
||||
//
|
||||
// Copyright © 2023 Darren Ford. All rights reserved.
|
||||
//
|
||||
// MIT license
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
||||
/// DSFFloatLabelledTextField delegate protocol
|
||||
@objc public protocol DSFFloatLabelled${field_type}FieldDelegate: NSObjectProtocol {
|
||||
/// Called when the label is shown or hidden
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelled${field_type}Field, didShowFloatingLabel didShow: Bool)
|
||||
/// Called when the field becomes or loses first responder status
|
||||
@objc optional func floatLabelledTextField(_ field: DSFFloatLabelled${field_type}Field, didFocus: Bool)
|
||||
/// Called when the content of the field changes
|
||||
@objc optional func floatLabelledTextFieldContentChanged(_ field: DSFFloatLabelled${field_type}Field)
|
||||
}
|
||||
|
||||
/// An NS${field_type}Field that implements the Float Label Pattern
|
||||
@IBDesignable open class DSFFloatLabelled${field_type}Field: NS${field_type}Field {
|
||||
|
||||
/// Optional delegate to provide callbacks for the floating label state.
|
||||
///
|
||||
/// This delegate can be set via Interface Builder or programatically
|
||||
@IBOutlet @objc public weak var floatLabelDelegate: DSFFloatLabelled${field_type}FieldDelegate?
|
||||
|
||||
/// The size (in pt) of the floating label text
|
||||
@IBInspectable public var placeholderTextSize: CGFloat = NSFont.smallSystemFontSize {
|
||||
didSet {
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
/// Spacing between the floating label and the text field text
|
||||
@IBInspectable public var placeholderSpacing: CGFloat = 0.0 {
|
||||
didSet {
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
// Override so that we can notify when the developer changes the text programatically too
|
||||
open override var stringValue: String {
|
||||
get {
|
||||
return super.stringValue
|
||||
}
|
||||
set {
|
||||
super.stringValue = newValue
|
||||
NotificationCenter.default.post(name: NSControl.textDidChangeNotification, object: self)
|
||||
}
|
||||
}
|
||||
|
||||
// Override so that we can update when the developer changes the placeholder string
|
||||
open override var placeholderString: String? {
|
||||
get {
|
||||
return super.placeholderString
|
||||
}
|
||||
set {
|
||||
super.placeholderString = newValue
|
||||
self.floatingLabel.stringValue = newValue ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
/// Floating label
|
||||
private let floatingLabel = NSTextField()
|
||||
|
||||
/// Is the label currently showing
|
||||
private var isShowing: Bool = false {
|
||||
didSet {
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didShowFloatingLabel: self.isShowing)
|
||||
}
|
||||
}
|
||||
|
||||
/// Constraint to tie the label to the top of the control
|
||||
private var floatingTop: NSLayoutConstraint?
|
||||
|
||||
/// Height of the control
|
||||
private var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
/// Observers for the font and placeholder text
|
||||
private var fontObserver: NSKeyValueObservation?
|
||||
private var placeholderObserver: NSKeyValueObservation?
|
||||
|
||||
/// Returns the height of the placeholder text
|
||||
var placeholderHeight: CGFloat {
|
||||
let layoutManager = NSLayoutManager()
|
||||
return layoutManager.defaultLineHeight(for: self.floatingLabel.font!) + 1
|
||||
}
|
||||
|
||||
/// Returns the height of the primary (editable) text
|
||||
private var textHeight: CGFloat {
|
||||
let layoutManager = NSLayoutManager()
|
||||
return layoutManager.defaultLineHeight(for: self.font!) + 1
|
||||
}
|
||||
|
||||
/// Returns the total height of the control given the font settings
|
||||
private var controlHeight: CGFloat {
|
||||
return self.textHeight + self.placeholderSpacing + self.placeholderHeight
|
||||
}
|
||||
|
||||
open override var intrinsicContentSize: NSSize {
|
||||
var sz = super.intrinsicContentSize
|
||||
sz.height = self.controlHeight
|
||||
return sz
|
||||
}
|
||||
|
||||
func configureCell() {
|
||||
let customCell = DSFFloatLabelled${field_type}FieldCell()
|
||||
customCell.isEditable = true
|
||||
customCell.wraps = false
|
||||
customCell.usesSingleLineMode = true
|
||||
customCell.placeholderString = self.placeholderString
|
||||
customCell.title = self.stringValue
|
||||
customCell.font = self.font
|
||||
customCell.isBordered = self.isBordered
|
||||
customCell.isBezeled = self.isBezeled
|
||||
customCell.bezelStyle = self.bezelStyle
|
||||
customCell.isScrollable = true
|
||||
customCell.isContinuous = self.isContinuous
|
||||
customCell.alignment = self.alignment
|
||||
customCell.formatter = self.formatter
|
||||
customCell.topOffset = self.placeholderHeight
|
||||
self.cell = customCell
|
||||
}
|
||||
|
||||
func setTopOffset(_ value: CGFloat) {
|
||||
guard var f = self.cell as? DSFFloatLabelledTextFieldCellProtocol else {
|
||||
return
|
||||
}
|
||||
f.topOffset = value
|
||||
}
|
||||
|
||||
/// Set the fonts to be used in the control
|
||||
open func setFonts(primary: NSFont, secondary: NSFont) {
|
||||
self.floatingLabel.font = secondary
|
||||
self.font = primary
|
||||
}
|
||||
|
||||
public override init(frame frameRect: NSRect) {
|
||||
super.init(frame: frameRect)
|
||||
self.setup()
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
self.setup()
|
||||
}
|
||||
|
||||
open override func viewDidMoveToWindow() {
|
||||
super.viewDidMoveToWindow()
|
||||
|
||||
// When we're added to the view, make sure that the floating label alignment matches us
|
||||
// (as the user might have changed the alignment BEFORE adding to the superview
|
||||
self.floatingLabel.alignment = self.alignment
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
// Setup the common elements of the control
|
||||
self.commonSetup()
|
||||
|
||||
// Configure a default text cell
|
||||
self.configureCell()
|
||||
|
||||
// Listen to changes in the primary font so we can reconfigure to match
|
||||
self.fontObserver = self.observe(\.font, options: [.new]) { [weak self] _, _ in
|
||||
self?.reconfigureControl()
|
||||
}
|
||||
|
||||
// Listen to changes in the placeholder text so we can reflect it in the floater
|
||||
self.placeholderObserver = self.observe(\.placeholderString, options: [.new]) { [weak self] _, _ in
|
||||
guard let `self` = self else { return }
|
||||
self.floatingLabel.stringValue = self.placeholderString!
|
||||
self.reconfigureControl()
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the floating label
|
||||
private func createFloatingLabel() {
|
||||
if self.floatingLabel.superview == nil {
|
||||
self.addSubview(self.floatingLabel)
|
||||
}
|
||||
|
||||
self.floatingLabel.wantsLayer = true
|
||||
self.floatingLabel.isEditable = false
|
||||
self.floatingLabel.isSelectable = false
|
||||
self.floatingLabel.isEnabled = true
|
||||
self.floatingLabel.isBezeled = false
|
||||
self.floatingLabel.isBordered = false
|
||||
self.floatingLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.floatingLabel.font = NSFont.systemFont(ofSize: self.placeholderTextSize)
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
self.floatingLabel.stringValue = self.placeholderString ?? ""
|
||||
self.floatingLabel.alphaValue = 0.0
|
||||
self.floatingLabel.alignment = self.alignment
|
||||
self.floatingLabel.drawsBackground = false
|
||||
|
||||
self.floatingTop = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .top,
|
||||
multiplier: 1.0, constant: 10
|
||||
)
|
||||
self.addConstraint(self.floatingTop!)
|
||||
|
||||
var x = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .leading,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .leading,
|
||||
multiplier: 1.0, constant: self.isBezeled ? 4 : 0
|
||||
)
|
||||
self.addConstraint(x)
|
||||
|
||||
x = NSLayoutConstraint(
|
||||
item: self.floatingLabel, attribute: .trailing,
|
||||
relatedBy: .equal,
|
||||
toItem: self, attribute: .trailing,
|
||||
multiplier: 1.0, constant: self.isBezeled ? -4 : 0
|
||||
)
|
||||
self.addConstraint(x)
|
||||
|
||||
self.floatingLabel.setContentHuggingPriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
self.floatingLabel.setContentCompressionResistancePriority(NSLayoutConstraint.Priority(10), for: .horizontal)
|
||||
}
|
||||
|
||||
private func commonSetup() {
|
||||
self.wantsLayer = true
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.usesSingleLineMode = true
|
||||
self.delegate = self
|
||||
|
||||
// Default to natural layout
|
||||
self.alignment = .natural
|
||||
|
||||
self.createFloatingLabel()
|
||||
|
||||
self.heightConstraint = NSLayoutConstraint(
|
||||
item: self, attribute: .height,
|
||||
relatedBy: .equal,
|
||||
toItem: nil, attribute: .notAnAttribute,
|
||||
multiplier: 1.0, constant: self.controlHeight
|
||||
)
|
||||
self.addConstraint(self.heightConstraint!)
|
||||
|
||||
// If the field already has text, make sure the placeholder is shown
|
||||
if self.stringValue.count > 0 {
|
||||
self.showPlaceholder(animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Change the layout if any changes occur
|
||||
private func reconfigureControl() {
|
||||
if self.isCurrentFocus() {
|
||||
/// If we are currently editing, then finish before changing.
|
||||
self.window?.endEditing(for: nil)
|
||||
}
|
||||
self.expandFrame()
|
||||
}
|
||||
|
||||
/// Rebuild the frame of the text field to match the new settings
|
||||
private func expandFrame() {
|
||||
self.heightConstraint?.constant = self.controlHeight
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
open override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.setTopOffset(self.placeholderHeight + self.placeholderSpacing)
|
||||
self.needsLayout = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Focus and editing
|
||||
|
||||
extension DSFFloatLabelled${field_type}Field: NSTextFieldDelegate {
|
||||
|
||||
// Change the floating label color to represent active state
|
||||
private func setFloatingLabelActive(_ active: Bool) {
|
||||
if active {
|
||||
self.floatingLabel.textColor = NSColor.simulatedAccentColor
|
||||
}
|
||||
else {
|
||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextField?(self, didFocus: active)
|
||||
}
|
||||
|
||||
public func controlTextDidChange(_ obj: Notification) {
|
||||
guard let field = obj.object as? NSTextField else {
|
||||
return
|
||||
}
|
||||
|
||||
if field.stringValue.count > 0, !self.isShowing {
|
||||
self.showPlaceholder(animated: true)
|
||||
}
|
||||
else if field.stringValue.count == 0, self.isShowing {
|
||||
self.hidePlaceholder()
|
||||
}
|
||||
|
||||
self.floatLabelDelegate?.floatLabelledTextFieldContentChanged?(self)
|
||||
}
|
||||
|
||||
open override func becomeFirstResponder() -> Bool {
|
||||
let becomeResult = super.becomeFirstResponder()
|
||||
if becomeResult, self.isCurrentFocus() {
|
||||
// Set the color of the 'label' to match the current focus color.
|
||||
// We need to perform this on the main thread after the current set of notifications are processed
|
||||
// Why? We (occasionally) receive a 'controlTextDidEndEditing' message AFTER we receive a
|
||||
// 'becomeFirstResponder'. I've read that this is related to the text field automatically selecting
|
||||
// text when taking focus, but I haven't been able to verify this in any useful manner.
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
if let `self` = self {
|
||||
self.setFloatingLabelActive(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return becomeResult
|
||||
}
|
||||
|
||||
open func controlTextDidEndEditing(_: Notification) {
|
||||
// When we lose focus, set the label color back to the placeholder color
|
||||
self.setFloatingLabelActive(false)
|
||||
}
|
||||
|
||||
/// Does our text field currently have input focus?
|
||||
private func isCurrentFocus() -> Bool {
|
||||
// 1. Get the window's first responder
|
||||
// 2. Check is has an active field editor
|
||||
// 3. Is the delegate of the field editor us?
|
||||
if let fr = self.window?.firstResponder as? NSTextView,
|
||||
self.window?.fieldEditor(false, for: nil) != nil,
|
||||
fr.delegate === self {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Animations
|
||||
|
||||
extension DSFFloatLabelled${field_type}Field {
|
||||
|
||||
/// Duration of the fade in/out of the secondary label
|
||||
private var animationDuration: TimeInterval {
|
||||
return shouldAnimate() ? 0.4 : 0.0
|
||||
}
|
||||
|
||||
/// Returns true if the system is NOT set to reduce motion (accessibility settings)
|
||||
private func shouldAnimate() -> Bool {
|
||||
if #available(OSX 10.12, *) {
|
||||
return !NSWorkspace.shared.accessibilityDisplayShouldReduceMotion
|
||||
} else {
|
||||
// Fallback on earlier versions. Just animate
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private func showPlaceholder(animated: Bool) {
|
||||
self.isShowing = true
|
||||
if animated {
|
||||
NSAnimationContext.runAnimationGroup({ [weak self] context in
|
||||
guard let `self` = self else { return }
|
||||
context.allowsImplicitAnimation = true
|
||||
context.duration = self.animationDuration
|
||||
self.floatingTop?.constant = 0
|
||||
self.floatingLabel.alphaValue = 1.0
|
||||
self.layoutSubtreeIfNeeded()
|
||||
}, completionHandler: {
|
||||
//
|
||||
})
|
||||
}
|
||||
else {
|
||||
self.setFloatingLabelActive(false)
|
||||
self.floatingTop?.constant = 0
|
||||
self.floatingLabel.alphaValue = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
private func hidePlaceholder() {
|
||||
self.isShowing = false
|
||||
let duration = self.animationDuration
|
||||
NSAnimationContext.runAnimationGroup({ [weak self] context in
|
||||
guard let `self` = self else { return }
|
||||
context.allowsImplicitAnimation = true
|
||||
context.duration = duration
|
||||
self.floatingTop?.constant = self.textHeight / 1.5
|
||||
self.floatingLabel.alphaValue = 0.0
|
||||
self.layoutSubtreeIfNeeded()
|
||||
}, completionHandler: {
|
||||
//
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Cell definition
|
||||
|
||||
private class DSFFloatLabelled${field_type}FieldCell: NS${field_type}FieldCell, DSFFloatLabelledTextFieldCellProtocol {
|
||||
var topOffset: CGFloat = 0
|
||||
|
||||
private func offset() -> CGFloat {
|
||||
return self.topOffset - (self.isBezeled ? 5 : 1)
|
||||
}
|
||||
|
||||
override func titleRect(forBounds rect: NSRect) -> NSRect {
|
||||
return NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
}
|
||||
|
||||
override func edit(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) {
|
||||
let insetRect = NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
super.edit(withFrame: insetRect, in: controlView, editor: textObj, delegate: delegate, event: event)
|
||||
}
|
||||
|
||||
override func select(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) {
|
||||
let insetRect = NSRect(x: rect.origin.x, y: rect.origin.y + self.offset(), width: rect.width, height: rect.height)
|
||||
super.select(withFrame: insetRect, in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
|
||||
}
|
||||
|
||||
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
|
||||
let insetRect = NSRect(x: cellFrame.origin.x, y: cellFrame.origin.y + self.offset(), width: cellFrame.width, height: cellFrame.height)
|
||||
super.drawInterior(withFrame: insetRect, in: controlView)
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Darren Ford. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// utils.swift
|
||||
//
|
||||
// Copyright © 2023 Darren Ford. All rights reserved.
|
||||
//
|
||||
// MIT license
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AppKit
|
||||
|
||||
protocol DSFFloatLabelledTextFieldCellProtocol {
|
||||
var topOffset: CGFloat { get set }
|
||||
}
|
||||
|
||||
extension NSColor {
|
||||
/// A backwards compatible `controlAccentColor`
|
||||
@inlinable static var simulatedAccentColor: NSColor {
|
||||
if #available(macOS 10.14, *) {
|
||||
// macOS 10.14 and above have a dedicated static NSColor
|
||||
return NSColor.controlAccentColor
|
||||
}
|
||||
else {
|
||||
// Just use the menu highlight color - there's no concept of 'accent' color pre 10.14
|
||||
return NSColor.selectedMenuItemColor
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
# A script to re-build the text field sources from the source template file
|
||||
|
||||
# Stop on error
|
||||
set -e
|
||||
|
||||
# The path where this script resides
|
||||
script_path="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||
|
||||
# The path for the package (one level up)
|
||||
package_path="$( cd -- "${script_path}/../" >/dev/null 2>&1 ; pwd -P )"
|
||||
|
||||
pushd .
|
||||
|
||||
# We have to run docbuild in the root of the source package
|
||||
cd "${package_path}"
|
||||
|
||||
# Generate the NSTextField implementation
|
||||
python3 ${script_path}/gyb --line-directive '' -D field_type="Text" -o "DSFFloatLabelledTextField.swift" "Sources/DSFFloatLabelledTextField/DSFFloatLabelledTextField.swift.gyb"
|
||||
# Generate the NSSecureTextField implementation
|
||||
python3 ${script_path}/gyb --line-directive '' -D field_type="SecureText" -o "DSFFloatLabelledSecureTextField.swift" "Sources/DSFFloatLabelledTextField/DSFFloatLabelledTextField.swift.gyb"
|
||||
|
||||
popd
|
||||
|
||||
echo "Done!"
|
Loading…
Reference in New Issue