no message

This commit is contained in:
Peter 2017-08-15 14:46:10 +03:00
parent 82499816e7
commit 4244aadacb
26 changed files with 772 additions and 94 deletions

View File

@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
D0078A681C92B21400DF6D92 /* StatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0078A671C92B21400DF6D92 /* StatusBar.swift */; }; D0078A681C92B21400DF6D92 /* StatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0078A671C92B21400DF6D92 /* StatusBar.swift */; };
D00C7CD21E3657570080C3D5 /* TextFieldNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD11E3657570080C3D5 /* TextFieldNode.swift */; }; D00C7CD21E3657570080C3D5 /* TextFieldNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD11E3657570080C3D5 /* TextFieldNode.swift */; };
D01159BB1F40E96C0039383E /* DisplayMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D01159B91F40E96C0039383E /* DisplayMac.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01159C21F40EA120039383E /* ListViewScrollerAppkit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01159C11F40EA120039383E /* ListViewScrollerAppkit.swift */; };
D015F7521D1AE08D00E269B5 /* ContainableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7511D1AE08D00E269B5 /* ContainableController.swift */; }; D015F7521D1AE08D00E269B5 /* ContainableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7511D1AE08D00E269B5 /* ContainableController.swift */; };
D015F7541D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7531D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift */; }; D015F7541D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7531D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift */; };
D015F7581D1B467200E269B5 /* ActionSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7571D1B467200E269B5 /* ActionSheetController.swift */; }; D015F7581D1B467200E269B5 /* ActionSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D015F7571D1B467200E269B5 /* ActionSheetController.swift */; };
@ -93,6 +95,7 @@
D0C0B59D1EE022CC000F4D2C /* NavigationBarContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B59C1EE022CC000F4D2C /* NavigationBarContentNode.swift */; }; D0C0B59D1EE022CC000F4D2C /* NavigationBarContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B59C1EE022CC000F4D2C /* NavigationBarContentNode.swift */; };
D0C0D28F1C997110001D2851 /* FBAnimationPerformanceTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = D0C0D28D1C997110001D2851 /* FBAnimationPerformanceTracker.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0C0D28F1C997110001D2851 /* FBAnimationPerformanceTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = D0C0D28D1C997110001D2851 /* FBAnimationPerformanceTracker.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0C0D2901C997110001D2851 /* FBAnimationPerformanceTracker.mm in Sources */ = {isa = PBXBuildFile; fileRef = D0C0D28E1C997110001D2851 /* FBAnimationPerformanceTracker.mm */; }; D0C0D2901C997110001D2851 /* FBAnimationPerformanceTracker.mm in Sources */ = {isa = PBXBuildFile; fileRef = D0C0D28E1C997110001D2851 /* FBAnimationPerformanceTracker.mm */; };
D0C12A1A1F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C12A191F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift */; };
D0C2DFC61CC4431D0044FF83 /* ASTransformLayerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBB1CC4431D0044FF83 /* ASTransformLayerNode.swift */; }; D0C2DFC61CC4431D0044FF83 /* ASTransformLayerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBB1CC4431D0044FF83 /* ASTransformLayerNode.swift */; };
D0C2DFC71CC4431D0044FF83 /* ListViewItemNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBC1CC4431D0044FF83 /* ListViewItemNode.swift */; }; D0C2DFC71CC4431D0044FF83 /* ListViewItemNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBC1CC4431D0044FF83 /* ListViewItemNode.swift */; };
D0C2DFC81CC4431D0044FF83 /* Spring.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBD1CC4431D0044FF83 /* Spring.swift */; }; D0C2DFC81CC4431D0044FF83 /* Spring.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBD1CC4431D0044FF83 /* Spring.swift */; };
@ -137,6 +140,10 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
D0078A671C92B21400DF6D92 /* StatusBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBar.swift; sourceTree = "<group>"; }; D0078A671C92B21400DF6D92 /* StatusBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBar.swift; sourceTree = "<group>"; };
D00C7CD11E3657570080C3D5 /* TextFieldNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldNode.swift; sourceTree = "<group>"; }; D00C7CD11E3657570080C3D5 /* TextFieldNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldNode.swift; sourceTree = "<group>"; };
D01159B71F40E96B0039383E /* DisplayMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DisplayMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D01159B91F40E96C0039383E /* DisplayMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayMac.h; sourceTree = "<group>"; };
D01159BA1F40E96C0039383E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D01159C11F40EA120039383E /* ListViewScrollerAppkit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewScrollerAppkit.swift; sourceTree = "<group>"; };
D015F7511D1AE08D00E269B5 /* ContainableController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainableController.swift; sourceTree = "<group>"; }; D015F7511D1AE08D00E269B5 /* ContainableController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainableController.swift; sourceTree = "<group>"; };
D015F7531D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemContainedControllerTransitionCoordinator.swift; sourceTree = "<group>"; }; D015F7531D1B0F6C00E269B5 /* SystemContainedControllerTransitionCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemContainedControllerTransitionCoordinator.swift; sourceTree = "<group>"; };
D015F7571D1B467200E269B5 /* ActionSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetController.swift; sourceTree = "<group>"; }; D015F7571D1B467200E269B5 /* ActionSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetController.swift; sourceTree = "<group>"; };
@ -224,6 +231,7 @@
D0C0B59C1EE022CC000F4D2C /* NavigationBarContentNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBarContentNode.swift; sourceTree = "<group>"; }; D0C0B59C1EE022CC000F4D2C /* NavigationBarContentNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBarContentNode.swift; sourceTree = "<group>"; };
D0C0D28D1C997110001D2851 /* FBAnimationPerformanceTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAnimationPerformanceTracker.h; sourceTree = "<group>"; }; D0C0D28D1C997110001D2851 /* FBAnimationPerformanceTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAnimationPerformanceTracker.h; sourceTree = "<group>"; };
D0C0D28E1C997110001D2851 /* FBAnimationPerformanceTracker.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FBAnimationPerformanceTracker.mm; sourceTree = "<group>"; }; D0C0D28E1C997110001D2851 /* FBAnimationPerformanceTracker.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FBAnimationPerformanceTracker.mm; sourceTree = "<group>"; };
D0C12A191F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBarTitleTransitionNode.swift; sourceTree = "<group>"; };
D0C2DFBB1CC4431D0044FF83 /* ASTransformLayerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASTransformLayerNode.swift; sourceTree = "<group>"; }; D0C2DFBB1CC4431D0044FF83 /* ASTransformLayerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASTransformLayerNode.swift; sourceTree = "<group>"; };
D0C2DFBC1CC4431D0044FF83 /* ListViewItemNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewItemNode.swift; sourceTree = "<group>"; }; D0C2DFBC1CC4431D0044FF83 /* ListViewItemNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewItemNode.swift; sourceTree = "<group>"; };
D0C2DFBD1CC4431D0044FF83 /* Spring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Spring.swift; sourceTree = "<group>"; }; D0C2DFBD1CC4431D0044FF83 /* Spring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Spring.swift; sourceTree = "<group>"; };
@ -257,6 +265,13 @@
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
D01159B31F40E96B0039383E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D05CC25F1B69316F00E235A3 /* Frameworks */ = { D05CC25F1B69316F00E235A3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -277,6 +292,15 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
D01159B81F40E96C0039383E /* DisplayMac */ = {
isa = PBXGroup;
children = (
D01159B91F40E96C0039383E /* DisplayMac.h */,
D01159BA1F40E96C0039383E /* Info.plist */,
);
path = DisplayMac;
sourceTree = "<group>";
};
D015F7501D1ADC6800E269B5 /* Window */ = { D015F7501D1ADC6800E269B5 /* Window */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -381,6 +405,7 @@
D05CC2591B69316F00E235A3 = { D05CC2591B69316F00E235A3 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D01159B81F40E96C0039383E /* DisplayMac */,
D05CC2A31B6932D500E235A3 /* Frameworks */, D05CC2A31B6932D500E235A3 /* Frameworks */,
D05CC2651B69316F00E235A3 /* Display */, D05CC2651B69316F00E235A3 /* Display */,
D05CC2711B69316F00E235A3 /* DisplayTests */, D05CC2711B69316F00E235A3 /* DisplayTests */,
@ -393,6 +418,7 @@
children = ( children = (
D05CC2631B69316F00E235A3 /* Display.framework */, D05CC2631B69316F00E235A3 /* Display.framework */,
D05CC26D1B69316F00E235A3 /* DisplayTests.xctest */, D05CC26D1B69316F00E235A3 /* DisplayTests.xctest */,
D01159B71F40E96B0039383E /* DisplayMac.framework */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -493,6 +519,7 @@
D05CC30D1B695A9500E235A3 /* NavigationBackButtonNode.swift */, D05CC30D1B695A9500E235A3 /* NavigationBackButtonNode.swift */,
D05CC30E1B695A9500E235A3 /* NavigationButtonNode.swift */, D05CC30E1B695A9500E235A3 /* NavigationButtonNode.swift */,
D05CC30F1B695A9500E235A3 /* NavigationTitleNode.swift */, D05CC30F1B695A9500E235A3 /* NavigationTitleNode.swift */,
D0C12A191F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift */,
D05CC3101B695A9600E235A3 /* BarButtonItemWrapper.swift */, D05CC3101B695A9600E235A3 /* BarButtonItemWrapper.swift */,
D05CC3281B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift */, D05CC3281B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift */,
D0AE3D4C1D25C816001CCE13 /* NavigationBarTransitionState.swift */, D0AE3D4C1D25C816001CCE13 /* NavigationBarTransitionState.swift */,
@ -561,6 +588,7 @@
D0C2DFC21CC4431D0044FF83 /* ListViewTransactionQueue.swift */, D0C2DFC21CC4431D0044FF83 /* ListViewTransactionQueue.swift */,
D0C2DFC31CC4431D0044FF83 /* ListViewAccessoryItem.swift */, D0C2DFC31CC4431D0044FF83 /* ListViewAccessoryItem.swift */,
D0C2DFC41CC4431D0044FF83 /* ListViewScroller.swift */, D0C2DFC41CC4431D0044FF83 /* ListViewScroller.swift */,
D01159C11F40EA120039383E /* ListViewScrollerAppkit.swift */,
D0C2DFC51CC4431D0044FF83 /* ListViewAccessoryItemNode.swift */, D0C2DFC51CC4431D0044FF83 /* ListViewAccessoryItemNode.swift */,
D0F7AB361DCFF6F8009AD9A1 /* ListViewItemHeader.swift */, D0F7AB361DCFF6F8009AD9A1 /* ListViewItemHeader.swift */,
); );
@ -605,6 +633,14 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */ /* Begin PBXHeadersBuildPhase section */
D01159B41F40E96B0039383E /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
D01159BB1F40E96C0039383E /* DisplayMac.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D05CC2601B69316F00E235A3 /* Headers */ = { D05CC2601B69316F00E235A3 /* Headers */ = {
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -630,6 +666,24 @@
/* End PBXHeadersBuildPhase section */ /* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
D01159B61F40E96B0039383E /* DisplayMac */ = {
isa = PBXNativeTarget;
buildConfigurationList = D01159C01F40E96C0039383E /* Build configuration list for PBXNativeTarget "DisplayMac" */;
buildPhases = (
D01159B21F40E96B0039383E /* Sources */,
D01159B31F40E96B0039383E /* Frameworks */,
D01159B41F40E96B0039383E /* Headers */,
D01159B51F40E96B0039383E /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = DisplayMac;
productName = DisplayMac;
productReference = D01159B71F40E96B0039383E /* DisplayMac.framework */;
productType = "com.apple.product-type.framework";
};
D05CC2621B69316F00E235A3 /* Display */ = { D05CC2621B69316F00E235A3 /* Display */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = D05CC2771B69316F00E235A3 /* Build configuration list for PBXNativeTarget "Display" */; buildConfigurationList = D05CC2771B69316F00E235A3 /* Build configuration list for PBXNativeTarget "Display" */;
@ -676,6 +730,12 @@
LastUpgradeCheck = 0800; LastUpgradeCheck = 0800;
ORGANIZATIONNAME = Telegram; ORGANIZATIONNAME = Telegram;
TargetAttributes = { TargetAttributes = {
D01159B61F40E96B0039383E = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = X834Q8SBVP;
LastSwiftMigration = 0830;
ProvisioningStyle = Automatic;
};
D05CC2621B69316F00E235A3 = { D05CC2621B69316F00E235A3 = {
CreatedOnToolsVersion = 7.0; CreatedOnToolsVersion = 7.0;
ProvisioningStyle = Manual; ProvisioningStyle = Manual;
@ -699,11 +759,19 @@
targets = ( targets = (
D05CC2621B69316F00E235A3 /* Display */, D05CC2621B69316F00E235A3 /* Display */,
D05CC26C1B69316F00E235A3 /* DisplayTests */, D05CC26C1B69316F00E235A3 /* DisplayTests */,
D01159B61F40E96B0039383E /* DisplayMac */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
D01159B51F40E96B0039383E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D05CC2611B69316F00E235A3 /* Resources */ = { D05CC2611B69316F00E235A3 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -723,6 +791,14 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
D01159B21F40E96B0039383E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D01159C21F40EA120039383E /* ListViewScrollerAppkit.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D05CC25E1B69316F00E235A3 /* Sources */ = { D05CC25E1B69316F00E235A3 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -779,6 +855,7 @@
D05CC2FA1B6955D000E235A3 /* UINavigationItem+Proxy.m in Sources */, D05CC2FA1B6955D000E235A3 /* UINavigationItem+Proxy.m in Sources */,
D096A4501EA64F580000A7AE /* ActionSheetCheckboxItem.swift in Sources */, D096A4501EA64F580000A7AE /* ActionSheetCheckboxItem.swift in Sources */,
D0C2DFCE1CC4431D0044FF83 /* ListViewAccessoryItem.swift in Sources */, D0C2DFCE1CC4431D0044FF83 /* ListViewAccessoryItem.swift in Sources */,
D0C12A1A1F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift in Sources */,
D0A749951E3A9E7B00AD786E /* SwitchNode.swift in Sources */, D0A749951E3A9E7B00AD786E /* SwitchNode.swift in Sources */,
D03725C51D6DF8B9007FC290 /* ContextMenuController.swift in Sources */, D03725C51D6DF8B9007FC290 /* ContextMenuController.swift in Sources */,
D03725C31D6DF7A6007FC290 /* ContextMenuAction.swift in Sources */, D03725C31D6DF7A6007FC290 /* ContextMenuAction.swift in Sources */,
@ -843,6 +920,254 @@
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
D01159BC1F40E96C0039383E /* Debug Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = DisplayMac/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.DisplayMac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Debug Hockeyapp";
};
D01159BD1F40E96C0039383E /* Debug AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = DisplayMac/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.DisplayMac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Debug AppStore";
};
D01159BE1F40E96C0039383E /* Release Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = DisplayMac/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.DisplayMac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Release Hockeyapp";
};
D01159BF1F40E96C0039383E /* Release AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = DisplayMac/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.DisplayMac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Release AppStore";
};
D05CC2751B69316F00E235A3 /* Debug Hockeyapp */ = { D05CC2751B69316F00E235A3 /* Debug Hockeyapp */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -1173,6 +1498,16 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
D01159C01F40E96C0039383E /* Build configuration list for PBXNativeTarget "DisplayMac" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D01159BC1F40E96C0039383E /* Debug Hockeyapp */,
D01159BD1F40E96C0039383E /* Debug AppStore */,
D01159BE1F40E96C0039383E /* Release Hockeyapp */,
D01159BF1F40E96C0039383E /* Release AppStore */,
);
defaultConfigurationIsVisible = 0;
};
D05CC25D1B69316F00E235A3 /* Build configuration list for PBXProject "Display" */ = { D05CC25D1B69316F00E235A3 /* Build configuration list for PBXProject "Display" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (

View File

@ -7,16 +7,26 @@
<key>Display.xcscheme</key> <key>Display.xcscheme</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>24</integer> <integer>22</integer>
</dict> </dict>
<key>DisplayTests.xcscheme</key> <key>DisplayMac.xcscheme</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>25</integer> <integer>25</integer>
</dict> </dict>
<key>DisplayTests.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>23</integer>
</dict>
</dict> </dict>
<key>SuppressBuildableAutocreation</key> <key>SuppressBuildableAutocreation</key>
<dict> <dict>
<key>D01159B61F40E96B0039383E</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>D05CC2621B69316F00E235A3</key> <key>D05CC2621B69316F00E235A3</key>
<dict> <dict>
<key>primary</key> <key>primary</key>

View File

@ -33,30 +33,36 @@ class ASTransformView: UIView {
open class ASTransformLayerNode: ASDisplayNode { open class ASTransformLayerNode: ASDisplayNode {
public override init() { public override init() {
super.init(layerBlock: { super.init()
self.setLayerBlock({
return ASTransformLayer() return ASTransformLayer()
}, didLoad: nil) })
} }
} }
open class ASTransformViewNode: ASDisplayNode { open class ASTransformViewNode: ASDisplayNode {
public override init() { public override init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return ASTransformView() return ASTransformView()
}, didLoad: nil) })
} }
} }
open class ASTransformNode: ASDisplayNode { open class ASTransformNode: ASDisplayNode {
public init(layerBacked: Bool = true) { public init(layerBacked: Bool = true) {
if layerBacked { if layerBacked {
super.init(layerBlock: { super.init()
self.setLayerBlock({
return ASTransformLayer() return ASTransformLayer()
}, didLoad: nil) })
} else { } else {
super.init(viewBlock: { super.init()
self.setViewBlock({
return ASTransformView() return ASTransformView()
}, didLoad: nil) })
} }
} }
} }

View File

@ -21,7 +21,7 @@ final class AlertControllerNode: ASDisplayNode {
self.effectNode = ASDisplayNode(viewBlock: { self.effectNode = ASDisplayNode(viewBlock: {
let view = UIView()//UIVisualEffectView(effect: UIBlurEffect(style: .light)) let view = UIView()//UIVisualEffectView(effect: UIBlurEffect(style: .light))
return view return view
}, didLoad: nil) })
self.contentNode = contentNode self.contentNode = contentNode

View File

@ -15,6 +15,15 @@ public extension ContainedViewLayoutTransitionCurve {
return kCAMediaTimingFunctionSpring return kCAMediaTimingFunctionSpring
} }
} }
var viewAnimationOptions: UIViewAnimationOptions {
switch self {
case .easeInOut:
return [.curveEaseInOut]
case .spring:
return UIViewAnimationOptions(rawValue: 7 << 16)
}
}
} }
public enum ContainedViewLayoutTransition { public enum ContainedViewLayoutTransition {
@ -251,6 +260,44 @@ public extension ContainedViewLayoutTransition {
} }
} }
func updateTransformScale(node: ASDisplayNode, scale: CGFloat, completion: ((Bool) -> Void)? = nil) {
let t = node.layer.transform
let currentScale = sqrt((t.m11 * t.m11) + (t.m12 * t.m12) + (t.m13 * t.m13))
if currentScale.isEqual(to: scale) {
if let completion = completion {
completion(true)
}
return
}
switch self {
case .immediate:
node.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
if let completion = completion {
completion(true)
}
case let .animated(duration, curve):
node.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
node.layer.animateScale(from: currentScale, to: scale, duration: duration, timingFunction: curve.timingFunction, completion: { result in
if let completion = completion {
completion(result)
}
})
}
}
}
public extension ContainedViewLayoutTransition {
public func animateView(_ f: @escaping () -> Void) {
switch self {
case .immediate:
f()
case let .animated(duration, curve):
UIView.animate(withDuration: duration, delay: 0.0, options: curve.viewAnimationOptions, animations: {
f()
}, completion: nil)
}
}
} }
public protocol ContainableController: class { public protocol ContainableController: class {

View File

@ -1,6 +1,7 @@
public enum ContextMenuActionContent { public enum ContextMenuActionContent {
case text(String) case text(String)
case icon(UIImage)
} }
public struct ContextMenuAction { public struct ContextMenuAction {

View File

@ -2,17 +2,31 @@ import Foundation
import AsyncDisplayKit import AsyncDisplayKit
final class ContextMenuActionNode: ASDisplayNode { final class ContextMenuActionNode: ASDisplayNode {
private let textNode: ASTextNode private let textNode: ASTextNode?
private let iconNode: ASImageNode?
private let action: () -> Void private let action: () -> Void
private let button: HighlightTrackingButton private let button: HighlightTrackingButton
var dismiss: (() -> Void)? var dismiss: (() -> Void)?
init(action: ContextMenuAction) { init(action: ContextMenuAction) {
self.textNode = ASTextNode()
switch action.content { switch action.content {
case let .text(title): case let .text(title):
self.textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: UIColor.white) let textNode = ASTextNode()
textNode.isLayerBacked = true
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: UIColor.white)
self.textNode = textNode
self.iconNode = nil
case let .icon(image):
let iconNode = ASImageNode()
iconNode.displaysAsynchronously = false
iconNode.displayWithoutProcessing = true
iconNode.image = image
self.iconNode = iconNode
self.textNode = nil
} }
self.action = action.action self.action = action.action
@ -21,7 +35,12 @@ final class ContextMenuActionNode: ASDisplayNode {
super.init() super.init()
self.backgroundColor = UIColor(white: 0.0, alpha: 0.8) self.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
self.addSubnode(self.textNode) if let textNode = self.textNode {
self.addSubnode(textNode)
}
if let iconNode = self.iconNode {
self.addSubnode(iconNode)
}
self.button.highligthedChanged = { [weak self] highlighted in self.button.highligthedChanged = { [weak self] highlighted in
self?.backgroundColor = highlighted ? UIColor(white: 0.0, alpha: 0.4) : UIColor(white: 0.0, alpha: 0.8) self?.backgroundColor = highlighted ? UIColor(white: 0.0, alpha: 0.4) : UIColor(white: 0.0, alpha: 0.8)
@ -45,14 +64,26 @@ final class ContextMenuActionNode: ASDisplayNode {
} }
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
let textSize = self.textNode.measure(constrainedSize) if let textNode = self.textNode {
return CGSize(width: textSize.width + 36.0, height: 54.0) let textSize = textNode.measure(constrainedSize)
return CGSize(width: textSize.width + 36.0, height: 54.0)
} else if let iconNode = self.iconNode, let image = iconNode.image {
return CGSize(width: image.size.width + 36.0, height: 54.0)
} else {
return CGSize(width: 36.0, height: 54.0)
}
} }
override func layout() { override func layout() {
super.layout() super.layout()
self.button.frame = self.bounds self.button.frame = self.bounds
self.textNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - self.textNode.calculatedSize.width) / 2.0), y: floor((self.bounds.size.height - self.textNode.calculatedSize.height) / 2.0)), size: self.textNode.calculatedSize) if let textNode = self.textNode {
textNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - textNode.calculatedSize.width) / 2.0), y: floor((self.bounds.size.height - textNode.calculatedSize.height) / 2.0)), size: textNode.calculatedSize)
}
if let iconNode = self.iconNode, let image = iconNode.image {
let iconSize = image.size
iconNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - iconSize.width) / 2.0), y: floor((self.bounds.size.height - iconSize.height) / 2.0)), size: iconSize)
}
} }
} }

View File

@ -15,10 +15,12 @@ public struct GridNodeInsertItem {
public struct GridNodeUpdateItem { public struct GridNodeUpdateItem {
public let index: Int public let index: Int
public let previousIndex: Int
public let item: GridItem public let item: GridItem
public init(index: Int, item: GridItem) { public init(index: Int, previousIndex: Int, item: GridItem) {
self.index = index self.index = index
self.previousIndex = previousIndex
self.item = item self.item = item
} }
} }
@ -139,15 +141,17 @@ public struct GridNodeTransaction {
public let updateItems: [GridNodeUpdateItem] public let updateItems: [GridNodeUpdateItem]
public let scrollToItem: GridNodeScrollToItem? public let scrollToItem: GridNodeScrollToItem?
public let updateLayout: GridNodeUpdateLayout? public let updateLayout: GridNodeUpdateLayout?
public let itemTransition: ContainedViewLayoutTransition
public let stationaryItems: GridNodeStationaryItems public let stationaryItems: GridNodeStationaryItems
public let updateFirstIndexInSectionOffset: Int? public let updateFirstIndexInSectionOffset: Int?
public init(deleteItems: [Int], insertItems: [GridNodeInsertItem], updateItems: [GridNodeUpdateItem], scrollToItem: GridNodeScrollToItem?, updateLayout: GridNodeUpdateLayout?, stationaryItems: GridNodeStationaryItems, updateFirstIndexInSectionOffset: Int?) { public init(deleteItems: [Int], insertItems: [GridNodeInsertItem], updateItems: [GridNodeUpdateItem], scrollToItem: GridNodeScrollToItem?, updateLayout: GridNodeUpdateLayout?, itemTransition: ContainedViewLayoutTransition, stationaryItems: GridNodeStationaryItems, updateFirstIndexInSectionOffset: Int?) {
self.deleteItems = deleteItems self.deleteItems = deleteItems
self.insertItems = insertItems self.insertItems = insertItems
self.updateItems = updateItems self.updateItems = updateItems
self.scrollToItem = scrollToItem self.scrollToItem = scrollToItem
self.updateLayout = updateLayout self.updateLayout = updateLayout
self.itemTransition = itemTransition
self.stationaryItems = stationaryItems self.stationaryItems = stationaryItems
self.updateFirstIndexInSectionOffset = updateFirstIndexInSectionOffset self.updateFirstIndexInSectionOffset = updateFirstIndexInSectionOffset
} }
@ -300,8 +304,8 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
} }
for updatedItem in transaction.updateItems { for updatedItem in transaction.updateItems {
self.items[updatedItem.index] = updatedItem.item self.items[updatedItem.previousIndex] = updatedItem.item
if let itemNode = self.itemNodes[updatedItem.index] { if let itemNode = self.itemNodes[updatedItem.previousIndex] {
updatedItem.item.update(node: itemNode) updatedItem.item.update(node: itemNode)
} }
} }
@ -377,7 +381,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
generatedScrollToItem = nil generatedScrollToItem = nil
} }
self.applyPresentaionLayoutTransition(self.generatePresentationLayoutTransition(stationaryItems: transaction.stationaryItems, layoutTransactionOffset: layoutTransactionOffset, scrollToItem: generatedScrollToItem), removedNodes: removedNodes, updateLayoutTransition: transaction.updateLayout?.transition, completion: completion) self.applyPresentaionLayoutTransition(self.generatePresentationLayoutTransition(stationaryItems: transaction.stationaryItems, layoutTransactionOffset: layoutTransactionOffset, scrollToItem: generatedScrollToItem), removedNodes: removedNodes, updateLayoutTransition: transaction.updateLayout?.transition, itemTransition: transaction.itemTransition, completion: completion)
} }
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
@ -396,7 +400,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) { public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !self.applyingContentOffset { if !self.applyingContentOffset {
self.applyPresentaionLayoutTransition(self.generatePresentationLayoutTransition(layoutTransactionOffset: 0.0), removedNodes: [], updateLayoutTransition: nil, completion: { _ in }) self.applyPresentaionLayoutTransition(self.generatePresentationLayoutTransition(layoutTransactionOffset: 0.0), removedNodes: [], updateLayoutTransition: nil, itemTransition: .immediate, completion: { _ in })
} }
} }
@ -736,25 +740,33 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
return lowestHeaderNode return lowestHeaderNode
} }
private func applyPresentaionLayoutTransition(_ presentationLayoutTransition: GridNodePresentationLayoutTransition, removedNodes: [GridItemNode], updateLayoutTransition: ContainedViewLayoutTransition?, completion: (GridNodeDisplayedItemRange) -> Void) { private func applyPresentaionLayoutTransition(_ presentationLayoutTransition: GridNodePresentationLayoutTransition, removedNodes: [GridItemNode], updateLayoutTransition: ContainedViewLayoutTransition?, itemTransition: ContainedViewLayoutTransition, completion: (GridNodeDisplayedItemRange) -> Void) {
var previousItemFrames: ([WrappedGridItemNode: CGRect])? var previousItemFrames: [WrappedGridItemNode: CGRect]?
var saveItemFrames = false
switch presentationLayoutTransition.transition { switch presentationLayoutTransition.transition {
case .animated: case .animated:
var itemFrames: [WrappedGridItemNode: CGRect] = [:] saveItemFrames = true
let contentOffset = self.scrollView.contentOffset
for (_, itemNode) in self.itemNodes {
itemFrames[WrappedGridItemNode(node: itemNode)] = itemNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
for (_, sectionNode) in self.sectionNodes {
itemFrames[WrappedGridItemNode(node: sectionNode)] = sectionNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
for itemNode in removedNodes {
itemFrames[WrappedGridItemNode(node: itemNode)] = itemNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
previousItemFrames = itemFrames
case .immediate: case .immediate:
break break
} }
if case .animated = itemTransition {
saveItemFrames = true
}
if saveItemFrames {
var itemFrames: [WrappedGridItemNode: CGRect] = [:]
let contentOffset = self.scrollView.contentOffset
for (_, itemNode) in self.itemNodes {
itemFrames[WrappedGridItemNode(node: itemNode)] = itemNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
for (_, sectionNode) in self.sectionNodes {
itemFrames[WrappedGridItemNode(node: sectionNode)] = sectionNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
for itemNode in removedNodes {
itemFrames[WrappedGridItemNode(node: itemNode)] = itemNode.frame.offsetBy(dx: 0.0, dy: -contentOffset.y)
}
previousItemFrames = itemFrames
}
applyingContentOffset = true applyingContentOffset = true
@ -941,6 +953,63 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate {
itemNode.removeFromSupernode() itemNode.removeFromSupernode()
} }
} }
} else if let previousItemFrames = previousItemFrames, case let .animated(duration, curve) = itemTransition {
let timingFunction: String
switch curve {
case .easeInOut:
timingFunction = kCAMediaTimingFunctionEaseInEaseOut
case .spring:
timingFunction = kCAMediaTimingFunctionSpring
}
for index in self.itemNodes.keys {
let itemNode = self.itemNodes[index]!
if !existingItemIndices.contains(index) {
if let _ = previousItemFrames[WrappedGridItemNode(node: itemNode)] {
self.removeItemNodeWithIndex(index, removeNode: false)
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false)
itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false, completion: { [weak itemNode] _ in
itemNode?.removeFromSupernode()
})
} else {
self.removeItemNodeWithIndex(index, removeNode: true)
}
} else if let previousFrame = previousItemFrames[WrappedGridItemNode(node: itemNode)] {
itemNode.layer.animatePosition(from: CGPoint(x: previousFrame.midX, y: previousFrame.midY), to: itemNode.layer.position, duration: duration, timingFunction: timingFunction)
} else {
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12, timingFunction: kCAMediaTimingFunctionEaseIn)
itemNode.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5)
}
}
for itemNode in removedNodes {
if let _ = previousItemFrames[WrappedGridItemNode(node: itemNode)] {
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false)
itemNode.layer.animateScale(from: 1.0, to: 0.1, duration: 0.18, timingFunction: kCAMediaTimingFunctionEaseIn, removeOnCompletion: false, completion: { [weak itemNode] _ in
itemNode?.removeFromSupernode()
})
} else {
itemNode.removeFromSupernode()
}
}
for wrappedSection in self.sectionNodes.keys {
let sectionNode = self.sectionNodes[wrappedSection]!
if !existingSections.contains(wrappedSection) {
if let _ = previousItemFrames[WrappedGridItemNode(node: sectionNode)] {
self.removeSectionNodeWithSection(wrappedSection, removeNode: false)
sectionNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: timingFunction, removeOnCompletion: false, completion: { [weak sectionNode] _ in
sectionNode?.removeFromSupernode()
})
} else {
self.removeSectionNodeWithSection(wrappedSection, removeNode: true)
}
} else if let previousFrame = previousItemFrames[WrappedGridItemNode(node: sectionNode)] {
sectionNode.layer.animatePosition(from: CGPoint(x: previousFrame.midX, y: previousFrame.midY), to: sectionNode.layer.position, duration: duration, timingFunction: timingFunction)
} else {
sectionNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseIn)
}
}
} else { } else {
for index in self.itemNodes.keys { for index in self.itemNodes.keys {
if !existingItemIndices.contains(index) { if !existingItemIndices.contains(index) {

View File

@ -25,9 +25,11 @@ open class GridNodeScroller: ASDisplayNode, UIGestureRecognizerDelegate {
} }
override init() { override init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return GridNodeScrollerView() return GridNodeScrollerView()
}, didLoad: nil) })
self.scrollView.scrollsToTop = false self.scrollView.scrollsToTop = false
} }

View File

@ -13,9 +13,11 @@ final class LegacyPresentedControllerNode: ASDisplayNode {
} }
override init() { override init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return UITracingLayerView() return UITracingLayerView()
}, didLoad: nil) })
} }
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {

View File

@ -4,6 +4,7 @@ import SwiftSignalKit
private let usePerformanceTracker = false private let usePerformanceTracker = false
private let useDynamicTuning = false private let useDynamicTuning = false
private let useBackgroundDeallocation = false
private let infiniteScrollSize: CGFloat = 10000.0 private let infiniteScrollSize: CGFloat = 10000.0
private let insertionAnimationDuration: Double = 0.4 private let insertionAnimationDuration: Double = 0.4
@ -29,7 +30,13 @@ private final class ListViewBackingLayer: CALayer {
} }
} }
final class ListViewBackingView: UIView { #if os(iOS)
typealias ListBaseView = UIView
#else
typealias ListBaseView = NSView
#endif
final class ListViewBackingView: ListBaseView {
weak var target: ListView? weak var target: ListView?
override class var layerClass: AnyClass { override class var layerClass: AnyClass {
@ -193,9 +200,11 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
performanceTrackerConfig.reportStackTraces = true performanceTrackerConfig.reportStackTraces = true
self.performanceTracker = FBAnimationPerformanceTracker(config: performanceTrackerConfig)*/ self.performanceTracker = FBAnimationPerformanceTracker(config: performanceTrackerConfig)*/
super.init(viewBlock: { Void -> UIView in super.init()
self.setViewBlock({ Void -> UIView in
return ListViewBackingView() return ListViewBackingView()
}, didLoad: nil) })
self.clipsToBounds = true self.clipsToBounds = true
@ -261,11 +270,20 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
self.pauseAnimations() self.pauseAnimations()
self.displayLink.invalidate() self.displayLink.invalidate()
for itemNode in self.itemNodes { if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode) for itemNode in self.itemNodes {
} ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
for itemHeaderNode in self.itemHeaderNodes { }
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemHeaderNode) for itemHeaderNode in self.itemHeaderNodes {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemHeaderNode)
}
} else {
for itemNode in self.itemNodes {
ASPerformMainThreadDeallocation(itemNode)
}
for itemHeaderNode in self.itemHeaderNodes {
ASPerformMainThreadDeallocation(itemHeaderNode)
}
} }
self.waitingForNodesDisposable.dispose() self.waitingForNodesDisposable.dispose()
@ -2089,17 +2107,31 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
animation.completion = { _ in animation.completion = { _ in
for itemNode in temporaryPreviousNodes { for itemNode in temporaryPreviousNodes {
itemNode.removeFromSupernode() itemNode.removeFromSupernode()
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode) if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
} else {
ASPerformMainThreadDeallocation(itemNode)
}
} }
for headerNode in temporaryHeaderNodes { for headerNode in temporaryHeaderNodes {
headerNode.removeFromSupernode() headerNode.removeFromSupernode()
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: headerNode) if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: headerNode)
} else {
ASPerformMainThreadDeallocation(headerNode)
}
} }
} }
self.layer.add(animation, forKey: nil) self.layer.add(animation, forKey: nil)
} else { } else {
for itemNode in temporaryPreviousNodes { if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode) for itemNode in temporaryPreviousNodes {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: itemNode)
}
} else {
for itemNode in temporaryPreviousNodes {
ASPerformMainThreadDeallocation(itemNode)
}
} }
} }
} }
@ -2135,7 +2167,11 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
for (previousNode, _) in previousApparentFrames { for (previousNode, _) in previousApparentFrames {
if previousNode.supernode == nil { if previousNode.supernode == nil {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: previousNode) if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: previousNode)
} else {
ASPerformMainThreadDeallocation(previousNode)
}
} }
} }
@ -2469,7 +2505,11 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
let node = self.itemNodes[i] let node = self.itemNodes[i]
if node.index == nil && node.apparentHeight <= CGFloat.ulpOfOne { if node.index == nil && node.apparentHeight <= CGFloat.ulpOfOne {
self.removeItemNodeAtIndex(i) self.removeItemNodeAtIndex(i)
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: node) if useBackgroundDeallocation {
ASDeallocQueue.sharedDeallocation().releaseObject(inBackground: node)
} else {
ASPerformMainThreadDeallocation(node)
}
} else { } else {
i += 1 i += 1
} }

View File

@ -62,13 +62,16 @@ open class ListViewItemHeaderNode: ASDisplayNode {
if seeThrough { if seeThrough {
if (layerBacked) { if (layerBacked) {
super.init(layerBlock: { super.init()
self.setLayerBlock({
return CASeeThroughTracingLayer() return CASeeThroughTracingLayer()
}, didLoad: nil) })
} else { } else {
super.init(viewBlock: { super.init()
self.setViewBlock({
return CASeeThroughTracingView() return CASeeThroughTracingView()
}, didLoad: nil) })
} }
} else { } else {
super.init() super.init()

View File

@ -174,22 +174,27 @@ open class ListViewItemNode: ASDisplayNode {
/*if layerBacked { /*if layerBacked {
super.init(layerBlock: { super.init(layerBlock: {
return ASTransformLayer() return ASTransformLayer()
}, didLoad: nil) })
} else { } else {
super.init(viewBlock: { super.init()
self.setViewBlock({
return ListViewItemView() return ListViewItemView()
}, didLoad: nil) })
}*/ }*/
if seeThrough { if seeThrough {
if (layerBacked) { if (layerBacked) {
super.init(layerBlock: { super.init()
self.setLayerBlock({
return CASeeThroughTracingLayer() return CASeeThroughTracingLayer()
}, didLoad: nil) })
} else { } else {
super.init(viewBlock: { super.init()
self.setViewBlock({
return CASeeThroughTracingView() return CASeeThroughTracingView()
}, didLoad: nil) })
} }
} else { } else {
super.init() super.init()

View File

@ -0,0 +1,5 @@
import Foundation
import AppKit
class ListViewScroller: CALayer {
}

View File

@ -23,6 +23,10 @@ public final class NavigationBarTheme {
self.backgroundColor = backgroundColor self.backgroundColor = backgroundColor
self.separatorColor = separatorColor self.separatorColor = separatorColor
} }
public func withUpdatedSeparatorColor(_ color: UIColor) -> NavigationBarTheme {
return NavigationBarTheme(buttonColor: self.buttonColor, primaryTextColor: self.primaryTextColor, backgroundColor: self.backgroundColor, separatorColor: color)
}
} }
private func backArrowImage(color: UIColor) -> UIImage? { private func backArrowImage(color: UIColor) -> UIImage? {
@ -478,7 +482,7 @@ open class NavigationBar: ASDisplayNode {
let finalX: CGFloat = floor((size.width - backButtonSize.width) / 2.0) - size.width let finalX: CGFloat = floor((size.width - backButtonSize.width) / 2.0) - size.width
self.backButtonNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - backButtonSize.height) / 2.0)), size: backButtonSize) self.backButtonNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - backButtonSize.height) / 2.0)), size: backButtonSize)
self.backButtonNode.alpha = 1.0 - progress self.backButtonNode.alpha = (1.0 - progress) * (1.0 - progress)
if let transitionTitleNode = self.transitionTitleNode { if let transitionTitleNode = self.transitionTitleNode {
let transitionTitleSize = transitionTitleNode.measure(CGSize(width: size.width, height: nominalHeight)) let transitionTitleSize = transitionTitleNode.measure(CGSize(width: size.width, height: nominalHeight))
@ -487,7 +491,7 @@ open class NavigationBar: ASDisplayNode {
let finalX: CGFloat = floor((size.width - transitionTitleSize.width) / 2.0) - size.width let finalX: CGFloat = floor((size.width - transitionTitleSize.width) / 2.0) - size.width
transitionTitleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - transitionTitleSize.height) / 2.0)), size: transitionTitleSize) transitionTitleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - transitionTitleSize.height) / 2.0)), size: transitionTitleSize)
transitionTitleNode.alpha = progress transitionTitleNode.alpha = progress * progress
} }
self.backButtonArrow.frame = CGRect(origin: CGPoint(x: 8.0 - progress * size.width, y: contentVerticalOrigin + floor((nominalHeight - 22.0) / 2.0)), size: CGSize(width: 13.0, height: 22.0)) self.backButtonArrow.frame = CGRect(origin: CGPoint(x: 8.0 - progress * size.width, y: contentVerticalOrigin + floor((nominalHeight - 22.0) / 2.0)), size: CGSize(width: 13.0, height: 22.0))
@ -532,7 +536,7 @@ open class NavigationBar: ASDisplayNode {
let finalX: CGFloat = floor((size.width - transitionBackButtonSize.width) / 2.0) let finalX: CGFloat = floor((size.width - transitionBackButtonSize.width) / 2.0)
transitionBackButtonNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - transitionBackButtonSize.height) / 2.0)), size: transitionBackButtonSize) transitionBackButtonNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floor((nominalHeight - transitionBackButtonSize.height) / 2.0)), size: transitionBackButtonSize)
transitionBackButtonNode.alpha = 1.0 - progress transitionBackButtonNode.alpha = (1.0 - progress) * (1.0 - progress)
} }
if let transitionBackArrowNode = self.transitionBackArrowNode { if let transitionBackArrowNode = self.transitionBackArrowNode {
@ -562,7 +566,7 @@ open class NavigationBar: ASDisplayNode {
let finalX: CGFloat = leftButtonInset let finalX: CGFloat = leftButtonInset
self.titleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize) self.titleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize)
self.titleNode.alpha = 1.0 - progress self.titleNode.alpha = (1.0 - progress) * (1.0 - progress)
case .bottom: case .bottom:
var initialX: CGFloat = backButtonInset var initialX: CGFloat = backButtonInset
if otherNavigationBar.backButtonNode.supernode != nil { if otherNavigationBar.backButtonNode.supernode != nil {
@ -572,7 +576,7 @@ open class NavigationBar: ASDisplayNode {
let finalX: CGFloat = floor((size.width - titleSize.width) / 2.0) let finalX: CGFloat = floor((size.width - titleSize.width) / 2.0)
self.titleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize) self.titleNode.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize)
self.titleNode.alpha = progress self.titleNode.alpha = progress * progress
} }
} else { } else {
self.titleNode.alpha = 1.0 self.titleNode.alpha = 1.0
@ -581,15 +585,45 @@ open class NavigationBar: ASDisplayNode {
} }
if let titleView = self.titleView { if let titleView = self.titleView {
let titleViewSize = CGSize(width: max(1.0, size.width - leftTitleInset - leftTitleInset), height: nominalHeight) let titleSize = CGSize(width: max(1.0, size.width - leftTitleInset - leftTitleInset), height: nominalHeight)
titleView.frame = CGRect(origin: CGPoint(x: leftTitleInset, y: contentVerticalOrigin), size: titleViewSize) titleView.frame = CGRect(origin: CGPoint(x: leftTitleInset, y: contentVerticalOrigin), size: titleSize)
if let transitionState = self.transitionState, let otherNavigationBar = transitionState.navigationBar {
let progress = transitionState.progress
switch transitionState.role {
case .top:
let initialX = floor((size.width - titleSize.width) / 2.0)
let finalX: CGFloat = leftButtonInset
titleView.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize)
titleView.alpha = (1.0 - progress) * (1.0 - progress)
case .bottom:
var initialX: CGFloat = backButtonInset
if otherNavigationBar.backButtonNode.supernode != nil {
initialX += floor((otherNavigationBar.backButtonNode.frame.size.width - titleSize.width) / 2.0)
}
initialX += size.width * 0.3
let finalX: CGFloat = floor((size.width - titleSize.width) / 2.0)
titleView.frame = CGRect(origin: CGPoint(x: initialX * (1.0 - progress) + finalX * progress, y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize)
titleView.alpha = progress * progress
}
} else {
titleView.alpha = 1.0
titleView.frame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize)
}
} }
//self.effectView.frame = self.bounds
} }
public func makeTransitionTitleNode(foregroundColor: UIColor) -> ASDisplayNode? { public func makeTransitionTitleNode(foregroundColor: UIColor) -> ASDisplayNode? {
if let title = self.title { if let titleView = self.titleView {
if let transitionView = titleView as? NavigationBarTitleTransitionNode {
return transitionView.makeTransitionMirrorNode()
} else {
return nil
}
} else if let title = self.title {
let node = ASTextNode() let node = ASTextNode()
node.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: foregroundColor) node.attributedText = NSAttributedString(string: title, font: Font.semibold(17.0), textColor: foregroundColor)
return node return node

View File

@ -0,0 +1,6 @@
import Foundation
import AsyncDisplayKit
public protocol NavigationBarTitleTransitionNode {
func makeTransitionMirrorNode() -> ASDisplayNode
}

View File

@ -78,23 +78,39 @@ public final class StatusBar: ASDisplayNode {
private var proxyNode: StatusBarProxyNode? private var proxyNode: StatusBarProxyNode?
private var removeProxyNodeScheduled = false private var removeProxyNodeScheduled = false
let offsetNode = ASDisplayNode()
private let inCallBackgroundNode = ASDisplayNode() private let inCallBackgroundNode = ASDisplayNode()
private let inCallLabel: StatusBarLabelNode private let inCallLabel: StatusBarLabelNode
private var inCallText: String? = nil private var inCallText: String? = nil
public var verticalOffset: CGFloat = 0.0 {
didSet {
if !self.verticalOffset.isEqual(to: oldValue) {
self.offsetNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -self.verticalOffset), size: CGSize())
self.layer.invalidateUpTheTree()
}
}
}
public override init() { public override init() {
self.inCallLabel = StatusBarLabelNode() self.inCallLabel = StatusBarLabelNode()
self.inCallLabel.isLayerBacked = true self.inCallLabel.isLayerBacked = true
self.offsetNode.isLayerBacked = true
let labelSize = self.inCallLabel.measure(CGSize(width: 300.0, height: 300.0)) let labelSize = self.inCallLabel.measure(CGSize(width: 300.0, height: 300.0))
self.inCallLabel.frame = CGRect(origin: CGPoint(x: 10.0, y: 20.0 + 4.0), size: labelSize) self.inCallLabel.frame = CGRect(origin: CGPoint(x: 10.0, y: 20.0 + 4.0), size: labelSize)
super.init(viewBlock: { super.init()
self.setViewBlock({
return StatusBarView() return StatusBarView()
}, didLoad: nil) })
(self.view as! StatusBarView).node = self (self.view as! StatusBarView).node = self
self.addSubnode(self.offsetNode)
self.addSubnode(self.inCallBackgroundNode) self.addSubnode(self.inCallBackgroundNode)
self.layer.setTraceableInfo(CATracingLayerInfo(shouldBeAdjustedToInverseTransform: true, userData: self, tracingTag: WindowTracingTags.statusBar)) self.layer.setTraceableInfo(CATracingLayerInfo(shouldBeAdjustedToInverseTransform: true, userData: self, tracingTag: WindowTracingTags.statusBar))

View File

@ -159,19 +159,21 @@ class StatusBarManager {
var visibleStatusBars: [StatusBar] = [] var visibleStatusBars: [StatusBar] = []
var globalStatusBar: (StatusBarStyle, CGFloat)? var globalStatusBar: (StatusBarStyle, CGFloat, CGFloat)?
var coveredIdentity = false var coveredIdentity = false
var statusBarIndex = 0 var statusBarIndex = 0
for i in 0 ..< mappedSurfaces.count { for i in 0 ..< mappedSurfaces.count {
for mappedStatusBar in mappedSurfaces[i].statusBars { for mappedStatusBar in mappedSurfaces[i].statusBars {
if let statusBar = mappedStatusBar.statusBar { if let statusBar = mappedStatusBar.statusBar {
if mappedStatusBar.frame.origin.equalTo(CGPoint()) && !statusBar.layer.hasPositionOrOpacityAnimations() { if mappedStatusBar.frame.origin.equalTo(CGPoint()) && !statusBar.layer.hasPositionOrOpacityAnimations() && !statusBar.offsetNode.layer.hasPositionAnimations() {
if !coveredIdentity { if !coveredIdentity {
if statusBar.statusBarStyle != .Hide { if statusBar.statusBarStyle != .Hide {
coveredIdentity = CGFloat(1.0).isLessThanOrEqualTo(statusBar.alpha) if statusBar.offsetNode.frame.origin.equalTo(CGPoint()) {
coveredIdentity = CGFloat(1.0).isLessThanOrEqualTo(statusBar.alpha)
}
if statusBarIndex == 0 && globalStatusBar == nil { if statusBarIndex == 0 && globalStatusBar == nil {
globalStatusBar = (mappedStatusBar.style, statusBar.alpha) globalStatusBar = (mappedStatusBar.style, statusBar.alpha, statusBar.offsetNode.frame.origin.y)
} else { } else {
visibleStatusBars.append(statusBar) visibleStatusBars.append(statusBar)
} }
@ -184,7 +186,7 @@ class StatusBarManager {
if !coveredIdentity { if !coveredIdentity {
coveredIdentity = true coveredIdentity = true
if statusBarIndex == 0 && globalStatusBar == nil { if statusBarIndex == 0 && globalStatusBar == nil {
globalStatusBar = (mappedStatusBar.style, 1.0) globalStatusBar = (mappedStatusBar.style, 1.0, 0.0)
} }
} }
} }
@ -223,7 +225,14 @@ class StatusBarManager {
if self.host.statusBarStyle != statusBarStyle { if self.host.statusBarStyle != statusBarStyle {
self.host.statusBarStyle = statusBarStyle self.host.statusBarStyle = statusBarStyle
} }
self.host.statusBarWindow?.alpha = globalStatusBar.1 if let statusBarWindow = self.host.statusBarWindow {
statusBarWindow.alpha = globalStatusBar.1
var statusBarBounds = statusBarWindow.bounds
if !statusBarBounds.origin.y.isEqual(to: globalStatusBar.2) {
statusBarBounds.origin.y = globalStatusBar.2
statusBarWindow.bounds = statusBarBounds
}
}
} else { } else {
self.host.statusBarWindow?.alpha = 0.0 self.host.statusBarWindow?.alpha = 0.0
} }

View File

@ -115,7 +115,7 @@ private func tintStatusBarItem(_ context: DrawingContext, type: StatusBarItemTyp
targetX += 1 targetX += 1
} }
let batteryColor = (baseMidRow + baseX).pointee let batteryColor = (baseMidRow + baseX + 2).pointee
let batteryR = (batteryColor >> 16) & 0xff let batteryR = (batteryColor >> 16) & 0xff
let batteryG = (batteryColor >> 8) & 0xff let batteryG = (batteryColor >> 8) & 0xff
let batteryB = batteryColor & 0xff let batteryB = batteryColor & 0xff

View File

@ -52,9 +52,11 @@ open class SwitchNode: ASDisplayNode {
} }
override public init() { override public init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return SwitchNodeView() return SwitchNodeView()
}, didLoad: nil) })
} }
override open func didLoad() { override open func didLoad() {

View File

@ -17,9 +17,11 @@ final class TabBarControllerNode: ASDisplayNode {
init(theme: TabBarControllerTheme, itemSelected: @escaping (Int) -> Void) { init(theme: TabBarControllerTheme, itemSelected: @escaping (Int) -> Void) {
self.tabBarNode = TabBarNode(theme: theme, itemSelected: itemSelected) self.tabBarNode = TabBarNode(theme: theme, itemSelected: itemSelected)
super.init(viewBlock: { super.init()
self.setViewBlock({
return UITracingLayerView() return UITracingLayerView()
}, didLoad: nil) })
self.backgroundColor = theme.backgroundColor self.backgroundColor = theme.backgroundColor

View File

@ -26,8 +26,10 @@ public class TextFieldNode: ASDisplayNode {
} }
override public init() { override public init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return TextFieldNodeView() return TextFieldNodeView()
}, didLoad: nil) })
} }
} }

View File

@ -182,6 +182,10 @@ public extension CGRect {
public var bottomRight: CGPoint { public var bottomRight: CGPoint {
return CGPoint(x: self.maxX, y: self.maxY) return CGPoint(x: self.maxX, y: self.maxY)
} }
public var center: CGPoint {
return CGPoint(x: self.midX, y: self.midY)
}
} }
public extension CGPoint { public extension CGPoint {

View File

@ -19,9 +19,11 @@ private final class ViewControllerTracingNodeView: UITracingLayerView {
open class ViewControllerTracingNode: ASDisplayNode { open class ViewControllerTracingNode: ASDisplayNode {
override public init() { override public init() {
super.init(viewBlock: { super.init()
self.setViewBlock({
return ViewControllerTracingNodeView() return ViewControllerTracingNodeView()
}, didLoad: nil) })
} }
override open func didLoad() { override open func didLoad() {

19
DisplayMac/DisplayMac.h Normal file
View File

@ -0,0 +1,19 @@
//
// DisplayMac.h
// DisplayMac
//
// Created by Peter on 8/13/17.
// Copyright © 2017 Telegram. All rights reserved.
//
#import <Cocoa/Cocoa.h>
//! Project version number for DisplayMac.
FOUNDATION_EXPORT double DisplayMacVersionNumber;
//! Project version string for DisplayMac.
FOUNDATION_EXPORT const unsigned char DisplayMacVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <DisplayMac/PublicHeader.h>

26
DisplayMac/Info.plist Normal file
View File

@ -0,0 +1,26 @@
<?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>en</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>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 Telegram. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>