First cut refactor secure
This commit is contained in:
parent
35523f5ec7
commit
344eab8512
|
@ -1,3 +1,4 @@
|
||||||
DSFFloatLabelledTextControls.xcodeproj/xcuserdata
|
DSFFloatLabelledTextControls.xcodeproj/xcuserdata
|
||||||
xcschememanagement.plist
|
xcschememanagement.plist
|
||||||
.swiftpm
|
.swiftpm
|
||||||
|
Demos/DSFFloatLabelledTextControls.xcodeproj/xcuserdata
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "DSFFloatLabelledTextControl"
|
s.name = "DSFFloatLabelledTextControl"
|
||||||
s.version = "1.8.0"
|
s.version = "1.8.0"
|
||||||
s.summary = "A macOS Cocoa single-line NSTextField that implements the Float Label Pattern"
|
s.summary = "A macOS Cocoa single-line NSTextField/NSSecureTextField that implements the Float Label Pattern"
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
A macOS Cocoa single-line NSTextField that implements the Float Label Pattern. Supports secure edit fields.
|
A macOS Cocoa single-line NSTextField/NSSecureTextField that implements the Float Label Pattern.
|
||||||
DESC
|
DESC
|
||||||
s.homepage = "https://github.com/dagronf/DSFFloatLabelledTextControl"
|
s.homepage = "https://github.com/dagronf/DSFFloatLabelledTextControl"
|
||||||
s.license = { :type => "MIT", :file => "LICENSE" }
|
s.license = { :type => "MIT", :file => "LICENSE" }
|
||||||
|
@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
||||||
s.social_media_url = ""
|
s.social_media_url = ""
|
||||||
s.osx.deployment_target = "10.11"
|
s.osx.deployment_target = "10.11"
|
||||||
s.source = { :git => ".git", :tag => s.version.to_s }
|
s.source = { :git => ".git", :tag => s.version.to_s }
|
||||||
s.source_files = "DSFFloatLabelledTextControl/DSFFloatLabelledTextField.swift"
|
s.source_files = "Sources/DSFFloatLabelledTextControl/*.swift"
|
||||||
s.frameworks = "Cocoa"
|
s.frameworks = "Cocoa"
|
||||||
s.swift_version = "5.0"
|
s.swift_version = "5.4"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,57 +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>All.xcscheme_^#shared#^_</key>
|
|
||||||
<dict>
|
|
||||||
<key>orderHint</key>
|
|
||||||
<integer>4</integer>
|
|
||||||
</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>3</integer>
|
|
||||||
</dict>
|
|
||||||
<key>DSFFloatLabelledTextControls RTL.xcscheme_^#shared#^_</key>
|
|
||||||
<dict>
|
|
||||||
<key>orderHint</key>
|
|
||||||
<integer>1</integer>
|
|
||||||
</dict>
|
|
||||||
<key>DSFFloatLabelledTextControls.xcscheme_^#shared#^_</key>
|
|
||||||
<dict>
|
|
||||||
<key>orderHint</key>
|
|
||||||
<integer>0</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,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 50;
|
objectVersion = 52;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXAggregateTarget section */
|
/* Begin PBXAggregateTarget section */
|
||||||
|
@ -22,38 +22,18 @@
|
||||||
/* End PBXAggregateTarget section */
|
/* End PBXAggregateTarget section */
|
||||||
|
|
||||||
/* Begin PBXBuildFile 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 */; };
|
23A2B7ED220792FE00B2FC77 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A2B7EC220792FE00B2FC77 /* AppDelegate.swift */; };
|
||||||
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23A2B7EE220792FF00B2FC77 /* Assets.xcassets */; };
|
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23A2B7EE220792FF00B2FC77 /* Assets.xcassets */; };
|
||||||
23A2B7F2220792FF00B2FC77 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 23A2B7F0220792FF00B2FC77 /* MainMenu.xib */; };
|
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 */; };
|
23C3AB9E23FBCFA30079D9C3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 23C3AB9D23FBCFA30079D9C3 /* AppDelegate.m */; };
|
||||||
23C3ABA023FBCFA40079D9C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23C3AB9F23FBCFA40079D9C3 /* Assets.xcassets */; };
|
23C3ABA023FBCFA40079D9C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 23C3AB9F23FBCFA40079D9C3 /* Assets.xcassets */; };
|
||||||
23C3ABA323FBCFA40079D9C3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 23C3ABA123FBCFA40079D9C3 /* MainMenu.xib */; };
|
23C3ABA323FBCFA40079D9C3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 23C3ABA123FBCFA40079D9C3 /* MainMenu.xib */; };
|
||||||
23C3ABA623FBCFA40079D9C3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 23C3ABA523FBCFA40079D9C3 /* main.m */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
2351F8502207D15C00EFA4F7 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 2351F84A2207D15C00EFA4F7;
|
|
||||||
remoteInfo = DSFFloatLabelledTextControl;
|
|
||||||
};
|
|
||||||
23C3ABAD23FBCFE40079D9C3 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 2351F84A2207D15C00EFA4F7;
|
|
||||||
remoteInfo = DSFFloatLabelledTextField;
|
|
||||||
};
|
|
||||||
23E825672575D17E0023A3C7 /* PBXContainerItemProxy */ = {
|
23E825672575D17E0023A3C7 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
containerPortal = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
||||||
|
@ -77,7 +57,6 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
2351F8532207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Embed Frameworks */,
|
|
||||||
);
|
);
|
||||||
name = "Embed Frameworks";
|
name = "Embed Frameworks";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -88,26 +67,19 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
23C3ABB023FBD0F80079D9C3 /* DSFFloatLabelledTextField.framework in CopyFiles */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference 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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
23A3061A29C12C9C00BEC98A /* DSFFloatLabelledTextControls */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DSFFloatLabelledTextControls; path = ..; sourceTree = "<group>"; };
|
||||||
23ACF96D228A3F6600FF6594 /* DSFFloatLabelledTextControl.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = DSFFloatLabelledTextControl.podspec; sourceTree = "<group>"; };
|
|
||||||
23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DSFFloatLabelledTextControls Demo objc.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
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>"; };
|
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>"; };
|
23C3AB9D23FBCFA30079D9C3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||||
|
@ -117,22 +89,14 @@
|
||||||
23C3ABA523FBCFA40079D9C3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; 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>"; };
|
23C3ABA723FBCFA40079D9C3 /* DSFFloatLabelledTextControls_Demo_objc.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DSFFloatLabelledTextControls_Demo_objc.entitlements; sourceTree = "<group>"; };
|
||||||
23E8256D2575D28A0023A3C7 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
23E8256D2575D28A0023A3C7 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||||
23FFF1CD23BD490F008FA55A /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
2351F8482207D15C00EFA4F7 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
23A2B7E6220792FE00B2FC77 /* Frameworks */ = {
|
23A2B7E6220792FE00B2FC77 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
2351F8522207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework in Frameworks */,
|
23A3061C29C12CB200BEC98A /* DSFFloatLabelledTextField in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -140,32 +104,18 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
23C3ABAC23FBCFDE0079D9C3 /* DSFFloatLabelledTextField.framework in Frameworks */,
|
23A3061E29C12CB800BEC98A /* DSFFloatLabelledTextField in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
2351F84C2207D15C00EFA4F7 /* DSFFloatLabelledTextField */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
23A2B7FA2207931500B2FC77 /* DSFFloatLabelledTextField.swift */,
|
|
||||||
2351F84D2207D15C00EFA4F7 /* DSFFloatLabelledTextControl.h */,
|
|
||||||
2351F84E2207D15C00EFA4F7 /* Info.plist */,
|
|
||||||
);
|
|
||||||
path = DSFFloatLabelledTextField;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
23A2B7E0220792FE00B2FC77 = {
|
23A2B7E0220792FE00B2FC77 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
23A3061A29C12C9C00BEC98A /* DSFFloatLabelledTextControls */,
|
||||||
23FFF1CF23BD4982008FA55A /* Demos */,
|
23FFF1CF23BD4982008FA55A /* Demos */,
|
||||||
23FFF1CE23BD496A008FA55A /* Sources */,
|
|
||||||
23ACF96D228A3F6600FF6594 /* DSFFloatLabelledTextControl.podspec */,
|
|
||||||
2351F85922082AD800EFA4F7 /* LICENSE */,
|
|
||||||
2351F85A22082AD800EFA4F7 /* README.md */,
|
|
||||||
23FFF1CD23BD490F008FA55A /* Package.swift */,
|
|
||||||
23A2B7EA220792FE00B2FC77 /* Products */,
|
23A2B7EA220792FE00B2FC77 /* Products */,
|
||||||
23C3ABAB23FBCFDE0079D9C3 /* Frameworks */,
|
23C3ABAB23FBCFDE0079D9C3 /* Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -175,7 +125,6 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */,
|
23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */,
|
||||||
2351F84B2207D15C00EFA4F7 /* DSFFloatLabelledTextField.framework */,
|
|
||||||
23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */,
|
23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
|
@ -214,14 +163,6 @@
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
23FFF1CE23BD496A008FA55A /* Sources */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
2351F84C2207D15C00EFA4F7 /* DSFFloatLabelledTextField */,
|
|
||||||
);
|
|
||||||
path = Sources;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
23FFF1CF23BD4982008FA55A /* Demos */ = {
|
23FFF1CF23BD4982008FA55A /* Demos */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -233,36 +174,7 @@
|
||||||
};
|
};
|
||||||
/* End PBXGroup section */
|
/* 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 */
|
/* 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 */ = {
|
23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 23A2B7F7220792FF00B2FC77 /* Build configuration list for PBXNativeTarget "DSFFloatLabelledTextControls" */;
|
buildConfigurationList = 23A2B7F7220792FF00B2FC77 /* Build configuration list for PBXNativeTarget "DSFFloatLabelledTextControls" */;
|
||||||
|
@ -275,9 +187,11 @@
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
2351F8512207D15C00EFA4F7 /* PBXTargetDependency */,
|
|
||||||
);
|
);
|
||||||
name = DSFFloatLabelledTextControls;
|
name = DSFFloatLabelledTextControls;
|
||||||
|
packageProductDependencies = (
|
||||||
|
23A3061B29C12CB200BEC98A /* DSFFloatLabelledTextField */,
|
||||||
|
);
|
||||||
productName = DSFFloatLabelledTextControls;
|
productName = DSFFloatLabelledTextControls;
|
||||||
productReference = 23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */;
|
productReference = 23A2B7E9220792FE00B2FC77 /* DSFFloatLabelledTextControls.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
|
@ -294,9 +208,11 @@
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
23C3ABAE23FBCFE40079D9C3 /* PBXTargetDependency */,
|
|
||||||
);
|
);
|
||||||
name = "DSFFloatLabelledTextControls Demo objc";
|
name = "DSFFloatLabelledTextControls Demo objc";
|
||||||
|
packageProductDependencies = (
|
||||||
|
23A3061D29C12CB800BEC98A /* DSFFloatLabelledTextField */,
|
||||||
|
);
|
||||||
productName = "DSFFloatLabelledTextControls Demo objc";
|
productName = "DSFFloatLabelledTextControls Demo objc";
|
||||||
productReference = 23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */;
|
productReference = 23C3AB9A23FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
|
@ -311,9 +227,6 @@
|
||||||
LastUpgradeCheck = 1010;
|
LastUpgradeCheck = 1010;
|
||||||
ORGANIZATIONNAME = "Darren Ford";
|
ORGANIZATIONNAME = "Darren Ford";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
2351F84A2207D15C00EFA4F7 = {
|
|
||||||
CreatedOnToolsVersion = 10.1;
|
|
||||||
};
|
|
||||||
23A2B7E8220792FE00B2FC77 = {
|
23A2B7E8220792FE00B2FC77 = {
|
||||||
CreatedOnToolsVersion = 10.1;
|
CreatedOnToolsVersion = 10.1;
|
||||||
};
|
};
|
||||||
|
@ -339,7 +252,6 @@
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */,
|
|
||||||
23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */,
|
23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */,
|
||||||
23C3AB9923FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc */,
|
23C3AB9923FBCFA30079D9C3 /* DSFFloatLabelledTextControls Demo objc */,
|
||||||
23E825612575D1760023A3C7 /* All */,
|
23E825612575D1760023A3C7 /* All */,
|
||||||
|
@ -348,20 +260,11 @@
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
2351F8492207D15C00EFA4F7 /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
23A2B7E7220792FE00B2FC77 /* Resources */ = {
|
23A2B7E7220792FE00B2FC77 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
2351F85B22082AD800EFA4F7 /* LICENSE in Resources */,
|
|
||||||
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */,
|
23A2B7EF220792FF00B2FC77 /* Assets.xcassets in Resources */,
|
||||||
2351F85C22082AD800EFA4F7 /* README.md in Resources */,
|
|
||||||
23A2B7F2220792FF00B2FC77 /* MainMenu.xib in Resources */,
|
23A2B7F2220792FF00B2FC77 /* MainMenu.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -378,14 +281,6 @@
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
2351F8472207D15C00EFA4F7 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
2351F8582207D16100EFA4F7 /* DSFFloatLabelledTextField.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
23A2B7E5220792FE00B2FC77 /* Sources */ = {
|
23A2B7E5220792FE00B2FC77 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -406,16 +301,6 @@
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
2351F8512207D15C00EFA4F7 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */;
|
|
||||||
targetProxy = 2351F8502207D15C00EFA4F7 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
23C3ABAE23FBCFE40079D9C3 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
target = 2351F84A2207D15C00EFA4F7 /* DSFFloatLabelledTextField */;
|
|
||||||
targetProxy = 23C3ABAD23FBCFE40079D9C3 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
23E825682575D17E0023A3C7 /* PBXTargetDependency */ = {
|
23E825682575D17E0023A3C7 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */;
|
target = 23A2B7E8220792FE00B2FC77 /* DSFFloatLabelledTextControls */;
|
||||||
|
@ -449,66 +334,6 @@
|
||||||
/* End PBXVariantGroup section */
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration 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 */ = {
|
23A2B7F5220792FF00B2FC77 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -629,7 +454,6 @@
|
||||||
23A2B7F8220792FF00B2FC77 /* Debug */ = {
|
23A2B7F8220792FF00B2FC77 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
||||||
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
||||||
|
@ -642,6 +466,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
MARKETING_VERSION = 1.5;
|
MARKETING_VERSION = 1.5;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -653,7 +478,6 @@
|
||||||
23A2B7F9220792FF00B2FC77 /* Release */ = {
|
23A2B7F9220792FF00B2FC77 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "";
|
||||||
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Demos/DSFFloatLabelledTextControls/DSFFloatLabelledTextControls.entitlements;
|
||||||
|
@ -666,6 +490,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
MARKETING_VERSION = 1.5;
|
MARKETING_VERSION = 1.5;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
PRODUCT_BUNDLE_IDENTIFIER = com.darrenford.DSFFloatLabelledTextControls;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -680,17 +505,17 @@
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
|
@ -702,17 +527,17 @@
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Demos/DSFFloatLabelledTextControls Demo objc/DSFFloatLabelledTextControls_Demo_objc.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = 3L6RK3LGGW;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
INFOPLIST_FILE = "Demos/DSFFloatLabelledTextControls Demo objc/Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.darrenford.DSFFloatLabelledTextControls-Demo-objc";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
|
@ -739,15 +564,6 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList 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" */ = {
|
23A2B7E4220792FE00B2FC77 /* Build configuration list for PBXProject "DSFFloatLabelledTextControls" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
@ -785,6 +601,17 @@
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* 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 */;
|
rootObject = 23A2B7E1220792FE00B2FC77 /* Project object */;
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@
|
||||||
// Insert code here to tear down your application
|
// Insert code here to tear down your application
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)floatLabelledTextFieldContentChanged:(DSFFloatLabelledTextField *)field {
|
- (void)floatLabelledTextFieldContentChanged:(DSFFloatLabelledSecureTextField *)field {
|
||||||
NSLog(@"Password is now `%@`", field.stringValue);
|
NSLog(@"Password is now `%@`", field.stringValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" 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>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -692,7 +692,7 @@
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="249.99998474121094" ambiguous="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Xn-w2-ecV">
|
<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"/>
|
<rect key="frame" x="20" y="27" width="440" height="98"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XPK-cR-iSb" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="24"/>
|
||||||
|
@ -705,7 +705,7 @@
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5uu-Hi-xn8" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="18"/>
|
||||||
|
@ -718,7 +718,7 @@
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="257-gt-5Ui" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="18"/>
|
||||||
|
@ -729,7 +729,6 @@
|
||||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
<userDefinedRuntimeAttribute type="number" keyPath="placeholderTextSize">
|
||||||
<real key="value" value="13"/>
|
<real key="value" value="13"/>
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
<userDefinedRuntimeAttribute type="boolean" keyPath="isSecure" value="YES"/>
|
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="fDf-Y2-VaF"/>
|
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="fDf-Y2-VaF"/>
|
|
@ -35,6 +35,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
@IBOutlet weak var window: NSWindow!
|
@IBOutlet weak var window: NSWindow!
|
||||||
@IBOutlet weak var topFloatingLabel: DSFFloatLabelledTextField!
|
@IBOutlet weak var topFloatingLabel: DSFFloatLabelledTextField!
|
||||||
|
|
||||||
|
@IBOutlet weak var secureTextField: DSFFloatLabelledSecureTextField!
|
||||||
@IBOutlet weak var passwordFloatingLabel: DSFFloatLabelledTextField!
|
@IBOutlet weak var passwordFloatingLabel: DSFFloatLabelledTextField!
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
|
@ -47,26 +48,34 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
let cv = self.window.contentView!
|
let cv = self.window.contentView!
|
||||||
|
|
||||||
let x = NSLayoutConstraint(item: ft, attribute: .width,
|
let x = NSLayoutConstraint(
|
||||||
|
item: ft, attribute: .width,
|
||||||
relatedBy: .equal,
|
relatedBy: .equal,
|
||||||
toItem: nil, attribute: .notAnAttribute,
|
toItem: nil, attribute: .notAnAttribute,
|
||||||
multiplier: 1, constant: 300)
|
multiplier: 1, constant: 300
|
||||||
|
)
|
||||||
ft.addConstraint(x)
|
ft.addConstraint(x)
|
||||||
cv.addSubview(ft)
|
cv.addSubview(ft)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let x1 = NSLayoutConstraint(item: ft, attribute: .left,
|
let x1 = NSLayoutConstraint(
|
||||||
|
item: ft, attribute: .leading,
|
||||||
relatedBy: .equal,
|
relatedBy: .equal,
|
||||||
toItem: cv, attribute: .left,
|
toItem: cv, attribute: .leading,
|
||||||
multiplier: 1, constant: 20)
|
multiplier: 1, constant: 20
|
||||||
|
)
|
||||||
cv.addConstraint(x1)
|
cv.addConstraint(x1)
|
||||||
|
|
||||||
let x2 = NSLayoutConstraint(item: ft, attribute: .bottom,
|
let x2 = NSLayoutConstraint(
|
||||||
|
item: ft, attribute: .bottom,
|
||||||
relatedBy: .equal,
|
relatedBy: .equal,
|
||||||
toItem: cv, attribute: .bottom,
|
toItem: cv, attribute: .bottom,
|
||||||
multiplier: 1, constant: -20)
|
multiplier: 1, constant: -20
|
||||||
|
)
|
||||||
cv.addConstraint(x2)
|
cv.addConstraint(x2)
|
||||||
|
|
||||||
|
self.secureTextField.stringValue = "caterpillar"
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func resetPressed(_ sender: Any) {
|
@IBAction func resetPressed(_ sender: Any) {
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" 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>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="DSFFloatLabelledTextControls" customModuleProvider="target">
|
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="DSFFloatLabelledTextControls" customModuleProvider="target">
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="passwordFloatingLabel" destination="VLP-0u-Kf3" id="9Lw-el-n78"/>
|
<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="topFloatingLabel" destination="tnz-85-NdV" id="Pyt-zO-up9"/>
|
||||||
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
@ -686,19 +687,19 @@
|
||||||
<window title="Floating Labels Test" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
<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"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="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="contentRect" x="335" y="390" width="497" height="592"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="497" height="491"/>
|
<rect key="frame" x="0.0" y="0.0" width="497" height="592"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<box boxType="secondary" title="Purchase Form" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="pnz-8U-z2F">
|
<box boxType="secondary" title="Purchase Form" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="pnz-8U-z2F">
|
||||||
<rect key="frame" x="17" y="333" width="463" height="140"/>
|
<rect key="frame" x="17" y="432" width="463" height="142"/>
|
||||||
<view key="contentView" id="fUJ-lp-O9s">
|
<view key="contentView" ambiguous="YES" id="fUJ-lp-O9s">
|
||||||
<rect key="frame" x="3" y="3" width="457" height="134"/>
|
<rect key="frame" x="4" y="5" width="455" height="134"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="tnz-85-NdV" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="18"/>
|
||||||
|
@ -714,7 +715,7 @@
|
||||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="62z-Xl-apm"/>
|
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="62z-Xl-apm"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<button toolTip="Check for programattic changing of stringValue" horizontalHuggingPriority="999" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nTi-Ym-3BC">
|
<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"/>
|
<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">
|
<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"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
@ -724,7 +725,7 @@
|
||||||
<action selector="resetPressed:" target="Voe-Tx-rLC" id="keN-c6-1wD"/>
|
<action selector="resetPressed:" target="Voe-Tx-rLC" id="keN-c6-1wD"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</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"/>
|
<rect key="frame" x="12" y="86" width="437" height="5"/>
|
||||||
</box>
|
</box>
|
||||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="zbB-HI-AVu" userLabel="Price Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="zbB-HI-AVu" userLabel="Price Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||||
|
@ -746,7 +747,7 @@
|
||||||
<box horizontalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Mrp-MT-gGa">
|
<box horizontalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Mrp-MT-gGa">
|
||||||
<rect key="frame" x="117" y="46" width="5" height="43"/>
|
<rect key="frame" x="117" y="46" width="5" height="43"/>
|
||||||
</box>
|
</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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="18"/>
|
||||||
|
@ -759,10 +760,10 @@
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</textField>
|
</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"/>
|
<rect key="frame" x="12" y="44" width="437" height="5"/>
|
||||||
</box>
|
</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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="18"/>
|
||||||
|
@ -804,10 +805,10 @@
|
||||||
</view>
|
</view>
|
||||||
</box>
|
</box>
|
||||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="CVr-p8-VOx">
|
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="CVr-p8-VOx">
|
||||||
<rect key="frame" x="20" y="303" width="457" height="5"/>
|
<rect key="frame" x="20" y="402" width="457" height="5"/>
|
||||||
</box>
|
</box>
|
||||||
<stackView distribution="fillEqually" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="waN-7O-qLn">
|
<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="242" width="457" height="33"/>
|
<rect key="frame" x="20" y="341" width="457" height="33"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="50" verticalHuggingPriority="750" horizontalCompressionResistancePriority="500" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="oU9-jl-8Ow" userLabel="Title Field" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<rect key="frame" x="0.0" y="0.0" width="50" height="33"/>
|
||||||
|
@ -852,10 +853,10 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="QuB-jf-wmu">
|
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="QuB-jf-wmu">
|
||||||
<rect key="frame" x="20" y="206" width="457" height="5"/>
|
<rect key="frame" x="20" y="305" width="457" height="5"/>
|
||||||
</box>
|
</box>
|
||||||
<stackView distribution="fillEqually" orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CBs-1o-JjM">
|
<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="112"/>
|
<rect key="frame" x="20" y="179" width="250" height="112"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3hp-BV-Ls3" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3hp-BV-Ls3" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
||||||
<rect key="frame" x="0.0" y="90" width="250" height="22"/>
|
<rect key="frame" x="0.0" y="90" width="250" height="22"/>
|
||||||
|
@ -873,7 +874,7 @@
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VLP-0u-Kf3" customClass="DSFFloatLabelledTextField" customModule="DSFFloatLabelledTextField">
|
<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"/>
|
<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">
|
<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"/>
|
<font key="font" metaFont="system" size="14"/>
|
||||||
|
@ -887,7 +888,6 @@
|
||||||
<userDefinedRuntimeAttribute type="number" keyPath="placeholderSpacing">
|
<userDefinedRuntimeAttribute type="number" keyPath="placeholderSpacing">
|
||||||
<real key="value" value="1"/>
|
<real key="value" value="1"/>
|
||||||
</userDefinedRuntimeAttribute>
|
</userDefinedRuntimeAttribute>
|
||||||
<userDefinedRuntimeAttribute type="boolean" keyPath="isSecure" value="YES"/>
|
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="IaQ-aC-gRR"/>
|
<outlet property="floatLabelDelegate" destination="Voe-Tx-rLC" id="IaQ-aC-gRR"/>
|
||||||
|
@ -971,7 +971,7 @@
|
||||||
<constraint firstItem="pnz-8U-z2F" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="zgF-Fx-OjE"/>
|
<constraint firstItem="pnz-8U-z2F" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="zgF-Fx-OjE"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<point key="canvasLocation" x="-480" y="220"/>
|
<point key="canvasLocation" x="-480.5" y="144"/>
|
||||||
</window>
|
</window>
|
||||||
</objects>
|
</objects>
|
||||||
</document>
|
</document>
|
|
@ -1,5 +1,4 @@
|
||||||
// swift-tools-version:5.1
|
// swift-tools-version: 5.4
|
||||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
|
||||||
|
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
|
@ -9,21 +8,16 @@ let package = Package(
|
||||||
.macOS(.v10_11)
|
.macOS(.v10_11)
|
||||||
],
|
],
|
||||||
products: [
|
products: [
|
||||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
|
||||||
.library(
|
.library(
|
||||||
name: "DSFFloatLabelledTextField",
|
name: "DSFFloatLabelledTextField",
|
||||||
targets: ["DSFFloatLabelledTextField"]),
|
targets: ["DSFFloatLabelledTextField"]
|
||||||
],
|
),
|
||||||
dependencies: [
|
|
||||||
// Dependencies declare other packages that this package depends on.
|
|
||||||
// .package(url: /* package url */, from: "1.0.0"),
|
|
||||||
],
|
],
|
||||||
targets: [
|
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(
|
.target(
|
||||||
name: "DSFFloatLabelledTextField",
|
name: "DSFFloatLabelledTextField",
|
||||||
dependencies: [])
|
dependencies: []
|
||||||
|
)
|
||||||
],
|
],
|
||||||
swiftLanguageVersions: [.v5]
|
swiftLanguageVersions: [.v5]
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,10 +30,10 @@ Copy the `DSFFloatLabelledTextField.swift` into your project. This class inheri
|
||||||
|
|
||||||
### Interface builder
|
### 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 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
|
* Set the size of the secondary font via the attributes inspector for the control
|
||||||
* If you want a secure field, set the `isSecure` property on the control
|
|
||||||
|
|
||||||
### Dynamically
|
### Dynamically
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ You can specify a delegate (`floatLabelDelegate`), either programatically or via
|
||||||
```
|
```
|
||||||
MIT 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -0,0 +1,451 @@
|
||||||
|
//
|
||||||
|
// DSFFloatLabelledSecureTextField.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 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 awakeFromNib() {
|
||||||
|
super.awakeFromNib()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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,31 +1,30 @@
|
||||||
//
|
//
|
||||||
// DSFFloatLabelledTextField.swift
|
// DSFFloatLabelledTextField.swift
|
||||||
// DSFFloatLabelledTextControls
|
|
||||||
//
|
//
|
||||||
// Created by Darren Ford on 4/2/19.
|
// Copyright © 2023 Darren Ford. All rights reserved.
|
||||||
// Copyright © 2020 Darren Ford. All rights reserved.
|
|
||||||
//
|
//
|
||||||
// MIT License
|
// MIT license
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
// in the Software without restriction, including without limitation the rights
|
// to deal in the Software without restriction, including without limitation
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
// furnished to do so, subject to the following conditions:
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
//
|
//
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
// The above copyright notice and this permission notice shall be included in
|
||||||
// copies or substantial portions of the Software.
|
// all copies or substantial portions of the Software.
|
||||||
//
|
//
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
import Cocoa
|
import AppKit
|
||||||
|
|
||||||
/// DSFFloatLabelledTextField delegate protocol
|
/// DSFFloatLabelledTextField delegate protocol
|
||||||
@objc public protocol DSFFloatLabelledTextFieldDelegate: NSObjectProtocol {
|
@objc public protocol DSFFloatLabelledTextFieldDelegate: NSObjectProtocol {
|
||||||
|
@ -61,13 +60,6 @@ import Cocoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spacing between the floating label and the text field text
|
|
||||||
@IBInspectable public var isSecure: Bool = false {
|
|
||||||
didSet {
|
|
||||||
self.configureCell(isSecure: self.isSecure)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override so that we can notify when the developer changes the text programatically too
|
// Override so that we can notify when the developer changes the text programatically too
|
||||||
open override var stringValue: String {
|
open override var stringValue: String {
|
||||||
get {
|
get {
|
||||||
|
@ -133,8 +125,8 @@ import Cocoa
|
||||||
return sz
|
return sz
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureCell(isSecure: Bool = false) {
|
func configureCell() {
|
||||||
let customCell: NSTextFieldCell = isSecure ? DSFFloatLabelledSecureTextFieldCell() : DSFFloatLabelledTextFieldCell()
|
let customCell = DSFFloatLabelledTextFieldCell()
|
||||||
customCell.isEditable = true
|
customCell.isEditable = true
|
||||||
customCell.wraps = false
|
customCell.wraps = false
|
||||||
customCell.usesSingleLineMode = true
|
customCell.usesSingleLineMode = true
|
||||||
|
@ -148,10 +140,7 @@ import Cocoa
|
||||||
customCell.isContinuous = self.isContinuous
|
customCell.isContinuous = self.isContinuous
|
||||||
customCell.alignment = self.alignment
|
customCell.alignment = self.alignment
|
||||||
customCell.formatter = self.formatter
|
customCell.formatter = self.formatter
|
||||||
|
customCell.topOffset = self.placeholderHeight
|
||||||
if var s = customCell as? DSFFloatLabelledTextFieldCellProtocol {
|
|
||||||
s.topOffset = self.placeholderHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cell = customCell
|
self.cell = customCell
|
||||||
}
|
}
|
||||||
|
@ -192,7 +181,7 @@ import Cocoa
|
||||||
self.commonSetup()
|
self.commonSetup()
|
||||||
|
|
||||||
// Configure a default text cell
|
// Configure a default text cell
|
||||||
self.configureCell(isSecure: false)
|
self.configureCell()
|
||||||
|
|
||||||
// Listen to changes in the primary font so we can reconfigure to match
|
// Listen to changes in the primary font so we can reconfigure to match
|
||||||
self.fontObserver = self.observe(\.font, options: [.new]) { [weak self] _, _ in
|
self.fontObserver = self.observe(\.font, options: [.new]) { [weak self] _, _ in
|
||||||
|
@ -312,7 +301,7 @@ extension DSFFloatLabelledTextField: NSTextFieldDelegate {
|
||||||
// Change the floating label color to represent active state
|
// Change the floating label color to represent active state
|
||||||
private func setFloatingLabelActive(_ active: Bool) {
|
private func setFloatingLabelActive(_ active: Bool) {
|
||||||
if active {
|
if active {
|
||||||
self.floatingLabel.textColor = NSColor.systemAccentColor
|
self.floatingLabel.textColor = NSColor.simulatedAccentColor
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
self.floatingLabel.textColor = NSColor.placeholderTextColor
|
||||||
|
@ -430,10 +419,6 @@ extension DSFFloatLabelledTextField {
|
||||||
|
|
||||||
// MARK: - Cell definition
|
// MARK: - Cell definition
|
||||||
|
|
||||||
protocol DSFFloatLabelledTextFieldCellProtocol {
|
|
||||||
var topOffset: CGFloat { get set }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DSFFloatLabelledTextFieldCell: NSTextFieldCell, DSFFloatLabelledTextFieldCellProtocol {
|
private class DSFFloatLabelledTextFieldCell: NSTextFieldCell, DSFFloatLabelledTextFieldCellProtocol {
|
||||||
var topOffset: CGFloat = 0
|
var topOffset: CGFloat = 0
|
||||||
|
|
||||||
|
@ -460,76 +445,3 @@ private class DSFFloatLabelledTextFieldCell: NSTextFieldCell, DSFFloatLabelledTe
|
||||||
super.drawInterior(withFrame: insetRect, in: controlView)
|
super.drawInterior(withFrame: insetRect, in: controlView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// MARK: - Utilities
|
|
||||||
|
|
||||||
fileprivate let kAccentColor: String = "AppleAccentColor"
|
|
||||||
fileprivate extension NSColor {
|
|
||||||
|
|
||||||
/// The system accent color, with fallbacks for older macOS versions
|
|
||||||
static var systemAccentColor: NSColor {
|
|
||||||
if #available(OSX 10.14, *) {
|
|
||||||
// macOS 10.14 and above have a dedicated static NSColor
|
|
||||||
return NSColor.controlAccentColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use standard user defaults for anything lower than 10.14
|
|
||||||
let userDefaults = UserDefaults.standard
|
|
||||||
guard userDefaults.object(forKey: kAccentColor) != nil else {
|
|
||||||
return DefaultColor()
|
|
||||||
}
|
|
||||||
|
|
||||||
return ColorForSystemColorOffset(userDefaults.integer(forKey: kAccentColor))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map an integer value to a system color
|
|
||||||
static func ColorForSystemColorOffset(_ value: Int) -> NSColor {
|
|
||||||
switch value {
|
|
||||||
case -1: return NSColor.systemGray
|
|
||||||
case 0: return NSColor.systemRed
|
|
||||||
case 1: return NSColor.systemOrange
|
|
||||||
case 2: return NSColor.systemYellow
|
|
||||||
case 3: return NSColor.systemGreen
|
|
||||||
case 4: return NSColor.systemBlue
|
|
||||||
case 5: return NSColor.systemPurple
|
|
||||||
case 6: return NSColor.systemPink
|
|
||||||
default: return DefaultColor()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func DefaultColor() -> NSColor {
|
|
||||||
if #available(OSX 11.0, *) {
|
|
||||||
return NSColor.systemGray
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NSColor.systemBlue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue