mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-28 08:30:11 +00:00
no message
This commit is contained in:
parent
8131db136d
commit
2d79df7e75
@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
D00701982029CAD6006B9E34 /* TooltipController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00701972029CAD6006B9E34 /* TooltipController.swift */; };
|
||||
D007019A2029CAE2006B9E34 /* TooltipControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00701992029CAE2006B9E34 /* TooltipControllerNode.swift */; };
|
||||
D0078A681C92B21400DF6D92 /* StatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0078A671C92B21400DF6D92 /* StatusBar.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, ); }; };
|
||||
@ -62,6 +64,7 @@
|
||||
D05174B41EAA833200A1BF36 /* CASeeThroughTracingLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = D05174B21EAA833200A1BF36 /* CASeeThroughTracingLayer.m */; };
|
||||
D053CB601D22B4F200DD41DF /* CATracingLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = D053CB5E1D22B4F200DD41DF /* CATracingLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D053CB611D22B4F200DD41DF /* CATracingLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = D053CB5F1D22B4F200DD41DF /* CATracingLayer.m */; };
|
||||
D053DAD12018ECF900993D32 /* WindowCoveringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D053DAD02018ECF900993D32 /* WindowCoveringView.swift */; };
|
||||
D05BE4AB1D1F25E3002BD72C /* PresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05BE4AA1D1F25E3002BD72C /* PresentationContext.swift */; };
|
||||
D05CC2671B69316F00E235A3 /* Display.h in Headers */ = {isa = PBXBuildFile; fileRef = D05CC2661B69316F00E235A3 /* Display.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D05CC26E1B69316F00E235A3 /* Display.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D05CC2631B69316F00E235A3 /* Display.framework */; };
|
||||
@ -90,7 +93,6 @@
|
||||
D05CC3191B695A9600E235A3 /* NavigationBackButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05CC30D1B695A9500E235A3 /* NavigationBackButtonNode.swift */; };
|
||||
D05CC31A1B695A9600E235A3 /* NavigationButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05CC30E1B695A9500E235A3 /* NavigationButtonNode.swift */; };
|
||||
D05CC31B1B695A9600E235A3 /* NavigationTitleNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05CC30F1B695A9500E235A3 /* NavigationTitleNode.swift */; };
|
||||
D05CC31C1B695A9600E235A3 /* BarButtonItemWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05CC3101B695A9600E235A3 /* BarButtonItemWrapper.swift */; };
|
||||
D05CC31D1B695A9600E235A3 /* UIBarButtonItem+Proxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D05CC3111B695A9600E235A3 /* UIBarButtonItem+Proxy.m */; };
|
||||
D05CC31E1B695A9600E235A3 /* UIBarButtonItem+Proxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D05CC3121B695A9600E235A3 /* UIBarButtonItem+Proxy.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D05CC31F1B695A9600E235A3 /* NavigationControllerProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D05CC3131B695A9600E235A3 /* NavigationControllerProxy.m */; };
|
||||
@ -125,7 +127,6 @@
|
||||
D0C2DFC61CC4431D0044FF83 /* ASTransformLayerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBB1CC4431D0044FF83 /* ASTransformLayerNode.swift */; };
|
||||
D0C2DFC71CC4431D0044FF83 /* ListViewItemNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBC1CC4431D0044FF83 /* ListViewItemNode.swift */; };
|
||||
D0C2DFC81CC4431D0044FF83 /* Spring.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBD1CC4431D0044FF83 /* Spring.swift */; };
|
||||
D0C2DFC91CC4431D0044FF83 /* ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBE1CC4431D0044FF83 /* ListView.swift */; };
|
||||
D0C2DFCA1CC4431D0044FF83 /* ListViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBF1CC4431D0044FF83 /* ListViewItem.swift */; };
|
||||
D0C2DFCB1CC4431D0044FF83 /* ListViewAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFC01CC4431D0044FF83 /* ListViewAnimation.swift */; };
|
||||
D0C2DFCD1CC4431D0044FF83 /* ListViewTransactionQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFC21CC4431D0044FF83 /* ListViewTransactionQueue.swift */; };
|
||||
@ -151,8 +152,11 @@
|
||||
D0E1D6721CBC201E00B04029 /* AsyncDisplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0E1D6711CBC201E00B04029 /* AsyncDisplayKit.framework */; };
|
||||
D0E35A031DE473B900BC6096 /* HighlightableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E35A021DE473B900BC6096 /* HighlightableButton.swift */; };
|
||||
D0E49C881B83A3580099E553 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E49C871B83A3580099E553 /* ImageCache.swift */; };
|
||||
D0E8175E2014ED7D00B82BBB /* CADisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E8175C2014ED7D00B82BBB /* CADisplayLink.swift */; };
|
||||
D0E8175F2014F18F00B82BBB /* ListViewTransactionQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFC21CC4431D0044FF83 /* ListViewTransactionQueue.swift */; };
|
||||
D0F1132F1D6F3C20008C3597 /* ContextMenuActionNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F1132E1D6F3C20008C3597 /* ContextMenuActionNode.swift */; };
|
||||
D0F7AB371DCFF6F8009AD9A1 /* ListViewItemHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F7AB361DCFF6F8009AD9A1 /* ListViewItemHeader.swift */; };
|
||||
D0F8C3932014FB7C00236FC5 /* ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2DFBE1CC4431D0044FF83 /* ListView.swift */; };
|
||||
D0FF9B301E7196F6000C66DB /* KeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FF9B2F1E7196F6000C66DB /* KeyboardManager.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -167,6 +171,8 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
D00701972029CAD6006B9E34 /* TooltipController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TooltipController.swift; sourceTree = "<group>"; };
|
||||
D00701992029CAE2006B9E34 /* TooltipControllerNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TooltipControllerNode.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>"; };
|
||||
D01159B71F40E96B0039383E /* DisplayMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DisplayMac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -211,6 +217,7 @@
|
||||
D05174B21EAA833200A1BF36 /* CASeeThroughTracingLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CASeeThroughTracingLayer.m; sourceTree = "<group>"; };
|
||||
D053CB5E1D22B4F200DD41DF /* CATracingLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CATracingLayer.h; sourceTree = "<group>"; };
|
||||
D053CB5F1D22B4F200DD41DF /* CATracingLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CATracingLayer.m; sourceTree = "<group>"; };
|
||||
D053DAD02018ECF900993D32 /* WindowCoveringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowCoveringView.swift; sourceTree = "<group>"; };
|
||||
D05BE4AA1D1F25E3002BD72C /* PresentationContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationContext.swift; sourceTree = "<group>"; };
|
||||
D05CC2631B69316F00E235A3 /* Display.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Display.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D05CC2661B69316F00E235A3 /* Display.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Display.h; sourceTree = "<group>"; };
|
||||
@ -242,7 +249,6 @@
|
||||
D05CC30D1B695A9500E235A3 /* NavigationBackButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBackButtonNode.swift; sourceTree = "<group>"; };
|
||||
D05CC30E1B695A9500E235A3 /* NavigationButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationButtonNode.swift; sourceTree = "<group>"; };
|
||||
D05CC30F1B695A9500E235A3 /* NavigationTitleNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationTitleNode.swift; sourceTree = "<group>"; };
|
||||
D05CC3101B695A9600E235A3 /* BarButtonItemWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarButtonItemWrapper.swift; sourceTree = "<group>"; };
|
||||
D05CC3111B695A9600E235A3 /* UIBarButtonItem+Proxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+Proxy.m"; sourceTree = "<group>"; };
|
||||
D05CC3121B695A9600E235A3 /* UIBarButtonItem+Proxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+Proxy.h"; sourceTree = "<group>"; };
|
||||
D05CC3131B695A9600E235A3 /* NavigationControllerProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationControllerProxy.m; sourceTree = "<group>"; };
|
||||
@ -304,6 +310,7 @@
|
||||
D0E1D6711CBC201E00B04029 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0E35A021DE473B900BC6096 /* HighlightableButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighlightableButton.swift; sourceTree = "<group>"; };
|
||||
D0E49C871B83A3580099E553 /* ImageCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
||||
D0E8175C2014ED7D00B82BBB /* CADisplayLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CADisplayLink.swift; sourceTree = "<group>"; };
|
||||
D0F1132E1D6F3C20008C3597 /* ContextMenuActionNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextMenuActionNode.swift; sourceTree = "<group>"; };
|
||||
D0F7AB361DCFF6F8009AD9A1 /* ListViewItemHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewItemHeader.swift; sourceTree = "<group>"; };
|
||||
D0FF9B2F1E7196F6000C66DB /* KeyboardManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardManager.swift; sourceTree = "<group>"; };
|
||||
@ -338,6 +345,15 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
D00701962029CAC4006B9E34 /* Tooltip */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D00701972029CAD6006B9E34 /* TooltipController.swift */,
|
||||
D00701992029CAE2006B9E34 /* TooltipControllerNode.swift */,
|
||||
);
|
||||
name = Tooltip;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D01159B81F40E96C0039383E /* DisplayMac */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -351,6 +367,7 @@
|
||||
D01847761FFA78C100075256 /* UIGestureRecognizer.swift */,
|
||||
D01847781FFA7A4E00075256 /* UITouch.swift */,
|
||||
D018477B1FFA7ABF00075256 /* UISlider.swift */,
|
||||
D0E8175C2014ED7D00B82BBB /* CADisplayLink.swift */,
|
||||
);
|
||||
path = DisplayMac;
|
||||
sourceTree = "<group>";
|
||||
@ -363,6 +380,7 @@
|
||||
D087BFB41F75181D003FD209 /* ChildWindowHostView.swift */,
|
||||
D0BB4EB91F96DCC60036D9DE /* WindowInputAccessoryHeightProvider.swift */,
|
||||
D0CB788F1F9822F8004AB79B /* WindowPanRecognizer.swift */,
|
||||
D053DAD02018ECF900993D32 /* WindowCoveringView.swift */,
|
||||
);
|
||||
name = Window;
|
||||
sourceTree = "<group>";
|
||||
@ -579,7 +597,6 @@
|
||||
D05CC30E1B695A9500E235A3 /* NavigationButtonNode.swift */,
|
||||
D05CC30F1B695A9500E235A3 /* NavigationTitleNode.swift */,
|
||||
D0C12A191F3375B400B3F66D /* NavigationBarTitleTransitionNode.swift */,
|
||||
D05CC3101B695A9600E235A3 /* BarButtonItemWrapper.swift */,
|
||||
D05CC3281B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift */,
|
||||
D0AE3D4C1D25C816001CCE13 /* NavigationBarTransitionState.swift */,
|
||||
D077B8E81F4637040046D27A /* NavigationBarBadge.swift */,
|
||||
@ -631,6 +648,7 @@
|
||||
D015F7551D1B142300E269B5 /* Tab Bar */,
|
||||
D015F7561D1B465600E269B5 /* Action Sheet */,
|
||||
D03725BF1D6DF57B007FC290 /* Context Menu */,
|
||||
D00701962029CAC4006B9E34 /* Tooltip */,
|
||||
D0DA444A1E4DCA36005FDCA7 /* Alert */,
|
||||
);
|
||||
name = Controllers;
|
||||
@ -860,6 +878,7 @@
|
||||
D01847691FFA756600075256 /* ListViewAccessoryItemNode.swift in Sources */,
|
||||
D01847611FFA703B00075256 /* UIKit.swift in Sources */,
|
||||
D01847701FFA773100075256 /* ListView.swift in Sources */,
|
||||
D0E8175F2014F18F00B82BBB /* ListViewTransactionQueue.swift in Sources */,
|
||||
D01847771FFA78C100075256 /* UIGestureRecognizer.swift in Sources */,
|
||||
D01C06C21FC254F8001561AB /* ASDisplayNode.swift in Sources */,
|
||||
D01847631FFA70FC00075256 /* UIView.swift in Sources */,
|
||||
@ -877,6 +896,7 @@
|
||||
D018476F1FFA76FD00075256 /* ListViewAccessoryItem.swift in Sources */,
|
||||
D018477A1FFA7A8800075256 /* ListViewOverscrollBackgroundNode.swift in Sources */,
|
||||
D01847741FFA780400075256 /* UIScrollView.swift in Sources */,
|
||||
D0E8175E2014ED7D00B82BBB /* CADisplayLink.swift in Sources */,
|
||||
D01847681FFA749F00075256 /* ListViewAnimation.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -891,6 +911,7 @@
|
||||
D0078A681C92B21400DF6D92 /* StatusBar.swift in Sources */,
|
||||
D05CC2F81B6955D000E235A3 /* UIViewController+Navigation.m in Sources */,
|
||||
D0F1132F1D6F3C20008C3597 /* ContextMenuActionNode.swift in Sources */,
|
||||
D053DAD12018ECF900993D32 /* WindowCoveringView.swift in Sources */,
|
||||
D02BDB021B6AC703008AFAD2 /* RuntimeUtils.swift in Sources */,
|
||||
D0BB4EBA1F96DCC60036D9DE /* WindowInputAccessoryHeightProvider.swift in Sources */,
|
||||
D05CC31F1B695A9600E235A3 /* NavigationControllerProxy.m in Sources */,
|
||||
@ -905,6 +926,7 @@
|
||||
D0BE93191E8ED71100DCC1E6 /* NativeWindowHostView.swift in Sources */,
|
||||
D05CC3251B695B0700E235A3 /* NavigationBarProxy.m in Sources */,
|
||||
D05174B41EAA833200A1BF36 /* CASeeThroughTracingLayer.m in Sources */,
|
||||
D0F8C3932014FB7C00236FC5 /* ListView.swift in Sources */,
|
||||
D03E7DE61C96B96E00C07816 /* NavigationBarTransitionContainer.swift in Sources */,
|
||||
D0C85DD01D1C082E00124894 /* ActionSheetItemGroupsContainerNode.swift in Sources */,
|
||||
D05CC2F71B6955D000E235A3 /* UIKitUtils.swift in Sources */,
|
||||
@ -916,9 +938,9 @@
|
||||
D0C2DFD01CC4431D0044FF83 /* ListViewAccessoryItemNode.swift in Sources */,
|
||||
D0DA44501E4DCBDE005FDCA7 /* AlertContentNode.swift in Sources */,
|
||||
D0D94A171D3814F900740E02 /* UniversalTapRecognizer.swift in Sources */,
|
||||
D00701982029CAD6006B9E34 /* TooltipController.swift in Sources */,
|
||||
D015F7581D1B467200E269B5 /* ActionSheetController.swift in Sources */,
|
||||
D0DA444C1E4DCA4A005FDCA7 /* AlertController.swift in Sources */,
|
||||
D0C2DFC91CC4431D0044FF83 /* ListView.swift in Sources */,
|
||||
D03E7DF91C96C5F200C07816 /* NSWeakReference.m in Sources */,
|
||||
D0DC48541BF93D8B00F672FD /* TabBarController.swift in Sources */,
|
||||
D03E7E011C974AB300C07816 /* DisplayLinkDispatcher.swift in Sources */,
|
||||
@ -933,7 +955,6 @@
|
||||
D05CC2E71B69555800E235A3 /* CAAnimationUtils.swift in Sources */,
|
||||
D05CC31B1B695A9600E235A3 /* NavigationTitleNode.swift in Sources */,
|
||||
D04C468E1F4C97BE00D30FE1 /* PageControlNode.swift in Sources */,
|
||||
D05CC31C1B695A9600E235A3 /* BarButtonItemWrapper.swift in Sources */,
|
||||
D0C2DFCF1CC4431D0044FF83 /* ListViewScroller.swift in Sources */,
|
||||
D00C7CD21E3657570080C3D5 /* TextFieldNode.swift in Sources */,
|
||||
D0DC485F1BF949FB00F672FD /* TabBarContollerNode.swift in Sources */,
|
||||
@ -966,6 +987,7 @@
|
||||
D02383821DDF798E004018B6 /* LegacyPresentedControllerNode.swift in Sources */,
|
||||
D05CC2FC1B6955D000E235A3 /* UIKitUtils.m in Sources */,
|
||||
D0C2DFC61CC4431D0044FF83 /* ASTransformLayerNode.swift in Sources */,
|
||||
D007019A2029CAE2006B9E34 /* TooltipControllerNode.swift in Sources */,
|
||||
D05CC3291B69750D00E235A3 /* InteractiveTransitionGestureRecognizer.swift in Sources */,
|
||||
D077B8E91F4637040046D27A /* NavigationBarBadge.swift in Sources */,
|
||||
D0CE67921F7DA11700FFB557 /* ActionSheetTheme.swift in Sources */,
|
||||
|
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D01159B61F40E96B0039383E"
|
||||
BuildableName = "DisplayMac.framework"
|
||||
BlueprintName = "DisplayMac"
|
||||
ReferencedContainer = "container:Display.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug Hockeyapp"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug Hockeyapp"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D01159B61F40E96B0039383E"
|
||||
BuildableName = "DisplayMac.framework"
|
||||
BlueprintName = "DisplayMac"
|
||||
ReferencedContainer = "container:Display.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release Hockeyapp"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D01159B61F40E96B0039383E"
|
||||
BuildableName = "DisplayMac.framework"
|
||||
BlueprintName = "DisplayMac"
|
||||
ReferencedContainer = "container:Display.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug Hockeyapp">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release Hockeyapp"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -12,7 +12,7 @@
|
||||
<key>DisplayMac.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>26</integer>
|
||||
<integer>24</integer>
|
||||
</dict>
|
||||
<key>DisplayTests.xcscheme</key>
|
||||
<dict>
|
||||
|
@ -54,6 +54,7 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
|
||||
|
||||
self.labelNode = ASTextNode()
|
||||
self.labelNode.maximumNumberOfLines = 1
|
||||
self.labelNode.truncationMode = .byTruncatingTail
|
||||
self.labelNode.isUserInteractionEnabled = false
|
||||
self.labelNode.displaysAsynchronously = false
|
||||
|
||||
|
@ -1,17 +1,41 @@
|
||||
import Foundation
|
||||
import AsyncDisplayKit
|
||||
|
||||
public final class AlertControllerTheme {
|
||||
public let backgroundColor: UIColor
|
||||
public let separatorColor: UIColor
|
||||
public let highlightedItemColor: UIColor
|
||||
public let primaryColor: UIColor
|
||||
public let secondaryColor: UIColor
|
||||
public let accentColor: UIColor
|
||||
public let destructiveColor: UIColor
|
||||
|
||||
public init(backgroundColor: UIColor, separatorColor: UIColor, highlightedItemColor: UIColor, primaryColor: UIColor, secondaryColor: UIColor, accentColor: UIColor, destructiveColor: UIColor) {
|
||||
self.backgroundColor = backgroundColor
|
||||
self.separatorColor = separatorColor
|
||||
self.highlightedItemColor = highlightedItemColor
|
||||
self.primaryColor = primaryColor
|
||||
self.secondaryColor = secondaryColor
|
||||
self.accentColor = accentColor
|
||||
self.destructiveColor = destructiveColor
|
||||
}
|
||||
}
|
||||
|
||||
open class AlertController: ViewController {
|
||||
private var controllerNode: AlertControllerNode {
|
||||
return self.displayNode as! AlertControllerNode
|
||||
}
|
||||
|
||||
private let theme: AlertControllerTheme
|
||||
private let contentNode: AlertContentNode
|
||||
|
||||
public init(contentNode: AlertContentNode) {
|
||||
public init(theme: AlertControllerTheme, contentNode: AlertContentNode) {
|
||||
self.theme = theme
|
||||
self.contentNode = contentNode
|
||||
|
||||
super.init(navigationBarTheme: nil)
|
||||
|
||||
self.statusBar.statusBarStyle = .Ignore
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
@ -19,7 +43,7 @@ open class AlertController: ViewController {
|
||||
}
|
||||
|
||||
override open func loadDisplayNode() {
|
||||
self.displayNode = AlertControllerNode(contentNode: self.contentNode)
|
||||
self.displayNode = AlertControllerNode(contentNode: self.contentNode, theme: self.theme)
|
||||
self.displayNodeDidLoad()
|
||||
|
||||
self.controllerNode.dismiss = { [weak self] in
|
||||
|
@ -9,17 +9,17 @@ final class AlertControllerNode: ASDisplayNode {
|
||||
|
||||
var dismiss: (() -> Void)?
|
||||
|
||||
init(contentNode: AlertContentNode) {
|
||||
init(contentNode: AlertContentNode, theme: AlertControllerTheme) {
|
||||
self.dimmingNode = ASDisplayNode()
|
||||
self.dimmingNode.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
|
||||
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.containerNode.backgroundColor = .white
|
||||
self.containerNode.backgroundColor = theme.backgroundColor
|
||||
self.containerNode.layer.cornerRadius = 14.0
|
||||
self.containerNode.layer.masksToBounds = true
|
||||
|
||||
self.effectNode = ASDisplayNode(viewBlock: {
|
||||
let view = UIView()//UIVisualEffectView(effect: UIBlurEffect(style: .light))
|
||||
let view = UIView()
|
||||
return view
|
||||
})
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
|
||||
internal class BarButtonItemWrapper {
|
||||
let parentNode: ASDisplayNode
|
||||
let barButtonItem: UIBarButtonItem
|
||||
let layoutNeeded: () -> ()
|
||||
|
||||
let buttonNode: NavigationButtonNode
|
||||
|
||||
private var setEnabledListenerKey: Int!
|
||||
private var setTitleListenerKey: Int!
|
||||
|
||||
init(parentNode: ASDisplayNode, barButtonItem: UIBarButtonItem, layoutNeeded: @escaping () -> ()) {
|
||||
self.parentNode = parentNode
|
||||
self.barButtonItem = barButtonItem
|
||||
self.layoutNeeded = layoutNeeded
|
||||
|
||||
self.buttonNode = NavigationButtonNode()
|
||||
self.buttonNode.pressed = { [weak self] in
|
||||
self?.barButtonItem.performActionOnTarget()
|
||||
return
|
||||
}
|
||||
self.parentNode.addSubnode(self.buttonNode)
|
||||
|
||||
self.setEnabledListenerKey = barButtonItem.addSetEnabledListener({ [weak self] enabled in
|
||||
self?.buttonNode.isEnabled = enabled
|
||||
return
|
||||
})
|
||||
|
||||
self.setTitleListenerKey = barButtonItem.addSetTitleListener({ [weak self] title in
|
||||
self?.buttonNode.text = title ?? ""
|
||||
if let layoutNeeded = self?.layoutNeeded {
|
||||
layoutNeeded()
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
self.buttonNode.text = barButtonItem.title ?? ""
|
||||
self.buttonNode.isEnabled = barButtonItem.isEnabled ?? true
|
||||
self.buttonNode.bold = (barButtonItem.style ?? UIBarButtonItemStyle.plain) == UIBarButtonItemStyle.done
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.barButtonItem.removeSetTitleListener(self.setTitleListenerKey)
|
||||
self.barButtonItem.removeSetEnabledListener(self.setEnabledListenerKey)
|
||||
self.buttonNode.removeFromSupernode()
|
||||
}
|
||||
}
|
@ -2,8 +2,6 @@
|
||||
|
||||
@interface CASeeThroughTracingLayer : CALayer
|
||||
|
||||
@property (nonatomic, copy) void (^updateRelativePosition)(CGPoint);
|
||||
|
||||
@end
|
||||
|
||||
@interface CASeeThroughTracingView : UIView
|
||||
|
@ -44,10 +44,6 @@
|
||||
[(CASeeThroughTracingLayer *)sublayer _mirrorTransformToSublayers];
|
||||
}
|
||||
}
|
||||
|
||||
if (_updateRelativePosition) {
|
||||
_updateRelativePosition(sublayerParentOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -45,6 +45,10 @@ final class ContextMenuContainerNode: ASDisplayNode {
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.updateLayout(transition: .immediate)
|
||||
}
|
||||
|
||||
func updateLayout(transition: ContainedViewLayoutTransition) {
|
||||
//self.effectView.frame = self.bounds
|
||||
|
||||
let maskParams = CachedMaskParams(size: self.bounds.size, relativeArrowPosition: self.relativeArrowPosition?.0 ?? self.bounds.size.width / 2.0, arrowOnBottom: self.relativeArrowPosition?.1 ?? true)
|
||||
@ -78,7 +82,12 @@ final class ContextMenuContainerNode: ASDisplayNode {
|
||||
path.close()
|
||||
|
||||
self.cachedMaskParams = maskParams
|
||||
(self.maskView.layer as? CAShapeLayer)?.path = path.cgPath
|
||||
if let layer = self.maskView.layer as? CAShapeLayer {
|
||||
if case let .animated(duration, curve) = transition, let previousPath = layer.path {
|
||||
layer.animate(from: previousPath, to: path.cgPath, keyPath: "path", timingFunction: curve.timingFunction, duration: duration)
|
||||
}
|
||||
layer.path = path.cgPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,30 @@ public struct Font {
|
||||
}
|
||||
}
|
||||
|
||||
public static func semiboldItalic(_ size: CGFloat) -> UIFont {
|
||||
if let descriptor = UIFont.systemFont(ofSize: size).fontDescriptor.withSymbolicTraits([.traitBold, .traitItalic]) {
|
||||
return UIFont(descriptor: descriptor, size: size)
|
||||
} else {
|
||||
return UIFont.italicSystemFont(ofSize: size)
|
||||
}
|
||||
}
|
||||
|
||||
public static func monospace(_ size: CGFloat) -> UIFont {
|
||||
return UIFont(name: "Menlo-Regular", size: size - 1.0) ?? UIFont.systemFont(ofSize: size)
|
||||
}
|
||||
|
||||
public static func semiboldMonospace(_ size: CGFloat) -> UIFont {
|
||||
return UIFont(name: "Menlo-Bold", size: size - 1.0) ?? UIFont.systemFont(ofSize: size)
|
||||
}
|
||||
|
||||
public static func italicMonospace(_ size: CGFloat) -> UIFont {
|
||||
return UIFont(name: "Menlo-Italic", size: size - 1.0) ?? UIFont.systemFont(ofSize: size)
|
||||
}
|
||||
|
||||
public static func semiboldItalicMonospace(_ size: CGFloat) -> UIFont {
|
||||
return UIFont(name: "Menlo-BoldItalic", size: size - 1.0) ?? UIFont.systemFont(ofSize: size)
|
||||
}
|
||||
|
||||
public static func italic(_ size: CGFloat) -> UIFont {
|
||||
return UIFont.italicSystemFont(ofSize: size)
|
||||
}
|
||||
|
@ -6,8 +6,6 @@ import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
#endif
|
||||
|
||||
private let usePerformanceTracker = false
|
||||
private let useDynamicTuning = false
|
||||
private let useBackgroundDeallocation = false
|
||||
|
||||
private let infiniteScrollSize: CGFloat = 10000.0
|
||||
@ -34,13 +32,7 @@ private final class ListViewBackingLayer: CALayer {
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
typealias ListBaseView = UIView
|
||||
#else
|
||||
typealias ListBaseView = NSView
|
||||
#endif
|
||||
|
||||
final class ListViewBackingView: ListBaseView {
|
||||
final class ListViewBackingView: UIView {
|
||||
weak var target: ListView?
|
||||
|
||||
override class var layerClass: AnyClass {
|
||||
@ -56,6 +48,7 @@ final class ListViewBackingView: ListBaseView {
|
||||
override func setNeedsDisplay() {
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
self.target?.touchesBegan(touches, with: event)
|
||||
}
|
||||
@ -80,6 +73,7 @@ final class ListViewBackingView: ListBaseView {
|
||||
}
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private final class ListViewTimerProxy: NSObject {
|
||||
@ -212,8 +206,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
private let freeResistanceSlider = UISlider()
|
||||
private let scrollingResistanceSlider = UISlider()
|
||||
|
||||
//let performanceTracker: FBAnimationPerformanceTracker
|
||||
|
||||
private var selectionTouchLocation: CGPoint?
|
||||
private var selectionTouchDelayTimer: Foundation.Timer?
|
||||
private var selectionLongTapDelayTimer: Foundation.Timer?
|
||||
@ -246,10 +238,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
|
||||
self.scroller = ListViewScroller()
|
||||
|
||||
/*var performanceTrackerConfig = FBAnimationPerformanceTracker.standardConfig()
|
||||
performanceTrackerConfig.reportStackTraces = true
|
||||
self.performanceTracker = FBAnimationPerformanceTracker(config: performanceTrackerConfig)*/
|
||||
|
||||
super.init()
|
||||
|
||||
self.setViewBlock({ () -> UIView in
|
||||
@ -266,8 +254,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
}
|
||||
}
|
||||
|
||||
//self.performanceTracker.delegate = self
|
||||
|
||||
self.scroller.alwaysBounceVertical = true
|
||||
self.scroller.contentSize = CGSize(width: 0.0, height: infiniteScrollSize * 2.0)
|
||||
self.scroller.isHidden = true
|
||||
@ -282,38 +268,12 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
|
||||
self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent))
|
||||
self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes)
|
||||
#if os(iOS)
|
||||
if #available(iOS 10.0, *) {
|
||||
self.displayLink.preferredFramesPerSecond = 60
|
||||
}
|
||||
#endif
|
||||
self.displayLink.isPaused = true
|
||||
|
||||
if useDynamicTuning {
|
||||
self.frictionSlider.addTarget(self, action: #selector(self.frictionSliderChanged(_:)), for: .valueChanged)
|
||||
self.springSlider.addTarget(self, action: #selector(self.springSliderChanged(_:)), for: .valueChanged)
|
||||
self.freeResistanceSlider.addTarget(self, action: #selector(self.freeResistanceSliderChanged(_:)), for: .valueChanged)
|
||||
self.scrollingResistanceSlider.addTarget(self, action: #selector(self.scrollingResistanceSliderChanged(_:)), for: .valueChanged)
|
||||
|
||||
self.frictionSlider.minimumValue = Float(testSpringFrictionLimits.0)
|
||||
self.frictionSlider.maximumValue = Float(testSpringFrictionLimits.1)
|
||||
self.frictionSlider.value = Float(testSpringFriction)
|
||||
|
||||
self.springSlider.minimumValue = Float(testSpringConstantLimits.0)
|
||||
self.springSlider.maximumValue = Float(testSpringConstantLimits.1)
|
||||
self.springSlider.value = Float(testSpringConstant)
|
||||
|
||||
self.freeResistanceSlider.minimumValue = Float(testSpringResistanceFreeLimits.0)
|
||||
self.freeResistanceSlider.maximumValue = Float(testSpringResistanceFreeLimits.1)
|
||||
self.freeResistanceSlider.value = Float(testSpringFreeResistance)
|
||||
|
||||
self.scrollingResistanceSlider.minimumValue = Float(testSpringResistanceScrollingLimits.0)
|
||||
self.scrollingResistanceSlider.maximumValue = Float(testSpringResistanceScrollingLimits.1)
|
||||
self.scrollingResistanceSlider.value = Float(testSpringScrollingResistance)
|
||||
|
||||
self.view.addSubview(self.frictionSlider)
|
||||
self.view.addSubview(self.springSlider)
|
||||
self.view.addSubview(self.freeResistanceSlider)
|
||||
self.view.addSubview(self.scrollingResistanceSlider)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -344,26 +304,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
self.waitingForNodesDisposable.dispose()
|
||||
}
|
||||
|
||||
@objc func frictionSliderChanged(_ slider: UISlider) {
|
||||
testSpringFriction = CGFloat(slider.value)
|
||||
print("friction: \(testSpringFriction)")
|
||||
}
|
||||
|
||||
@objc func springSliderChanged(_ slider: UISlider) {
|
||||
testSpringConstant = CGFloat(slider.value)
|
||||
print("spring: \(testSpringConstant)")
|
||||
}
|
||||
|
||||
@objc func freeResistanceSliderChanged(_ slider: UISlider) {
|
||||
testSpringFreeResistance = CGFloat(slider.value)
|
||||
print("free resistance: \(testSpringFreeResistance)")
|
||||
}
|
||||
|
||||
@objc func scrollingResistanceSliderChanged(_ slider: UISlider) {
|
||||
testSpringScrollingResistance = CGFloat(slider.value)
|
||||
print("free resistance: \(testSpringScrollingResistance)")
|
||||
}
|
||||
|
||||
private func displayLinkEvent() {
|
||||
self.updateAnimations()
|
||||
}
|
||||
@ -451,9 +391,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
self.updateHeaderItemsFlashing(animated: true)
|
||||
|
||||
self.lastContentOffsetTimestamp = 0.0
|
||||
/*if usePerformanceTracker {
|
||||
self.performanceTracker.stop()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,10 +399,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
self.isDeceleratingAfterTracking = false
|
||||
self.resetHeaderItemsFlashTimer(start: true)
|
||||
self.updateHeaderItemsFlashing(animated: true)
|
||||
|
||||
/*if usePerformanceTracker {
|
||||
self.performanceTracker.stop()
|
||||
}*/
|
||||
}
|
||||
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
@ -1083,14 +1016,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
self.visibleSize = updateSizeAndInsets.size
|
||||
self.insets = updateSizeAndInsets.insets
|
||||
|
||||
if useDynamicTuning {
|
||||
let size = updateSizeAndInsets.size
|
||||
self.frictionSlider.frame = CGRect(x: 10.0, y: size.height - insets.bottom - 10.0 - self.frictionSlider.bounds.height, width: size.width - 20.0, height: self.frictionSlider.bounds.height)
|
||||
self.springSlider.frame = CGRect(x: 10.0, y: self.frictionSlider.frame.minY - self.springSlider.bounds.height, width: size.width - 20.0, height: self.springSlider.bounds.height)
|
||||
self.freeResistanceSlider.frame = CGRect(x: 10.0, y: self.springSlider.frame.minY - self.freeResistanceSlider.bounds.height, width: size.width - 20.0, height: self.freeResistanceSlider.bounds.height)
|
||||
self.scrollingResistanceSlider.frame = CGRect(x: 10.0, y: self.freeResistanceSlider.frame.minY - self.scrollingResistanceSlider.bounds.height, width: size.width - 20.0, height: self.scrollingResistanceSlider.bounds.height)
|
||||
}
|
||||
|
||||
let wasIgnoringScrollingEvents = self.ignoreScrollingEvents
|
||||
self.ignoreScrollingEvents = true
|
||||
self.scroller.frame = CGRect(origin: CGPoint(), size: updateSizeAndInsets.size)
|
||||
@ -1596,12 +1521,6 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
apply().1()
|
||||
self.itemNodes.insert(node, at: nodeIndex)
|
||||
|
||||
if useDynamicTuning {
|
||||
self.insertSubnode(node, at: 0)
|
||||
} else {
|
||||
//self.addSubnode(node)
|
||||
}
|
||||
|
||||
var offsetHeight = node.apparentHeight
|
||||
var takenAnimation = false
|
||||
|
||||
@ -2954,6 +2873,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
let touchesPosition = touches.first!.location(in: self.view)
|
||||
|
||||
@ -3043,6 +2963,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
|
||||
self.updateScroller(transition: .immediate)
|
||||
}
|
||||
#endif
|
||||
|
||||
public func clearHighlightAnimated(_ animated: Bool) {
|
||||
if let highlightedItemIndex = self.highlightedItemIndex {
|
||||
@ -3096,6 +3017,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
return nil
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
override open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
if let selectionTouchLocation = self.selectionTouchLocation {
|
||||
let location = touches.first!.location(in: self.view)
|
||||
@ -3177,6 +3099,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
break
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
return true
|
||||
@ -3189,6 +3112,7 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
fileprivate func internalHitTest(_ point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
if self.limitHitTestToNodes {
|
||||
var foundHit = false
|
||||
@ -3204,4 +3128,5 @@ open class ListView: ASDisplayNode, UIScrollViewDelegate, UIGestureRecognizerDel
|
||||
}
|
||||
return true
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -7,10 +7,12 @@ class ListViewScroller: UIScrollView, UIGestureRecognizerDelegate {
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
#if os(iOS)
|
||||
self.scrollsToTop = false
|
||||
if #available(iOSApplicationExtension 11.0, *) {
|
||||
self.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@ -21,7 +23,9 @@ class ListViewScroller: UIScrollView, UIGestureRecognizerDelegate {
|
||||
return false
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
override func touchesShouldCancel(in view: UIView) -> Bool {
|
||||
return true
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
import Foundation
|
||||
#if os(iOS)
|
||||
import SwiftSignalKit
|
||||
#else
|
||||
import SwiftSignalKitMac
|
||||
#endif
|
||||
|
||||
public typealias ListViewTransaction = (@escaping () -> Void) -> Void
|
||||
|
||||
|
@ -75,7 +75,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
private let stripeNode: ASDisplayNode
|
||||
private let clippingNode: ASDisplayNode
|
||||
|
||||
var contentNode: NavigationBarContentNode?
|
||||
public private(set) var contentNode: NavigationBarContentNode?
|
||||
|
||||
private var itemTitleListenerKey: Int?
|
||||
private var itemTitleViewListenerKey: Int?
|
||||
@ -84,7 +84,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
private var itemLeftButtonSetEnabledListenerKey: Int?
|
||||
|
||||
private var itemRightButtonListenerKey: Int?
|
||||
private var itemRightButtonSetEnabledListenerKey: Int?
|
||||
private var itemRightButtonsListenerKey: Int?
|
||||
|
||||
private var itemBadgeListenerKey: Int?
|
||||
|
||||
@ -116,9 +116,9 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.itemRightButtonListenerKey = nil
|
||||
}
|
||||
|
||||
if let itemRightButtonSetEnabledListenerKey = self.itemRightButtonSetEnabledListenerKey {
|
||||
previousValue.rightBarButtonItem?.removeSetEnabledListener(itemRightButtonSetEnabledListenerKey)
|
||||
self.itemRightButtonSetEnabledListenerKey = nil
|
||||
if let itemRightButtonsListenerKey = self.itemRightButtonsListenerKey {
|
||||
previousValue.removeSetMultipleRightBarButtonItemsListener(itemRightButtonsListenerKey)
|
||||
self.itemRightButtonsListenerKey = nil
|
||||
}
|
||||
|
||||
if let itemBadgeListenerKey = self.itemBadgeListenerKey {
|
||||
@ -165,19 +165,14 @@ open class NavigationBar: ASDisplayNode {
|
||||
|
||||
self.itemRightButtonListenerKey = item.addSetRightBarButtonItemListener { [weak self] previousItem, currentItem, animated in
|
||||
if let strongSelf = self {
|
||||
if let itemRightButtonSetEnabledListenerKey = strongSelf.itemRightButtonSetEnabledListenerKey {
|
||||
previousItem?.removeSetEnabledListener(itemRightButtonSetEnabledListenerKey)
|
||||
strongSelf.itemRightButtonSetEnabledListenerKey = nil
|
||||
}
|
||||
|
||||
if let currentItem = currentItem {
|
||||
strongSelf.itemRightButtonSetEnabledListenerKey = currentItem.addSetEnabledListener { _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateRightButton(animated: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
strongSelf.updateRightButton(animated: animated)
|
||||
strongSelf.invalidateCalculatedLayout()
|
||||
strongSelf.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
self.itemRightButtonsListenerKey = item.addSetMultipleRightBarButtonItemsListener { [weak self] items, animated in
|
||||
if let strongSelf = self {
|
||||
strongSelf.updateRightButton(animated: animated)
|
||||
strongSelf.invalidateCalculatedLayout()
|
||||
strongSelf.requestLayout()
|
||||
@ -260,9 +255,9 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.previousItemListenerKey = previousItem.addSetTitleListener { [weak self] _, _ in
|
||||
if let strongSelf = self, let previousItem = strongSelf.previousItem {
|
||||
if let backBarButtonItem = previousItem.backBarButtonItem {
|
||||
strongSelf.backButtonNode.text = backBarButtonItem.title ?? ""
|
||||
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "")
|
||||
} else {
|
||||
strongSelf.backButtonNode.text = previousItem.title ?? ""
|
||||
strongSelf.backButtonNode.updateManualText(previousItem.title ?? "")
|
||||
}
|
||||
strongSelf.invalidateCalculatedLayout()
|
||||
strongSelf.requestLayout()
|
||||
@ -272,9 +267,9 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.previousItemBackListenerKey = previousItem.addSetBackBarButtonItemListener { [weak self] _, _, _ in
|
||||
if let strongSelf = self, let previousItem = strongSelf.previousItem {
|
||||
if let backBarButtonItem = previousItem.backBarButtonItem {
|
||||
strongSelf.backButtonNode.text = backBarButtonItem.title ?? ""
|
||||
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "")
|
||||
} else {
|
||||
strongSelf.backButtonNode.text = previousItem.title ?? ""
|
||||
strongSelf.backButtonNode.updateManualText(previousItem.title ?? "")
|
||||
}
|
||||
strongSelf.invalidateCalculatedLayout()
|
||||
strongSelf.requestLayout()
|
||||
@ -348,9 +343,8 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.backButtonArrow.removeFromSupernode()
|
||||
self.badgeNode.removeFromSupernode()
|
||||
|
||||
self.leftButtonNode.text = leftBarButtonItem.title ?? ""
|
||||
self.leftButtonNode.bold = leftBarButtonItem.style == .done
|
||||
self.leftButtonNode.isEnabled = leftBarButtonItem.isEnabled
|
||||
self.leftButtonNode.updateItems([leftBarButtonItem])
|
||||
|
||||
if self.leftButtonNode.supernode == nil {
|
||||
self.clippingNode.addSubnode(self.leftButtonNode)
|
||||
}
|
||||
@ -384,7 +378,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
}
|
||||
|
||||
if let backTitle = backTitle {
|
||||
self.backButtonNode.text = backTitle
|
||||
self.backButtonNode.updateManualText(backTitle)
|
||||
if self.backButtonNode.supernode == nil {
|
||||
self.clippingNode.addSubnode(self.backButtonNode)
|
||||
self.clippingNode.addSubnode(self.backButtonArrow)
|
||||
@ -414,7 +408,14 @@ open class NavigationBar: ASDisplayNode {
|
||||
|
||||
private func updateRightButton(animated: Bool) {
|
||||
if let item = self.item {
|
||||
if let rightBarButtonItem = item.rightBarButtonItem {
|
||||
var items: [UIBarButtonItem] = []
|
||||
if let rightBarButtonItems = item.rightBarButtonItems, !rightBarButtonItems.isEmpty {
|
||||
items = rightBarButtonItems
|
||||
} else if let rightBarButtonItem = item.rightBarButtonItem {
|
||||
items = [rightBarButtonItem]
|
||||
}
|
||||
|
||||
if !items.isEmpty {
|
||||
if animated, self.rightButtonNode.view.superview != nil {
|
||||
if let snapshotView = self.rightButtonNode.view.snapshotContentTree() {
|
||||
snapshotView.frame = self.rightButtonNode.frame
|
||||
@ -424,11 +425,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
})
|
||||
}
|
||||
}
|
||||
self.rightButtonNode.text = rightBarButtonItem.title ?? ""
|
||||
self.rightButtonNode.image = rightBarButtonItem.image
|
||||
self.rightButtonNode.bold = rightBarButtonItem.style == .done
|
||||
self.rightButtonNode.isEnabled = rightBarButtonItem.isEnabled
|
||||
self.rightButtonNode.node = rightBarButtonItem.customDisplayNode
|
||||
self.rightButtonNode.updateItems(items)
|
||||
if self.rightButtonNode.supernode == nil {
|
||||
self.clippingNode.addSubnode(self.rightButtonNode)
|
||||
}
|
||||
@ -565,13 +562,13 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.titleNode.truncationMode = .byTruncatingTail
|
||||
self.titleNode.isOpaque = false
|
||||
|
||||
self.backButtonNode.highlightChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
self.backButtonNode.highlightChanged = { [weak self] index, highlighted in
|
||||
if let strongSelf = self, index == 0 {
|
||||
strongSelf.backButtonArrow.alpha = (highlighted ? 0.4 : 1.0)
|
||||
}
|
||||
}
|
||||
self.backButtonNode.pressed = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
self.backButtonNode.pressed = { [weak self] index in
|
||||
if let strongSelf = self, index == 0 {
|
||||
if let leftBarButtonItem = strongSelf.item?.leftBarButtonItem, leftBarButtonItem.backButtonAppearance {
|
||||
leftBarButtonItem.performActionOnTarget()
|
||||
} else {
|
||||
@ -580,15 +577,25 @@ open class NavigationBar: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
self.leftButtonNode.pressed = { [weak self] in
|
||||
if let item = self?.item, let leftBarButtonItem = item.leftBarButtonItem {
|
||||
leftBarButtonItem.performActionOnTarget()
|
||||
self.leftButtonNode.pressed = { [weak self] index in
|
||||
if let item = self?.item {
|
||||
if index == 0 {
|
||||
if let leftBarButtonItem = item.leftBarButtonItem {
|
||||
leftBarButtonItem.performActionOnTarget()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.rightButtonNode.pressed = { [weak self] in
|
||||
if let item = self?.item, let rightBarButtonItem = item.rightBarButtonItem {
|
||||
rightBarButtonItem.performActionOnTarget()
|
||||
self.rightButtonNode.pressed = { [weak self] index in
|
||||
if let item = self?.item {
|
||||
if let rightBarButtonItems = item.rightBarButtonItems, !rightBarButtonItems.isEmpty {
|
||||
if index < rightBarButtonItems.count {
|
||||
rightBarButtonItems[index].performActionOnTarget()
|
||||
}
|
||||
} else if let rightBarButtonItem = item.rightBarButtonItem {
|
||||
rightBarButtonItem.performActionOnTarget()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -645,7 +652,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
var leftTitleInset: CGFloat = leftInset + 4.0
|
||||
var rightTitleInset: CGFloat = rightInset + 4.0
|
||||
if self.backButtonNode.supernode != nil {
|
||||
let backButtonSize = self.backButtonNode.measure(CGSize(width: size.width, height: nominalHeight))
|
||||
let backButtonSize = self.backButtonNode.updateLayout(constrainedSize: CGSize(width: size.width, height: nominalHeight))
|
||||
leftTitleInset += backButtonSize.width + backButtonInset + 4.0 + 4.0
|
||||
|
||||
let topHitTestSlop = (nominalHeight - backButtonSize.height) * 0.5
|
||||
@ -690,7 +697,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.badgeNode.alpha = 1.0
|
||||
}
|
||||
} else if self.leftButtonNode.supernode != nil {
|
||||
let leftButtonSize = self.leftButtonNode.measure(CGSize(width: size.width, height: nominalHeight))
|
||||
let leftButtonSize = self.leftButtonNode.updateLayout(constrainedSize: CGSize(width: size.width, height: nominalHeight))
|
||||
leftTitleInset += leftButtonSize.width + leftButtonInset + 8.0 + 8.0
|
||||
|
||||
self.leftButtonNode.alpha = 1.0
|
||||
@ -702,7 +709,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
self.badgeNode.frame = CGRect(origin: backButtonArrowFrame.origin.offsetBy(dx: 7.0, dy: -9.0), size: badgeSize)
|
||||
|
||||
if self.rightButtonNode.supernode != nil {
|
||||
let rightButtonSize = self.rightButtonNode.measure(CGSize(width: size.width, height: nominalHeight))
|
||||
let rightButtonSize = self.rightButtonNode.updateLayout(constrainedSize: (CGSize(width: size.width, height: nominalHeight)))
|
||||
rightTitleInset += rightButtonSize.width + leftButtonInset + 8.0 + 8.0
|
||||
self.rightButtonNode.alpha = 1.0
|
||||
self.rightButtonNode.frame = CGRect(origin: CGPoint(x: size.width - leftButtonInset - rightButtonSize.width, y: contentVerticalOrigin + floor((nominalHeight - rightButtonSize.height) / 2.0)), size: rightButtonSize)
|
||||
@ -716,7 +723,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
break
|
||||
case .bottom:
|
||||
if let transitionBackButtonNode = self.transitionBackButtonNode {
|
||||
let transitionBackButtonSize = transitionBackButtonNode.measure(CGSize(width: size.width, height: nominalHeight))
|
||||
let transitionBackButtonSize = transitionBackButtonNode.updateLayout(constrainedSize: CGSize(width: size.width, height: nominalHeight))
|
||||
let initialX: CGFloat = backButtonInset + size.width * 0.3
|
||||
let finalX: CGFloat = floor((size.width - transitionBackButtonSize.width) / 2.0)
|
||||
|
||||
@ -831,7 +838,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
private func makeTransitionBackButtonNode(accentColor: UIColor) -> NavigationButtonNode? {
|
||||
if self.backButtonNode.supernode != nil {
|
||||
let node = NavigationButtonNode()
|
||||
node.text = self.backButtonNode.text
|
||||
node.updateManualText(self.backButtonNode.manualText)
|
||||
node.color = accentColor
|
||||
return node
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
|
||||
public class NavigationButtonNode: ASTextNode {
|
||||
private final class NavigationButtonItemNode: ASTextNode {
|
||||
private func fontForCurrentState() -> UIFont {
|
||||
return self.bold ? UIFont.boldSystemFont(ofSize: 17.0) : UIFont.systemFont(ofSize: 17.0)
|
||||
}
|
||||
@ -13,6 +13,25 @@ public class NavigationButtonNode: ASTextNode {
|
||||
]
|
||||
}
|
||||
|
||||
private var setEnabledListener: Int?
|
||||
|
||||
var item: UIBarButtonItem? {
|
||||
didSet {
|
||||
if self.item !== oldValue {
|
||||
if let oldValue = oldValue, let setEnabledListener = self.setEnabledListener {
|
||||
oldValue.removeSetEnabledListener(setEnabledListener)
|
||||
self.setEnabledListener = nil
|
||||
}
|
||||
|
||||
if let item = self.item {
|
||||
self.setEnabledListener = item.addSetEnabledListener { [weak self] value in
|
||||
self?.isEnabled = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var _text: String?
|
||||
public var text: String {
|
||||
get {
|
||||
@ -174,13 +193,13 @@ public class NavigationButtonNode: ASTextNode {
|
||||
let alpha: CGFloat = !self.isEnabled ? 1.0 : (highlighted ? 0.4 : 1.0)
|
||||
|
||||
/*if animated {
|
||||
UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.beginFromCurrentState, animations: { () -> Void in
|
||||
self.alpha = alpha
|
||||
}, completion: nil)
|
||||
}
|
||||
else {*/
|
||||
self.alpha = alpha
|
||||
self.highlightChanged(highlighted)
|
||||
UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.beginFromCurrentState, animations: { () -> Void in
|
||||
self.alpha = alpha
|
||||
}, completion: nil)
|
||||
}
|
||||
else {*/
|
||||
self.alpha = alpha
|
||||
self.highlightChanged(highlighted)
|
||||
//}
|
||||
}
|
||||
}
|
||||
@ -198,3 +217,127 @@ public class NavigationButtonNode: ASTextNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final class NavigationButtonNode: ASDisplayNode {
|
||||
private var nodes: [NavigationButtonItemNode] = []
|
||||
|
||||
public var pressed: (Int) -> () = { _ in }
|
||||
public var highlightChanged: (Int, Bool) -> () = { _, _ in }
|
||||
|
||||
public var color: UIColor = UIColor(rgb: 0x007ee5) {
|
||||
didSet {
|
||||
if !self.color.isEqual(oldValue) {
|
||||
for node in self.nodes {
|
||||
node.color = self.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
var manualText: String {
|
||||
return self.nodes.first?.text ?? ""
|
||||
}
|
||||
|
||||
func updateManualText(_ text: String) {
|
||||
let node: NavigationButtonItemNode
|
||||
if self.nodes.count > 0 {
|
||||
node = self.nodes[0]
|
||||
} else {
|
||||
node = NavigationButtonItemNode()
|
||||
node.color = self.color
|
||||
node.highlightChanged = { [weak node, weak self] value in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.index(where: { $0 === node }) {
|
||||
strongSelf.highlightChanged(index, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
node.pressed = { [weak self, weak node] in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.index(where: { $0 === node }) {
|
||||
strongSelf.pressed(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.nodes.append(node)
|
||||
self.addSubnode(node)
|
||||
}
|
||||
node.item = nil
|
||||
node.text = text
|
||||
node.image = nil
|
||||
node.bold = false
|
||||
node.isEnabled = true
|
||||
node.node = nil
|
||||
|
||||
if 1 < self.nodes.count {
|
||||
for i in 1 ..< self.nodes.count {
|
||||
self.nodes[i].removeFromSupernode()
|
||||
}
|
||||
self.nodes.removeSubrange(1...)
|
||||
}
|
||||
}
|
||||
|
||||
func updateItems(_ items: [UIBarButtonItem]) {
|
||||
for i in 0 ..< items.count {
|
||||
let node: NavigationButtonItemNode
|
||||
if self.nodes.count > i {
|
||||
node = self.nodes[i]
|
||||
} else {
|
||||
node = NavigationButtonItemNode()
|
||||
node.color = self.color
|
||||
node.highlightChanged = { [weak node, weak self] value in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.index(where: { $0 === node }) {
|
||||
strongSelf.highlightChanged(index, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
node.pressed = { [weak self, weak node] in
|
||||
if let strongSelf = self, let node = node {
|
||||
if let index = strongSelf.nodes.index(where: { $0 === node }) {
|
||||
strongSelf.pressed(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.nodes.append(node)
|
||||
self.addSubnode(node)
|
||||
}
|
||||
node.item = items[i]
|
||||
node.text = items[i].title ?? ""
|
||||
node.image = items[i].image
|
||||
node.bold = items[i].style == .done
|
||||
node.isEnabled = items[i].isEnabled
|
||||
node.node = items[i].customDisplayNode
|
||||
}
|
||||
if items.count < self.nodes.count {
|
||||
for i in items.count ..< self.nodes.count {
|
||||
self.nodes[i].removeFromSupernode()
|
||||
}
|
||||
self.nodes.removeSubrange(items.count...)
|
||||
}
|
||||
}
|
||||
|
||||
func updateLayout(constrainedSize: CGSize) -> CGSize {
|
||||
var nodeOrigin = CGPoint()
|
||||
var totalSize = CGSize()
|
||||
for node in self.nodes {
|
||||
if !totalSize.width.isZero {
|
||||
totalSize.width += 16.0
|
||||
nodeOrigin.x += 16.0
|
||||
}
|
||||
var nodeSize = node.calculateSizeThatFits(constrainedSize)
|
||||
nodeSize.width = ceil(nodeSize.width)
|
||||
nodeSize.height = ceil(nodeSize.height)
|
||||
totalSize.width += nodeSize.width
|
||||
totalSize.height = max(totalSize.height, nodeSize.height)
|
||||
node.frame = CGRect(origin: nodeOrigin, size: nodeSize)
|
||||
nodeOrigin.x += node.bounds.width
|
||||
}
|
||||
return totalSize
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class NavigationTransitionCoordinator {
|
||||
self.dimView.backgroundColor = UIColor.black
|
||||
self.shadowView = UIImageView(image: shadowImage)
|
||||
|
||||
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar, !topNavigationBar.isHidden, !bottomNavigationBar.isHidden {
|
||||
if let topNavigationBar = topNavigationBar, let bottomNavigationBar = bottomNavigationBar, !topNavigationBar.isHidden, !bottomNavigationBar.isHidden, topNavigationBar.contentNode == nil, bottomNavigationBar.contentNode == nil {
|
||||
var topFrame = topNavigationBar.view.convert(topNavigationBar.bounds, to: container)
|
||||
var bottomFrame = bottomNavigationBar.view.convert(bottomNavigationBar.bounds, to: container)
|
||||
topFrame.origin.x = 0.0
|
||||
|
@ -24,10 +24,10 @@ private final class TextAlertContentActionNode: HighlightableButtonNode {
|
||||
|
||||
let action: TextAlertAction
|
||||
|
||||
init(action: TextAlertAction) {
|
||||
init(theme: AlertControllerTheme, action: TextAlertAction) {
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.backgroundNode.isLayerBacked = true
|
||||
self.backgroundNode.backgroundColor = UIColor(rgb: 0xe0e5e6)
|
||||
self.backgroundNode.backgroundColor = theme.highlightedItemColor
|
||||
self.backgroundNode.alpha = 0.0
|
||||
|
||||
self.action = action
|
||||
@ -36,12 +36,12 @@ private final class TextAlertContentActionNode: HighlightableButtonNode {
|
||||
|
||||
self.titleNode.maximumNumberOfLines = 2
|
||||
let font = Font.regular(17.0)
|
||||
var color = UIColor(rgb: 0x007ee5)
|
||||
var color = theme.accentColor
|
||||
switch action.type {
|
||||
case .defaultAction, .genericAction:
|
||||
break
|
||||
case .destructiveAction:
|
||||
color = UIColor(rgb: 0xff3b30)
|
||||
color = theme.destructiveColor
|
||||
}
|
||||
self.setAttributedTitle(NSAttributedString(string: action.title, font: font, textColor: color, paragraphAlignment: .center), for: [])
|
||||
|
||||
@ -86,7 +86,7 @@ final class TextAlertContentNode: AlertContentNode {
|
||||
private let actionNodes: [TextAlertContentActionNode]
|
||||
private let actionVerticalSeparators: [ASDisplayNode]
|
||||
|
||||
init(title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction]) {
|
||||
init(theme: AlertControllerTheme, title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction]) {
|
||||
if let title = title {
|
||||
let titleNode = ASTextNode()
|
||||
titleNode.attributedText = title
|
||||
@ -106,10 +106,10 @@ final class TextAlertContentNode: AlertContentNode {
|
||||
|
||||
self.actionNodesSeparator = ASDisplayNode()
|
||||
self.actionNodesSeparator.isLayerBacked = true
|
||||
self.actionNodesSeparator.backgroundColor = UIColor(rgb: 0xc9cdd7)
|
||||
self.actionNodesSeparator.backgroundColor = theme.separatorColor
|
||||
|
||||
self.actionNodes = actions.map { action -> TextAlertContentActionNode in
|
||||
return TextAlertContentActionNode(action: action)
|
||||
return TextAlertContentActionNode(theme: theme, action: action)
|
||||
}
|
||||
|
||||
var actionVerticalSeparators: [ASDisplayNode] = []
|
||||
@ -117,7 +117,7 @@ final class TextAlertContentNode: AlertContentNode {
|
||||
for _ in 0 ..< actions.count - 1 {
|
||||
let separatorNode = ASDisplayNode()
|
||||
separatorNode.isLayerBacked = true
|
||||
separatorNode.backgroundColor = UIColor(rgb: 0xc9cdd7)
|
||||
separatorNode.backgroundColor = theme.separatorColor
|
||||
actionVerticalSeparators.append(separatorNode)
|
||||
}
|
||||
}
|
||||
@ -216,13 +216,13 @@ final class TextAlertContentNode: AlertContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
public func textAlertController(title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction]) -> AlertController {
|
||||
return AlertController(contentNode: TextAlertContentNode(title: title, text: text, actions: actions))
|
||||
public func textAlertController(theme: AlertControllerTheme, title: NSAttributedString?, text: NSAttributedString, actions: [TextAlertAction]) -> AlertController {
|
||||
return AlertController(theme: theme, contentNode: TextAlertContentNode(theme: theme, title: title, text: text, actions: actions))
|
||||
}
|
||||
|
||||
public func standardTextAlertController(title: String?, text: String, actions: [TextAlertAction]) -> AlertController {
|
||||
public func standardTextAlertController(theme: AlertControllerTheme, title: String?, text: String, actions: [TextAlertAction]) -> AlertController {
|
||||
var dismissImpl: (() -> Void)?
|
||||
let controller = AlertController(contentNode: TextAlertContentNode(title: title != nil ? NSAttributedString(string: title!, font: Font.medium(17.0), textColor: .black, paragraphAlignment: .center) : nil, text: NSAttributedString(string: text, font: title == nil ? Font.semibold(17.0) : Font.regular(13.0), textColor: .black, paragraphAlignment: .center), actions: actions.map { action in
|
||||
let controller = AlertController(theme: theme, contentNode: TextAlertContentNode(theme: theme, title: title != nil ? NSAttributedString(string: title!, font: Font.medium(17.0), textColor: theme.primaryColor, paragraphAlignment: .center) : nil, text: NSAttributedString(string: text, font: title == nil ? Font.semibold(17.0) : Font.regular(13.0), textColor: theme.primaryColor, paragraphAlignment: .center), actions: actions.map { action in
|
||||
return TextAlertAction(type: action.type, title: action.title, action: {
|
||||
dismissImpl?()
|
||||
action.action()
|
||||
|
114
Display/TooltipController.swift
Normal file
114
Display/TooltipController.swift
Normal file
@ -0,0 +1,114 @@
|
||||
import Foundation
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
|
||||
public final class TooltipControllerPresentationArguments {
|
||||
fileprivate let sourceNodeAndRect: () -> (ASDisplayNode, CGRect)?
|
||||
|
||||
public init(sourceNodeAndRect: @escaping () -> (ASDisplayNode, CGRect)?) {
|
||||
self.sourceNodeAndRect = sourceNodeAndRect
|
||||
}
|
||||
}
|
||||
|
||||
public final class TooltipController: ViewController {
|
||||
private var controllerNode: TooltipControllerNode {
|
||||
return self.displayNode as! TooltipControllerNode
|
||||
}
|
||||
|
||||
public var text: String {
|
||||
didSet {
|
||||
if self.text != oldValue {
|
||||
if self.isNodeLoaded {
|
||||
self.controllerNode.updateText(self.text, transition: .animated(duration: 0.25, curve: .easeInOut))
|
||||
if self.timeoutTimer != nil {
|
||||
self.timeoutTimer?.invalidate()
|
||||
self.timeoutTimer = nil
|
||||
self.beginTimeout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let timeout: Double
|
||||
private var timeoutTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private var layout: ContainerViewLayout?
|
||||
|
||||
public var dismissed: (() -> Void)?
|
||||
|
||||
public init(text: String, timeout: Double = 1.0) {
|
||||
self.text = text
|
||||
self.timeout = timeout
|
||||
|
||||
super.init(navigationBarTheme: nil)
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.timeoutTimer?.invalidate()
|
||||
}
|
||||
|
||||
open override func loadDisplayNode() {
|
||||
self.displayNode = TooltipControllerNode(text: self.text, dismiss: { [weak self] in
|
||||
self?.dismissed?()
|
||||
self?.controllerNode.animateOut { [weak self] in
|
||||
self?.presentingViewController?.dismiss(animated: false)
|
||||
}
|
||||
})
|
||||
self.displayNodeDidLoad()
|
||||
}
|
||||
|
||||
override public func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.controllerNode.animateIn()
|
||||
self.beginTimeout()
|
||||
}
|
||||
|
||||
override open func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
if self.layout != nil && self.layout! != layout {
|
||||
self.dismissed?()
|
||||
self.controllerNode.animateOut { [weak self] in
|
||||
self?.presentingViewController?.dismiss(animated: false)
|
||||
}
|
||||
} else {
|
||||
self.layout = layout
|
||||
|
||||
if let presentationArguments = self.presentationArguments as? TooltipControllerPresentationArguments, let (sourceNode, sourceRect) = presentationArguments.sourceNodeAndRect() {
|
||||
self.controllerNode.sourceRect = sourceNode.view.convert(sourceRect, to: nil)
|
||||
} else {
|
||||
self.controllerNode.sourceRect = nil
|
||||
}
|
||||
|
||||
self.controllerNode.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
open override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.controllerNode.animateIn()
|
||||
self.beginTimeout()
|
||||
}
|
||||
|
||||
private func beginTimeout() {
|
||||
if self.timeoutTimer == nil {
|
||||
let timeoutTimer = SwiftSignalKit.Timer(timeout: self.timeout, repeat: false, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.dismissed?()
|
||||
strongSelf.controllerNode.animateOut {
|
||||
self?.presentingViewController?.dismiss(animated: false)
|
||||
}
|
||||
}
|
||||
}, queue: Queue.mainQueue())
|
||||
self.timeoutTimer = timeoutTimer
|
||||
timeoutTimer.start()
|
||||
}
|
||||
}
|
||||
}
|
118
Display/TooltipControllerNode.swift
Normal file
118
Display/TooltipControllerNode.swift
Normal file
@ -0,0 +1,118 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
|
||||
final class TooltipControllerNode: ASDisplayNode {
|
||||
private let dismiss: () -> Void
|
||||
|
||||
private var validLayout: ContainerViewLayout?
|
||||
|
||||
private let containerNode: ContextMenuContainerNode
|
||||
private let textNode: ASTextNode
|
||||
|
||||
var sourceRect: CGRect?
|
||||
var arrowOnBottom: Bool = true
|
||||
|
||||
private var dismissedByTouchOutside = false
|
||||
|
||||
init(text: String, dismiss: @escaping () -> Void) {
|
||||
self.containerNode = ContextMenuContainerNode()
|
||||
self.containerNode.backgroundColor = UIColor(white: 0.0, alpha: 0.8)
|
||||
|
||||
self.textNode = ASTextNode()
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white, paragraphAlignment: .center)
|
||||
self.textNode.isLayerBacked = true
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
self.dismiss = dismiss
|
||||
|
||||
super.init()
|
||||
|
||||
self.containerNode.addSubnode(self.textNode)
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
}
|
||||
|
||||
func updateText(_ text: String, transition: ContainedViewLayoutTransition) {
|
||||
if transition.isAnimated, let copyLayer = self.textNode.layer.snapshotContentTree() {
|
||||
copyLayer.frame = self.textNode.layer.frame
|
||||
self.textNode.layer.superlayer?.addSublayer(copyLayer)
|
||||
transition.updateAlpha(layer: copyLayer, alpha: 0.0, completion: { [weak copyLayer] _ in
|
||||
copyLayer?.removeFromSuperlayer()
|
||||
})
|
||||
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.12)
|
||||
}
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(14.0), textColor: .white, paragraphAlignment: .center)
|
||||
if let layout = self.validLayout {
|
||||
self.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
self.validLayout = layout
|
||||
|
||||
let maxActionsWidth = layout.size.width - 20.0
|
||||
|
||||
var textSize = self.textNode.measure(CGSize(width: maxActionsWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
textSize.width = ceil(textSize.width / 2.0) * 2.0
|
||||
textSize.height = ceil(textSize.height / 2.0) * 2.0
|
||||
let contentSize = CGSize(width: textSize.width + 12.0, height: textSize.height + 34.0)
|
||||
|
||||
let sourceRect: CGRect = self.sourceRect ?? CGRect(origin: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0), size: CGSize())
|
||||
|
||||
let insets = layout.insets(options: [.statusBar, .input])
|
||||
|
||||
let verticalOrigin: CGFloat
|
||||
var arrowOnBottom = true
|
||||
if sourceRect.minY - 54.0 > insets.top {
|
||||
verticalOrigin = sourceRect.minY - contentSize.height
|
||||
} else {
|
||||
verticalOrigin = min(layout.size.height - insets.bottom - contentSize.height, sourceRect.maxY)
|
||||
arrowOnBottom = false
|
||||
}
|
||||
self.arrowOnBottom = arrowOnBottom
|
||||
|
||||
let horizontalOrigin: CGFloat = floor(min(max(8.0, sourceRect.midX - contentSize.width / 2.0), layout.size.width - contentSize.width - 8.0))
|
||||
|
||||
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: horizontalOrigin, y: verticalOrigin), size: contentSize))
|
||||
self.containerNode.relativeArrowPosition = (sourceRect.midX - horizontalOrigin, arrowOnBottom)
|
||||
|
||||
self.containerNode.updateLayout(transition: transition)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: 6.0, y: 17.0), size: textSize)
|
||||
if transition.isAnimated, textFrame.size != self.textNode.frame.size {
|
||||
transition.animatePositionAdditive(node: self.textNode, offset: CGPoint(x: textFrame.minX - self.textNode.frame.minX, y: 0.0))
|
||||
}
|
||||
self.textNode.frame = textFrame
|
||||
}
|
||||
|
||||
func animateIn() {
|
||||
self.containerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
}
|
||||
|
||||
func animateOut(completion: @escaping () -> Void) {
|
||||
self.containerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if let event = event {
|
||||
var eventIsPresses = false
|
||||
if #available(iOSApplicationExtension 9.0, *) {
|
||||
eventIsPresses = event.type == .presses
|
||||
}
|
||||
if event.type == .touches || eventIsPresses {
|
||||
if self.containerNode.frame.contains(point) {
|
||||
if !self.dismissedByTouchOutside {
|
||||
self.dismissedByTouchOutside = true
|
||||
self.dismiss()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ typedef void (^UINavigationItemSetTitleListener)(NSString * _Nullable, bool);
|
||||
typedef void (^UINavigationItemSetTitleViewListener)(UIView * _Nullable);
|
||||
typedef void (^UINavigationItemSetImageListener)(UIImage * _Nullable);
|
||||
typedef void (^UINavigationItemSetBarButtonItemListener)(UIBarButtonItem * _Nullable, UIBarButtonItem * _Nullable, BOOL);
|
||||
typedef void (^UINavigationItemSetMutipleBarButtonItemsListener)(NSArray<UIBarButtonItem *> * _Nullable, BOOL);
|
||||
typedef void (^UITabBarItemSetBadgeListener)(NSString * _Nullable);
|
||||
|
||||
@interface UINavigationItem (Proxy)
|
||||
@ -20,6 +21,8 @@ typedef void (^UITabBarItemSetBadgeListener)(NSString * _Nullable);
|
||||
- (void)removeSetLeftBarButtonItemListener:(NSInteger)key;
|
||||
- (NSInteger)addSetRightBarButtonItemListener:(UINavigationItemSetBarButtonItemListener _Nonnull)listener;
|
||||
- (void)removeSetRightBarButtonItemListener:(NSInteger)key;
|
||||
- (NSInteger)addSetMultipleRightBarButtonItemsListener:(UINavigationItemSetMutipleBarButtonItemsListener _Nonnull)listener;
|
||||
- (void)removeSetMultipleRightBarButtonItemsListener:(NSInteger)key;
|
||||
- (NSInteger)addSetBackBarButtonItemListener:(UINavigationItemSetBarButtonItemListener _Nonnull)listener;
|
||||
- (void)removeSetBackBarButtonItemListener:(NSInteger)key;
|
||||
- (NSInteger)addSetBadgeListener:(UITabBarItemSetBadgeListener _Nonnull)listener;
|
||||
|
@ -12,6 +12,7 @@ static const void *setSelectedImageListenerBagKey = &setSelectedImageListenerBag
|
||||
static const void *setTitleViewListenerBagKey = &setTitleViewListenerBagKey;
|
||||
static const void *setLeftBarButtonItemListenerBagKey = &setLeftBarButtonItemListenerBagKey;
|
||||
static const void *setRightBarButtonItemListenerBagKey = &setRightBarButtonItemListenerBagKey;
|
||||
static const void *setMultipleRightBarButtonItemsListenerKey = &setMultipleRightBarButtonItemsListenerKey;
|
||||
static const void *setBackBarButtonItemListenerBagKey = &setBackBarButtonItemListenerBagKey;
|
||||
static const void *setBadgeListenerBagKey = &setBadgeListenerBagKey;
|
||||
static const void *badgeKey = &badgeKey;
|
||||
@ -29,6 +30,8 @@ static const void *badgeKey = &badgeKey;
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setLeftBarButtonItem:animated:) newSelector:@selector(_ac91f40f_setLeftBarButtonItem:animated:)];
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItem:) newSelector:@selector(_ac91f40f_setRightBarButtonItem:)];
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItem:animated:) newSelector:@selector(_ac91f40f_setRightBarButtonItem:animated:)];
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItems:) newSelector:@selector(_ac91f40f_setRightBarButtonItems:)];
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItems:animated:) newSelector:@selector(_ac91f40f_setRightBarButtonItems:animated:)];
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setBackBarButtonItem:) newSelector:@selector(_ac91f40f_setBackBarButtonItem:)];
|
||||
});
|
||||
}
|
||||
@ -114,6 +117,24 @@ static const void *badgeKey = &badgeKey;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_ac91f40f_setRightBarButtonItems:(NSArray<UIBarButtonItem *> *)rightBarButtonItems {
|
||||
[self setRightBarButtonItems:rightBarButtonItems animated:false];
|
||||
}
|
||||
|
||||
- (void)_ac91f40f_setRightBarButtonItems:(NSArray<UIBarButtonItem *> *)rightBarButtonItems animated:(BOOL)animated
|
||||
{
|
||||
[self _ac91f40f_setRightBarButtonItems:rightBarButtonItems animated:animated];
|
||||
|
||||
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
||||
if (targetItem != nil) {
|
||||
[targetItem setRightBarButtonItems:rightBarButtonItems animated:animated];
|
||||
} else {
|
||||
[(NSBag *)[self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey] enumerateItems:^(UINavigationItemSetMutipleBarButtonItemsListener listener) {
|
||||
listener(rightBarButtonItems, animated);
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_ac91f40f_setBackBarButtonItem:(UIBarButtonItem *)backBarButtonItem
|
||||
{
|
||||
UIBarButtonItem *previousItem = self.rightBarButtonItem;
|
||||
@ -218,6 +239,20 @@ static const void *badgeKey = &badgeKey;
|
||||
[(NSBag *)[self associatedObjectForKey:setRightBarButtonItemListenerBagKey] removeItem:key];
|
||||
}
|
||||
|
||||
- (NSInteger)addSetMultipleRightBarButtonItemsListener:(UINavigationItemSetMutipleBarButtonItemsListener _Nonnull)listener {
|
||||
NSBag *bag = [self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey];
|
||||
if (bag == nil)
|
||||
{
|
||||
bag = [[NSBag alloc] init];
|
||||
[self setAssociatedObject:bag forKey:setMultipleRightBarButtonItemsListenerKey];
|
||||
}
|
||||
return [bag addItem:[listener copy]];
|
||||
}
|
||||
|
||||
- (void)removeSetMultipleRightBarButtonItemsListener:(NSInteger)key {
|
||||
[(NSBag *)[self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey] removeItem:key];
|
||||
}
|
||||
|
||||
- (NSInteger)addSetBackBarButtonItemListener:(UINavigationItemSetBarButtonItemListener)listener {
|
||||
NSBag *bag = [self associatedObjectForKey:setBackBarButtonItemListenerBagKey];
|
||||
if (bag == nil)
|
||||
|
@ -45,15 +45,11 @@ private struct WindowLayout: Equatable {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsInputHeight = lhs.inputHeight {
|
||||
if let rhsInputHeight = rhs.inputHeight {
|
||||
if !lhsInputHeight.isEqual(to: rhsInputHeight) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if let lhsInputHeight = lhs.inputHeight, let rhsInputHeight = rhs.inputHeight {
|
||||
if !lhsInputHeight.isEqual(to: rhsInputHeight) {
|
||||
return false
|
||||
}
|
||||
} else if let _ = rhs.inputHeight {
|
||||
} else if (lhs.inputHeight != nil) != (rhs.inputHeight != nil) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -345,6 +341,7 @@ public class Window1 {
|
||||
}
|
||||
}
|
||||
|
||||
private var windowPanRecognizer: WindowPanRecognizer?
|
||||
private let keyboardGestureRecognizerDelegate = KeyboardGestureRecognizerDelegate()
|
||||
private var keyboardGestureBeginLocation: CGPoint?
|
||||
private var keyboardGestureAccessoryHeight: CGFloat?
|
||||
@ -431,7 +428,20 @@ public class Window1 {
|
||||
self.keyboardFrameChangeObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil, using: { [weak self] notification in
|
||||
if let strongSelf = self {
|
||||
let keyboardFrame: CGRect = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue ?? CGRect()
|
||||
let keyboardHeight = max(0.0, UIScreen.main.bounds.size.height - keyboardFrame.minY)
|
||||
|
||||
let screenHeight: CGFloat
|
||||
|
||||
if true || !UIScreen.main.bounds.width.isEqual(to: strongSelf.windowLayout.size.width) {
|
||||
if keyboardFrame.width.isEqual(to: UIScreen.main.bounds.width) {
|
||||
screenHeight = UIScreen.main.bounds.height
|
||||
} else {
|
||||
screenHeight = UIScreen.main.bounds.width
|
||||
}
|
||||
} else {
|
||||
screenHeight = UIScreen.main.bounds.height
|
||||
}
|
||||
|
||||
let keyboardHeight = max(0.0, screenHeight - keyboardFrame.minY)
|
||||
var duration: Double = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
|
||||
if duration > Double.ulpOfOne {
|
||||
duration = 0.5
|
||||
@ -491,6 +501,7 @@ public class Window1 {
|
||||
recognizer.ended = { [weak self] point, velocity in
|
||||
self?.panGestureEnded(location: point, velocity: velocity)
|
||||
}
|
||||
self.windowPanRecognizer = recognizer
|
||||
self.hostView.view.addGestureRecognizer(recognizer)
|
||||
}
|
||||
|
||||
@ -536,6 +547,9 @@ public class Window1 {
|
||||
}
|
||||
|
||||
public func cancelInteractiveKeyboardGestures() {
|
||||
self.windowPanRecognizer?.isEnabled = false
|
||||
self.windowPanRecognizer?.isEnabled = true
|
||||
|
||||
if self.windowLayout.upperKeyboardInputPositionBound != nil {
|
||||
self.updateLayout {
|
||||
$0.update(upperKeyboardInputPositionBound: nil, transition: .animated(duration: 0.25, curve: .spring), overrideTransition: false)
|
||||
@ -594,7 +608,11 @@ public class Window1 {
|
||||
rootController.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout), transition: .immediate)
|
||||
}
|
||||
|
||||
self.hostView.view.addSubview(rootController.view)
|
||||
if let coveringView = self.coveringView {
|
||||
self.hostView.view.insertSubview(rootController.view, belowSubview: coveringView)
|
||||
} else {
|
||||
self.hostView.view.addSubview(rootController.view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -613,13 +631,32 @@ public class Window1 {
|
||||
for controller in self._topLevelOverlayControllers {
|
||||
controller.containerLayoutUpdated(containedLayoutForWindowLayout(self.windowLayout), transition: .immediate)
|
||||
|
||||
self.hostView.view.addSubview(controller.view)
|
||||
if let coveringView = self.coveringView {
|
||||
self.hostView.view.insertSubview(controller.view, belowSubview: coveringView)
|
||||
} else {
|
||||
self.hostView.view.addSubview(controller.view)
|
||||
}
|
||||
}
|
||||
|
||||
self.presentationContext.topLevelSubview = self._topLevelOverlayControllers.first?.view
|
||||
}
|
||||
}
|
||||
|
||||
public var coveringView: WindowCoveringView? {
|
||||
didSet {
|
||||
if self.coveringView !== oldValue {
|
||||
oldValue?.removeFromSuperview()
|
||||
if let coveringView = self.coveringView {
|
||||
self.hostView.view.addSubview(coveringView)
|
||||
if !self.windowLayout.size.width.isZero {
|
||||
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||
coveringView.updateLayout(self.windowLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func layoutSubviews() {
|
||||
var hasPreview = false
|
||||
var updatedHasPreview = false
|
||||
@ -783,6 +820,11 @@ public class Window1 {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if let coveringView = self.coveringView {
|
||||
coveringView.frame = CGRect(origin: CGPoint(), size: self.windowLayout.size)
|
||||
coveringView.updateLayout(self.windowLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
Display/WindowCoveringView.swift
Normal file
7
Display/WindowCoveringView.swift
Normal file
@ -0,0 +1,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
open class WindowCoveringView: UIView {
|
||||
open func updateLayout(_ size: CGSize) {
|
||||
}
|
||||
}
|
@ -9,6 +9,9 @@ open class ASDisplayNode: NSObject {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
weak var supernode: ASDisplayNode?
|
||||
private(set) var subnodes: [ASDisplayNode] = []
|
||||
|
||||
open var frame: CGRect {
|
||||
get {
|
||||
return self.layer.frame
|
||||
@ -55,6 +58,14 @@ open class ASDisplayNode: NSObject {
|
||||
|
||||
var isLayerBacked: Bool = false
|
||||
|
||||
var clipsToBounds: Bool {
|
||||
get {
|
||||
return self.layer.masksToBounds
|
||||
} set(value) {
|
||||
self.layer.masksToBounds = value
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
@ -74,11 +85,27 @@ open class ASDisplayNode: NSObject {
|
||||
|
||||
}
|
||||
|
||||
open func insertSubnode(belowSubnode: ASDisplayNode) {
|
||||
open func insertSubnode(_ subnode: ASDisplayNode, belowSubnode: ASDisplayNode) {
|
||||
|
||||
}
|
||||
|
||||
open func insertSubnode(aboveSubnode: ASDisplayNode) {
|
||||
open func insertSubnode(_ subnode: ASDisplayNode, aboveSubnode: ASDisplayNode) {
|
||||
|
||||
}
|
||||
|
||||
open func insertSubnode(_ subnode: ASDisplayNode, at: Int) {
|
||||
|
||||
}
|
||||
|
||||
open func removeFromSupernode() {
|
||||
|
||||
}
|
||||
|
||||
func recursivelyEnsureDisplaySynchronously(_ synchronously: Bool) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func ASPerformMainThreadDeallocation(_ ref: inout AnyObject?) {
|
||||
|
||||
}
|
||||
|
89
DisplayMac/CADisplayLink.swift
Normal file
89
DisplayMac/CADisplayLink.swift
Normal file
@ -0,0 +1,89 @@
|
||||
import Foundation
|
||||
import CoreVideo
|
||||
import SwiftSignalKitMac
|
||||
|
||||
private final class CADisplayLinkContext {
|
||||
weak var impl: CADisplayLink?
|
||||
|
||||
init(_ impl: CADisplayLink) {
|
||||
self.impl = impl
|
||||
}
|
||||
}
|
||||
|
||||
private final class CADisplayLinkContexts {
|
||||
private var nextId: Int32 = 0
|
||||
var contexts: [Int32: CADisplayLinkContext] = [:]
|
||||
|
||||
func add(_ impl: CADisplayLink) -> Int32 {
|
||||
let id = self.nextId
|
||||
self.nextId += 1
|
||||
self.contexts[id] = CADisplayLinkContext(impl)
|
||||
return id
|
||||
}
|
||||
|
||||
func remove(_ id: Int32) {
|
||||
self.contexts.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
func get(id: Int32) -> CADisplayLink? {
|
||||
return self.contexts[id]?.impl
|
||||
}
|
||||
}
|
||||
|
||||
private let contexts = Atomic<CADisplayLinkContexts>(value: CADisplayLinkContexts())
|
||||
|
||||
public final class CADisplayLink {
|
||||
private var id: Int32?
|
||||
private var displayLink: CVDisplayLink?
|
||||
|
||||
public var isPaused: Bool = true {
|
||||
didSet {
|
||||
if self.isPaused != oldValue {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let target: Any?
|
||||
private let action: Selector?
|
||||
|
||||
init(target: Any?, selector: Selector?) {
|
||||
self.target = target
|
||||
self.action = selector
|
||||
|
||||
let id = contexts.with { contexts in
|
||||
return contexts.add(self)
|
||||
}
|
||||
self.id = id
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&self.displayLink)
|
||||
if let displayLink = self.displayLink {
|
||||
CVDisplayLinkSetOutputCallback(displayLink, { _, _, _, _, _, ref in
|
||||
let id: Int32 = Int32(unsafeBitCast(ref, to: intptr_t.self))
|
||||
if let impl = (contexts.with { contexts in
|
||||
return contexts.get(id: id)
|
||||
}) {
|
||||
impl.performAction()
|
||||
}
|
||||
return kCVReturnSuccess
|
||||
}, UnsafeMutableRawPointer(bitPattern: Int(id)))
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let id = self.id {
|
||||
contexts.with { contexts in
|
||||
contexts.remove(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func invalidate() {
|
||||
|
||||
}
|
||||
|
||||
private func performAction() {
|
||||
if let target = self.target, let action = self.action {
|
||||
let _ = (target as? AnyObject)?.perform(action)
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,10 @@ import Foundation
|
||||
import QuartzCore
|
||||
|
||||
public struct UIEdgeInsets: Equatable {
|
||||
public let top: CGFloat
|
||||
public let left: CGFloat
|
||||
public let bottom: CGFloat
|
||||
public let right: CGFloat
|
||||
public var top: CGFloat
|
||||
public var left: CGFloat
|
||||
public var bottom: CGFloat
|
||||
public var right: CGFloat
|
||||
|
||||
public init() {
|
||||
self.top = 0.0
|
||||
|
@ -19,6 +19,10 @@ open class UIScrollView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
public var alwaysBoundsVertical: Bool = false
|
||||
public var alwaysBoundsHorizontal: Bool = false
|
||||
public var alwaysBounceVertical: Bool = false
|
||||
public var alwaysBounceHorizontal: Bool = false
|
||||
|
||||
public func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
|
||||
self.contentOffset = contentOffset
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,19 @@ open class UIView: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
init(frame: CGRect) {
|
||||
open var isHidden: Bool {
|
||||
get {
|
||||
return self.layer.isHidden
|
||||
} set(value) {
|
||||
self.layer.isHidden = value
|
||||
}
|
||||
}
|
||||
|
||||
open class var layerClass: AnyClass {
|
||||
return CALayer.self
|
||||
}
|
||||
|
||||
public init(frame: CGRect) {
|
||||
self.layer = CALayer()
|
||||
self.layer.frame = frame
|
||||
|
||||
@ -46,4 +58,25 @@ open class UIView: NSObject {
|
||||
public func bringSubview(toFront: UIView) {
|
||||
|
||||
}
|
||||
|
||||
public func addSubview(_ subview: UIView) {
|
||||
|
||||
}
|
||||
|
||||
public func removeFromSuperview() {
|
||||
|
||||
}
|
||||
|
||||
open func setNeedsLayout() {
|
||||
}
|
||||
|
||||
open func layoutSubviews() {
|
||||
}
|
||||
|
||||
open func setNeedsDisplay() {
|
||||
}
|
||||
|
||||
open func snapshotView(afterScreenUpdates: Bool) -> UIView? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user