Merge branch 'iOS_master' into combine
This commit is contained in:
commit
8fa2b69e5a
54
doric-iOS/.gitignore
vendored
54
doric-iOS/.gitignore
vendored
@ -1,8 +1,12 @@
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
@ -11,27 +15,43 @@ build/
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
xcuserdata
|
||||
*.xcscheme
|
||||
|
||||
## Other
|
||||
*.xccheckout
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.xcuserstate
|
||||
*.xcscmblueprint
|
||||
.idea
|
||||
.svn
|
||||
.DS_Store
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
*.ipa
|
||||
Example/Pods
|
||||
# Bundler
|
||||
.bundle
|
||||
|
||||
# CocoaPods
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
|
||||
Pods/
|
||||
Podfile.lock
|
||||
|
||||
|
||||
# Carthage
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||
# Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
|
||||
#
|
||||
# Note: if you ignore the Pods directory, make sure to uncomment
|
||||
# `pod install` in .travis.yml
|
||||
#
|
||||
# Pods/
|
||||
*.lock
|
||||
.clang-format
|
||||
settings.json
|
||||
Podfile.local
|
||||
Podfile
|
||||
ModulesDebug
|
||||
|
28
doric-iOS/DoricCore.podspec
Normal file
28
doric-iOS/DoricCore.podspec
Normal file
@ -0,0 +1,28 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'DoricCore'
|
||||
s.version = '0.1.2'
|
||||
s.summary = 'Doric iOS SDK'
|
||||
|
||||
|
||||
s.description = <<-DESC
|
||||
Doric iOS SDK for cross platform develpment
|
||||
DESC
|
||||
|
||||
s.homepage = 'https://github.com/doric-pub/doric'
|
||||
s.license = { :type => 'Apache-2.0', :file => 'LICENSE' }
|
||||
s.author = { 'pengfei.zhou' => 'pengfeizhou@foxmail.com' }
|
||||
s.source = { :git => 'https://github.com/doric-pub/doric-iOS.git', :tag => s.version.to_s }
|
||||
|
||||
s.ios.deployment_target = '8.0'
|
||||
|
||||
s.source_files = 'Pod/Classes/**/*'
|
||||
s.resource_bundles = {
|
||||
'Doric' => ['Pod/Assets/**/*']
|
||||
}
|
||||
|
||||
s.public_header_files = 'Pod/Classes/**/*.h'
|
||||
s.dependency 'YYWebImage', '~>1.0.5'
|
||||
s.dependency 'YYImage/WebP'
|
||||
s.dependency 'SocketRocket', '~> 0.5.1'
|
||||
s.dependency 'YYCache', '~> 1.0.4'
|
||||
end
|
@ -3,15 +3,15 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1B5560FDC1A57040A84A35AB /* libPods-ExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30CF3CCBAF1F8AD594763E4A /* libPods-ExampleTests.a */; };
|
||||
2EB14575543B0285648B858D /* libPods-Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C3CFA4394FF1344386170022 /* libPods-Example.a */; };
|
||||
835F4CD080BABFE95A6BFD16 /* libPods-ExampleUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 563C5AC823878F4913BBCDF2 /* libPods-ExampleUITests.a */; };
|
||||
26047AF7D618FF60281DC778 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92C4B99C431BD381198935DE /* Pods_Example.framework */; };
|
||||
C6AF7EB0B40D76A46B2BB384 /* Pods_ExampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF50786B1D1793EC3228133B /* Pods_ExampleUITests.framework */; };
|
||||
D751D4B065D8D4FA6594B5EE /* DemoVC.m in Sources */ = {isa = PBXBuildFile; fileRef = D751D19E97EF4EDD7588FEBE /* DemoVC.m */; };
|
||||
D751D4FCC0A2322211DE3D55 /* QRScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D751DA399F1ADB6D34563B5D /* QRScanViewController.m */; };
|
||||
D751DDB012BAF476A252CD93 /* DemoLibrary.m in Sources */ = {isa = PBXBuildFile; fileRef = D751D2175D09F2C10691FB81 /* DemoLibrary.m */; };
|
||||
E2334AF022E9D2060098A085 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334AEF22E9D2060098A085 /* AppDelegate.m */; };
|
||||
E2334AF322E9D2060098A085 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334AF222E9D2060098A085 /* ViewController.m */; };
|
||||
E2334AF622E9D2060098A085 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2334AF422E9D2060098A085 /* Main.storyboard */; };
|
||||
@ -21,6 +21,7 @@
|
||||
E2334B0822E9D2070098A085 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B0722E9D2070098A085 /* ExampleTests.m */; };
|
||||
E2334B1322E9D2070098A085 /* ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B1222E9D2070098A085 /* ExampleUITests.m */; };
|
||||
E2F4481723839AC500073C7F /* demo in Resources */ = {isa = PBXBuildFile; fileRef = E2F4481623839AC500073C7F /* demo */; };
|
||||
E778063CA90E2DD797D11D7C /* Pods_ExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00A2FF6380A526AB267988ED /* Pods_ExampleTests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -41,17 +42,19 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
00A2FF6380A526AB267988ED /* Pods_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
016E930415B91D826F9FFF47 /* Pods-ExampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleUITests/Pods-ExampleUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
30CF3CCBAF1F8AD594763E4A /* libPods-ExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3D75F592D76A665674B31A66 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
|
||||
563C5AC823878F4913BBCDF2 /* libPods-ExampleUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExampleUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8231E841CCAF382F85C9F576 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
92C4B99C431BD381198935DE /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B93423722F2E06DC238CDD18 /* Pods-ExampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleUITests/Pods-ExampleUITests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
B93D4DB00FD244178B7CE7C4 /* Pods-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
C3CFA4394FF1344386170022 /* libPods-Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BF50786B1D1793EC3228133B /* Pods_ExampleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D751D18AD6496F4A9BE1AB45 /* QRScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRScanViewController.h; sourceTree = "<group>"; };
|
||||
D751D19E97EF4EDD7588FEBE /* DemoVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoVC.m; sourceTree = "<group>"; };
|
||||
D751D2175D09F2C10691FB81 /* DemoLibrary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoLibrary.m; sourceTree = "<group>"; };
|
||||
D751DA399F1ADB6D34563B5D /* QRScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRScanViewController.m; sourceTree = "<group>"; };
|
||||
D751DB0CB3009E12990F661E /* DemoLibrary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoLibrary.h; sourceTree = "<group>"; };
|
||||
D751DDEC114E037231257E64 /* DemoVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoVC.h; sourceTree = "<group>"; };
|
||||
D91241144B5A3356A3C60644 /* Pods-ExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
E2334AEB22E9D2060098A085 /* Doric Playground.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Doric Playground.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -78,7 +81,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2EB14575543B0285648B858D /* libPods-Example.a in Frameworks */,
|
||||
26047AF7D618FF60281DC778 /* Pods_Example.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -86,7 +89,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1B5560FDC1A57040A84A35AB /* libPods-ExampleTests.a in Frameworks */,
|
||||
E778063CA90E2DD797D11D7C /* Pods_ExampleTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -94,7 +97,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
835F4CD080BABFE95A6BFD16 /* libPods-ExampleUITests.a in Frameworks */,
|
||||
C6AF7EB0B40D76A46B2BB384 /* Pods_ExampleUITests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -117,9 +120,9 @@
|
||||
D80A9B07B39AD04027CAE17B /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C3CFA4394FF1344386170022 /* libPods-Example.a */,
|
||||
30CF3CCBAF1F8AD594763E4A /* libPods-ExampleTests.a */,
|
||||
563C5AC823878F4913BBCDF2 /* libPods-ExampleUITests.a */,
|
||||
92C4B99C431BD381198935DE /* Pods_Example.framework */,
|
||||
00A2FF6380A526AB267988ED /* Pods_ExampleTests.framework */,
|
||||
BF50786B1D1793EC3228133B /* Pods_ExampleUITests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -163,6 +166,8 @@
|
||||
D751DDEC114E037231257E64 /* DemoVC.h */,
|
||||
D751DA399F1ADB6D34563B5D /* QRScanViewController.m */,
|
||||
D751D18AD6496F4A9BE1AB45 /* QRScanViewController.h */,
|
||||
D751D2175D09F2C10691FB81 /* DemoLibrary.m */,
|
||||
D751DB0CB3009E12990F661E /* DemoLibrary.h */,
|
||||
);
|
||||
path = Example;
|
||||
sourceTree = "<group>";
|
||||
@ -197,8 +202,8 @@
|
||||
E2334AE722E9D2060098A085 /* Sources */,
|
||||
E2334AE822E9D2060098A085 /* Frameworks */,
|
||||
E2334AE922E9D2060098A085 /* Resources */,
|
||||
2719DACF05C7A7C1EB4AD553 /* [CP] Embed Pods Frameworks */,
|
||||
C232600D894D85358A6ABF4D /* [CP] Copy Pods Resources */,
|
||||
223E53E328880489770F8C93 /* [CP] Embed Pods Frameworks */,
|
||||
EEF1C3B3FE5FE92E603C3B08 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -217,8 +222,8 @@
|
||||
E2334AFF22E9D2070098A085 /* Sources */,
|
||||
E2334B0022E9D2070098A085 /* Frameworks */,
|
||||
E2334B0122E9D2070098A085 /* Resources */,
|
||||
68729F70B03CECDBAD2022E4 /* [CP] Embed Pods Frameworks */,
|
||||
D5C1C722575685F99C382E01 /* [CP] Copy Pods Resources */,
|
||||
9908F148F5F00DD2EB349A08 /* [CP] Embed Pods Frameworks */,
|
||||
17E0A19B8E5C4C4883C8AB85 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -238,8 +243,8 @@
|
||||
E2334B0A22E9D2070098A085 /* Sources */,
|
||||
E2334B0B22E9D2070098A085 /* Frameworks */,
|
||||
E2334B0C22E9D2070098A085 /* Resources */,
|
||||
AC45D4A1B85D5D5A2F6E3DBD /* [CP] Embed Pods Frameworks */,
|
||||
F0AA1A5ADB99F5ECA1F9331E /* [CP] Copy Pods Resources */,
|
||||
5FE5475A2ECF1794CBF57C61 /* [CP] Embed Pods Frameworks */,
|
||||
C09BD0B68592DA6641E3B65D /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -344,7 +349,7 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
2719DACF05C7A7C1EB4AD553 /* [CP] Embed Pods Frameworks */ = {
|
||||
17E0A19B8E5C4C4883C8AB85 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@ -353,10 +358,40 @@
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
223E53E328880489770F8C93 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/DoricCore/DoricCore.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YYWebImage/YYWebImage.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DoricCore.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYWebImage.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@ -385,26 +420,7 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
68729F70B03CECDBAD2022E4 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
AC45D4A1B85D5D5A2F6E3DBD /* [CP] Embed Pods Frameworks */ = {
|
||||
5FE5475A2ECF1794CBF57C61 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@ -423,6 +439,25 @@
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleUITests/Pods-ExampleUITests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9908F148F5F00DD2EB349A08 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
BE34CD8291B20D26F2ADE3E1 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -445,66 +480,7 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C232600D894D85358A6ABF4D /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/Doric/Doric.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Doric.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
D5C1C722575685F99C382E01 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E24A030C22EED0D500AB4631 /* Package JS Bundle */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Package JS Bundle";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\nexport NVM_DIR=\"$HOME/.nvm\"\n[ -s \"$NVM_DIR/nvm.sh\" ] && \\. \"$NVM_DIR/nvm.sh\" # This loads nvm\n[ -s \"$NVM_DIR/bash_completion\" ] && \\. \"$NVM_DIR/bash_completion\" # This loads nvm bash_completion\n\ncd ../../js-framework && npm run build\ncd ../demo && npm run build\n";
|
||||
};
|
||||
F0AA1A5ADB99F5ECA1F9331E /* [CP] Copy Pods Resources */ = {
|
||||
C09BD0B68592DA6641E3B65D /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@ -523,6 +499,43 @@
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ExampleUITests/Pods-ExampleUITests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E24A030C22EED0D500AB4631 /* Package JS Bundle */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Package JS Bundle";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\nexport NVM_DIR=\"$HOME/.nvm\"\n[ -s \"$NVM_DIR/nvm.sh\" ] && \\. \"$NVM_DIR/nvm.sh\" # This loads nvm\n[ -s \"$NVM_DIR/bash_completion\" ] && \\. \"$NVM_DIR/bash_completion\" # This loads nvm bash_completion\n\nsh ../../bundle.sh\n";
|
||||
};
|
||||
EEF1C3B3FE5FE92E603C3B08 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@ -535,6 +548,7 @@
|
||||
E2334AF022E9D2060098A085 /* AppDelegate.m in Sources */,
|
||||
D751D4B065D8D4FA6594B5EE /* DemoVC.m in Sources */,
|
||||
D751D4FCC0A2322211DE3D55 /* QRScanViewController.m in Sources */,
|
||||
D751DDB012BAF476A252CD93 /* DemoLibrary.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
10
doric-iOS/Example/Example.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
doric-iOS/Example/Example.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Example.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -0,0 +1,8 @@
|
||||
<?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>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
10
doric-iOS/Example/Example/DemoLibrary.h
Normal file
10
doric-iOS/Example/Example/DemoLibrary.h
Normal file
@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/11.
|
||||
// Copyright (c) 2019 pengfei.zhou. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <DoricCore/Doric.h>
|
||||
|
||||
@interface DemoLibrary : DoricLibrary
|
||||
@end
|
24
doric-iOS/Example/Example/DemoLibrary.m
Normal file
24
doric-iOS/Example/Example/DemoLibrary.m
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/11.
|
||||
// Copyright (c) 2019 pengfei.zhou. All rights reserved.
|
||||
//
|
||||
|
||||
#import "DemoLibrary.h"
|
||||
|
||||
@interface DoricDemoPlugin : DoricNativePlugin
|
||||
|
||||
@end
|
||||
|
||||
@implementation DoricDemoPlugin
|
||||
- (void)test {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
ShowToast(@"Test called", CENTER);
|
||||
});
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DemoLibrary
|
||||
- (void)load:(DoricRegistry *)registry {
|
||||
[registry registerNativePlugin:[DoricDemoPlugin class] withName:@"demo"];
|
||||
}
|
||||
@end
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
|
||||
#import "DemoVC.h"
|
||||
#import "Doric.h"
|
||||
#import <DoricCore/Doric.h>
|
||||
|
||||
@interface DemoVC ()
|
||||
@property(nonatomic, copy) NSString *filePath;
|
||||
@ -33,7 +33,7 @@ - (void)viewDidLoad {
|
||||
[self.view addSubview:it];
|
||||
}];
|
||||
[self addChildViewController:panel];
|
||||
[panel config:jsContent alias:self.filePath];
|
||||
[panel config:jsContent alias:self.filePath extra:nil];
|
||||
}
|
||||
|
||||
@end
|
@ -5,7 +5,7 @@
|
||||
|
||||
#import "QRScanViewController.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import "Doric.h"
|
||||
#import <DoricCore/Doric.h>
|
||||
|
||||
@interface QRScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
|
||||
@property(strong, nonatomic) AVCaptureDevice *device;
|
||||
|
@ -7,9 +7,10 @@
|
||||
//
|
||||
|
||||
#import "ViewController.h"
|
||||
#import "Doric.h"
|
||||
#import <DoricCore/Doric.h>
|
||||
#import "DemoVC.h"
|
||||
#import "QRScanViewController.h"
|
||||
#import "DemoLibrary.h"
|
||||
|
||||
@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
|
||||
@property(nonatomic, copy) NSArray <NSString *> *demoFilePaths;
|
||||
@ -27,6 +28,11 @@ - (void)viewDidLoad {
|
||||
return ![obj containsString:@".map"];
|
||||
}];
|
||||
NSMutableArray <NSString *> *tmp = [self.demoFilePaths mutableCopy];
|
||||
NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch;
|
||||
[tmp sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
|
||||
NSRange range = NSMakeRange(0, obj1.length);
|
||||
return [obj1 compare:obj2 options:comparisonOptions range:range];
|
||||
}];
|
||||
[tmp insertObject:@"Dev Kit" atIndex:0];
|
||||
self.demoFilePaths = tmp;
|
||||
[self.view addSubview:[[UITableView new] also:^(UITableView *it) {
|
||||
@ -36,6 +42,7 @@ - (void)viewDidLoad {
|
||||
it.dataSource = self;
|
||||
it.delegate = self;
|
||||
}]];
|
||||
[DoricRegistry register:[DemoLibrary new]];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
@ -72,7 +79,9 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
|
||||
if ([file containsString:@"NavigatorDemo"]) {
|
||||
DoricViewController *doricViewController = [[DoricViewController alloc]
|
||||
initWithScheme:[NSString stringWithFormat:@"assets://demo/%@", file]
|
||||
alias:self.demoFilePaths[(NSUInteger) indexPath.row]];
|
||||
alias:self.demoFilePaths[(NSUInteger) indexPath.row]
|
||||
extra:nil
|
||||
];
|
||||
[self.navigationController pushViewController:doricViewController animated:NO];
|
||||
} else {
|
||||
DemoVC *demoVC = [[DemoVC alloc] initWithPath:file];
|
||||
|
@ -1 +0,0 @@
|
||||
../../../demo/bundle/src/
|
1
doric-iOS/Example/Example/demo/.gitignore
vendored
Normal file
1
doric-iOS/Example/Example/demo/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.js
|
@ -1 +0,0 @@
|
||||
../../../js-framework/bundle
|
1
doric-iOS/Pod/Assets/bundle/.gitignore
vendored
Normal file
1
doric-iOS/Pod/Assets/bundle/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.js
|
@ -26,3 +26,5 @@
|
||||
#import "DoricNavBarDelegate.h"
|
||||
#import "DoricViewController.h"
|
||||
#import "DoricPromise.h"
|
||||
#import "DoricLibrary.h"
|
||||
#import "DoricNativePlugin.h"
|
@ -41,8 +41,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic, strong) NSMutableDictionary *initialParams;
|
||||
@property(nonatomic, strong) DoricRootNode *rootNode;
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, DoricViewNode *> *headNodes;
|
||||
@property(nonatomic, copy) NSString *extra;
|
||||
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source;
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source extra:(NSString *)extra;
|
||||
|
||||
- (DoricAsyncResult *)callEntity:(NSString *)method, ...;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
@implementation DoricContext
|
||||
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
|
||||
- (instancetype)initWithScript:(NSString *)script source:(NSString *)source extra:(NSString *)extra {
|
||||
if (self = [super init]) {
|
||||
_driver = [DoricDriver instance];
|
||||
_pluginInstanceMap = [NSMutableDictionary new];
|
||||
@ -39,6 +39,7 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source {
|
||||
_script = script;
|
||||
_source = source;
|
||||
_initialParams = [@{@"width": @(0), @"height": @(0)} mutableCopy];
|
||||
_extra = extra;
|
||||
[self callEntity:DORIC_ENTITY_CREATE, nil];
|
||||
}
|
||||
return self;
|
||||
@ -78,7 +79,7 @@ - (void)initContextWithWidth:(CGFloat)width height:(CGFloat)height {
|
||||
it[@"width"] = @(width);
|
||||
it[@"height"] = @(height);
|
||||
}];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, nil];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, self.extra, nil];
|
||||
}
|
||||
|
||||
- (void)reload:(NSString *)script {
|
||||
@ -86,6 +87,7 @@ - (void)reload:(NSString *)script {
|
||||
self.script = script;
|
||||
[self.driver createContext:self.contextId script:script source:self.source];
|
||||
[self callEntity:DORIC_ENTITY_INIT, self.initialParams, nil];
|
||||
[self onShow];
|
||||
}
|
||||
|
||||
- (void)onShow {
|
||||
|
@ -26,7 +26,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DoricContextHolder : NSObject
|
||||
@property(nonatomic, strong) DoricContext *doricContext;
|
||||
@property(nonatomic, weak) DoricContext *doricContext;
|
||||
|
||||
- (instancetype)initWithContext:(DoricContext *)doricContext;
|
||||
|
||||
|
25
doric-iOS/Pod/Classes/DoricLibrary.h
Normal file
25
doric-iOS/Pod/Classes/DoricLibrary.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DoricRegistry.h"
|
||||
|
||||
@interface DoricLibrary : NSObject
|
||||
- (void)load:(DoricRegistry *)registry;
|
||||
@end
|
26
doric-iOS/Pod/Classes/DoricLibrary.m
Normal file
26
doric-iOS/Pod/Classes/DoricLibrary.m
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/11.
|
||||
//
|
||||
|
||||
#import "DoricLibrary.h"
|
||||
|
||||
|
||||
@implementation DoricLibrary
|
||||
- (void)load:(DoricRegistry *)registry {
|
||||
}
|
||||
@end
|
@ -25,5 +25,5 @@
|
||||
@interface DoricPanel : UIViewController
|
||||
@property(nonatomic, strong) DoricContext *doricContext;
|
||||
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias;
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias extra:(NSString *)extra;
|
||||
@end
|
@ -22,8 +22,8 @@
|
||||
|
||||
@implementation DoricPanel
|
||||
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias {
|
||||
self.doricContext = [[[DoricContext alloc] initWithScript:script source:alias] also:^(DoricContext *it) {
|
||||
- (void)config:(NSString *)script alias:(NSString *)alias extra:(NSString *)extra {
|
||||
self.doricContext = [[[DoricContext alloc] initWithScript:script source:alias extra:extra] also:^(DoricContext *it) {
|
||||
[it.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) {
|
||||
[self.view addSubview:it];
|
||||
}]];
|
||||
|
@ -23,6 +23,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@class DoricLibrary;
|
||||
|
||||
@interface DoricRegistry : NSObject
|
||||
|
||||
@ -38,6 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)registerViewNode:(Class)nodeClass withName:(NSString *)name;
|
||||
|
||||
- (Class)acquireViewNode:(NSString *)name;
|
||||
|
||||
+ (void)register:(DoricLibrary *)library;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@ -42,6 +42,35 @@
|
||||
#import "DoricFlowLayoutNode.h"
|
||||
#import "DoricPopoverPlugin.h"
|
||||
#import "DoricAnimatePlugin.h"
|
||||
#import "DoricNestedSliderNode.h"
|
||||
#import "DoricInputNode.h"
|
||||
#import "DoricLibrary.h"
|
||||
|
||||
|
||||
@interface DoricLibraries : NSObject
|
||||
@property(nonatomic, strong) NSMutableSet <DoricLibrary *> *libraries;
|
||||
|
||||
+ (instancetype)instance;
|
||||
@end
|
||||
|
||||
@implementation DoricLibraries
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_libraries = [NSMutableSet new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)instance {
|
||||
static DoricLibraries *_instance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_instance = [[DoricLibraries alloc] init];
|
||||
});
|
||||
return _instance;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface DoricRegistry ()
|
||||
|
||||
@ -53,12 +82,19 @@ @interface DoricRegistry ()
|
||||
|
||||
@implementation DoricRegistry
|
||||
|
||||
+ (void)register:(DoricLibrary *)library {
|
||||
[DoricLibraries.instance.libraries addObject:library];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_bundles = [[NSMutableDictionary alloc] init];
|
||||
_plugins = [[NSMutableDictionary alloc] init];
|
||||
_nodes = [[NSMutableDictionary alloc] init];
|
||||
[self innerRegister];
|
||||
[DoricLibraries.instance.libraries enumerateObjectsUsingBlock:^(DoricLibrary *obj, BOOL *stop) {
|
||||
[obj load:self];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -86,6 +122,8 @@ - (void)innerRegister {
|
||||
[self registerViewNode:DoricRefreshableNode.class withName:@"Refreshable"];
|
||||
[self registerViewNode:DoricFlowLayoutItemNode.class withName:@"FlowLayoutItem"];
|
||||
[self registerViewNode:DoricFlowLayoutNode.class withName:@"FlowLayout"];
|
||||
[self registerViewNode:DoricNestedSliderNode.class withName:@"NestedSlider"];
|
||||
[self registerViewNode:DoricInputNode.class withName:@"Input"];
|
||||
}
|
||||
|
||||
- (void)registerJSBundle:(NSString *)bundle withName:(NSString *)name {
|
||||
|
@ -8,7 +8,7 @@
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* distributed under the License is distributed onO an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
@ -22,5 +22,5 @@
|
||||
#import "DoricNavBarDelegate.h"
|
||||
|
||||
@interface DoricViewController : UIViewController <DoricNavigatorDelegate, DoricNavBarDelegate>
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias;
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias extra:(NSString *)extra;
|
||||
@end
|
@ -32,7 +32,7 @@ @interface DoricViewController ()
|
||||
@end
|
||||
|
||||
@implementation DoricViewController
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias {
|
||||
- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias extra:(NSString *)extra {
|
||||
if (self = [super init]) {
|
||||
self.edgesForExtendedLayout = UIRectEdgeNone;
|
||||
DoricAsyncResult <NSString *> *result = [DoricJSLoaderManager.instance request:scheme];
|
||||
@ -46,7 +46,7 @@ - (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias {
|
||||
}];
|
||||
[self.view addSubview:panel.view];
|
||||
[self addChildViewController:panel];
|
||||
[panel config:result alias:alias];
|
||||
[panel config:result alias:alias extra:extra];
|
||||
panel.doricContext.navigator = self;
|
||||
panel.doricContext.navBar = self;
|
||||
self.doricPanel = panel;
|
||||
@ -78,8 +78,8 @@ - (void)viewWillLayoutSubviews {
|
||||
self.doricPanel.view.height = self.view.height;
|
||||
}
|
||||
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated {
|
||||
DoricViewController *viewController = [[DoricViewController alloc] initWithScheme:scheme alias:alias];
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated extra:(NSString *)extra {
|
||||
DoricViewController *viewController = [[DoricViewController alloc] initWithScheme:scheme alias:alias extra:extra];
|
||||
[self.navigationController pushViewController:viewController animated:animated];
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,15 @@ - (instancetype)init {
|
||||
|
||||
- (void)initJSExecutor {
|
||||
__weak typeof(self) _self = self;
|
||||
|
||||
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_ENVIRONMENT obj:@{
|
||||
@"platform": @"iOS",
|
||||
@"platformVersion": [[UIDevice currentDevice] systemVersion],
|
||||
@"appName": infoDictionary[@"CFBundleName"],
|
||||
@"appVersion": infoDictionary[@"CFBundleShortVersionString"],
|
||||
@"screenWidth": @([[UIScreen mainScreen] bounds].size.width),
|
||||
@"screenHeight": @([[UIScreen mainScreen] bounds].size.height),
|
||||
}];
|
||||
[self.jsExecutor injectGlobalJSObject:INJECT_LOG obj:^(NSString *type, NSString *message) {
|
||||
DoricLog(@"JS:%@", message);
|
||||
}];
|
||||
|
@ -50,6 +50,7 @@ - (instancetype)init {
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - SRWebSocketDelegate
|
||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
|
||||
DoricLog(@"debugger webSocketDidOpen");
|
||||
DC_UNLOCK(self.semaphore);
|
||||
@ -93,6 +94,8 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
|
||||
result = ((Block4)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3]);
|
||||
} else if (argsArr.count == 5) {
|
||||
result = ((Block5)tmpBlk)(argsArr[0], argsArr[1], argsArr[2], argsArr[3], argsArr[4]);
|
||||
}else {
|
||||
DoricLog(@"error:args to more than 5. args:%@",argsArr);
|
||||
}
|
||||
|
||||
} else if ([cmd isEqualToString:@"invokeMethod"]) {
|
||||
@ -115,6 +118,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reas
|
||||
DoricLog(@"debugger webSocketdidCloseWithCode");
|
||||
}
|
||||
|
||||
#pragma mark - DoricJSExecutorProtocol
|
||||
- (NSString *)loadJSScript:(NSString *)script source:(NSString *)source {
|
||||
|
||||
return nil;
|
||||
@ -141,10 +145,7 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(
|
||||
|
||||
NSMutableArray *argsMArr = [NSMutableArray new];
|
||||
for (id arg in args) {
|
||||
NSDictionary *dic = @{
|
||||
@"type": @(DoricargTypeWithArg(arg)),
|
||||
@"value": arg
|
||||
};
|
||||
NSDictionary *dic = [self dicForArg:arg];
|
||||
[argsMArr addObject:dic];
|
||||
}
|
||||
|
||||
@ -168,6 +169,19 @@ - (JSValue *)invokeObject:(NSString *)objName method:(NSString *)funcName args:(
|
||||
return self.temp;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dicForArg:(id)arg {
|
||||
DoricJSRemoteArgType type = DoricargTypeWithArg(arg);
|
||||
if (type == DoricJSRemoteArgTypeObject || type == DoricJSRemoteArgTypeArray) {
|
||||
NSString *jsonStr = [NSString dc_convertToJsonWithDic:(NSDictionary *)arg];
|
||||
arg = jsonStr;
|
||||
}
|
||||
NSDictionary *dic = @{
|
||||
@"type": @(type),
|
||||
@"value": arg
|
||||
};
|
||||
return dic;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
[self.srWebSocket close];
|
||||
}
|
||||
|
@ -73,11 +73,15 @@ - (id)findClass:(Class)clz target:(id)target context:(DoricContext *)context met
|
||||
dispatch_block_t block = ^() {
|
||||
__strong __typeof__(_self) self = _self;
|
||||
@try {
|
||||
NSMutableArray *tempArray = [NSMutableArray new];
|
||||
for (NSUInteger idx = 2; idx < methodSignature.numberOfArguments; idx++) {
|
||||
if (idx - 2 > [array count]) {
|
||||
break;
|
||||
}
|
||||
id args = [self createParamWithMethodName:array[idx - 2] context:context callbackId:callbackId argument:argument];
|
||||
if (args) {
|
||||
[tempArray addObject:args];
|
||||
}
|
||||
[invocation setArgument:&args atIndex:idx];
|
||||
}
|
||||
[invocation invoke];
|
||||
|
@ -18,7 +18,7 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol DoricNavBarDelegate <NSObject>
|
||||
- (BOOL)doric_navBar_isHidden;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol DoricNavigatorDelegate <NSObject>
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated;
|
||||
- (void)doric_navigator_push:(NSString *)scheme alias:(NSString *)alias animated:(BOOL)animated extra:(NSString *)extra;
|
||||
|
||||
- (void)doric_navigator_pop:(BOOL)animated;
|
||||
@end
|
@ -20,9 +20,9 @@
|
||||
// Created by pengfei.zhou on 2019/7/29.
|
||||
//
|
||||
|
||||
#import <Doric/Doric.h>
|
||||
#import "DoricModalPlugin.h"
|
||||
#import "DoricUtil.h"
|
||||
#import "DoricExtensions.h"
|
||||
|
||||
@implementation DoricModalPlugin
|
||||
|
||||
|
@ -24,10 +24,19 @@ @implementation DoricNavigatorPlugin
|
||||
- (void)push:(NSDictionary *)params {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
BOOL animated = YES;
|
||||
if (params[@"animated"]) {
|
||||
animated = [params[@"animated"] boolValue];
|
||||
NSString *scheme = params[@"scheme"];
|
||||
NSString *alias = scheme;
|
||||
NSDictionary *config = params[@"config"];
|
||||
if (config) {
|
||||
if (config[@"animated"]) {
|
||||
animated = [config[@"animated"] boolValue];
|
||||
}
|
||||
|
||||
if (config[@"alias"]) {
|
||||
alias = config[@"alias"];
|
||||
}
|
||||
}
|
||||
[self.doricContext.navigator doric_navigator_push:params[@"scheme"] alias:params[@"alias"] animated:animated];
|
||||
[self.doricContext.navigator doric_navigator_push:scheme alias:alias animated:animated extra:config[@"extra"]];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
@protocol DoricFlowLayoutDelegate
|
||||
- (CGFloat)doricFlowLayoutItemHeightAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (CGFloat)doricFlowLayoutItemWidthAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (CGFloat)doricFlowLayoutColumnSpace;
|
||||
|
||||
- (CGFloat)doricFlowLayoutRowSpace;
|
||||
@ -93,15 +95,23 @@ - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSInde
|
||||
}
|
||||
}
|
||||
|
||||
CGFloat width = (self.collectionView.width - self.columnSpace * (self.columnCount - 1)) / self.columnCount;
|
||||
CGFloat width = [self.delegate doricFlowLayoutItemWidthAtIndexPath:indexPath];
|
||||
CGFloat height = [self.delegate doricFlowLayoutItemHeightAtIndexPath:indexPath];
|
||||
CGFloat x = (width + self.columnSpace) * [minYOfColumn integerValue];
|
||||
CGFloat y = [self.columnHeightInfo[minYOfColumn] floatValue];
|
||||
if (y > 0) {
|
||||
y += self.rowSpace;
|
||||
}
|
||||
self.columnHeightInfo[minYOfColumn] = @(y + height);
|
||||
|
||||
if (width == self.collectionView.width) {
|
||||
CGFloat maxY = 0;
|
||||
for (NSNumber *column in self.columnHeightInfo.allValues) {
|
||||
maxY = MAX(maxY, [column floatValue]);
|
||||
}
|
||||
y = maxY + self.rowSpace;
|
||||
} else {
|
||||
self.columnHeightInfo[minYOfColumn] = @(y + height);
|
||||
}
|
||||
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
|
||||
attrs.frame = CGRectMake(x, y, width, height);
|
||||
return attrs;
|
||||
@ -156,6 +166,11 @@ @interface DoricFlowLayoutNode () <UICollectionViewDataSource, UICollectionViewD
|
||||
@property(nonatomic, assign) NSUInteger columnCount;
|
||||
@property(nonatomic, assign) CGFloat columnSpace;
|
||||
@property(nonatomic, assign) CGFloat rowSpace;
|
||||
@property(nonatomic, copy) NSString *renderItemFuncId;
|
||||
|
||||
@property(nonatomic, copy) NSString *onLoadMoreFuncId;
|
||||
@property(nonatomic, copy) NSString *loadMoreViewId;
|
||||
@property(nonatomic, assign) BOOL loadMore;
|
||||
@end
|
||||
|
||||
@implementation DoricFlowLayoutNode
|
||||
@ -180,6 +195,7 @@ - (UICollectionView *)build {
|
||||
it.delegate = self;
|
||||
it.dataSource = self;
|
||||
[it registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:@"doricCell"];
|
||||
[it registerClass:[DoricFlowLayoutViewCell class] forCellWithReuseIdentifier:@"doricLoadMoreCell"];
|
||||
}];
|
||||
}
|
||||
|
||||
@ -198,17 +214,31 @@ - (void)blendView:(UICollectionView *)view forPropName:(NSString *)name propValu
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderItem" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if ([self.renderItemFuncId isEqualToString:prop]) {
|
||||
} else {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
self.renderItemFuncId = prop;
|
||||
}
|
||||
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onLoadMore" isEqualToString:name]) {
|
||||
self.onLoadMoreFuncId = prop;
|
||||
} else if ([@"loadMoreView" isEqualToString:name]) {
|
||||
self.loadMoreViewId = prop;
|
||||
} else if ([@"loadMore" isEqualToString:name]) {
|
||||
self.loadMore = [prop boolValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
if (position >= self.itemCount) {
|
||||
return [self subModelOf:self.loadMoreViewId];
|
||||
}
|
||||
NSString *viewId = self.itemViewIds[@(position)];
|
||||
if (viewId && viewId.length > 0) {
|
||||
return [self subModelOf:viewId];
|
||||
@ -243,24 +273,26 @@ - (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
|
||||
}
|
||||
|
||||
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadItemsAtIndexPaths:@[indexPath]];
|
||||
}];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
}];
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadItemsAtIndexPaths:@[indexPath]];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)callItem:(NSUInteger)position size:(CGSize)size {
|
||||
@ -273,13 +305,14 @@ - (void)callItem:(NSUInteger)position size:(CGSize)size {
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
return self.itemCount;
|
||||
return self.itemCount + (self.loadMore ? 1 : 0);
|
||||
}
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSUInteger position = (NSUInteger) indexPath.row;
|
||||
NSDictionary *model = [self itemModelAt:position];
|
||||
NSDictionary *props = model[@"props"];
|
||||
|
||||
DoricFlowLayoutViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"doricCell" forIndexPath:indexPath];
|
||||
if (!cell.viewNode) {
|
||||
DoricFlowLayoutItemNode *itemNode = [[DoricFlowLayoutItemNode alloc] initWithContext:self.doricContext];
|
||||
@ -287,11 +320,17 @@ - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collection
|
||||
cell.viewNode = itemNode;
|
||||
[cell.contentView addSubview:itemNode.view];
|
||||
}
|
||||
|
||||
DoricFlowLayoutItemNode *node = cell.viewNode;
|
||||
node.viewId = model[@"id"];
|
||||
[node blend:props];
|
||||
CGFloat width = (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount;
|
||||
CGSize size = [node.view measureSize:CGSizeMake(width, collectionView.height)];
|
||||
if (position > 0 && position >= self.itemCount && self.onLoadMoreFuncId) {
|
||||
size = CGSizeMake(collectionView.width, size.height);
|
||||
[self callJSResponse:self.onLoadMoreFuncId, nil];
|
||||
}
|
||||
|
||||
[node.view layoutSelf:size];
|
||||
[self callItem:position size:size];
|
||||
return cell;
|
||||
@ -307,6 +346,17 @@ - (CGFloat)doricFlowLayoutItemHeightAtIndexPath:(NSIndexPath *)indexPath {
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)doricFlowLayoutItemWidthAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSUInteger position = (NSUInteger) indexPath.row;
|
||||
NSValue *value = self.itemSizeInfo[@(position)];
|
||||
if (value) {
|
||||
return [value CGSizeValue].width;
|
||||
} else {
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (CGFloat)doricFlowLayoutColumnSpace {
|
||||
return self.columnSpace;
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
// Created by pengfei.zhou on 2019/7/30.
|
||||
//
|
||||
|
||||
#import <Doric/DoricExtensions.h>
|
||||
#import "DoricGroupNode.h"
|
||||
|
||||
@interface DoricGroupNode ()
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
@interface DoricImageNode ()
|
||||
@property(nonatomic, copy) NSString *loadCallbackId;
|
||||
@property(nonatomic, assign) BOOL isBlur;
|
||||
@end
|
||||
|
||||
@implementation DoricImageNode
|
||||
@ -36,6 +37,15 @@ - (UIImageView *)build {
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)blend:(NSDictionary *)props {
|
||||
NSInteger value = [props[@"isBlur"] intValue];
|
||||
if(value == 1) {
|
||||
self.isBlur = YES;
|
||||
}
|
||||
|
||||
[super blend:props];
|
||||
}
|
||||
|
||||
- (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([@"imageUrl" isEqualToString:name]) {
|
||||
__weak typeof(self) _self = self;
|
||||
@ -53,6 +63,13 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
|
||||
}
|
||||
[self requestLayout];
|
||||
}
|
||||
|
||||
if(self.isBlur) {
|
||||
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
|
||||
UIVisualEffectView *effectView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];
|
||||
effectView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
|
||||
[view addSubview:effectView];
|
||||
}
|
||||
}];
|
||||
} else if ([@"scaleType" isEqualToString:name]) {
|
||||
switch ([prop integerValue]) {
|
||||
|
31
doric-iOS/Pod/Classes/Shader/DoricInputNode.h
Normal file
31
doric-iOS/Pod/Classes/Shader/DoricInputNode.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// DoricInputNode.h
|
||||
// Doric
|
||||
//
|
||||
// Created by 姜腾 on 2019/12/11.
|
||||
//
|
||||
|
||||
#import "DoricViewNode.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DoricInputNode : DoricViewNode<UITextView *>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
173
doric-iOS/Pod/Classes/Shader/DoricInputNode.m
Normal file
173
doric-iOS/Pod/Classes/Shader/DoricInputNode.m
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// DoricInputNode.m
|
||||
// Doric
|
||||
//
|
||||
// Created by 姜腾 on 2019/12/11.
|
||||
//
|
||||
|
||||
#import "DoricInputNode.h"
|
||||
#import "DoricUtil.h"
|
||||
#import "DoricPromise.h"
|
||||
|
||||
typedef void (^onTextChangeBlock)(NSString *text,DoricInputNode *node);
|
||||
typedef void (^onFocusChangeBlock)(BOOL focused,DoricInputNode *node);
|
||||
|
||||
@interface DoricInputNode()<UITextViewDelegate>
|
||||
@property(nonatomic, copy) onTextChangeBlock onTextChange;
|
||||
@property(nonatomic, copy) onFocusChangeBlock onFocusShange;
|
||||
@property(nonatomic, strong) UILabel *placeholderLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DoricInputNode
|
||||
- (UITextView *)build {
|
||||
UITextView *v = [[UITextView alloc] init];
|
||||
v.delegate = self;
|
||||
return v;
|
||||
}
|
||||
|
||||
- (void)blendView:(UITextView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([name isEqualToString:@"text"]) {
|
||||
view.text = prop;
|
||||
} else if ([name isEqualToString:@"textSize"]) {
|
||||
view.font = [UIFont systemFontOfSize:[(NSNumber *) prop floatValue]];
|
||||
} else if ([name isEqualToString:@"textColor"]) {
|
||||
view.textColor = DoricColor(prop);
|
||||
} else if ([name isEqualToString:@"textAlignment"]) {
|
||||
DoricGravity gravity = (DoricGravity) [(NSNumber *) prop integerValue];
|
||||
NSTextAlignment alignment = NSTextAlignmentCenter;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
alignment = NSTextAlignmentLeft;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
alignment = NSTextAlignmentRight;
|
||||
}
|
||||
view.textAlignment = alignment;
|
||||
} else if ([name isEqualToString:@"multiline"]) {
|
||||
BOOL mutilin = [(NSNumber *) prop boolValue];
|
||||
if (!mutilin) {
|
||||
view.textContainer.maximumNumberOfLines = 1;
|
||||
}else {
|
||||
view.textContainer.maximumNumberOfLines = 0;
|
||||
}
|
||||
} else if ([name isEqualToString:@"hintText"]) {
|
||||
self.placeholderLabel.text = (NSString *)prop;
|
||||
} else if ([name isEqualToString:@"hintTextColor"]) {
|
||||
self.placeholderLabel.textColor = DoricColor(prop);
|
||||
} else if ([name isEqualToString:@"onTextChange"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onTextChange = ^(NSString *text, DoricInputNode *node) {
|
||||
[node callJSResponse:prop,text,nil];
|
||||
};
|
||||
}else {
|
||||
self.onTextChange = nil;
|
||||
}
|
||||
} else if ([name isEqualToString:@"onFocusChange"]) {
|
||||
if ([prop isKindOfClass:[NSString class]]) {
|
||||
self.onFocusShange = ^(BOOL focused, DoricInputNode *node) {
|
||||
[node callJSResponse:prop,@(focused),nil];
|
||||
};
|
||||
}else {
|
||||
self.onFocusShange = nil;
|
||||
}
|
||||
|
||||
} else{
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)blend:(NSDictionary *)props {
|
||||
[super blend:props];
|
||||
[self updatePlaceholderLabel];
|
||||
[self.view.superview setNeedsLayout];
|
||||
}
|
||||
|
||||
#pragma mark - Doric-JS api
|
||||
- (NSString *)getText {
|
||||
return self.view.text;
|
||||
}
|
||||
|
||||
- (void)setSelection:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSString *start = params[@"start"];
|
||||
NSString *end = params[@"end"];
|
||||
|
||||
if (([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]]) &&
|
||||
([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]])) {
|
||||
self.view.selectedRange = NSMakeRange(start.intValue, end.intValue - start.intValue);
|
||||
}
|
||||
|
||||
[promise resolve:nil];
|
||||
}
|
||||
|
||||
- (void)requestFocus {
|
||||
[self.view becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void)releaseFocus {
|
||||
[self.view resignFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark - UITextViewDelegate
|
||||
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(YES, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
|
||||
if (self.onFocusShange) {
|
||||
self.onFocusShange(NO, self);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)textViewDidChange:(UITextView *)textView {
|
||||
if (self.onTextChange) {
|
||||
self.onTextChange(textView.text, self);
|
||||
}
|
||||
[self updatePlaceholderLabel];
|
||||
}
|
||||
|
||||
#pragma mark - placeholderLabel
|
||||
- (UILabel *)placeholderLabel {
|
||||
if (!_placeholderLabel) {
|
||||
_placeholderLabel = [[UILabel alloc] init];
|
||||
_placeholderLabel.numberOfLines = 0;
|
||||
_placeholderLabel.userInteractionEnabled = NO;
|
||||
}
|
||||
return _placeholderLabel;
|
||||
}
|
||||
|
||||
- (void)updatePlaceholderLabel {
|
||||
if (self.view.text.length) {
|
||||
[self.placeholderLabel removeFromSuperview];
|
||||
return;
|
||||
} else {
|
||||
[self.view insertSubview:self.placeholderLabel atIndex:0];
|
||||
}
|
||||
|
||||
self.placeholderLabel.textAlignment = self.view.textAlignment;
|
||||
CGFloat lineFragmentPadding = self.view.textContainer.lineFragmentPadding;
|
||||
UIEdgeInsets textContainerInset = self.view.textContainerInset;
|
||||
|
||||
CGFloat x = lineFragmentPadding + textContainerInset.left;
|
||||
CGFloat y = textContainerInset.top;
|
||||
CGFloat width = CGRectGetWidth(self.view.bounds) - x - lineFragmentPadding - textContainerInset.right;
|
||||
CGFloat height = [self.placeholderLabel sizeThatFits:CGSizeMake(width, 0)].height;
|
||||
self.placeholderLabel.frame = CGRectMake(x, y, width, height);
|
||||
}
|
||||
@end
|
@ -18,8 +18,11 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef UIEdgeInsets DoricMargin;
|
||||
typedef UIEdgeInsets DoricPadding;
|
||||
|
||||
DoricMargin DoricMarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom);
|
||||
|
||||
@ -82,6 +85,10 @@ typedef NS_ENUM(NSInteger, DoricGravity) {
|
||||
@property(nonatomic, strong) DoricLayoutConfig *layoutConfig;
|
||||
@end
|
||||
|
||||
@interface UIView (DoricPadding)
|
||||
@property(nonatomic, assign) DoricPadding padding;
|
||||
@end
|
||||
|
||||
@interface UIView (DoricTag)
|
||||
@property(nonatomic, copy) NSString *tagString;
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#import "DoricLayouts.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <Doric/DoricLayouts.h>
|
||||
#import "UIView+Doric.h"
|
||||
|
||||
static const void *kLayoutConfig = &kLayoutConfig;
|
||||
@ -37,6 +36,24 @@ - (DoricLayoutConfig *)layoutConfig {
|
||||
|
||||
@end
|
||||
|
||||
static const void *kLayoutPadding = &kLayoutPadding;
|
||||
|
||||
@implementation UIView (DoricPadding)
|
||||
@dynamic padding;
|
||||
|
||||
- (void)setPadding:(DoricPadding)padding {
|
||||
objc_setAssociatedObject(self, kLayoutPadding, [NSValue value:&padding withObjCType:@encode(DoricPadding)], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (DoricPadding)padding {
|
||||
DoricPadding value;
|
||||
value.left = value.right = value.top = value.bottom = 0;
|
||||
[objc_getAssociatedObject(self, kLayoutPadding) getValue:&value];
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static const void *kTagString = &kTagString;
|
||||
|
||||
@implementation UIView (DoricTag)
|
||||
@ -79,13 +96,15 @@ - (CGSize)measureSize:(CGSize)targetSize {
|
||||
|| config.heightSpec == DoricLayoutWrapContent) {
|
||||
height = targetSize.height - config.margin.top - config.margin.bottom;
|
||||
}
|
||||
|
||||
CGSize contentSize = [self sizeThatFits:CGSizeMake(width, height)];
|
||||
DoricPadding padding = self.padding;
|
||||
CGSize contentSize = [self sizeThatFits:CGSizeMake(
|
||||
width - padding.left - padding.right,
|
||||
height - padding.top - padding.bottom)];
|
||||
if (config.widthSpec == DoricLayoutWrapContent) {
|
||||
width = contentSize.width;
|
||||
width = contentSize.width + padding.left + padding.right;
|
||||
}
|
||||
if (config.heightSpec == DoricLayoutWrapContent) {
|
||||
height = contentSize.height;
|
||||
height = contentSize.height + padding.left + padding.top + padding.bottom;
|
||||
}
|
||||
return CGSizeMake(width, height);
|
||||
}
|
||||
@ -208,6 +227,8 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
DoricPadding padding = self.padding;
|
||||
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@ -219,33 +240,35 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
if (!childConfig) {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width, targetSize.height)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - padding.left - padding.right,
|
||||
targetSize.height - padding.top - padding.bottom)];
|
||||
[child layoutSelf:size];
|
||||
DoricGravity gravity = childConfig.alignment;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
child.left = 0;
|
||||
child.left = padding.left;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
child.right = targetSize.width;
|
||||
child.right = targetSize.width - padding.right;
|
||||
} else if ((gravity & CENTER_X) == CENTER_X) {
|
||||
child.centerX = targetSize.width / 2;
|
||||
} else {
|
||||
if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left;
|
||||
child.left = childConfig.margin.left + padding.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right;
|
||||
child.right = targetSize.width - childConfig.margin.right - padding.right;
|
||||
}
|
||||
}
|
||||
if ((gravity & TOP) == TOP) {
|
||||
child.top = 0;
|
||||
child.top = padding.top;
|
||||
} else if ((gravity & BOTTOM) == BOTTOM) {
|
||||
child.bottom = targetSize.height;
|
||||
child.bottom = targetSize.height - padding.bottom;
|
||||
} else if ((gravity & CENTER_Y) == CENTER_Y) {
|
||||
child.centerY = targetSize.height / 2;
|
||||
} else {
|
||||
if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top;
|
||||
child.top = childConfig.margin.top + padding.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom;
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom - padding.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,15 +315,16 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
CGFloat yStart = 0;
|
||||
DoricPadding padding = self.padding;
|
||||
CGFloat yStart = padding.top;
|
||||
if ((self.gravity & TOP) == TOP) {
|
||||
yStart = 0;
|
||||
yStart = padding.top;
|
||||
} else if ((self.gravity & BOTTOM) == BOTTOM) {
|
||||
yStart = targetSize.height - self.contentHeight;
|
||||
yStart = targetSize.height - self.contentHeight - padding.bottom;
|
||||
} else if ((self.gravity & CENTER_Y) == CENTER_Y) {
|
||||
yStart = (targetSize.height - self.contentHeight) / 2;
|
||||
yStart = (targetSize.height - self.contentHeight - padding.top - padding.bottom) / 2 + padding.top;
|
||||
}
|
||||
CGFloat remain = targetSize.height - self.contentHeight;
|
||||
CGFloat remain = targetSize.height - self.contentHeight - padding.top - padding.bottom;
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@ -313,24 +337,26 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width, targetSize.height - yStart)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - padding.left - padding.right,
|
||||
targetSize.height - yStart - padding.bottom)];
|
||||
if (childConfig.weight) {
|
||||
size.height += remain / self.contentWeight * childConfig.weight;
|
||||
}
|
||||
[child layoutSelf:size];
|
||||
DoricGravity gravity = childConfig.alignment | self.gravity;
|
||||
if ((gravity & LEFT) == LEFT) {
|
||||
child.left = 0;
|
||||
child.left = padding.left;
|
||||
} else if ((gravity & RIGHT) == RIGHT) {
|
||||
child.right = self.width;
|
||||
child.right = self.width - padding.right;
|
||||
} else if ((gravity & CENTER_X) == CENTER_X) {
|
||||
child.centerX = targetSize.width / 2;
|
||||
} else if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left + padding.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right - padding.right;
|
||||
} else {
|
||||
if (childConfig.margin.left) {
|
||||
child.left = childConfig.margin.left;
|
||||
} else if (childConfig.margin.right) {
|
||||
child.right = targetSize.width - childConfig.margin.right;
|
||||
}
|
||||
child.left = padding.left;
|
||||
}
|
||||
if (childConfig.margin.top) {
|
||||
yStart += childConfig.margin.top;
|
||||
@ -380,17 +406,16 @@ - (CGSize)sizeThatFits:(CGSize)size {
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
self.width = targetSize.width;
|
||||
self.height = targetSize.height;
|
||||
CGFloat xStart = 0;
|
||||
if (self.contentWeight) {
|
||||
xStart = 0;
|
||||
} else if ((self.gravity & LEFT) == LEFT) {
|
||||
xStart = 0;
|
||||
DoricPadding padding = self.padding;
|
||||
CGFloat xStart = padding.left;
|
||||
if ((self.gravity & LEFT) == LEFT) {
|
||||
xStart = padding.left;
|
||||
} else if ((self.gravity & RIGHT) == RIGHT) {
|
||||
xStart = targetSize.width - self.contentWidth;
|
||||
xStart = targetSize.width - self.contentWidth - padding.right;
|
||||
} else if ((self.gravity & CENTER_X) == CENTER_X) {
|
||||
xStart = (targetSize.width - self.contentWidth) / 2;
|
||||
xStart = (targetSize.width - self.contentWidth - padding.left - padding.right) / 2 + padding.left;
|
||||
}
|
||||
CGFloat remain = targetSize.width - self.contentWidth;
|
||||
CGFloat remain = targetSize.width - self.contentWidth - padding.left - padding.right;
|
||||
for (UIView *child in self.subviews) {
|
||||
if (child.isHidden) {
|
||||
continue;
|
||||
@ -403,7 +428,9 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
childConfig = [DoricLayoutConfig new];
|
||||
}
|
||||
|
||||
CGSize size = [child measureSize:CGSizeMake(targetSize.width - xStart, targetSize.height)];
|
||||
CGSize size = [child measureSize:CGSizeMake(
|
||||
targetSize.width - xStart - padding.right,
|
||||
targetSize.height - padding.top - padding.bottom)];
|
||||
if (childConfig.weight) {
|
||||
size.width += remain / self.contentWeight * childConfig.weight;
|
||||
}
|
||||
@ -412,17 +439,17 @@ - (void)layoutSelf:(CGSize)targetSize {
|
||||
|
||||
DoricGravity gravity = childConfig.alignment | self.gravity;
|
||||
if ((gravity & TOP) == TOP) {
|
||||
child.top = 0;
|
||||
child.top = padding.top;
|
||||
} else if ((gravity & BOTTOM) == BOTTOM) {
|
||||
child.bottom = targetSize.height;
|
||||
child.bottom = targetSize.height - padding.bottom;
|
||||
} else if ((gravity & CENTER_Y) == CENTER_Y) {
|
||||
child.centerY = targetSize.height / 2;
|
||||
} else if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top + padding.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom - padding.bottom;
|
||||
} else {
|
||||
if (childConfig.margin.top) {
|
||||
child.top = childConfig.margin.top;
|
||||
} else if (childConfig.margin.bottom) {
|
||||
child.bottom = targetSize.height - childConfig.margin.bottom;
|
||||
}
|
||||
child.top = padding.top;
|
||||
}
|
||||
|
||||
if (childConfig.margin.left) {
|
||||
|
@ -62,6 +62,10 @@ @interface DoricListNode () <UITableViewDataSource, UITableViewDelegate>
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSNumber *> *itemHeights;
|
||||
@property(nonatomic, assign) NSUInteger itemCount;
|
||||
@property(nonatomic, assign) NSUInteger batchCount;
|
||||
@property(nonatomic, copy) NSString *onLoadMoreFuncId;
|
||||
@property(nonatomic, copy) NSString *renderItemFuncId;
|
||||
@property(nonatomic, copy) NSString *loadMoreViewId;
|
||||
@property(nonatomic, assign) BOOL loadMore;
|
||||
@end
|
||||
|
||||
@implementation DoricListNode
|
||||
@ -86,6 +90,7 @@ - (UITableView *)build {
|
||||
it.dataSource = self;
|
||||
it.delegate = self;
|
||||
it.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
it.allowsSelection = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
@ -94,11 +99,22 @@ - (void)blendView:(UITableView *)view forPropName:(NSString *)name propValue:(id
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderItem" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if (![self.renderItemFuncId isEqualToString:prop]) {
|
||||
self.renderItemFuncId = prop;
|
||||
[self.itemViewIds.allValues forEach:^(NSString *obj) {
|
||||
[self removeSubModel:obj];
|
||||
}];
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self.view reloadData];
|
||||
}
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onLoadMore" isEqualToString:name]) {
|
||||
self.onLoadMoreFuncId = prop;
|
||||
} else if ([@"loadMoreView" isEqualToString:name]) {
|
||||
self.loadMoreViewId = prop;
|
||||
} else if ([@"loadMore" isEqualToString:name]) {
|
||||
self.loadMore = [prop boolValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@ -109,7 +125,7 @@ - (void)blend:(NSDictionary *)props {
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.itemCount;
|
||||
return self.itemCount + (self.loadMore ? 1 : 0);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
@ -117,7 +133,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
|
||||
NSDictionary *model = [self itemModelAt:position];
|
||||
NSDictionary *props = model[@"props"];
|
||||
NSString *reuseId = props[@"identifier"];
|
||||
|
||||
if (position > 0 && position >= self.itemCount && self.onLoadMoreFuncId) {
|
||||
reuseId = @"doricLoadMoreCell";
|
||||
[self callJSResponse:self.onLoadMoreFuncId, nil];
|
||||
}
|
||||
DoricTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId ?: @"doriccell"];
|
||||
if (!cell) {
|
||||
cell = [[DoricTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseId ?: @"doriccell"];
|
||||
@ -147,6 +166,9 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
|
||||
}
|
||||
|
||||
- (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
if (position >= self.itemCount) {
|
||||
return [self subModelOf:self.loadMoreViewId];
|
||||
}
|
||||
NSString *viewId = self.itemViewIds[@(position)];
|
||||
if (viewId && viewId.length > 0) {
|
||||
return [self subModelOf:viewId];
|
||||
@ -160,29 +182,37 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position {
|
||||
NSUInteger pos = position + idx;
|
||||
self.itemViewIds[@(pos)] = thisViewId;
|
||||
}];
|
||||
return array[0];
|
||||
if (array.count > 0) {
|
||||
return array[0];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
///Here async blend sub node because the item count need to be applied first.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *viewId = subModel[@"id"];
|
||||
DoricViewNode *viewNode = [self subNodeWithViewId:viewId];
|
||||
if (viewNode) {
|
||||
[viewNode blend:subModel[@"props"]];
|
||||
} else {
|
||||
NSMutableDictionary *model = [[self subModelOf:viewId] mutableCopy];
|
||||
[self recursiveMixin:subModel to:model];
|
||||
[self setSubModel:model in:viewId];
|
||||
}
|
||||
}];
|
||||
[self.itemViewIds enumerateKeysAndObjectsUsingBlock:^(NSNumber *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
|
||||
if ([viewId isEqualToString:obj]) {
|
||||
*stop = YES;
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[key integerValue] inSection:0];
|
||||
[UIView performWithoutAnimation:^{
|
||||
[self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
- (void)callItem:(NSUInteger)position height:(CGFloat)height {
|
||||
|
24
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.h
Normal file
24
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/7.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "DoricGroupNode.h"
|
||||
|
||||
@interface DoricNestedSliderNode : DoricGroupNode<UIScrollView *>
|
||||
@end
|
101
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m
Normal file
101
doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// Created by pengfei.zhou on 2019/12/7.
|
||||
//
|
||||
|
||||
#import "DoricNestedSliderNode.h"
|
||||
#import "Doric.h"
|
||||
|
||||
@interface DoricNestedSliderView : UIScrollView
|
||||
|
||||
@end
|
||||
|
||||
@implementation DoricNestedSliderView
|
||||
- (CGSize)sizeThatFits:(CGSize)size {
|
||||
if (self.subviews.count > 0) {
|
||||
CGFloat width = size.width;
|
||||
CGFloat height = size.height;
|
||||
for (UIView *child in self.subviews) {
|
||||
CGSize childSize = [child measureSize:size];
|
||||
width = MAX(childSize.width, width);
|
||||
height = MAX(childSize.height, height);
|
||||
}
|
||||
return CGSizeMake(width, height);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)layoutSelf:(CGSize)targetSize {
|
||||
[super layoutSelf:targetSize];
|
||||
[self.subviews forEachIndexed:^(__kindof UIView *obj, NSUInteger idx) {
|
||||
obj.left = idx * self.width;
|
||||
}];
|
||||
[self setContentSize:CGSizeMake(self.subviews.count * self.width, self.height)];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface DoricNestedSliderNode () <UIScrollViewDelegate>
|
||||
@property(nonatomic, copy) NSString *onPageSelectedFuncId;
|
||||
@property(nonatomic, assign) NSUInteger lastPosition;
|
||||
@end
|
||||
|
||||
@implementation DoricNestedSliderNode
|
||||
- (UIScrollView *)build {
|
||||
return [[DoricNestedSliderView new] also:^(DoricNestedSliderView *it) {
|
||||
it.delegate = self;
|
||||
it.pagingEnabled = YES;
|
||||
[it setShowsVerticalScrollIndicator:NO];
|
||||
[it setShowsHorizontalScrollIndicator:NO];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)blendView:(UIScrollView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||
if ([@"onPageSlided" isEqualToString:name]) {
|
||||
self.onPageSelectedFuncId = prop;
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
||||
NSUInteger pageIndex = (NSUInteger) (scrollView.contentOffset.x / scrollView.width);
|
||||
[scrollView setContentOffset:CGPointMake(pageIndex * scrollView.width, scrollView.contentOffset.y) animated:YES];
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
if (pageIndex != self.lastPosition) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
self.lastPosition = pageIndex;
|
||||
}
|
||||
|
||||
|
||||
- (void)slidePage:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSUInteger pageIndex = [params[@"page"] unsignedIntegerValue];
|
||||
BOOL smooth = [params[@"smooth"] boolValue];
|
||||
[self.view setContentOffset:CGPointMake(pageIndex * self.view.width, self.view.contentOffset.y) animated:smooth];
|
||||
[promise resolve:nil];
|
||||
self.lastPosition = pageIndex;
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)getSlidedPage {
|
||||
NSUInteger pageIndex = (NSUInteger) (self.view.contentOffset.x / self.view.width);
|
||||
return @(pageIndex);
|
||||
}
|
||||
@end
|
@ -54,7 +54,11 @@ @interface DoricScrollerNode ()
|
||||
|
||||
@implementation DoricScrollerNode
|
||||
- (DoricScrollView *)build {
|
||||
return [DoricScrollView new];
|
||||
return [[DoricScrollView new] also:^(DoricScrollView *it) {
|
||||
if (@available(iOS 11, *)) {
|
||||
it.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||
|
@ -35,6 +35,9 @@ @interface DoricSliderNode () <UICollectionViewDataSource, UICollectionViewDeleg
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSString *> *itemViewIds;
|
||||
@property(nonatomic, assign) NSUInteger itemCount;
|
||||
@property(nonatomic, assign) NSUInteger batchCount;
|
||||
@property(nonatomic, copy) NSString *onPageSelectedFuncId;
|
||||
@property(nonatomic, assign) NSUInteger lastPosition;
|
||||
@property(nonatomic, copy) NSString *renderPageFuncId;
|
||||
@end
|
||||
|
||||
@interface DoricSliderView : UICollectionView
|
||||
@ -90,11 +93,18 @@ - (void)blendView:(UICollectionView *)view forPropName:(NSString *)name propValu
|
||||
self.itemCount = [prop unsignedIntegerValue];
|
||||
[self.view reloadData];
|
||||
} else if ([@"renderPage" isEqualToString:name]) {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
if ([self.renderPageFuncId isEqualToString:prop]) {
|
||||
|
||||
} else {
|
||||
[self.itemViewIds removeAllObjects];
|
||||
[self clearSubModel];
|
||||
[self.view reloadData];
|
||||
self.renderPageFuncId = prop;
|
||||
}
|
||||
} else if ([@"batchCount" isEqualToString:name]) {
|
||||
self.batchCount = [prop unsignedIntegerValue];
|
||||
} else if ([@"onPageSlided" isEqualToString:name]) {
|
||||
self.onPageSelectedFuncId = prop;
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
@ -197,5 +207,28 @@ - (void)blendSubNode:(NSDictionary *)subModel {
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
||||
NSUInteger pageIndex = (NSUInteger) (scrollView.contentOffset.x / scrollView.width);
|
||||
scrollView.contentOffset = CGPointMake(pageIndex * scrollView.width, scrollView.contentOffset.y);
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
if (pageIndex != self.lastPosition) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
self.lastPosition = pageIndex;
|
||||
}
|
||||
|
||||
- (void)slidePage:(NSDictionary *)params withPromise:(DoricPromise *)promise {
|
||||
NSUInteger pageIndex = [params[@"page"] unsignedIntegerValue];
|
||||
BOOL smooth = [params[@"smooth"] boolValue];
|
||||
[self.view setContentOffset:CGPointMake(pageIndex * self.view.width, self.view.contentOffset.y) animated:smooth];
|
||||
[promise resolve:nil];
|
||||
self.lastPosition = pageIndex;
|
||||
if (self.onPageSelectedFuncId && self.onPageSelectedFuncId.length > 0) {
|
||||
[self callJSResponse:self.onPageSelectedFuncId, @(pageIndex), nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)getSlidedPage {
|
||||
NSUInteger pageIndex = (NSUInteger) (self.view.contentOffset.x / self.view.width);
|
||||
return @(pageIndex);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
- (void)clearSubModel;
|
||||
|
||||
- (void)removeSubModel:(NSString *)viewId;
|
||||
|
||||
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId;
|
||||
|
||||
- (void)recursiveMixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel;
|
||||
|
@ -62,7 +62,6 @@ - (void)mixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
|
||||
targetProp[key] = obj;
|
||||
}
|
||||
}];
|
||||
targetModel[@"props"] = targetProp;
|
||||
}
|
||||
|
||||
- (void)recursiveMixin:(NSDictionary *)srcModel to:(NSMutableDictionary *)targetModel {
|
||||
@ -149,11 +148,16 @@ - (void)clearSubModel {
|
||||
[self.subNodes removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)removeSubModel:(NSString *)viewId {
|
||||
[self.subNodes removeObjectForKey:viewId];
|
||||
}
|
||||
|
||||
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
|
||||
NSAssert(NO, @"Should override class:%@ ,method:%@.", NSStringFromClass([self class]),
|
||||
NSStringFromSelector(_cmd));
|
||||
NSStringFromSelector(_cmd));
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)requestLayout {
|
||||
[self.view setNeedsLayout];
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ - (void)blendView:(UILabel *)view forPropName:(NSString *)name propValue:(id)pro
|
||||
alignment = NSTextAlignmentRight;
|
||||
}
|
||||
view.textAlignment = alignment;
|
||||
} else if ([name isEqualToString:@"maxLines"]) {
|
||||
view.numberOfLines = [prop integerValue];
|
||||
} else {
|
||||
[super blendView:view forPropName:name propValue:prop];
|
||||
}
|
||||
|
@ -235,7 +235,6 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
||||
} else {
|
||||
view.clipsToBounds = YES;
|
||||
}
|
||||
|
||||
} else if ([name isEqualToString:@"translationX"]) {
|
||||
self.translationX = prop;
|
||||
} else if ([name isEqualToString:@"translationY"]) {
|
||||
@ -250,6 +249,19 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
|
||||
self.pivotY = prop;
|
||||
} else if ([name isEqualToString:@"rotation"]) {
|
||||
self.rotation = prop;
|
||||
} else if ([name isEqualToString:@"padding"]) {
|
||||
DoricPadding padding;
|
||||
padding.left = padding.right = padding.top = padding.bottom = 0;
|
||||
if ([prop isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *dictionary = prop;
|
||||
padding.left = [dictionary[@"left"] floatValue];
|
||||
padding.right = [dictionary[@"right"] floatValue];
|
||||
padding.top = [dictionary[@"top"] floatValue];
|
||||
padding.bottom = [dictionary[@"bottom"] floatValue];
|
||||
}
|
||||
self.view.padding = padding;
|
||||
} else if ([name isEqualToString:@"hidden"]) {
|
||||
self.view.hidden = [prop boolValue];
|
||||
} else {
|
||||
DoricLog(@"Blend View error for View Type :%@, prop is %@", self.class, name);
|
||||
}
|
||||
@ -305,6 +317,11 @@ - (NSNumber *)getHeight {
|
||||
return @(self.view.height);
|
||||
}
|
||||
|
||||
- (NSDictionary *)getLocationOnScreen {
|
||||
CGPoint point = [self.view convertPoint:CGPointMake(0, 0) toView:[UIApplication sharedApplication].windows.lastObject];
|
||||
return @{@"x": @(point.x), @"y": @(point.y)};
|
||||
}
|
||||
|
||||
- (void)blendLayoutConfig:(NSDictionary *)params {
|
||||
[params[@"widthSpec"] also:^(NSNumber *it) {
|
||||
if (it) {
|
||||
@ -357,6 +374,8 @@ - (NSDictionary *)transformation {
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
#pragma animations
|
||||
|
||||
- (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
CAAnimation *animation = [self parseAnimation:params];
|
||||
AnimationCallback *originDelegate = animation.delegate;
|
||||
@ -371,6 +390,7 @@ - (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
if (originDelegate) {
|
||||
originDelegate.endBlock(callback);
|
||||
}
|
||||
[self.view.layer removeAllAnimations];
|
||||
[self transformProperties];
|
||||
[promise resolve:self.transformation];
|
||||
};
|
||||
@ -379,6 +399,8 @@ - (void)doAnimation:(id)params withPromise:(DoricPromise *)promise {
|
||||
if (params[@"delay"]) {
|
||||
animation.beginTime = CACurrentMediaTime() + [params[@"delay"] floatValue] / 1000;
|
||||
}
|
||||
animation.removedOnCompletion = NO;
|
||||
animation.fillMode = kCAFillModeForwards;
|
||||
[self.view.layer addAnimation:animation forKey:nil];
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ - (void)setupError:(NSException *)exception {
|
||||
}
|
||||
|
||||
- (BOOL)hasResult {
|
||||
return self.result;
|
||||
return self.result != nil;
|
||||
}
|
||||
|
||||
- (id)getResult {
|
||||
|
@ -26,7 +26,7 @@ extern NSString *const DORIC_BUNDLE_SANDBOX;
|
||||
extern NSString *const DORIC_BUNDLE_LIB;
|
||||
extern NSString *const DORIC_MODULE_LIB;
|
||||
|
||||
|
||||
extern NSString *const INJECT_ENVIRONMENT;
|
||||
extern NSString *const INJECT_LOG;
|
||||
extern NSString *const INJECT_REQUIRE;
|
||||
extern NSString *const INJECT_TIMER_SET;
|
||||
|
@ -26,6 +26,7 @@
|
||||
NSString *const DORIC_BUNDLE_LIB = @"doric-lib";
|
||||
NSString *const DORIC_MODULE_LIB = @"doric";
|
||||
|
||||
NSString *const INJECT_ENVIRONMENT = @"Environment";
|
||||
|
||||
NSString *const INJECT_LOG = @"nativeLog";
|
||||
NSString *const INJECT_REQUIRE = @"nativeRequire";
|
||||
|
@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
||||
DoricJSRemoteArgTypeNil = 0,
|
||||
DoricJSRemoteArgTypeInteger,
|
||||
DoricJSRemoteArgTypeNumber,
|
||||
DoricJSRemoteArgTypeBool,
|
||||
DoricJSRemoteArgTypeString,
|
||||
DoricJSRemoteArgTypeObject,
|
||||
@ -20,4 +20,5 @@ typedef NS_ENUM(NSUInteger, DoricJSRemoteArgType) {
|
||||
|
||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg);
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@ -7,6 +7,15 @@
|
||||
|
||||
#import "DoricJSRemoteArgType.h"
|
||||
DoricJSRemoteArgType DoricargTypeWithArg(id arg) {
|
||||
// TODO: 类型缺失
|
||||
return DoricJSRemoteArgTypeString;
|
||||
DoricJSRemoteArgType type = DoricJSRemoteArgTypeNil;
|
||||
if ([arg isKindOfClass:[NSNumber class]]) {
|
||||
type = DoricJSRemoteArgTypeNumber;
|
||||
}else if ([arg isKindOfClass:[NSString class]]) {
|
||||
type = DoricJSRemoteArgTypeString;
|
||||
}else if ([arg isKindOfClass:[NSDictionary class]]) {
|
||||
type = DoricJSRemoteArgTypeObject;
|
||||
}else if ([arg isKindOfClass:[NSMutableArray class]]) {
|
||||
type = DoricJSRemoteArgTypeArray;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
@ -39,4 +39,4 @@ NSBundle *_Nonnull DoricBundle(void);
|
||||
|
||||
void ShowToast(NSString *_Nonnull text, DoricGravity gravity);
|
||||
|
||||
UIImage *_Nonnull UIImageWithColor(UIColor *color);
|
||||
UIImage *_Nonnull UIImageWithColor(UIColor * _Nonnull color);
|
||||
|
3
doric-iOS/README.md
Normal file
3
doric-iOS/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Doric iOS SDK
|
||||
|
||||
## Usages
|
Reference in New Issue
Block a user