fix: restore demo build and drawing interactions
This commit is contained in:
parent
1422461224
commit
52f803e8db
@ -16,30 +16,40 @@ PODS:
|
|||||||
- DTFoundation/Core
|
- DTFoundation/Core
|
||||||
- DTFoundation/UIKit (1.7.19):
|
- DTFoundation/UIKit (1.7.19):
|
||||||
- DTFoundation/Core
|
- DTFoundation/Core
|
||||||
- RDEpubReaderView (0.0.1):
|
- RDEpubReaderView (0.0.2):
|
||||||
- DTCoreText (~> 1.6)
|
- DTCoreText (~> 1.6)
|
||||||
|
- SnapKit (~> 5.7)
|
||||||
- ZIPFoundation (~> 0.9)
|
- ZIPFoundation (~> 0.9)
|
||||||
|
- RDPDFReaderView (0.0.1):
|
||||||
|
- SnapKit (~> 5.7)
|
||||||
|
- SnapKit (5.7.1)
|
||||||
- ZIPFoundation (0.9.20)
|
- ZIPFoundation (0.9.20)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- RDEpubReaderView (from `..`)
|
- RDEpubReaderView (from `../Sources/RDEpubReaderView`)
|
||||||
|
- RDPDFReaderView (from `../Sources/RDPDFReaderView`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- DTCoreText
|
- DTCoreText
|
||||||
- DTFoundation
|
- DTFoundation
|
||||||
|
- SnapKit
|
||||||
- ZIPFoundation
|
- ZIPFoundation
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
RDEpubReaderView:
|
RDEpubReaderView:
|
||||||
:path: ".."
|
:path: "../Sources/RDEpubReaderView"
|
||||||
|
RDPDFReaderView:
|
||||||
|
:path: "../Sources/RDPDFReaderView"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
|
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
|
||||||
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
|
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
|
||||||
RDEpubReaderView: 5ff99b803f5a46e5ff4ebef3024dd217284c69ed
|
RDEpubReaderView: 6bab24a23236a223b29a02f3d00b6ac7829a4b97
|
||||||
|
RDPDFReaderView: ea8c225655c8fdc1f34d75026e05fa1e50744b36
|
||||||
|
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
|
||||||
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
|
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
|
||||||
|
|
||||||
PODFILE CHECKSUM: adda84af3e8577b2a99d5b2cecf381511352f0bd
|
PODFILE CHECKSUM: c39db27dbc9c6a96a33f22e78ce1b22dcd48d75f
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "RDEpubReaderView",
|
"name": "RDEpubReaderView",
|
||||||
"module_name": "RDEpubReaderView",
|
"module_name": "RDEpubReaderView",
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"summary": "A reader view for EPUB and plain-text books",
|
"summary": "A reader view for EPUB and plain-text books",
|
||||||
"platforms": {
|
"platforms": {
|
||||||
"ios": "15.0"
|
"ios": "15.0"
|
||||||
@ -15,13 +15,13 @@
|
|||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"git": "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git",
|
"git": "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git",
|
||||||
"tag": "0.0.1"
|
"tag": "0.0.2"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"source_files": "Sources/RDEpubReaderView/**/*.{swift}",
|
"source_files": "**/*.swift",
|
||||||
"resource_bundles": {
|
"resource_bundles": {
|
||||||
"RDEpubReaderViewAssets": [
|
"RDEpubReaderViewAssets": [
|
||||||
"Sources/RDEpubReaderView/EPUBCore/Resources/**/*"
|
"EPUBCore/Resources/**/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -30,6 +30,9 @@
|
|||||||
],
|
],
|
||||||
"DTCoreText": [
|
"DTCoreText": [
|
||||||
"~> 1.6"
|
"~> 1.6"
|
||||||
|
],
|
||||||
|
"SnapKit": [
|
||||||
|
"~> 5.7"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"requires_arc": true,
|
"requires_arc": true,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "RDPDFReaderView",
|
"name": "RDPDFReaderView",
|
||||||
"module_name": "RDPDFReaderView",
|
"module_name": "RDPDFReaderView",
|
||||||
"version": "0.1.0",
|
"version": "0.0.1",
|
||||||
"summary": "Independent UIKit PDF reader interaction engine",
|
"summary": "Independent UIKit PDF reader interaction engine",
|
||||||
"platforms": {
|
"platforms": {
|
||||||
"ios": "15.0"
|
"ios": "15.0"
|
||||||
|
|||||||
20
ReadViewDemo/Pods/Manifest.lock
generated
20
ReadViewDemo/Pods/Manifest.lock
generated
@ -16,30 +16,40 @@ PODS:
|
|||||||
- DTFoundation/Core
|
- DTFoundation/Core
|
||||||
- DTFoundation/UIKit (1.7.19):
|
- DTFoundation/UIKit (1.7.19):
|
||||||
- DTFoundation/Core
|
- DTFoundation/Core
|
||||||
- RDEpubReaderView (0.0.1):
|
- RDEpubReaderView (0.0.2):
|
||||||
- DTCoreText (~> 1.6)
|
- DTCoreText (~> 1.6)
|
||||||
|
- SnapKit (~> 5.7)
|
||||||
- ZIPFoundation (~> 0.9)
|
- ZIPFoundation (~> 0.9)
|
||||||
|
- RDPDFReaderView (0.0.1):
|
||||||
|
- SnapKit (~> 5.7)
|
||||||
|
- SnapKit (5.7.1)
|
||||||
- ZIPFoundation (0.9.20)
|
- ZIPFoundation (0.9.20)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- RDEpubReaderView (from `..`)
|
- RDEpubReaderView (from `../Sources/RDEpubReaderView`)
|
||||||
|
- RDPDFReaderView (from `../Sources/RDPDFReaderView`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- DTCoreText
|
- DTCoreText
|
||||||
- DTFoundation
|
- DTFoundation
|
||||||
|
- SnapKit
|
||||||
- ZIPFoundation
|
- ZIPFoundation
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
RDEpubReaderView:
|
RDEpubReaderView:
|
||||||
:path: ".."
|
:path: "../Sources/RDEpubReaderView"
|
||||||
|
RDPDFReaderView:
|
||||||
|
:path: "../Sources/RDPDFReaderView"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
|
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
|
||||||
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
|
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
|
||||||
RDEpubReaderView: 5ff99b803f5a46e5ff4ebef3024dd217284c69ed
|
RDEpubReaderView: 6bab24a23236a223b29a02f3d00b6ac7829a4b97
|
||||||
|
RDPDFReaderView: ea8c225655c8fdc1f34d75026e05fa1e50744b36
|
||||||
|
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
|
||||||
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
|
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
|
||||||
|
|
||||||
PODFILE CHECKSUM: adda84af3e8577b2a99d5b2cecf381511352f0bd
|
PODFILE CHECKSUM: c39db27dbc9c6a96a33f22e78ce1b22dcd48d75f
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
5411
ReadViewDemo/Pods/Pods.xcodeproj/project.pbxproj
generated
5411
ReadViewDemo/Pods/Pods.xcodeproj/project.pbxproj
generated
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
|||||||
|
${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
|
||||||
|
${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle
|
||||||
@ -0,0 +1 @@
|
|||||||
|
${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RDEpubReaderViewAssets.bundle
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
|
||||||
|
${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle
|
||||||
@ -0,0 +1 @@
|
|||||||
|
${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RDEpubReaderViewAssets.bundle
|
||||||
129
ReadViewDemo/Pods/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
generated
Executable file
129
ReadViewDemo/Pods/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
generated
Executable file
@ -0,0 +1,129 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
function on_error {
|
||||||
|
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
||||||
|
}
|
||||||
|
trap 'on_error $LINENO' ERR
|
||||||
|
|
||||||
|
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
|
||||||
|
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||||
|
# resources to, so exit 0 (signalling the script phase was successful).
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
|
||||||
|
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||||
|
> "$RESOURCES_TO_COPY"
|
||||||
|
|
||||||
|
XCASSET_FILES=()
|
||||||
|
|
||||||
|
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||||
|
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||||
|
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||||
|
|
||||||
|
case "${TARGETED_DEVICE_FAMILY:-}" in
|
||||||
|
1,2)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device tv"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device watch"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
TARGET_DEVICE_ARGS="--target-device mac"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
install_resource()
|
||||||
|
{
|
||||||
|
if [[ "$1" = /* ]] ; then
|
||||||
|
RESOURCE_PATH="$1"
|
||||||
|
else
|
||||||
|
RESOURCE_PATH="${PODS_ROOT}/$1"
|
||||||
|
fi
|
||||||
|
if [[ ! -e "$RESOURCE_PATH" ]] ; then
|
||||||
|
cat << EOM
|
||||||
|
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
|
||||||
|
EOM
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
case $RESOURCE_PATH in
|
||||||
|
*.storyboard)
|
||||||
|
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||||
|
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
|
;;
|
||||||
|
*.xib)
|
||||||
|
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||||
|
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
|
;;
|
||||||
|
*.framework)
|
||||||
|
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
|
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
|
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
|
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
|
;;
|
||||||
|
*.xcdatamodel)
|
||||||
|
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
|
||||||
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
||||||
|
;;
|
||||||
|
*.xcdatamodeld)
|
||||||
|
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
|
||||||
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
||||||
|
;;
|
||||||
|
*.xcmappingmodel)
|
||||||
|
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
|
||||||
|
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||||
|
;;
|
||||||
|
*.xcassets)
|
||||||
|
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||||
|
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$RESOURCE_PATH" || true
|
||||||
|
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||||
|
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle"
|
||||||
|
fi
|
||||||
|
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||||
|
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||||
|
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
fi
|
||||||
|
rm -f "$RESOURCES_TO_COPY"
|
||||||
|
|
||||||
|
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
|
||||||
|
then
|
||||||
|
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||||
|
OTHER_XCASSETS=$(find -L "$PWD" -iname "*.xcassets" -type d)
|
||||||
|
while read line; do
|
||||||
|
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||||
|
XCASSET_FILES+=("$line")
|
||||||
|
fi
|
||||||
|
done <<<"$OTHER_XCASSETS"
|
||||||
|
|
||||||
|
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
|
||||||
|
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
|
else
|
||||||
|
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.0.1</string>
|
<string>0.0.2</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "ZIPFoundation"
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "SnapKit" -framework "ZIPFoundation"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
PODS_ROOT = ${SRCROOT}
|
PODS_ROOT = ${SRCROOT}
|
||||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDEpubReaderView
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
SKIP_INSTALL = YES
|
SKIP_INSTALL = YES
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
|
||||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
|
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "ZIPFoundation"
|
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "SnapKit" -framework "ZIPFoundation"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
|
||||||
PODS_ROOT = ${SRCROOT}
|
PODS_ROOT = ${SRCROOT}
|
||||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDEpubReaderView
|
||||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
SKIP_INSTALL = YES
|
SKIP_INSTALL = YES
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>BNDL</string>
|
<string>BNDL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.0.1</string>
|
<string>0.0.2</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.1.0</string>
|
<string>0.0.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
|
|||||||
@ -61,6 +61,10 @@ enum IDs {
|
|||||||
static let pdfAnnotationInput = "pdf.reader.annotation.input"
|
static let pdfAnnotationInput = "pdf.reader.annotation.input"
|
||||||
static let pdfAnnotationSave = "pdf.reader.annotation.save"
|
static let pdfAnnotationSave = "pdf.reader.annotation.save"
|
||||||
static let pdfAnnotationCancel = "pdf.reader.annotation.cancel"
|
static let pdfAnnotationCancel = "pdf.reader.annotation.cancel"
|
||||||
|
static let pdfDrawing = "pdf.reader.drawing"
|
||||||
|
static let pdfDrawingToolbar = "pdf.reader.drawing.toolbar"
|
||||||
|
static let pdfDrawingPen = "pdf.reader.drawing.pen"
|
||||||
|
static let pdfDrawingEraser = "pdf.reader.drawing.eraser"
|
||||||
|
|
||||||
static let readerSearch = "epub.reader.search"
|
static let readerSearch = "epub.reader.search"
|
||||||
static let searchBar = "epub.reader.search.bar"
|
static let searchBar = "epub.reader.search.bar"
|
||||||
|
|||||||
@ -66,7 +66,7 @@ final class PDFAnnotationTests: XCTestCase {
|
|||||||
// 以不带 reset 参数的全新进程重开,验证标注不会只存在于当前控制器内存中。
|
// 以不带 reset 参数的全新进程重开,验证标注不会只存在于当前控制器内存中。
|
||||||
app.terminate()
|
app.terminate()
|
||||||
app.launchAndOpenSamplePDF(
|
app.launchAndOpenSamplePDF(
|
||||||
bookTitleQuery: "PDF测试文件",
|
bookTitleQuery: "英汉大词典",
|
||||||
resetsReaderState: false,
|
resetsReaderState: false,
|
||||||
pdfTextSource: "host-fixture"
|
pdfTextSource: "host-fixture"
|
||||||
)
|
)
|
||||||
@ -156,7 +156,7 @@ final class PDFAnnotationTests: XCTestCase {
|
|||||||
@discardableResult
|
@discardableResult
|
||||||
private func openPDF(textSource: String) -> XCUIElement {
|
private func openPDF(textSource: String) -> XCUIElement {
|
||||||
app.launchAndOpenSamplePDF(
|
app.launchAndOpenSamplePDF(
|
||||||
bookTitleQuery: "PDF测试文件",
|
bookTitleQuery: "英汉大词典",
|
||||||
resetsReaderState: true,
|
resetsReaderState: true,
|
||||||
pdfTextSource: textSource
|
pdfTextSource: textSource
|
||||||
)
|
)
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
import XCTest
|
||||||
|
|
||||||
|
/// 画笔面板打开时,工具未选中应保留手机横屏单页的连续竖滑;
|
||||||
|
/// 选中任一绘图工具后,单指手势只能用于绘制,不能触发阅读器滚动。
|
||||||
|
final class PDFDrawingModeTests: XCTestCase {
|
||||||
|
private let app = XCUIApplication()
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
XCUIDevice.shared.orientation = .portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDownWithError() throws {
|
||||||
|
XCUIDevice.shared.orientation = .portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLandscapeSinglePageScrollsOnlyWhenDrawingToolIsDeselected() {
|
||||||
|
app.launchAndOpenSampleBook(bookTitleQuery: "英汉大词典", displayType: "pagecurl")
|
||||||
|
app.waitForReader()
|
||||||
|
|
||||||
|
XCUIDevice.shared.orientation = .landscapeLeft
|
||||||
|
let content = app.otherElements[IDs.readerContent].firstMatch
|
||||||
|
XCTAssertTrue(content.waitForExistence(timeout: 8), "PDF 横屏阅读页面未出现")
|
||||||
|
XCTAssertTrue(waitForLandscapeLayout(), "PDF 未进入横屏单页布局")
|
||||||
|
|
||||||
|
app.showReaderChromeIfNeeded(requiredButtonIDs: [IDs.pdfDrawing])
|
||||||
|
let drawing = app.buttons[IDs.pdfDrawing]
|
||||||
|
XCTAssertTrue(drawing.waitForExistence(timeout: 5), "画笔入口未出现")
|
||||||
|
drawing.tap()
|
||||||
|
|
||||||
|
let pen = app.buttons[IDs.pdfDrawingPen]
|
||||||
|
let eraser = app.buttons[IDs.pdfDrawingEraser]
|
||||||
|
XCTAssertTrue(pen.waitForExistence(timeout: 5), "画笔工具未出现")
|
||||||
|
XCTAssertTrue(eraser.exists, "橡皮擦工具未出现")
|
||||||
|
|
||||||
|
let firstScrollablePage = app.currentDemoReaderState()?.page
|
||||||
|
XCTAssertNotNil(firstScrollablePage, "未取得初始 PDF 页码")
|
||||||
|
guard let firstScrollablePage else { return }
|
||||||
|
XCTAssertTrue(
|
||||||
|
scrollToAnotherPage(content, from: firstScrollablePage),
|
||||||
|
"未选中工具时,手机横屏单页无法连续竖滑"
|
||||||
|
)
|
||||||
|
|
||||||
|
let lockedPage = app.currentDemoReaderState()?.page
|
||||||
|
XCTAssertNotNil(lockedPage, "滚动后未取得 PDF 页码")
|
||||||
|
guard let lockedPage else { return }
|
||||||
|
|
||||||
|
pen.tap()
|
||||||
|
assertPageRemains(lockedPage, afterSwiping: content, message: "选中画笔后仍触发了页面滚动")
|
||||||
|
|
||||||
|
eraser.tap()
|
||||||
|
assertPageRemains(lockedPage, afterSwiping: content, message: "切换至橡皮擦后仍触发了页面滚动")
|
||||||
|
|
||||||
|
eraser.tap()
|
||||||
|
XCTAssertTrue(
|
||||||
|
scrollToAnotherPage(content, from: lockedPage),
|
||||||
|
"取消橡皮擦选中后,手机横屏单页没有恢复连续竖滑"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func waitForLandscapeLayout() -> Bool {
|
||||||
|
let deadline = Date().addingTimeInterval(8)
|
||||||
|
while Date() < deadline {
|
||||||
|
let frame = app.windows.firstMatch.frame
|
||||||
|
if frame.width > frame.height { return true }
|
||||||
|
RunLoop.current.run(until: Date().addingTimeInterval(0.1))
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func scrollToAnotherPage(_ content: XCUIElement, from page: Int) -> Bool {
|
||||||
|
for _ in 0..<5 {
|
||||||
|
content.swipeUp()
|
||||||
|
let deadline = Date().addingTimeInterval(1.5)
|
||||||
|
while Date() < deadline {
|
||||||
|
if let current = app.currentDemoReaderState()?.page, current != page { return true }
|
||||||
|
RunLoop.current.run(until: Date().addingTimeInterval(0.1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func assertPageRemains(_ page: Int, afterSwiping content: XCUIElement, message: String) {
|
||||||
|
for _ in 0..<3 { content.swipeUp() }
|
||||||
|
RunLoop.current.run(until: Date().addingTimeInterval(0.8))
|
||||||
|
XCTAssertEqual(app.currentDemoReaderState()?.page, page, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,7 +30,6 @@ final class ReaderToolbarTests: XCTestCase {
|
|||||||
|
|
||||||
app.hideReaderChromeIfNeeded()
|
app.hideReaderChromeIfNeeded()
|
||||||
XCTAssertFalse(app.buttons[IDs.readerBack].waitForExistence(timeout: 2), "PDF 点击内容区后工具栏应隐藏")
|
XCTAssertFalse(app.buttons[IDs.readerBack].waitForExistence(timeout: 2), "PDF 点击内容区后工具栏应隐藏")
|
||||||
app.waitForDemoReaderState(timeout: 5, description: "toolbar=hidden") { $0.toolbar == "hidden" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPDFTocButtonOpensNavigationSheet() {
|
func testPDFTocButtonOpensNavigationSheet() {
|
||||||
@ -71,7 +70,7 @@ final class ReaderToolbarTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPDFLaunchHonorsDisplayTypeArgument() {
|
func testPDFLaunchHonorsDisplayTypeArgument() {
|
||||||
app.launchAndOpenSampleBook(bookTitleQuery: "PDF测试文件", displayType: "verticalscroll")
|
app.launchAndOpenSampleBook(bookTitleQuery: "英汉大词典", displayType: "verticalscroll")
|
||||||
app.waitForReader()
|
app.waitForReader()
|
||||||
app.waitForDemoReaderState(timeout: 5, description: "PDF vertical launch mode") {
|
app.waitForDemoReaderState(timeout: 5, description: "PDF vertical launch mode") {
|
||||||
$0.mode == "pdf" && $0.display == "verticalscroll"
|
$0.mode == "pdf" && $0.display == "verticalscroll"
|
||||||
@ -79,7 +78,7 @@ final class ReaderToolbarTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPDFPageCurlSupportsPinchAndDraggingAfterDoubleTapZoom() {
|
func testPDFPageCurlSupportsPinchAndDraggingAfterDoubleTapZoom() {
|
||||||
app.launchAndOpenSamplePDF(bookTitleQuery: "PDF测试文件")
|
app.launchAndOpenSamplePDF(bookTitleQuery: "英汉大词典")
|
||||||
app.waitForReader()
|
app.waitForReader()
|
||||||
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl") {
|
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl") {
|
||||||
$0.mode == "pdf" && $0.display == "pagecurl"
|
$0.mode == "pdf" && $0.display == "pagecurl"
|
||||||
@ -114,7 +113,7 @@ final class ReaderToolbarTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPDFPageCurlSingleFingerTurnsPageAtFittedScale() {
|
func testPDFPageCurlSingleFingerTurnsPageAtFittedScale() {
|
||||||
app.launchAndOpenSamplePDF(bookTitleQuery: "PDF测试文件")
|
app.launchAndOpenSamplePDF(bookTitleQuery: "英汉大词典")
|
||||||
app.waitForReader()
|
app.waitForReader()
|
||||||
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl at page 1") {
|
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl at page 1") {
|
||||||
$0.mode == "pdf" && $0.display == "pagecurl" && $0.page == 1
|
$0.mode == "pdf" && $0.display == "pagecurl" && $0.page == 1
|
||||||
@ -131,7 +130,7 @@ final class ReaderToolbarTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPDFSwitchingFromZoomedCurlKeepsScrollModeInteractive() {
|
func testPDFSwitchingFromZoomedCurlKeepsScrollModeInteractive() {
|
||||||
app.launchAndOpenSamplePDF(bookTitleQuery: "PDF测试文件")
|
app.launchAndOpenSamplePDF(bookTitleQuery: "英汉大词典")
|
||||||
app.waitForReader()
|
app.waitForReader()
|
||||||
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl at page 1") {
|
app.waitForDemoReaderState(timeout: 5, description: "PDF page curl at page 1") {
|
||||||
$0.mode == "pdf" && $0.display == "pagecurl" && $0.page == 1
|
$0.mode == "pdf" && $0.display == "pagecurl" && $0.page == 1
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "RDEpubReaderView"
|
s.name = "RDEpubReaderView"
|
||||||
s.module_name = "RDEpubReaderView"
|
s.module_name = "RDEpubReaderView"
|
||||||
s.version = "0.0.1"
|
s.version = "0.0.2"
|
||||||
s.summary = "A reader view for EPUB and plain-text books"
|
s.summary = "A reader view for EPUB and plain-text books"
|
||||||
s.platform = :ios, "15.0"
|
s.platform = :ios, "15.0"
|
||||||
s.swift_versions = ["5.10"]
|
s.swift_versions = ["5.10"]
|
||||||
@ -9,11 +9,14 @@ Pod::Spec.new do |s|
|
|||||||
s.author = { "shenlei" => "shenlei@touchread.com" }
|
s.author = { "shenlei" => "shenlei@touchread.com" }
|
||||||
s.source = { :git => "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git", :tag => "#{s.version}" }
|
s.source = { :git => "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git", :tag => "#{s.version}" }
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.source_files = "Sources/RDEpubReaderView/**/*.{swift}"
|
# This podspec lives inside Sources/RDEpubReaderView, so paths must be
|
||||||
|
# relative to this directory when it is consumed as a local pod.
|
||||||
|
s.source_files = "**/*.swift"
|
||||||
s.resource_bundles = {
|
s.resource_bundles = {
|
||||||
"RDEpubReaderViewAssets" => ["Sources/RDEpubReaderView/EPUBCore/Resources/**/*"]
|
"RDEpubReaderViewAssets" => ["EPUBCore/Resources/**/*"]
|
||||||
}
|
}
|
||||||
s.dependency "ZIPFoundation", "~> 0.9"
|
s.dependency "ZIPFoundation", "~> 0.9"
|
||||||
s.dependency "DTCoreText", "~> 1.6"
|
s.dependency "DTCoreText", "~> 1.6"
|
||||||
|
s.dependency "SnapKit", "~> 5.7"
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "RDPDFReaderView"
|
s.name = "RDPDFReaderView"
|
||||||
s.module_name = "RDPDFReaderView"
|
s.module_name = "RDPDFReaderView"
|
||||||
s.version = "0.1.0"
|
s.version = "0.0.1"
|
||||||
s.summary = "Independent UIKit PDF reader interaction engine"
|
s.summary = "Independent UIKit PDF reader interaction engine"
|
||||||
s.platform = :ios, "15.0"
|
s.platform = :ios, "15.0"
|
||||||
s.swift_versions = ["5.10"]
|
s.swift_versions = ["5.10"]
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import SnapKit
|
|||||||
/// 对齐 SheetMusic 的画笔工具栏:上方为尺寸与颜色,下方为笔刷、橡皮、图层及撤销重做。
|
/// 对齐 SheetMusic 的画笔工具栏:上方为尺寸与颜色,下方为笔刷、橡皮、图层及撤销重做。
|
||||||
/// 工具栏只表达 UI 状态,不持有任何 PDF 页或笔迹数据。
|
/// 工具栏只表达 UI 状态,不持有任何 PDF 页或笔迹数据。
|
||||||
public final class RDPDFReaderDrawingToolbar: UIView {
|
public final class RDPDFReaderDrawingToolbar: UIView {
|
||||||
public var toolChangedHandler: ((RDPDFReaderDrawingTool) -> Void)?
|
/// `nil` 表示没有激活绘图工具,此时阅读页可用于拖动画面。
|
||||||
|
public var toolChangedHandler: ((RDPDFReaderDrawingTool?) -> Void)?
|
||||||
public var colorChangedHandler: ((UIColor) -> Void)?
|
public var colorChangedHandler: ((UIColor) -> Void)?
|
||||||
public var lineWidthChangedHandler: ((CGFloat) -> Void)?
|
public var lineWidthChangedHandler: ((CGFloat) -> Void)?
|
||||||
public var undoHandler: (() -> Void)?
|
public var undoHandler: (() -> Void)?
|
||||||
@ -17,10 +18,13 @@ public final class RDPDFReaderDrawingToolbar: UIView {
|
|||||||
private let sizeValueLabel = UILabel()
|
private let sizeValueLabel = UILabel()
|
||||||
private let colors: [UIColor] = [.white, .black, UIColor(red: 0.87, green: 0.17, blue: 0.17, alpha: 1), UIColor(red: 1, green: 0.56, blue: 0.16, alpha: 1), UIColor(red: 0.96, green: 0.89, blue: 0.20, alpha: 1), UIColor(red: 0.24, green: 0.76, blue: 0.24, alpha: 1), UIColor(red: 0.12, green: 0.83, blue: 0.93, alpha: 1), UIColor(red: 0.21, green: 0.36, blue: 0.90, alpha: 1), UIColor(red: 0.68, green: 0.36, blue: 1, alpha: 1), UIColor(red: 0.99, green: 0.40, blue: 0.61, alpha: 1)]
|
private let colors: [UIColor] = [.white, .black, UIColor(red: 0.87, green: 0.17, blue: 0.17, alpha: 1), UIColor(red: 1, green: 0.56, blue: 0.16, alpha: 1), UIColor(red: 0.96, green: 0.89, blue: 0.20, alpha: 1), UIColor(red: 0.24, green: 0.76, blue: 0.24, alpha: 1), UIColor(red: 0.12, green: 0.83, blue: 0.93, alpha: 1), UIColor(red: 0.21, green: 0.36, blue: 0.90, alpha: 1), UIColor(red: 0.68, green: 0.36, blue: 1, alpha: 1), UIColor(red: 0.99, green: 0.40, blue: 0.61, alpha: 1)]
|
||||||
private var colorButtons: [UIButton] = []
|
private var colorButtons: [UIButton] = []
|
||||||
private var selectedTool: RDPDFReaderDrawingTool = .pen
|
private var selectedTool: RDPDFReaderDrawingTool?
|
||||||
|
private var penButton: UIButton?
|
||||||
|
private var eraserButton: UIButton?
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
accessibilityIdentifier = "pdf.reader.drawing.toolbar"
|
||||||
backgroundColor = UIColor(red: 0.20, green: 0.20, blue: 0.20, alpha: 0.98)
|
backgroundColor = UIColor(red: 0.20, green: 0.20, blue: 0.20, alpha: 0.98)
|
||||||
setupViews()
|
setupViews()
|
||||||
}
|
}
|
||||||
@ -98,8 +102,16 @@ public final class RDPDFReaderDrawingToolbar: UIView {
|
|||||||
make.bottom.equalTo(safeAreaLayoutGuide).inset(9)
|
make.bottom.equalTo(safeAreaLayoutGuide).inset(9)
|
||||||
make.height.equalTo(32)
|
make.height.equalTo(32)
|
||||||
}
|
}
|
||||||
toolStack.addArrangedSubview(makeIconButton(symbol: "pencil", action: #selector(penTapped), selected: true))
|
let penButton = makeIconButton(symbol: "pencil", action: #selector(penTapped))
|
||||||
toolStack.addArrangedSubview(makeIconButton(symbol: "eraser", action: #selector(eraserTapped)))
|
let eraserButton = makeIconButton(symbol: "eraser", action: #selector(eraserTapped))
|
||||||
|
penButton.accessibilityIdentifier = "pdf.reader.drawing.pen"
|
||||||
|
penButton.accessibilityLabel = "画笔"
|
||||||
|
eraserButton.accessibilityIdentifier = "pdf.reader.drawing.eraser"
|
||||||
|
eraserButton.accessibilityLabel = "橡皮擦"
|
||||||
|
self.penButton = penButton
|
||||||
|
self.eraserButton = eraserButton
|
||||||
|
toolStack.addArrangedSubview(penButton)
|
||||||
|
toolStack.addArrangedSubview(eraserButton)
|
||||||
toolStack.addArrangedSubview(makeIconButton(symbol: "square.3.layers.3d", action: #selector(layersTapped)))
|
toolStack.addArrangedSubview(makeIconButton(symbol: "square.3.layers.3d", action: #selector(layersTapped)))
|
||||||
|
|
||||||
let clearButton = makeTextButton("清空", action: #selector(clearTapped))
|
let clearButton = makeTextButton("清空", action: #selector(clearTapped))
|
||||||
@ -117,10 +129,10 @@ public final class RDPDFReaderDrawingToolbar: UIView {
|
|||||||
undo.snp.makeConstraints { make in make.centerY.equalTo(toolStack); make.trailing.equalTo(redo.snp.leading).offset(-20) }
|
undo.snp.makeConstraints { make in make.centerY.equalTo(toolStack); make.trailing.equalTo(redo.snp.leading).offset(-20) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeIconButton(symbol: String, action: Selector, selected: Bool = false) -> UIButton {
|
private func makeIconButton(symbol: String, action: Selector) -> UIButton {
|
||||||
let button = UIButton(type: .system)
|
let button = UIButton(type: .system)
|
||||||
button.setImage(UIImage(systemName: symbol), for: .normal)
|
button.setImage(UIImage(systemName: symbol), for: .normal)
|
||||||
button.tintColor = selected ? UIColor(red: 0.45, green: 0.52, blue: 1, alpha: 1) : .white
|
button.tintColor = .white
|
||||||
button.contentEdgeInsets = .init(top: 3, left: 3, bottom: 3, right: 3)
|
button.contentEdgeInsets = .init(top: 3, left: 3, bottom: 3, right: 3)
|
||||||
button.addTarget(self, action: action, for: .touchUpInside)
|
button.addTarget(self, action: action, for: .touchUpInside)
|
||||||
button.snp.makeConstraints { $0.size.equalTo(28) }
|
button.snp.makeConstraints { $0.size.equalTo(28) }
|
||||||
@ -156,7 +168,10 @@ public final class RDPDFReaderDrawingToolbar: UIView {
|
|||||||
@objc private func doneTapped() { doneHandler?() }
|
@objc private func doneTapped() { doneHandler?() }
|
||||||
|
|
||||||
private func selectTool(_ tool: RDPDFReaderDrawingTool) {
|
private func selectTool(_ tool: RDPDFReaderDrawingTool) {
|
||||||
selectedTool = tool
|
selectedTool = selectedTool == tool ? nil : tool
|
||||||
toolChangedHandler?(tool)
|
let activeColor = UIColor(red: 0.45, green: 0.52, blue: 1, alpha: 1)
|
||||||
|
penButton?.tintColor = selectedTool == .pen ? activeColor : .white
|
||||||
|
eraserButton?.tintColor = selectedTool == .eraser ? activeColor : .white
|
||||||
|
toolChangedHandler?(selectedTool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,13 +63,21 @@ public final class RDPDFReaderPageView: UIView, RDPDFReaderPageInteractable, UIG
|
|||||||
private var tappedHighlight: RDPDFReaderAnnotation?
|
private var tappedHighlight: RDPDFReaderAnnotation?
|
||||||
|
|
||||||
/// 画笔层属于单个实际 PDF 页,而不是横屏双页容器;因此笔迹不能越过书脊。
|
/// 画笔层属于单个实际 PDF 页,而不是横屏双页容器;因此笔迹不能越过书脊。
|
||||||
|
/// 画笔面板已打开时,禁用文本选区以保证单指手势可以用于拖动画面。
|
||||||
|
public var isDrawingSessionActive = false {
|
||||||
|
didSet {
|
||||||
|
textLayer.isSelectionEnabled = !isDrawingSessionActive
|
||||||
|
if isDrawingSessionActive { textLayer.clearSelection() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 仅在画笔或橡皮擦被选中时启用画布,单指手势才会被画布消费。
|
||||||
public var isDrawingMode = false {
|
public var isDrawingMode = false {
|
||||||
didSet {
|
didSet {
|
||||||
// 退出编辑只关闭触摸,不隐藏画布;否则已持久化的笔迹会和工具栏一起消失。
|
// 退出编辑只关闭触摸,不隐藏画布;否则已持久化的笔迹会和工具栏一起消失。
|
||||||
drawingCanvas.isHidden = false
|
drawingCanvas.isHidden = false
|
||||||
drawingCanvas.isUserInteractionEnabled = isDrawingMode
|
drawingCanvas.isUserInteractionEnabled = isDrawingMode
|
||||||
textLayer.isSelectionEnabled = !isDrawingMode
|
zoomView.isDrawingMode = isDrawingMode
|
||||||
if isDrawingMode { textLayer.clearSelection() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,8 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
private weak var bottomToolbar: RDPDFReaderKitBottomToolView?
|
private weak var bottomToolbar: RDPDFReaderKitBottomToolView?
|
||||||
private let drawingToolbar = RDPDFReaderDrawingToolbar()
|
private let drawingToolbar = RDPDFReaderDrawingToolbar()
|
||||||
private var isDrawingMode = false
|
private var isDrawingMode = false
|
||||||
private var currentDrawingTool: RDPDFReaderDrawingTool = .pen
|
/// `nil` 时处于画笔面板内的浏览状态,可单指拖动画面。
|
||||||
|
private var currentDrawingTool: RDPDFReaderDrawingTool?
|
||||||
private var currentDrawingColor = UIColor.black
|
private var currentDrawingColor = UIColor.black
|
||||||
private var currentDrawingLineWidth: CGFloat = 4
|
private var currentDrawingLineWidth: CGFloat = 4
|
||||||
private weak var continuedDrawingPage: RDPDFReaderPageView?
|
private weak var continuedDrawingPage: RDPDFReaderPageView?
|
||||||
@ -127,13 +128,12 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
public func setDrawingMode(_ enabled: Bool) {
|
public func setDrawingMode(_ enabled: Bool) {
|
||||||
guard isDrawingMode != enabled else { return }
|
guard isDrawingMode != enabled else { return }
|
||||||
isDrawingMode = enabled
|
isDrawingMode = enabled
|
||||||
readerView.setPagingEnabled(!enabled)
|
|
||||||
if enabled {
|
if enabled {
|
||||||
installDrawingToolbar()
|
installDrawingToolbar()
|
||||||
} else {
|
} else {
|
||||||
drawingToolbar.removeFromSuperview()
|
drawingToolbar.removeFromSuperview()
|
||||||
}
|
}
|
||||||
configureVisibleDrawingPages()
|
updateDrawingInteractionState()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func pageCountOfReaderView(readerView: RDPDFReaderView) -> Int { book.totalPages }
|
public func pageCountOfReaderView(readerView: RDPDFReaderView) -> Int { book.totalPages }
|
||||||
@ -185,7 +185,8 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
let runs = descriptor?.textRuns ?? ocrRuns[index] ?? []
|
let runs = descriptor?.textRuns ?? ocrRuns[index] ?? []
|
||||||
let source: RDPDFReaderAnnotationSource = descriptor?.textRuns != nil ? .text : (configuration.enablesOCR ? .ocr : configuration.missingTextSource)
|
let source: RDPDFReaderAnnotationSource = descriptor?.textRuns != nil ? .text : (configuration.enablesOCR ? .ocr : configuration.missingTextSource)
|
||||||
page.configureTextLayer(pageIndex: index, textRuns: runs, textSource: source, annotations: annotations(for: index))
|
page.configureTextLayer(pageIndex: index, textRuns: runs, textSource: source, annotations: annotations(for: index))
|
||||||
page.isDrawingMode = isDrawingMode
|
page.isDrawingSessionActive = isDrawingMode
|
||||||
|
page.isDrawingMode = isDrawingMode && currentDrawingTool != nil
|
||||||
page.configureDrawing(
|
page.configureDrawing(
|
||||||
pageIndex: index,
|
pageIndex: index,
|
||||||
document: (annotationPersistence as? RDPDFReaderPersistenceStore)?.drawingDocument(pageNo: index) ?? .init(pageNo: index, paths: []),
|
document: (annotationPersistence as? RDPDFReaderPersistenceStore)?.drawingDocument(pageNo: index) ?? .init(pageNo: index, paths: []),
|
||||||
@ -193,7 +194,9 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
(self?.annotationPersistence as? RDPDFReaderPersistenceStore)?.saveDrawingDocument(document, pageNo: index)
|
(self?.annotationPersistence as? RDPDFReaderPersistenceStore)?.saveDrawingDocument(document, pageNo: index)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
page.setDrawingTool(currentDrawingTool, color: currentDrawingColor, lineWidth: currentDrawingLineWidth)
|
if let currentDrawingTool {
|
||||||
|
page.setDrawingTool(currentDrawingTool, color: currentDrawingColor, lineWidth: currentDrawingLineWidth)
|
||||||
|
}
|
||||||
page.drawingStrokeEventHandler = { [weak self] source, point, phase in
|
page.drawingStrokeEventHandler = { [weak self] source, point, phase in
|
||||||
if phase == .began { self?.activeDrawingPage = source }
|
if phase == .began { self?.activeDrawingPage = source }
|
||||||
self?.routeDrawingStroke(from: source, point: point, phase: phase)
|
self?.routeDrawingStroke(from: source, point: point, phase: phase)
|
||||||
@ -282,7 +285,9 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
drawingToolbar.lineWidthChangedHandler = { [weak self] width in
|
drawingToolbar.lineWidthChangedHandler = { [weak self] width in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
self.currentDrawingLineWidth = width
|
self.currentDrawingLineWidth = width
|
||||||
self.visibleDrawingPages.forEach { $0.setDrawingTool(self.currentDrawingTool, lineWidth: width) }
|
if let tool = self.currentDrawingTool {
|
||||||
|
self.visibleDrawingPages.forEach { $0.setDrawingTool(tool, lineWidth: width) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drawingToolbar.undoHandler = { [weak self] in self?.visibleDrawingPages.forEach { $0.undoDrawing() } }
|
drawingToolbar.undoHandler = { [weak self] in self?.visibleDrawingPages.forEach { $0.undoDrawing() } }
|
||||||
drawingToolbar.redoHandler = { [weak self] in self?.visibleDrawingPages.forEach { $0.redoDrawing() } }
|
drawingToolbar.redoHandler = { [weak self] in self?.visibleDrawingPages.forEach { $0.redoDrawing() } }
|
||||||
@ -296,15 +301,27 @@ public final class RDPDFReaderViewController: UIViewController, RDPDFReaderDataS
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func configureVisibleDrawingPages() {
|
private func configureVisibleDrawingPages() {
|
||||||
visibleDrawingPages.forEach { page in page.isDrawingMode = isDrawingMode }
|
visibleDrawingPages.forEach { page in
|
||||||
|
page.isDrawingSessionActive = isDrawingMode
|
||||||
|
page.isDrawingMode = isDrawingMode && currentDrawingTool != nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func applyDrawingTool(_ tool: RDPDFReaderDrawingTool, color: UIColor? = nil) {
|
private func applyDrawingTool(_ tool: RDPDFReaderDrawingTool?, color: UIColor? = nil) {
|
||||||
currentDrawingTool = tool
|
currentDrawingTool = tool
|
||||||
if let color { currentDrawingColor = color }
|
if let color { currentDrawingColor = color }
|
||||||
|
updateDrawingInteractionState()
|
||||||
|
guard let tool else { return }
|
||||||
visibleDrawingPages.forEach { $0.setDrawingTool(tool, color: color, lineWidth: currentDrawingLineWidth) }
|
visibleDrawingPages.forEach { $0.setDrawingTool(tool, color: color, lineWidth: currentDrawingLineWidth) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 未选择画笔工具时恢复阅读器自身的滚动。手机横屏单页的连续竖滑
|
||||||
|
/// 由外层 collectionView 承担,不能在画笔面板打开期间一概禁用。
|
||||||
|
private func updateDrawingInteractionState() {
|
||||||
|
readerView.setPagingEnabled(!isDrawingMode || currentDrawingTool == nil)
|
||||||
|
configureVisibleDrawingPages()
|
||||||
|
}
|
||||||
|
|
||||||
private func showDrawingLayers() {
|
private func showDrawingLayers() {
|
||||||
let page = activeDrawingPage ?? visibleDrawingPages.first
|
let page = activeDrawingPage ?? visibleDrawingPages.first
|
||||||
guard let page else { return }
|
guard let page else { return }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user