mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Refactored PasscodeInputFieldNode
This commit is contained in:
parent
d36c7a9fb2
commit
5c80f423bb
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1980,6 +1980,20 @@
|
||||
ReferencedContainer = "container:submodules/OpusBinding/OpusBinding.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "E66DC04E928346B000000000"
|
||||
BuildableName = "libPasscodeInputFieldNode.a"
|
||||
BlueprintName = "PasscodeInputFieldNode"
|
||||
ReferencedContainer = "container:submodules/PasscodeInputFieldNode/PasscodeInputFieldNode.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
|
17
submodules/PasscodeInputFieldNode/BUCK
Normal file
17
submodules/PasscodeInputFieldNode/BUCK
Normal file
@ -0,0 +1,17 @@
|
||||
load("//Config:buck_rule_macros.bzl", "static_library")
|
||||
|
||||
static_library(
|
||||
name = "PasscodeInputFieldNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
deps = [
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit#shared",
|
||||
"//submodules/Display:Display#shared",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/UIKit.framework",
|
||||
],
|
||||
)
|
22
submodules/PasscodeInputFieldNode/Info.plist
Normal file
22
submodules/PasscodeInputFieldNode/Info.plist
Normal file
@ -0,0 +1,22 @@
|
||||
<?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>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,401 @@
|
||||
<?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>archiveVersion</key>
|
||||
<string>1</string>
|
||||
<key>classes</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>objectVersion</key>
|
||||
<string>46</string>
|
||||
<key>objects</key>
|
||||
<dict>
|
||||
<key>1DD70E2954723C0500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode-Debug.xcconfig</string>
|
||||
<key>path</key>
|
||||
<string>../../buck-out/gen/submodules/PasscodeInputFieldNode/PasscodeInputFieldNode-Debug.xcconfig</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>text.xcconfig</string>
|
||||
</dict>
|
||||
<key>1DD70E29E5F5E62F00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode-Profile.xcconfig</string>
|
||||
<key>path</key>
|
||||
<string>../../buck-out/gen/submodules/PasscodeInputFieldNode/PasscodeInputFieldNode-Profile.xcconfig</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>text.xcconfig</string>
|
||||
</dict>
|
||||
<key>1DD70E29598C919100000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode-Release.xcconfig</string>
|
||||
<key>path</key>
|
||||
<string>../../buck-out/gen/submodules/PasscodeInputFieldNode/PasscodeInputFieldNode-Release.xcconfig</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>text.xcconfig</string>
|
||||
</dict>
|
||||
<key>B401C9792F7F325000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>Buck (Do Not Modify)</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>1DD70E2954723C0500000000</string>
|
||||
<string>1DD70E29E5F5E62F00000000</string>
|
||||
<string>1DD70E29598C919100000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>B401C979B781F65D00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>Configurations</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>B401C9792F7F325000000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>1DD70E29FF334B1F00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libDisplay.dylib</string>
|
||||
<key>path</key>
|
||||
<string>libDisplay.dylib</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>compiled.mach-o.dylib</string>
|
||||
</dict>
|
||||
<key>1DD70E29D65BA68200000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libSwiftSignalKit.dylib</string>
|
||||
<key>path</key>
|
||||
<string>libSwiftSignalKit.dylib</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>compiled.mach-o.dylib</string>
|
||||
</dict>
|
||||
<key>B401C97968022A5500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>Frameworks</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>1DD70E29FF334B1F00000000</string>
|
||||
<string>1DD70E29D65BA68200000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>1DD70E29001F47FB00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>BUCK</string>
|
||||
<key>path</key>
|
||||
<string>BUCK</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>text.script.python</string>
|
||||
</dict>
|
||||
<key>1DD70E290BCAAD5500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode.swift</string>
|
||||
<key>path</key>
|
||||
<string>Sources/PasscodeInputFieldNode.swift</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
</dict>
|
||||
<key>B401C979EAB5339800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>Sources</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>1DD70E290BCAAD5500000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>B401C979928346B000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>1DD70E29001F47FB00000000</string>
|
||||
<string>B401C979EAB5339800000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>1DD70E2989A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>path</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>B401C979C806358400000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>Products</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>B401C979EFB6AC4600000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXGroup</string>
|
||||
<key>name</key>
|
||||
<string>mainGroup</string>
|
||||
<key>sourceTree</key>
|
||||
<string><![CDATA[<group>]]></string>
|
||||
<key>children</key>
|
||||
<array>
|
||||
<string>B401C979B781F65D00000000</string>
|
||||
<string>B401C97968022A5500000000</string>
|
||||
<string>B401C979928346B000000000</string>
|
||||
<string>B401C979C806358400000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>E7A30F040BCAAD5500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E290BCAAD5500000000</string>
|
||||
</dict>
|
||||
<key>1870857F0000000000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXSourcesBuildPhase</string>
|
||||
<key>files</key>
|
||||
<array>
|
||||
<string>E7A30F040BCAAD5500000000</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>E7A30F04FF334B1F00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29FF334B1F00000000</string>
|
||||
</dict>
|
||||
<key>E7A30F04D65BA68200000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29D65BA68200000000</string>
|
||||
</dict>
|
||||
<key>FAF5FAC90000000000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXCopyFilesBuildPhase</string>
|
||||
<key>files</key>
|
||||
<array>
|
||||
<string>E7A30F04FF334B1F00000000</string>
|
||||
<string>E7A30F04D65BA68200000000</string>
|
||||
</array>
|
||||
<key>name</key>
|
||||
<string>Fake Swift Dependencies (Copy Files Phase)</string>
|
||||
<key>runOnlyForDeploymentPostprocessing</key>
|
||||
<integer>1</integer>
|
||||
<key>dstSubfolderSpec</key>
|
||||
<integer>16</integer>
|
||||
<key>dstPath</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
<key>4952437303EDA63300000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Debug</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>baseConfigurationReference</key>
|
||||
<string>1DD70E2954723C0500000000</string>
|
||||
</dict>
|
||||
<key>4952437350C7218900000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Profile</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>baseConfigurationReference</key>
|
||||
<string>1DD70E29E5F5E62F00000000</string>
|
||||
</dict>
|
||||
<key>49524373A439BFE700000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Release</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
<key>baseConfigurationReference</key>
|
||||
<string>1DD70E29598C919100000000</string>
|
||||
</dict>
|
||||
<key>218C37090000000000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCConfigurationList</string>
|
||||
<key>buildConfigurations</key>
|
||||
<array>
|
||||
<string>4952437303EDA63300000000</string>
|
||||
<string>4952437350C7218900000000</string>
|
||||
<string>49524373A439BFE700000000</string>
|
||||
</array>
|
||||
<key>defaultConfigurationIsVisible</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>E66DC04E928346B000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXNativeTarget</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode</string>
|
||||
<key>productName</key>
|
||||
<string>PasscodeInputFieldNode</string>
|
||||
<key>productReference</key>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
<key>productType</key>
|
||||
<string>com.apple.product-type.library.static</string>
|
||||
<key>dependencies</key>
|
||||
<array>
|
||||
</array>
|
||||
<key>buildPhases</key>
|
||||
<array>
|
||||
<string>1870857F0000000000000000</string>
|
||||
<string>FAF5FAC90000000000000000</string>
|
||||
</array>
|
||||
<key>buildConfigurationList</key>
|
||||
<string>218C37090000000000000000</string>
|
||||
</dict>
|
||||
<key>4952437303EDA63300000001</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Debug</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>4952437350C7218900000001</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Profile</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>49524373A439BFE700000001</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCBuildConfiguration</string>
|
||||
<key>name</key>
|
||||
<string>Release</string>
|
||||
<key>buildSettings</key>
|
||||
<dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>218C37090000000000000001</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>XCConfigurationList</string>
|
||||
<key>buildConfigurations</key>
|
||||
<array>
|
||||
<string>4952437303EDA63300000001</string>
|
||||
<string>4952437350C7218900000001</string>
|
||||
<string>49524373A439BFE700000001</string>
|
||||
</array>
|
||||
<key>defaultConfigurationIsVisible</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>96C84793928346B000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXProject</string>
|
||||
<key>mainGroup</key>
|
||||
<string>B401C979EFB6AC4600000000</string>
|
||||
<key>targets</key>
|
||||
<array>
|
||||
<string>E66DC04E928346B000000000</string>
|
||||
</array>
|
||||
<key>buildConfigurationList</key>
|
||||
<string>218C37090000000000000001</string>
|
||||
<key>compatibilityVersion</key>
|
||||
<string>Xcode 3.2</string>
|
||||
<key>attributes</key>
|
||||
<dict>
|
||||
<key>LastUpgradeCheck</key>
|
||||
<string>9999</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rootObject</key>
|
||||
<string>96C84793928346B000000000</string>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Scheme LastUpgradeVersion="9999" version="1.7"><BuildAction buildImplicitDependencies="YES" parallelizeBuildables="YES"><BuildActionEntries><BuildActionEntry buildForAnalyzing="YES" buildForArchiving="YES" buildForProfiling="YES" buildForRunning="YES" buildForTesting="YES"><BuildableReference BlueprintIdentifier="E66DC04E928346B000000000" BlueprintName="PasscodeInputFieldNode" BuildableIdentifier="primary" BuildableName="libPasscodeInputFieldNode.a" ReferencedContainer="container:PasscodeInputFieldNode.xcodeproj"/></BuildActionEntry></BuildActionEntries></BuildAction><TestAction buildConfiguration="Debug" shouldUseLaunchSchemeArgsEnv="YES"><Testables/></TestAction><LaunchAction buildConfiguration="Debug"/><ProfileAction buildConfiguration="Release"/><AnalyzeAction buildConfiguration="Debug"/><ArchiveAction buildConfiguration="Release" revealArchiveInOrganizer="YES"/></Scheme>
|
@ -0,0 +1,11 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for PasscodeInputFieldNode.
|
||||
FOUNDATION_EXPORT double PasscodeInputFieldNodeVersionNumber;
|
||||
|
||||
//! Project version string for PasscodeInputFieldNode.
|
||||
FOUNDATION_EXPORT const unsigned char PasscodeInputFieldNodeVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <PasscodeInputFieldNode/PublicHeader.h>
|
||||
|
||||
|
@ -24,19 +24,19 @@ private func generateDotImage(color: UIColor, filled: Bool) -> UIImage? {
|
||||
})
|
||||
}
|
||||
|
||||
private func generateFieldBackgroundImage(background: PasscodeBackground, frame: CGRect) -> UIImage? {
|
||||
private func generateFieldBackgroundImage(backgroundImage: UIImage, backgroundSize: CGSize, frame: CGRect) -> UIImage? {
|
||||
return generateImage(frame.size, contextGenerator: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let relativeFrame = CGRect(x: -frame.minX, y: frame.minY - background.size.height + frame.size.height
|
||||
, width: background.size.width, height: background.size.height)
|
||||
let relativeFrame = CGRect(x: -frame.minX, y: frame.minY - backgroundSize.height + frame.size.height
|
||||
, width: backgroundSize.width, height: backgroundSize.height)
|
||||
|
||||
let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height), cornerRadius: 6.0)
|
||||
context.addPath(path.cgPath)
|
||||
context.clip()
|
||||
|
||||
context.draw(background.foregroundImage.cgImage!, in: relativeFrame)
|
||||
context.draw(backgroundImage.cgImage!, in: relativeFrame)
|
||||
|
||||
context.setBlendMode(.clear)
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
@ -128,8 +128,8 @@ private class PasscodeEntryDotNode: ASImageNode {
|
||||
}
|
||||
}
|
||||
|
||||
public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private var background: PasscodeBackground?
|
||||
public final class PasscodeInputFieldNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private var background: (UIImage, CGSize)?
|
||||
private var color: UIColor
|
||||
private var accentColor: UIColor
|
||||
private var fieldType: PasscodeEntryFieldType
|
||||
@ -139,7 +139,7 @@ public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelega
|
||||
private let borderNode: ASImageNode
|
||||
private let dotNodes: [PasscodeEntryDotNode]
|
||||
|
||||
private var validLayout: PasscodeLayout?
|
||||
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||
|
||||
public var complete: ((String) -> Void)?
|
||||
|
||||
@ -202,15 +202,15 @@ public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelega
|
||||
|
||||
self.textFieldNode.textField.keyboardType = self.fieldType.keyboardType
|
||||
|
||||
if let validLayout = self.validLayout {
|
||||
let _ = self.updateLayout(layout: validLayout, transition: animated ? .animated(duration: 0.25, curve: .easeInOut) : .immediate)
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: animated ? .animated(duration: 0.25, curve: .easeInOut) : .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
func updateBackground(_ background: PasscodeBackground) {
|
||||
self.background = background
|
||||
if let validLayout = self.validLayout {
|
||||
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
||||
func updateBackground(_ image: UIImage, size: CGSize) {
|
||||
self.background = (image, size)
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,13 +302,13 @@ public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelega
|
||||
self.textFieldNode.textField.text = ""
|
||||
}
|
||||
self.fieldType = fieldType
|
||||
if let validLayout = self.validLayout {
|
||||
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateLayout(layout: PasscodeLayout, transition: ContainedViewLayoutTransition) -> CGRect {
|
||||
self.validLayout = layout
|
||||
public func updateLayout(layout: ContainerViewLayout, topOffset: CGFloat, transition: ContainedViewLayoutTransition) -> CGRect {
|
||||
self.validLayout = (layout, topOffset)
|
||||
|
||||
let fieldAlpha: CGFloat
|
||||
switch self.fieldType {
|
||||
@ -321,7 +321,7 @@ public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelega
|
||||
transition.updateAlpha(node: self.textFieldNode, alpha: fieldAlpha)
|
||||
transition.updateAlpha(node: self.borderNode, alpha: fieldAlpha)
|
||||
|
||||
let origin = CGPoint(x: floor((layout.layout.size.width - dotDiameter * 6 - dotSpacing * 5) / 2.0), y: layout.inputFieldOffset)
|
||||
let origin = CGPoint(x: floor((layout.size.width - dotDiameter * 6 - dotSpacing * 5) / 2.0), y: topOffset)
|
||||
for i in 0 ..< self.dotNodes.count {
|
||||
let node = self.dotNodes[i]
|
||||
let dotAlpha: CGFloat
|
||||
@ -343,11 +343,11 @@ public final class PasscodeEntryInputFieldNode: ASDisplayNode, UITextFieldDelega
|
||||
if !self.useCustomNumpad {
|
||||
inset = 16.0
|
||||
}
|
||||
let fieldFrame = CGRect(x: inset, y: origin.y, width: layout.layout.size.width - inset * 2.0, height: fieldHeight)
|
||||
let fieldFrame = CGRect(x: inset, y: origin.y, width: layout.size.width - inset * 2.0, height: fieldHeight)
|
||||
transition.updateFrame(node: self.borderNode, frame: fieldFrame)
|
||||
transition.updateFrame(node: self.textFieldNode, frame: fieldFrame.insetBy(dx: 13.0, dy: 0.0))
|
||||
if let background = self.background {
|
||||
self.borderNode.image = generateFieldBackgroundImage(background: background, frame: fieldFrame)
|
||||
if let (backgroundImage, backgroundSize) = self.background {
|
||||
self.borderNode.image = generateFieldBackgroundImage(backgroundImage: backgroundImage, backgroundSize: backgroundSize, frame: fieldFrame)
|
||||
}
|
||||
|
||||
return fieldFrame
|
@ -19,6 +19,7 @@ static_library(
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/ImageBlur:ImageBlur",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/PasscodeInputFieldNode:PasscodeInputFieldNode",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
@ -169,6 +169,19 @@
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E2989A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>path</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E290F1A3C6400000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -329,6 +342,7 @@
|
||||
<string>1DD70E29A889192100000000</string>
|
||||
<string>1DD70E29CE34063500000000</string>
|
||||
<string>1DD70E2936DE2CF900000000</string>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
<string>1DD70E290F1A3C6400000000</string>
|
||||
<string>1DD70E29DB6520C800000000</string>
|
||||
<string>1DD70E29D65BA68200000000</string>
|
||||
@ -388,17 +402,6 @@
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
</dict>
|
||||
<key>1DD70E293E85462B00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeEntryInputFieldNode.swift</string>
|
||||
<key>path</key>
|
||||
<string>Sources/PasscodeEntryInputFieldNode.swift</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
</dict>
|
||||
<key>1DD70E293E99570200000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -421,6 +424,17 @@
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
</dict>
|
||||
<key>1DD70E290BCAAD5500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>PasscodeInputFieldNode.swift</string>
|
||||
<key>path</key>
|
||||
<string>Sources/PasscodeInputFieldNode.swift</string>
|
||||
<key>sourceTree</key>
|
||||
<string>SOURCE_ROOT</string>
|
||||
</dict>
|
||||
<key>1DD70E299AE87B0D00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -478,9 +492,9 @@
|
||||
<string>1DD70E2944FAB31100000000</string>
|
||||
<string>1DD70E298C702AD500000000</string>
|
||||
<string>1DD70E297F6C137700000000</string>
|
||||
<string>1DD70E293E85462B00000000</string>
|
||||
<string>1DD70E293E99570200000000</string>
|
||||
<string>1DD70E29A75DC52700000000</string>
|
||||
<string>1DD70E290BCAAD5500000000</string>
|
||||
<string>1DD70E299AE87B0D00000000</string>
|
||||
<string>1DD70E29E2D8E4C900000000</string>
|
||||
<string>1DD70E298FD9E6E000000000</string>
|
||||
@ -564,13 +578,6 @@
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E297F6C137700000000</string>
|
||||
</dict>
|
||||
<key>E7A30F043E85462B00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E293E85462B00000000</string>
|
||||
</dict>
|
||||
<key>E7A30F043E99570200000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -585,6 +592,13 @@
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29A75DC52700000000</string>
|
||||
</dict>
|
||||
<key>E7A30F040BCAAD5500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E290BCAAD5500000000</string>
|
||||
</dict>
|
||||
<key>E7A30F049AE87B0D00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -622,9 +636,9 @@
|
||||
<string>E7A30F0444FAB31100000000</string>
|
||||
<string>E7A30F048C702AD500000000</string>
|
||||
<string>E7A30F047F6C137700000000</string>
|
||||
<string>E7A30F043E85462B00000000</string>
|
||||
<string>E7A30F043E99570200000000</string>
|
||||
<string>E7A30F04A75DC52700000000</string>
|
||||
<string>E7A30F040BCAAD5500000000</string>
|
||||
<string>E7A30F049AE87B0D00000000</string>
|
||||
<string>E7A30F04E2D8E4C900000000</string>
|
||||
<string>E7A30F048FD9E6E000000000</string>
|
||||
@ -757,6 +771,13 @@
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29A889192100000000</string>
|
||||
</dict>
|
||||
<key>E7A30F0489A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
</dict>
|
||||
<key>FAF5FAC90000000000000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -781,6 +802,7 @@
|
||||
<string>E7A30F049D2580DA00000000</string>
|
||||
<string>E7A30F04D6F14E1000000000</string>
|
||||
<string>E7A30F04A889192100000000</string>
|
||||
<string>E7A30F0489A0042800000000</string>
|
||||
</array>
|
||||
<key>name</key>
|
||||
<string>Fake Swift Dependencies (Copy Files Phase)</string>
|
||||
|
@ -9,6 +9,7 @@ import TelegramPresentationData
|
||||
import AccountContext
|
||||
import LocalAuth
|
||||
import AppBundle
|
||||
import PasscodeInputFieldNode
|
||||
|
||||
private let titleFont = Font.regular(20.0)
|
||||
private let subtitleFont = Font.regular(15.0)
|
||||
@ -29,7 +30,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
private let backgroundNode: ASImageNode
|
||||
private let iconNode: PasscodeLockIconNode
|
||||
private let titleNode: PasscodeEntryLabelNode
|
||||
private let inputFieldNode: PasscodeEntryInputFieldNode
|
||||
private let inputFieldNode: PasscodeInputFieldNode
|
||||
private let subtitleNode: PasscodeEntryLabelNode
|
||||
private let keyboardNode: PasscodeEntryKeyboardNode
|
||||
private let cancelButtonNode: HighlightableButtonNode
|
||||
@ -62,7 +63,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
|
||||
self.iconNode = PasscodeLockIconNode()
|
||||
self.titleNode = PasscodeEntryLabelNode()
|
||||
self.inputFieldNode = PasscodeEntryInputFieldNode(color: .white, accentColor: .white, fieldType: passcodeType, keyboardAppearance: .dark, useCustomNumpad: true)
|
||||
self.inputFieldNode = PasscodeInputFieldNode(color: .white, accentColor: .white, fieldType: passcodeType, keyboardAppearance: .dark, useCustomNumpad: true)
|
||||
self.subtitleNode = PasscodeEntryLabelNode()
|
||||
self.keyboardNode = PasscodeEntryKeyboardNode()
|
||||
self.cancelButtonNode = HighlightableButtonNode()
|
||||
@ -188,7 +189,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
if let background = self.background {
|
||||
self.backgroundNode.image = background.backgroundImage
|
||||
self.keyboardNode.updateBackground(background)
|
||||
self.inputFieldNode.updateBackground(background)
|
||||
self.inputFieldNode.updateBackground(background.foregroundImage, size: background.size)
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +347,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
||||
|
||||
let passcodeLayout = PasscodeLayout(layout: layout)
|
||||
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: passcodeLayout, transition: transition)
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: passcodeLayout.layout, topOffset: passcodeLayout.inputFieldOffset, transition: transition)
|
||||
transition.updateFrame(node: self.inputFieldNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
|
||||
let titleSize = self.titleNode.updateLayout(layout: layout, transition: transition)
|
||||
|
382
submodules/PasscodeUI/Sources/PasscodeInputFieldNode.swift
Normal file
382
submodules/PasscodeUI/Sources/PasscodeInputFieldNode.swift
Normal file
@ -0,0 +1,382 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
|
||||
private let dotDiameter: CGFloat = 13.0
|
||||
private let dotSpacing: CGFloat = 24.0
|
||||
private let fieldHeight: CGFloat = 38.0
|
||||
|
||||
private func generateDotImage(color: UIColor, filled: Bool) -> UIImage? {
|
||||
return generateImage(CGSize(width: dotDiameter, height: dotDiameter), contextGenerator: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
if filled {
|
||||
context.setFillColor(color.cgColor)
|
||||
context.fillEllipse(in: bounds)
|
||||
} else {
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setLineWidth(1.0)
|
||||
context.strokeEllipse(in: bounds.insetBy(dx: 0.5, dy: 0.5))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func generateFieldBackgroundImage(backgroundImage: UIImage, backgroundSize: CGSize, frame: CGRect) -> UIImage? {
|
||||
return generateImage(frame.size, contextGenerator: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let relativeFrame = CGRect(x: -frame.minX, y: frame.minY - backgroundSize.height + frame.size.height
|
||||
, width: backgroundSize.width, height: backgroundSize.height)
|
||||
|
||||
let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height), cornerRadius: 6.0)
|
||||
context.addPath(path.cgPath)
|
||||
context.clip()
|
||||
|
||||
context.draw(backgroundImage.cgImage!, in: relativeFrame)
|
||||
|
||||
context.setBlendMode(.clear)
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
|
||||
let innerPath = UIBezierPath(roundedRect: CGRect(x: 1.0, y: 1.0, width: size.width - 2.0, height: size.height - 2.0), cornerRadius: 6.0)
|
||||
context.addPath(innerPath.cgPath)
|
||||
context.fillPath()
|
||||
})
|
||||
}
|
||||
|
||||
private let validDigitsSet: CharacterSet = {
|
||||
return CharacterSet(charactersIn: "0".unicodeScalars.first! ... "9".unicodeScalars.first!)
|
||||
}()
|
||||
|
||||
public enum PasscodeEntryFieldType {
|
||||
case digits6
|
||||
case digits4
|
||||
case alphanumeric
|
||||
|
||||
public var maxLength: Int? {
|
||||
switch self {
|
||||
case .digits6:
|
||||
return 6
|
||||
case .digits4:
|
||||
return 4
|
||||
case .alphanumeric:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public var allowedCharacters: CharacterSet? {
|
||||
switch self {
|
||||
case .digits6, .digits4:
|
||||
return validDigitsSet
|
||||
case .alphanumeric:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public var keyboardType: UIKeyboardType {
|
||||
switch self {
|
||||
case .digits6, .digits4:
|
||||
if #available(iOS 10.0, *) {
|
||||
return .asciiCapableNumberPad
|
||||
} else {
|
||||
return .numberPad
|
||||
}
|
||||
case .alphanumeric:
|
||||
return .default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PasscodeEntryInputView: UIView {
|
||||
|
||||
}
|
||||
|
||||
private class PasscodeEntryDotNode: ASImageNode {
|
||||
private let regularImage: UIImage
|
||||
private let filledImage: UIImage
|
||||
private var currentImage: UIImage
|
||||
|
||||
init(color: UIColor) {
|
||||
self.regularImage = generateDotImage(color: color, filled: false)!
|
||||
self.filledImage = generateDotImage(color: color, filled: true)!
|
||||
self.currentImage = self.regularImage
|
||||
|
||||
super.init()
|
||||
|
||||
self.image = self.currentImage
|
||||
}
|
||||
|
||||
func updateState(filled: Bool, animated: Bool = false, delay: Double = 0.0) {
|
||||
let image = filled ? self.filledImage : self.regularImage
|
||||
if self.currentImage !== image {
|
||||
let currentContents = self.layer.contents
|
||||
self.layer.removeAnimation(forKey: "contents")
|
||||
if let currentContents = currentContents, animated {
|
||||
self.layer.animate(from: currentContents as AnyObject, to: image.cgImage!, keyPath: "contents", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: image === self.regularImage ? 0.25 : 0.05, delay: delay, removeOnCompletion: false, completion: { finished in
|
||||
if finished {
|
||||
self.image = image
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.image = image
|
||||
}
|
||||
self.currentImage = image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class PasscodeInputFieldNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private var background: (UIImage, CGSize)?
|
||||
private var color: UIColor
|
||||
private var accentColor: UIColor
|
||||
private var fieldType: PasscodeEntryFieldType
|
||||
private let useCustomNumpad: Bool
|
||||
|
||||
private let textFieldNode: TextFieldNode
|
||||
private let borderNode: ASImageNode
|
||||
private let dotNodes: [PasscodeEntryDotNode]
|
||||
|
||||
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||
|
||||
public var complete: ((String) -> Void)?
|
||||
|
||||
public var text: String {
|
||||
return self.textFieldNode.textField.text ?? ""
|
||||
}
|
||||
|
||||
public var keyboardAppearance: UIKeyboardAppearance {
|
||||
didSet {
|
||||
self.textFieldNode.textField.keyboardAppearance = self.keyboardAppearance
|
||||
}
|
||||
}
|
||||
|
||||
public init(color: UIColor, accentColor: UIColor, fieldType: PasscodeEntryFieldType, keyboardAppearance: UIKeyboardAppearance, useCustomNumpad: Bool = false) {
|
||||
self.color = color
|
||||
self.accentColor = accentColor
|
||||
self.fieldType = fieldType
|
||||
self.keyboardAppearance = keyboardAppearance
|
||||
self.useCustomNumpad = useCustomNumpad
|
||||
|
||||
self.textFieldNode = TextFieldNode()
|
||||
self.borderNode = ASImageNode()
|
||||
self.dotNodes = (0 ..< 6).map { _ in PasscodeEntryDotNode(color: color) }
|
||||
|
||||
super.init()
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
|
||||
for node in self.dotNodes {
|
||||
self.addSubnode(node)
|
||||
}
|
||||
self.addSubnode(self.textFieldNode)
|
||||
self.addSubnode(self.borderNode)
|
||||
}
|
||||
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.textFieldNode.textField.isSecureTextEntry = true
|
||||
self.textFieldNode.textField.textColor = self.color
|
||||
self.textFieldNode.textField.delegate = self
|
||||
self.textFieldNode.textField.returnKeyType = .done
|
||||
self.textFieldNode.textField.tintColor = self.accentColor
|
||||
self.textFieldNode.textField.keyboardAppearance = self.keyboardAppearance
|
||||
self.textFieldNode.textField.keyboardType = self.fieldType.keyboardType
|
||||
self.textFieldNode.textField.tintColor = self.accentColor
|
||||
|
||||
if self.useCustomNumpad {
|
||||
switch self.fieldType {
|
||||
case .digits6, .digits4:
|
||||
self.textFieldNode.textField.inputView = PasscodeEntryInputView()
|
||||
case .alphanumeric:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateFieldType(_ fieldType: PasscodeEntryFieldType, animated: Bool) {
|
||||
self.fieldType = fieldType
|
||||
|
||||
self.textFieldNode.textField.keyboardType = self.fieldType.keyboardType
|
||||
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: animated ? .animated(duration: 0.25, curve: .easeInOut) : .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
func updateBackground(_ image: UIImage, size: CGSize) {
|
||||
self.background = (image, size)
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
public func activateInput() {
|
||||
self.textFieldNode.textField.becomeFirstResponder()
|
||||
}
|
||||
|
||||
func animateIn() {
|
||||
switch self.fieldType {
|
||||
case .digits6, .digits4:
|
||||
for node in self.dotNodes {
|
||||
node.layer.animateScale(from: 0.0001, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
|
||||
}
|
||||
case .alphanumeric:
|
||||
self.textFieldNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
|
||||
self.borderNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
func animateSuccess() {
|
||||
switch self.fieldType {
|
||||
case .digits6, .digits4:
|
||||
var delay: Double = 0.0
|
||||
for node in self.dotNodes {
|
||||
node.updateState(filled: true, animated: true, delay: delay)
|
||||
delay += 0.01
|
||||
}
|
||||
case .alphanumeric:
|
||||
if (self.textFieldNode.textField.text ?? "").isEmpty {
|
||||
self.textFieldNode.textField.text = "passwordpassword"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func reset(animated: Bool = true) {
|
||||
var delay: Double = 0.0
|
||||
for node in self.dotNodes.reversed() {
|
||||
if node.alpha < 1.0 {
|
||||
continue
|
||||
}
|
||||
|
||||
node.updateState(filled: false, animated: animated, delay: delay)
|
||||
delay += 0.05
|
||||
}
|
||||
self.textFieldNode.textField.text = ""
|
||||
}
|
||||
|
||||
func append(_ string: String) {
|
||||
var text = (self.textFieldNode.textField.text ?? "") + string
|
||||
let maxLength = self.fieldType.maxLength
|
||||
if let maxLength = maxLength, text.count > maxLength {
|
||||
return
|
||||
}
|
||||
self.textFieldNode.textField.text = text
|
||||
|
||||
text = self.textFieldNode.textField.text ?? "" + string
|
||||
self.updateDots(count: text.count, animated: false)
|
||||
|
||||
if let maxLength = maxLength, text.count == maxLength {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
self.complete?(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func delete() {
|
||||
var text = self.textFieldNode.textField.text ?? ""
|
||||
guard !text.isEmpty else {
|
||||
return
|
||||
}
|
||||
text = String(text[text.startIndex ..< text.index(text.endIndex, offsetBy: -1)])
|
||||
self.textFieldNode.textField.text = text
|
||||
self.updateDots(count: text.count, animated: true)
|
||||
}
|
||||
|
||||
func updateDots(count: Int, animated: Bool) {
|
||||
var i = -1
|
||||
for node in self.dotNodes {
|
||||
if node.alpha < 1.0 {
|
||||
continue
|
||||
}
|
||||
i += 1
|
||||
node.updateState(filled: i < count, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
public func update(fieldType: PasscodeEntryFieldType) {
|
||||
if fieldType != self.fieldType {
|
||||
self.textFieldNode.textField.text = ""
|
||||
}
|
||||
self.fieldType = fieldType
|
||||
if let (layout, topOffset) = self.validLayout {
|
||||
let _ = self.updateLayout(layout: layout, topOffset: topOffset, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateLayout(layout: ContainerViewLayout, topOffset: CGFloat, transition: ContainedViewLayoutTransition) -> CGRect {
|
||||
self.validLayout = (layout, topOffset)
|
||||
|
||||
let fieldAlpha: CGFloat
|
||||
switch self.fieldType {
|
||||
case .digits6, .digits4:
|
||||
fieldAlpha = 0.0
|
||||
case .alphanumeric:
|
||||
fieldAlpha = 1.0
|
||||
}
|
||||
|
||||
transition.updateAlpha(node: self.textFieldNode, alpha: fieldAlpha)
|
||||
transition.updateAlpha(node: self.borderNode, alpha: fieldAlpha)
|
||||
|
||||
let origin = CGPoint(x: floor((layout.size.width - dotDiameter * 6 - dotSpacing * 5) / 2.0), y: topOffset)
|
||||
for i in 0 ..< self.dotNodes.count {
|
||||
let node = self.dotNodes[i]
|
||||
let dotAlpha: CGFloat
|
||||
switch self.fieldType {
|
||||
case .digits6:
|
||||
dotAlpha = 1.0
|
||||
case .digits4:
|
||||
dotAlpha = (i > 0 && i < self.dotNodes.count - 1) ? 1.0 : 0.0
|
||||
case .alphanumeric:
|
||||
dotAlpha = 0.0
|
||||
}
|
||||
transition.updateAlpha(node: node, alpha: dotAlpha)
|
||||
|
||||
let dotFrame = CGRect(x: origin.x + CGFloat(i) * (dotDiameter + dotSpacing), y: origin.y, width: dotDiameter, height: dotDiameter)
|
||||
transition.updateFrame(node: node, frame: dotFrame)
|
||||
}
|
||||
|
||||
var inset: CGFloat = 50.0
|
||||
if !self.useCustomNumpad {
|
||||
inset = 16.0
|
||||
}
|
||||
let fieldFrame = CGRect(x: inset, y: origin.y, width: layout.size.width - inset * 2.0, height: fieldHeight)
|
||||
transition.updateFrame(node: self.borderNode, frame: fieldFrame)
|
||||
transition.updateFrame(node: self.textFieldNode, frame: fieldFrame.insetBy(dx: 13.0, dy: 0.0))
|
||||
if let (backgroundImage, backgroundSize) = self.background {
|
||||
self.borderNode.image = generateFieldBackgroundImage(backgroundImage: backgroundImage, backgroundSize: backgroundSize, frame: fieldFrame)
|
||||
}
|
||||
|
||||
return fieldFrame
|
||||
}
|
||||
|
||||
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
let currentText = textField.text ?? ""
|
||||
let text = (currentText as NSString).replacingCharacters(in: range, with: string)
|
||||
if let maxLength = self.fieldType.maxLength, text.count > maxLength {
|
||||
return false
|
||||
}
|
||||
if let allowedCharacters = self.fieldType.allowedCharacters, let _ = text.rangeOfCharacter(from: allowedCharacters.inverted) {
|
||||
return false
|
||||
}
|
||||
self.updateDots(count: text.count, animated: text.count < currentText.count)
|
||||
|
||||
if string == "\n" {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
self.complete?(currentText)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if let maxLength = self.fieldType.maxLength, text.count == maxLength {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
self.complete?(text)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import AsyncDisplayKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import PasscodeInputFieldNode
|
||||
|
||||
enum PasscodeSetupInitialState {
|
||||
case createPasscode
|
||||
@ -36,7 +37,7 @@ final class PasscodeSetupControllerNode: ASDisplayNode {
|
||||
|
||||
private let titleNode: ASTextNode
|
||||
private let subtitleNode: ASTextNode
|
||||
private let inputFieldNode: PasscodeEntryInputFieldNode
|
||||
private let inputFieldNode: PasscodeInputFieldNode
|
||||
private let inputFieldBackgroundNode: ASImageNode
|
||||
private let modeButtonNode: HighlightableButtonNode
|
||||
|
||||
@ -82,7 +83,7 @@ final class PasscodeSetupControllerNode: ASDisplayNode {
|
||||
passcodeType = .digits6
|
||||
}
|
||||
|
||||
self.inputFieldNode = PasscodeEntryInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: passcodeType, keyboardAppearance: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance)
|
||||
self.inputFieldNode = PasscodeInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: passcodeType, keyboardAppearance: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance)
|
||||
self.inputFieldBackgroundNode = ASImageNode()
|
||||
self.inputFieldBackgroundNode.alpha = passcodeType == .alphanumeric ? 1.0 : 0.0
|
||||
self.inputFieldBackgroundNode.contentMode = .scaleToFill
|
||||
@ -145,8 +146,7 @@ final class PasscodeSetupControllerNode: ASDisplayNode {
|
||||
|
||||
self.wrapperNode.frame = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height)
|
||||
|
||||
let passcodeLayout = PasscodeLayout(layout: layout, titleOffset: 0.0, subtitleOffset: 0.0, inputFieldOffset: floor(insets.top + navigationBarHeight + (layout.size.height - navigationBarHeight - insets.top - insets.bottom - 24.0) / 2.0))
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: passcodeLayout, transition: transition)
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: layout, topOffset: floor(insets.top + navigationBarHeight + (layout.size.height - navigationBarHeight - insets.top - insets.bottom - 24.0) / 2.0), transition: transition)
|
||||
transition.updateFrame(node: self.inputFieldNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
|
||||
transition.updateFrame(node: self.inputFieldBackgroundNode, frame: CGRect(x: 0.0, y: inputFieldFrame.minY - 6.0, width: layout.size.width, height: 48.0))
|
||||
|
@ -832,6 +832,19 @@
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E2989A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>path</key>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E29D0DBC52A00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -1602,6 +1615,7 @@
|
||||
<string>1DD70E2937C1167400000000</string>
|
||||
<string>1DD70E29AF00DC4900000000</string>
|
||||
<string>1DD70E29BBAF750C00000000</string>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
<string>1DD70E29D0DBC52A00000000</string>
|
||||
<string>1DD70E29300245BE00000000</string>
|
||||
<string>1DD70E299856EB2400000000</string>
|
||||
@ -4691,6 +4705,13 @@
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E2937C1167400000000</string>
|
||||
</dict>
|
||||
<key>E7A30F0489A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
</dict>
|
||||
<key>E7A30F04D0DBC52A00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -4899,6 +4920,7 @@
|
||||
<string>E7A30F04A889192100000000</string>
|
||||
<string>E7A30F04A3994F2C00000000</string>
|
||||
<string>E7A30F0437C1167400000000</string>
|
||||
<string>E7A30F0489A0042800000000</string>
|
||||
<string>E7A30F04D0DBC52A00000000</string>
|
||||
<string>E7A30F0479E58A0000000000</string>
|
||||
<string>E7A30F049856EB2400000000</string>
|
||||
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Test.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 107 KiB |
@ -16,16 +16,16 @@ static_library(
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode",
|
||||
"//submodules/ItemListUI:ItemListUI",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
"//submodules/AlertUI:AlertUI",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
"//submodules/AlertUI:AlertUI",
|
||||
"//submodules/TextFormat:TextFormat",
|
||||
"//submodules/Camera:Camera",
|
||||
"//submodules/ShareController:ShareController",
|
||||
"//submodules/PasscodeUI:PasscodeUI",
|
||||
"//submodules/PasscodeInputFieldNode:PasscodeInputFieldNode",
|
||||
"//submodules/QrCode:QrCode",
|
||||
"//submodules/MergeLists:MergeLists",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/MergeLists:MergeLists",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
@ -10,7 +10,7 @@ import TelegramCore
|
||||
import AnimationUI
|
||||
import SwiftSignalKit
|
||||
import OverlayStatusController
|
||||
import PasscodeUI
|
||||
import PasscodeInputFieldNode
|
||||
|
||||
public enum WalletPasscodeMode {
|
||||
case setup
|
||||
@ -118,7 +118,7 @@ private final class WalletPasscodeScreenNode: ViewControllerTracingNode {
|
||||
private let titleNode: ImmediateTextNode
|
||||
private let biometricsActionTitleNode: ImmediateTextNode
|
||||
private let biometricsActionButtonNode: HighlightTrackingButtonNode
|
||||
private let inputFieldNode: PasscodeEntryInputFieldNode
|
||||
private let inputFieldNode: PasscodeInputFieldNode
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
@ -154,7 +154,7 @@ private final class WalletPasscodeScreenNode: ViewControllerTracingNode {
|
||||
|
||||
self.biometricsActionButtonNode = HighlightTrackingButtonNode()
|
||||
|
||||
self.inputFieldNode = PasscodeEntryInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: .digits4, keyboardAppearance: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance)
|
||||
self.inputFieldNode = PasscodeInputFieldNode(color: self.presentationData.theme.list.itemPrimaryTextColor, accentColor: self.presentationData.theme.list.itemAccentColor, fieldType: .digits4, keyboardAppearance: self.presentationData.theme.rootController.keyboardColor.keyboardAppearance)
|
||||
|
||||
super.init()
|
||||
|
||||
@ -221,8 +221,7 @@ private final class WalletPasscodeScreenNode: ViewControllerTracingNode {
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleSize)
|
||||
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
|
||||
|
||||
let passcodeLayout = PasscodeLayout(layout: layout, titleOffset: 0.0, subtitleOffset: 0.0, inputFieldOffset: titleFrame.maxY + titleSpacing)
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: passcodeLayout, transition: transition)
|
||||
let inputFieldFrame = self.inputFieldNode.updateLayout(layout: layout, topOffset: titleFrame.maxY + titleSpacing, transition: transition)
|
||||
transition.updateFrame(node: self.inputFieldNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
|
||||
let minimalBottomInset: CGFloat = 60.0
|
||||
|
@ -56,11 +56,6 @@ public final class WalletQrScanScreen: ViewController {
|
||||
private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
||||
private var presentationData: PresentationData
|
||||
|
||||
private let navigationBackgroundNode: ASDisplayNode
|
||||
private let navigationSeparatorNode: ASDisplayNode
|
||||
private let navigationTitleNode: ImmediateTextNode
|
||||
private let scrollNode: ASScrollNode
|
||||
private let iconNode: ASImageNode
|
||||
private let titleNode: ImmediateTextNode
|
||||
private let textNode: ImmediateTextNode
|
||||
|
||||
@ -69,23 +64,9 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV
|
||||
init(presentationData: PresentationData) {
|
||||
self.presentationData = presentationData
|
||||
|
||||
self.navigationBackgroundNode = ASDisplayNode()
|
||||
self.navigationBackgroundNode.backgroundColor = self.presentationData.theme.rootController.navigationBar.backgroundColor
|
||||
self.navigationBackgroundNode.alpha = 0.0
|
||||
self.navigationSeparatorNode = ASDisplayNode()
|
||||
self.navigationSeparatorNode.backgroundColor = self.presentationData.theme.rootController.navigationBar.separatorColor
|
||||
|
||||
self.scrollNode = ASScrollNode()
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.displayWithoutProcessing = true
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
|
||||
let title: String = "24 Secret Words"
|
||||
let text: String = "Write down these 24 words in the correct order and store them in a secret place.\n\nUse these secret words to restore access to your wallet if you lose your passcode or Telegram account."
|
||||
let buttonText: String = "Done"
|
||||
|
||||
self.iconNode.image = UIImage(bundleImageName: "Settings/Wallet/WordsDisplayIcon")
|
||||
|
||||
let title: String = ""
|
||||
let text: String = ""
|
||||
|
||||
self.titleNode = ImmediateTextNode()
|
||||
self.titleNode.displaysAsynchronously = false
|
||||
@ -93,12 +74,6 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV
|
||||
self.titleNode.maximumNumberOfLines = 0
|
||||
self.titleNode.textAlignment = .center
|
||||
|
||||
self.navigationTitleNode = ImmediateTextNode()
|
||||
self.navigationTitleNode.displaysAsynchronously = false
|
||||
self.navigationTitleNode.attributedText = NSAttributedString(string: title, font: Font.bold(17.0), textColor: self.presentationData.theme.list.itemPrimaryTextColor)
|
||||
self.navigationTitleNode.maximumNumberOfLines = 0
|
||||
self.navigationTitleNode.textAlignment = .center
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(16.0), textColor: self.presentationData.theme.list.itemPrimaryTextColor)
|
||||
@ -110,75 +85,29 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV
|
||||
|
||||
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||
|
||||
self.addSubnode(self.scrollNode)
|
||||
|
||||
self.scrollNode.addSubnode(self.iconNode)
|
||||
self.scrollNode.addSubnode(self.titleNode)
|
||||
self.scrollNode.addSubnode(self.textNode)
|
||||
|
||||
self.navigationBackgroundNode.addSubnode(self.navigationSeparatorNode)
|
||||
self.navigationBackgroundNode.addSubnode(self.navigationTitleNode)
|
||||
self.addSubnode(self.navigationBackgroundNode)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.scrollNode.view.alwaysBounceVertical = false
|
||||
self.scrollNode.view.showsVerticalScrollIndicator = false
|
||||
self.scrollNode.view.showsHorizontalScrollIndicator = false
|
||||
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
|
||||
self.scrollNode.view.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
self.scrollNode.view.delegate = self
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
let navigationHeight = self.navigationHeight ?? 0.0
|
||||
let alpha: CGFloat = scrollView.contentOffset.y >= (self.titleNode.frame.maxY - navigationHeight) ? 1.0 : 0.0
|
||||
if self.navigationBackgroundNode.alpha != alpha {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.12, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.navigationBackgroundNode, alpha: alpha, beginWithCurrentState: true)
|
||||
}
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.textNode)
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
self.navigationHeight = navigationHeight
|
||||
|
||||
let sideInset: CGFloat = 32.0
|
||||
let buttonSideInset: CGFloat = 48.0
|
||||
let iconSpacing: CGFloat = 5.0
|
||||
let titleSpacing: CGFloat = 19.0
|
||||
let textSpacing: CGFloat = 37.0
|
||||
let buttonHeight: CGFloat = 50.0
|
||||
let buttonSpacing: CGFloat = 45.0
|
||||
let wordSpacing: CGFloat = 12.0
|
||||
let indexSpacing: CGFloat = 4.0
|
||||
|
||||
transition.updateFrame(node: self.navigationBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: navigationHeight)))
|
||||
transition.updateFrame(node: self.navigationSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationHeight), size: CGSize(width: layout.size.width, height: UIScreenPixel)))
|
||||
|
||||
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
|
||||
let iconSize = self.iconNode.image?.size ?? CGSize(width: 50.0, height: 50.0)
|
||||
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||
let navigationTitleSize = self.navigationTitleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height))
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
|
||||
let contentVerticalOrigin = navigationHeight + 10.0
|
||||
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: contentVerticalOrigin), size: iconSize)
|
||||
transition.updateFrameAdditive(node: self.iconNode, frame: iconFrame)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: contentVerticalOrigin), size: titleSize)
|
||||
transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame)
|
||||
let textFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - textSize.width) / 2.0), y: titleFrame.maxY + titleSpacing), size: textSize)
|
||||
transition.updateFrameAdditive(node: self.textNode, frame: textFrame)
|
||||
|
||||
transition.updateFrameAdditive(node: self.navigationTitleNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - navigationTitleSize.width) / 2.0), y: navigationHeight - 44.0 + floor((44.0 - navigationTitleSize.height) / 2.0)), size: navigationTitleSize))
|
||||
|
||||
contentHeight = textFrame.maxY + textSpacing
|
||||
}
|
||||
}
|
||||
|
@ -299,19 +299,6 @@
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E29A889192100000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libLocalAuth.a</string>
|
||||
<key>path</key>
|
||||
<string>libLocalAuth.a</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E29CE34063500000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
@ -364,14 +351,14 @@
|
||||
<key>explicitFileType</key>
|
||||
<string>archive.ar</string>
|
||||
</dict>
|
||||
<key>1DD70E29D0DBC52A00000000</key>
|
||||
<key>1DD70E2989A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXFileReference</string>
|
||||
<key>name</key>
|
||||
<string>libPasscodeUI.a</string>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>path</key>
|
||||
<string>libPasscodeUI.a</string>
|
||||
<string>libPasscodeInputFieldNode.a</string>
|
||||
<key>sourceTree</key>
|
||||
<string>BUILT_PRODUCTS_DIR</string>
|
||||
<key>explicitFileType</key>
|
||||
@ -768,12 +755,11 @@
|
||||
<string>1DD70E29D6F14E1000000000</string>
|
||||
<string>1DD70E295A26607D00000000</string>
|
||||
<string>1DD70E29AC43662400000000</string>
|
||||
<string>1DD70E29A889192100000000</string>
|
||||
<string>1DD70E29CE34063500000000</string>
|
||||
<string>1DD70E2936DE2CF900000000</string>
|
||||
<string>1DD70E29C37F741500000000</string>
|
||||
<string>1DD70E29BBAF750C00000000</string>
|
||||
<string>1DD70E29D0DBC52A00000000</string>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
<string>1DD70E29928D142900000000</string>
|
||||
<string>1DD70E29D233F68C00000000</string>
|
||||
<string>1DD70E290F1A3C6400000000</string>
|
||||
@ -1363,19 +1349,12 @@
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29BBAF750C00000000</string>
|
||||
</dict>
|
||||
<key>E7A30F04A889192100000000</key>
|
||||
<key>E7A30F0489A0042800000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29A889192100000000</string>
|
||||
</dict>
|
||||
<key>E7A30F04D0DBC52A00000000</key>
|
||||
<dict>
|
||||
<key>isa</key>
|
||||
<string>PBXBuildFile</string>
|
||||
<key>fileRef</key>
|
||||
<string>1DD70E29D0DBC52A00000000</string>
|
||||
<string>1DD70E2989A0042800000000</string>
|
||||
</dict>
|
||||
<key>E7A30F04AA32BBC600000000</key>
|
||||
<dict>
|
||||
@ -1546,8 +1525,7 @@
|
||||
<string>E7A30F0425BBFEEE00000000</string>
|
||||
<string>E7A30F045A26607D00000000</string>
|
||||
<string>E7A30F04BBAF750C00000000</string>
|
||||
<string>E7A30F04A889192100000000</string>
|
||||
<string>E7A30F04D0DBC52A00000000</string>
|
||||
<string>E7A30F0489A0042800000000</string>
|
||||
<string>E7A30F04AA32BBC600000000</string>
|
||||
<string>E7A30F04A54A195300000000</string>
|
||||
<string>E7A30F041E16CC6C00000000</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user