Compare commits
9 Commits
Company/v0
...
Company/v0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a62183a2c | ||
![]() |
681b011c99 | ||
![]() |
4256e01820 | ||
![]() |
9777c3de28 | ||
![]() |
7b88912b37 | ||
![]() |
4706f4bcc6 | ||
![]() |
37e105f04f | ||
![]() |
c8173bf034 | ||
![]() |
6f5ab10562 |
32
Podfile
32
Podfile
@@ -6,9 +6,6 @@ target 'YuMi' do
|
|||||||
#pag动画
|
#pag动画
|
||||||
pod 'libpag'
|
pod 'libpag'
|
||||||
pod 'Bugly'
|
pod 'Bugly'
|
||||||
pod 'FBSDKLoginKit'
|
|
||||||
pod 'FBSDKCoreKit'
|
|
||||||
pod 'FBSDKShareKit'
|
|
||||||
# 滑动标签栏
|
# 滑动标签栏
|
||||||
pod 'JXCategoryView'
|
pod 'JXCategoryView'
|
||||||
pod 'JXPagingView/Pager'
|
pod 'JXPagingView/Pager'
|
||||||
@@ -53,14 +50,7 @@ target 'YuMi' do
|
|||||||
pod 'NIMSDK_LITE', '~> 10.9.40'
|
pod 'NIMSDK_LITE', '~> 10.9.40'
|
||||||
pod 'GKCycleScrollView'
|
pod 'GKCycleScrollView'
|
||||||
pod 'SVGAPlayer'
|
pod 'SVGAPlayer'
|
||||||
pod 'GoogleSignIn'
|
|
||||||
pod 'mob_linksdk_pro'
|
|
||||||
pod 'mob_sharesdk'
|
|
||||||
pod 'mob_sharesdk/ShareSDKPlatforms/Apple'
|
|
||||||
pod 'mob_sharesdk/ShareSDKExtension'
|
|
||||||
|
|
||||||
pod 'UMCommon', '7.5.3'
|
|
||||||
pod 'UMDevice'
|
|
||||||
pod 'ZLCollectionViewFlowLayout'
|
pod 'ZLCollectionViewFlowLayout'
|
||||||
pod 'TABAnimated'
|
pod 'TABAnimated'
|
||||||
pod 'YuMi',:path=>'yum'
|
pod 'YuMi',:path=>'yum'
|
||||||
@@ -85,4 +75,26 @@ post_install do |installer|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 🔧 自动修复 SVGAPlayer 的 OSAtomic 导入问题
|
||||||
|
# 原因: SVGAPlayer 2.5.7 的 Svga.pbobjc.m 使用旧版 protoc 生成,
|
||||||
|
# 代码中使用了 OSAtomicCompareAndSwapPtrBarrier 但未导入头文件
|
||||||
|
svga_pbobjc_path = 'Pods/SVGAPlayer/Source/pbobjc/Svga.pbobjc.m'
|
||||||
|
if File.exist?(svga_pbobjc_path)
|
||||||
|
text = File.read(svga_pbobjc_path)
|
||||||
|
# 检查是否已经包含 OSAtomic 导入
|
||||||
|
unless text.include?('#import <libkern/OSAtomic.h>')
|
||||||
|
# 在 #endif 后的第一个空行位置插入导入语句
|
||||||
|
new_text = text.sub(
|
||||||
|
/(#define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0\n#endif\n)/,
|
||||||
|
"\\1\n#import <libkern/OSAtomic.h>\n"
|
||||||
|
)
|
||||||
|
File.write(svga_pbobjc_path, new_text)
|
||||||
|
puts "✅ [自动修复] SVGAPlayer OSAtomic 导入问题已解决"
|
||||||
|
else
|
||||||
|
puts "✓ [检查通过] SVGAPlayer OSAtomic 导入已存在"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts "⚠️ [警告] 未找到 SVGAPlayer pbobjc 文件,跳过修复"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
133
Podfile.lock
133
Podfile.lock
@@ -14,77 +14,37 @@ PODS:
|
|||||||
- AFNetworking/Serialization (4.0.1)
|
- AFNetworking/Serialization (4.0.1)
|
||||||
- AFNetworking/UIKit (4.0.1):
|
- AFNetworking/UIKit (4.0.1):
|
||||||
- AFNetworking/NSURLSession
|
- AFNetworking/NSURLSession
|
||||||
- AppAuth (1.7.6):
|
|
||||||
- AppAuth/Core (= 1.7.6)
|
|
||||||
- AppAuth/ExternalUserAgent (= 1.7.6)
|
|
||||||
- AppAuth/Core (1.7.6)
|
|
||||||
- AppAuth/ExternalUserAgent (1.7.6):
|
|
||||||
- AppAuth/Core
|
|
||||||
- Base64 (1.1.2)
|
- Base64 (1.1.2)
|
||||||
- Bugly (2.6.1)
|
- Bugly (2.6.1)
|
||||||
- CocoaAsyncSocket (7.6.5)
|
- CocoaAsyncSocket (7.6.5)
|
||||||
- FBAEMKit (14.1.0):
|
|
||||||
- FBSDKCoreKit_Basics (= 14.1.0)
|
|
||||||
- FBSDKCoreKit (14.1.0):
|
|
||||||
- FBAEMKit (= 14.1.0)
|
|
||||||
- FBSDKCoreKit_Basics (= 14.1.0)
|
|
||||||
- FBSDKCoreKit_Basics (14.1.0)
|
|
||||||
- FBSDKLoginKit (14.1.0):
|
|
||||||
- FBSDKCoreKit (= 14.1.0)
|
|
||||||
- FBSDKShareKit (14.1.0):
|
|
||||||
- FBSDKCoreKit (= 14.1.0)
|
|
||||||
- FFPopup (1.1.5)
|
- FFPopup (1.1.5)
|
||||||
- FLAnimatedImage (1.0.17)
|
- FLAnimatedImage (1.0.17)
|
||||||
- FlyVerifyCSDK (1.0.7)
|
|
||||||
- GKCycleScrollView (1.2.3)
|
- GKCycleScrollView (1.2.3)
|
||||||
- GoogleSignIn (7.1.0):
|
|
||||||
- AppAuth (< 2.0, >= 1.7.3)
|
|
||||||
- GTMAppAuth (< 5.0, >= 4.1.1)
|
|
||||||
- GTMSessionFetcher/Core (~> 3.3)
|
|
||||||
- GTMAppAuth (4.1.1):
|
|
||||||
- AppAuth/Core (~> 1.7)
|
|
||||||
- GTMSessionFetcher/Core (< 4.0, >= 3.3)
|
|
||||||
- GTMSessionFetcher/Core (3.5.0)
|
|
||||||
- IQKeyboardManager (6.5.19)
|
- IQKeyboardManager (6.5.19)
|
||||||
- JXCategoryView (1.6.8)
|
- JXCategoryView (1.6.8)
|
||||||
- JXPagingView/Pager (2.1.3)
|
- JXPagingView/Pager (2.1.3)
|
||||||
- libpag (4.4.32)
|
- libpag (4.5.3)
|
||||||
- MarqueeLabel (4.4.0)
|
- MarqueeLabel (4.5.3)
|
||||||
- Masonry (1.1.0)
|
- Masonry (1.1.0)
|
||||||
- MBProgressHUD (1.2.0)
|
- MBProgressHUD (1.2.0)
|
||||||
- MJExtension (3.4.2)
|
- MJExtension (3.4.2)
|
||||||
- MJRefresh (3.7.9)
|
- MJRefresh (3.7.9)
|
||||||
- mob_linksdk_pro (3.3.20):
|
- NIMSDK_LITE (10.9.53):
|
||||||
- MOBFoundation
|
- NIMSDK_LITE/NOS (= 10.9.53)
|
||||||
- mob_sharesdk (4.4.35):
|
|
||||||
- mob_sharesdk/ShareSDK (= 4.4.35)
|
|
||||||
- MOBFoundation (>= 3.2.9)
|
|
||||||
- mob_sharesdk/ShareSDK (4.4.35):
|
|
||||||
- MOBFoundation (>= 3.2.9)
|
|
||||||
- mob_sharesdk/ShareSDKExtension (4.4.35):
|
|
||||||
- mob_sharesdk/ShareSDK
|
|
||||||
- MOBFoundation (>= 3.2.9)
|
|
||||||
- mob_sharesdk/ShareSDKPlatforms/Apple (4.4.35):
|
|
||||||
- mob_sharesdk/ShareSDK
|
|
||||||
- MOBFoundation (>= 3.2.9)
|
|
||||||
- MOBFoundation (20250528):
|
|
||||||
- FlyVerifyCSDK (>= 0.0.7)
|
|
||||||
- NIMSDK_LITE (10.9.42):
|
|
||||||
- NIMSDK_LITE/NOS (= 10.9.42)
|
|
||||||
- YXArtemis_XCFramework
|
- YXArtemis_XCFramework
|
||||||
- NIMSDK_LITE/NOS (10.9.42):
|
- NIMSDK_LITE/NOS (10.9.53):
|
||||||
- YXArtemis_XCFramework
|
- YXArtemis_XCFramework
|
||||||
- pop (1.0.12)
|
- pop (1.0.12)
|
||||||
- Protobuf (3.29.5)
|
- Protobuf (3.29.5)
|
||||||
- QCloudCore (6.4.9):
|
- QCloudCore (6.5.1):
|
||||||
- QCloudCore/Default (= 6.4.9)
|
- QCloudCore/Default (= 6.5.1)
|
||||||
- QCloudCore/Default (6.4.9):
|
- QCloudCore/Default (6.5.1):
|
||||||
- QCloudTrack/Beacon (= 6.4.9)
|
- QCloudTrack/Beacon (= 6.5.1)
|
||||||
- QCloudCOSXML (6.4.9):
|
- QCloudCOSXML (6.5.1):
|
||||||
- QCloudCOSXML/Default (= 6.4.9)
|
- QCloudCOSXML/Default (= 6.5.1)
|
||||||
- QCloudCOSXML/Default (6.4.9):
|
- QCloudCOSXML/Default (6.5.1):
|
||||||
- QCloudCore (= 6.4.9)
|
- QCloudCore (= 6.5.1)
|
||||||
- QCloudTrack/Beacon (6.4.9)
|
- QCloudTrack/Beacon (6.5.1)
|
||||||
- QGVAPlayer (1.0.19)
|
- QGVAPlayer (1.0.19)
|
||||||
- ReactiveObjC (3.1.1)
|
- ReactiveObjC (3.1.1)
|
||||||
- SDCycleScrollView (1.82):
|
- SDCycleScrollView (1.82):
|
||||||
@@ -108,18 +68,15 @@ PODS:
|
|||||||
- Protobuf (~> 3.4)
|
- Protobuf (~> 3.4)
|
||||||
- SZTextView (1.3.0)
|
- SZTextView (1.3.0)
|
||||||
- TABAnimated (2.6.6)
|
- TABAnimated (2.6.6)
|
||||||
- TXLiteAVSDK_TRTC (12.6.18866):
|
- TXLiteAVSDK_TRTC (12.8.19666):
|
||||||
- TXLiteAVSDK_TRTC/TRTC (= 12.6.18866)
|
- TXLiteAVSDK_TRTC/TRTC (= 12.8.19666)
|
||||||
- TXLiteAVSDK_TRTC/TRTC (12.6.18866)
|
- TXLiteAVSDK_TRTC/TRTC (12.8.19666)
|
||||||
- TYCyclePagerView (1.2.0)
|
- TYCyclePagerView (1.2.0)
|
||||||
- TZImagePickerController (3.8.9):
|
- TZImagePickerController (3.8.9):
|
||||||
- TZImagePickerController/Basic (= 3.8.9)
|
- TZImagePickerController/Basic (= 3.8.9)
|
||||||
- TZImagePickerController/Location (= 3.8.9)
|
- TZImagePickerController/Location (= 3.8.9)
|
||||||
- TZImagePickerController/Basic (3.8.9)
|
- TZImagePickerController/Basic (3.8.9)
|
||||||
- TZImagePickerController/Location (3.8.9)
|
- TZImagePickerController/Location (3.8.9)
|
||||||
- UMCommon (7.5.3):
|
|
||||||
- UMDevice
|
|
||||||
- UMDevice (3.4.0)
|
|
||||||
- YuMi (0.0.1)
|
- YuMi (0.0.1)
|
||||||
- YXArtemis_XCFramework (1.1.6)
|
- YXArtemis_XCFramework (1.1.6)
|
||||||
- YYCache (1.0.4)
|
- YYCache (1.0.4)
|
||||||
@@ -137,13 +94,9 @@ DEPENDENCIES:
|
|||||||
- Base64
|
- Base64
|
||||||
- Bugly
|
- Bugly
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- FBSDKCoreKit
|
|
||||||
- FBSDKLoginKit
|
|
||||||
- FBSDKShareKit
|
|
||||||
- FFPopup
|
- FFPopup
|
||||||
- FLAnimatedImage
|
- FLAnimatedImage
|
||||||
- GKCycleScrollView
|
- GKCycleScrollView
|
||||||
- GoogleSignIn
|
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
- JXPagingView/Pager
|
- JXPagingView/Pager
|
||||||
@@ -153,10 +106,6 @@ DEPENDENCIES:
|
|||||||
- MBProgressHUD
|
- MBProgressHUD
|
||||||
- MJExtension (= 3.4.2)
|
- MJExtension (= 3.4.2)
|
||||||
- MJRefresh (= 3.7.9)
|
- MJRefresh (= 3.7.9)
|
||||||
- mob_linksdk_pro
|
|
||||||
- mob_sharesdk
|
|
||||||
- mob_sharesdk/ShareSDKExtension
|
|
||||||
- mob_sharesdk/ShareSDKPlatforms/Apple
|
|
||||||
- NIMSDK_LITE (~> 10.9.40)
|
- NIMSDK_LITE (~> 10.9.40)
|
||||||
- pop
|
- pop
|
||||||
- QCloudCOSXML
|
- QCloudCOSXML
|
||||||
@@ -173,8 +122,6 @@ DEPENDENCIES:
|
|||||||
- TXLiteAVSDK_TRTC
|
- TXLiteAVSDK_TRTC
|
||||||
- TYCyclePagerView
|
- TYCyclePagerView
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- UMCommon (= 7.5.3)
|
|
||||||
- UMDevice
|
|
||||||
- YuMi (from `yum`)
|
- YuMi (from `yum`)
|
||||||
- YYText
|
- YYText
|
||||||
- YYWebImage
|
- YYWebImage
|
||||||
@@ -183,22 +130,12 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
|
https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
|
||||||
- AFNetworking
|
- AFNetworking
|
||||||
- AppAuth
|
|
||||||
- Base64
|
- Base64
|
||||||
- Bugly
|
- Bugly
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- FBAEMKit
|
|
||||||
- FBSDKCoreKit
|
|
||||||
- FBSDKCoreKit_Basics
|
|
||||||
- FBSDKLoginKit
|
|
||||||
- FBSDKShareKit
|
|
||||||
- FFPopup
|
- FFPopup
|
||||||
- FLAnimatedImage
|
- FLAnimatedImage
|
||||||
- FlyVerifyCSDK
|
|
||||||
- GKCycleScrollView
|
- GKCycleScrollView
|
||||||
- GoogleSignIn
|
|
||||||
- GTMAppAuth
|
|
||||||
- GTMSessionFetcher
|
|
||||||
- IQKeyboardManager
|
- IQKeyboardManager
|
||||||
- JXCategoryView
|
- JXCategoryView
|
||||||
- JXPagingView
|
- JXPagingView
|
||||||
@@ -208,9 +145,6 @@ SPEC REPOS:
|
|||||||
- MBProgressHUD
|
- MBProgressHUD
|
||||||
- MJExtension
|
- MJExtension
|
||||||
- MJRefresh
|
- MJRefresh
|
||||||
- mob_linksdk_pro
|
|
||||||
- mob_sharesdk
|
|
||||||
- MOBFoundation
|
|
||||||
- NIMSDK_LITE
|
- NIMSDK_LITE
|
||||||
- pop
|
- pop
|
||||||
- Protobuf
|
- Protobuf
|
||||||
@@ -231,8 +165,6 @@ SPEC REPOS:
|
|||||||
- TXLiteAVSDK_TRTC
|
- TXLiteAVSDK_TRTC
|
||||||
- TYCyclePagerView
|
- TYCyclePagerView
|
||||||
- TZImagePickerController
|
- TZImagePickerController
|
||||||
- UMCommon
|
|
||||||
- UMDevice
|
|
||||||
- YXArtemis_XCFramework
|
- YXArtemis_XCFramework
|
||||||
- YYCache
|
- YYCache
|
||||||
- YYImage
|
- YYImage
|
||||||
@@ -246,40 +178,27 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58
|
AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58
|
||||||
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
|
|
||||||
Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
|
Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
|
||||||
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
FBAEMKit: a899515e45476027f73aef377b5cffadcd56ca3a
|
|
||||||
FBSDKCoreKit: 24f8bc8d3b5b2a8c5c656a1329492a12e8efa792
|
|
||||||
FBSDKCoreKit_Basics: 6e578c9bdc7aa1365dbbbde633c9ebb536bcaa98
|
|
||||||
FBSDKLoginKit: 787de205d524c3a4b17d527916f1d066e4361660
|
|
||||||
FBSDKShareKit: b9c1cd1fa6a320a50f0f353cf30d589049c8db77
|
|
||||||
FFPopup: a208dcee8db3e54ec4a88fcd6481f6f5d85b7a83
|
FFPopup: a208dcee8db3e54ec4a88fcd6481f6f5d85b7a83
|
||||||
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
|
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
|
||||||
FlyVerifyCSDK: e0a13f11d4f29aca7fb7fdcff3f27e3b7ba2de5d
|
|
||||||
GKCycleScrollView: 8ed79d2142e62895a701973358b6f94b661b4829
|
GKCycleScrollView: 8ed79d2142e62895a701973358b6f94b661b4829
|
||||||
GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db
|
|
||||||
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
|
|
||||||
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
|
|
||||||
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
|
||||||
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
|
||||||
JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e
|
JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e
|
||||||
libpag: 6e8253018ee4e7f310c8c07d9d9a89d7ae58ae27
|
libpag: c59ae60dbae9e025465e9541ee03ee96994f4c73
|
||||||
MarqueeLabel: d2388949ac58d587303178d56a792ba8a001b037
|
MarqueeLabel: 0c57d4c6634e04a6d015af79f7c9a175b2309525
|
||||||
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
|
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
|
||||||
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
|
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
|
||||||
MJExtension: e97d164cb411aa9795cf576093a1fa208b4a8dd8
|
MJExtension: e97d164cb411aa9795cf576093a1fa208b4a8dd8
|
||||||
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
|
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
|
||||||
mob_linksdk_pro: d6ac555e9bb8d2743a8634032a70ea1d34119a50
|
NIMSDK_LITE: 79bc52b8ad905e6c088053d8d29e7863fb9cdb98
|
||||||
mob_sharesdk: 409503324d18f231dd27b4d26428c0c168b20c36
|
|
||||||
MOBFoundation: a1f193058aba95440dadeb799fb398ff92cfe45e
|
|
||||||
NIMSDK_LITE: 67f6815667acefdc8f9969f8c955b5c1fab490df
|
|
||||||
pop: d582054913807fd11fd50bfe6a539d91c7e1a55a
|
pop: d582054913807fd11fd50bfe6a539d91c7e1a55a
|
||||||
Protobuf: 164aea2ae380c3951abdc3e195220c01d17400e0
|
Protobuf: 164aea2ae380c3951abdc3e195220c01d17400e0
|
||||||
QCloudCore: 0e70cda608d1ac485e039e83be1c4a1197197e6b
|
QCloudCore: 6f8c67b96448472d2c6a92b9cfe1bdb5abbb1798
|
||||||
QCloudCOSXML: b7f0b9cac61780a03318d40367a879f8d7eb3d86
|
QCloudCOSXML: 92f50a787b4e8d9a7cb6ea8e626775256b4840a7
|
||||||
QCloudTrack: cc101dd57be7f87bffc3f2fb692a781d5efeda98
|
QCloudTrack: 20b79388365b4c8ed150019c82a56f1569f237f8
|
||||||
QGVAPlayer: a0bca68c9bd6f1c8de5ac2d10ddf98be6038cce9
|
QGVAPlayer: a0bca68c9bd6f1c8de5ac2d10ddf98be6038cce9
|
||||||
ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
|
ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
|
||||||
SDCycleScrollView: a0d74c3384caa72bdfc81470bdbc8c14b3e1fbcf
|
SDCycleScrollView: a0d74c3384caa72bdfc81470bdbc8c14b3e1fbcf
|
||||||
@@ -291,11 +210,9 @@ SPEC CHECKSUMS:
|
|||||||
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
|
||||||
SZTextView: 094dc6acc9beec537685c545d6e3e0d4975174e1
|
SZTextView: 094dc6acc9beec537685c545d6e3e0d4975174e1
|
||||||
TABAnimated: 75fece541a774193565697c7a11539d3c6f631b3
|
TABAnimated: 75fece541a774193565697c7a11539d3c6f631b3
|
||||||
TXLiteAVSDK_TRTC: 09552a5bb5571c85c851d8dd858064724639f55e
|
TXLiteAVSDK_TRTC: b576b0c6a477fa98b5d2b33be63fa9aa7c41f0eb
|
||||||
TYCyclePagerView: 2b051dade0615c70784aa34f40c646feeddb7344
|
TYCyclePagerView: 2b051dade0615c70784aa34f40c646feeddb7344
|
||||||
TZImagePickerController: 456f470b5dea97b37226ec7a694994a8663340b2
|
TZImagePickerController: 456f470b5dea97b37226ec7a694994a8663340b2
|
||||||
UMCommon: 3b850836e8bc162b4e7f6b527d30071ed8ea75a1
|
|
||||||
UMDevice: dcdf7ec167387837559d149fbc7d793d984faf82
|
|
||||||
YuMi: 6c5f00f1eccbcea3304feae03cbe659025fdb9cb
|
YuMi: 6c5f00f1eccbcea3304feae03cbe659025fdb9cb
|
||||||
YXArtemis_XCFramework: d9a8b9439d7a6c757ed00ada53a6d2dd9b13f9c7
|
YXArtemis_XCFramework: d9a8b9439d7a6c757ed00ada53a6d2dd9b13f9c7
|
||||||
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
|
||||||
@@ -304,6 +221,6 @@ SPEC CHECKSUMS:
|
|||||||
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
|
||||||
ZLCollectionViewFlowLayout: c99024652ce9f0c57d33ab53052c9b85e4a936b7
|
ZLCollectionViewFlowLayout: c99024652ce9f0c57d33ab53052c9b85e4a936b7
|
||||||
|
|
||||||
PODFILE CHECKSUM: 581cecb560110b972c7e8c7d4b01e24a5deaf833
|
PODFILE CHECKSUM: 3ef6e2b784d16a5b9d2c5cdd03f8bbf3ed3483ce
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
@@ -394,7 +394,6 @@
|
|||||||
4C06427F2E97BD6D00BAF413 /* EPMineHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642732E97BD6D00BAF413 /* EPMineHeaderView.m */; };
|
4C06427F2E97BD6D00BAF413 /* EPMineHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642732E97BD6D00BAF413 /* EPMineHeaderView.m */; };
|
||||||
4C0642802E97BD6D00BAF413 /* EPMomentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C06427A2E97BD6D00BAF413 /* EPMomentCell.m */; };
|
4C0642802E97BD6D00BAF413 /* EPMomentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C06427A2E97BD6D00BAF413 /* EPMomentCell.m */; };
|
||||||
4C0642852E97BD9500BAF413 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642842E97BD9500BAF413 /* APIConfig.swift */; };
|
4C0642852E97BD9500BAF413 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642842E97BD9500BAF413 /* APIConfig.swift */; };
|
||||||
4C0642882E97BDA300BAF413 /* GlobalEventManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642872E97BDA300BAF413 /* GlobalEventManager.m */; };
|
|
||||||
4C06428B2E98DC5F00BAF413 /* EPTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06428A2E98DC5F00BAF413 /* EPTabBarController.swift */; };
|
4C06428B2E98DC5F00BAF413 /* EPTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06428A2E98DC5F00BAF413 /* EPTabBarController.swift */; };
|
||||||
4C0642912E98DC8700BAF413 /* EPMomentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642902E98DC8700BAF413 /* EPMomentViewController.m */; };
|
4C0642912E98DC8700BAF413 /* EPMomentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642902E98DC8700BAF413 /* EPMomentViewController.m */; };
|
||||||
4C0642992E98F77900BAF413 /* EPMomentListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642982E98F77900BAF413 /* EPMomentListView.m */; };
|
4C0642992E98F77900BAF413 /* EPMomentListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0642982E98F77900BAF413 /* EPMomentListView.m */; };
|
||||||
@@ -417,6 +416,12 @@
|
|||||||
4C1392962D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1392952D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m */; };
|
4C1392962D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1392952D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m */; };
|
||||||
4C13929D2D70441500A6DFB5 /* giftgift.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 4C13929B2D70441500A6DFB5 /* giftgift.mp4 */; };
|
4C13929D2D70441500A6DFB5 /* giftgift.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 4C13929B2D70441500A6DFB5 /* giftgift.mp4 */; };
|
||||||
4C1392A12D71675900A6DFB5 /* coincoin.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 4C1392A02D71675900A6DFB5 /* coincoin.mp4 */; };
|
4C1392A12D71675900A6DFB5 /* coincoin.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 4C1392A02D71675900A6DFB5 /* coincoin.mp4 */; };
|
||||||
|
4C14398D2EA62D3C0037B074 /* EPClientAPIBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C14398C2EA62D3C0037B074 /* EPClientAPIBridge.m */; };
|
||||||
|
4C1439912EA62DD30037B074 /* EPConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C14398F2EA62DD30037B074 /* EPConfigManager.swift */; };
|
||||||
|
4C1439922EA62DD30037B074 /* EPConfigStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1439902EA62DD30037B074 /* EPConfigStorage.m */; };
|
||||||
|
4C1439942EA630490037B074 /* EPConfigAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1439932EA630490037B074 /* EPConfigAPI.swift */; };
|
||||||
|
4C14399C2EA635EB0037B074 /* EPNIMConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1439972EA635EB0037B074 /* EPNIMConfig.m */; };
|
||||||
|
4C14399D2EA635EB0037B074 /* EPNIMManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1439992EA635EB0037B074 /* EPNIMManager.m */; };
|
||||||
4C1892992CF84349004D4426 /* RoomCahtCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1892982CF84349004D4426 /* RoomCahtCell.m */; };
|
4C1892992CF84349004D4426 /* RoomCahtCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1892982CF84349004D4426 /* RoomCahtCell.m */; };
|
||||||
4C1A141B2DCB4AB700B6D0CA /* ChatFaceVo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A141A2DCB4AB700B6D0CA /* ChatFaceVo.m */; };
|
4C1A141B2DCB4AB700B6D0CA /* ChatFaceVo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A141A2DCB4AB700B6D0CA /* ChatFaceVo.m */; };
|
||||||
4C1E98BF2E9A3A540031AE79 /* EPMineAPIHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E98BD2E9A3A540031AE79 /* EPMineAPIHelper.m */; };
|
4C1E98BF2E9A3A540031AE79 /* EPMineAPIHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E98BD2E9A3A540031AE79 /* EPMineAPIHelper.m */; };
|
||||||
@@ -442,6 +447,11 @@
|
|||||||
4C520D882D89A78C0051C784 /* VisitorListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C520D872D89A78C0051C784 /* VisitorListViewController.m */; };
|
4C520D882D89A78C0051C784 /* VisitorListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C520D872D89A78C0051C784 /* VisitorListViewController.m */; };
|
||||||
4C5527BC2D1BDCDE00833FFD /* RoomLevelInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5527BB2D1BDCDE00833FFD /* RoomLevelInfoModel.m */; };
|
4C5527BC2D1BDCDE00833FFD /* RoomLevelInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5527BB2D1BDCDE00833FFD /* RoomLevelInfoModel.m */; };
|
||||||
4C5527BF2D1C099500833FFD /* RoomResourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5527BE2D1C099500833FFD /* RoomResourceManager.m */; };
|
4C5527BF2D1C099500833FFD /* RoomResourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5527BE2D1C099500833FFD /* RoomResourceManager.m */; };
|
||||||
|
4C59C0FD2EA2508F00D1F7BD /* EPFriendFollowingFans.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C59C0F82EA2508F00D1F7BD /* EPFriendFollowingFans.swift */; };
|
||||||
|
4C59C0FE2EA2508F00D1F7BD /* EPMessageSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C59C0FB2EA2508F00D1F7BD /* EPMessageSegmentView.swift */; };
|
||||||
|
4C59C0FF2EA2508F00D1F7BD /* EPMessageMainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C59C0FA2EA2508F00D1F7BD /* EPMessageMainViewController.swift */; };
|
||||||
|
4C59C1002EA2508F00D1F7BD /* EPBaseListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C59C0F72EA2508F00D1F7BD /* EPBaseListViewController.swift */; };
|
||||||
|
4C59C1012EA2508F00D1F7BD /* EPMessageListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C59C0F92EA2508F00D1F7BD /* EPMessageListVC.swift */; };
|
||||||
4C5C37232D0C1C7900BA9AB8 /* RegionListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5C37222D0C1C7900BA9AB8 /* RegionListViewController.m */; };
|
4C5C37232D0C1C7900BA9AB8 /* RegionListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C5C37222D0C1C7900BA9AB8 /* RegionListViewController.m */; };
|
||||||
4C6C92C02D1172D9000A4693 /* RegionListInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6C92BF2D1172D9000A4693 /* RegionListInfo.m */; };
|
4C6C92C02D1172D9000A4693 /* RegionListInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6C92BF2D1172D9000A4693 /* RegionListInfo.m */; };
|
||||||
4C6E1F752CEAEC3C0073D0A3 /* ShoppingMallTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E1F742CEAEC3C0073D0A3 /* ShoppingMallTagView.m */; };
|
4C6E1F752CEAEC3C0073D0A3 /* ShoppingMallTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E1F742CEAEC3C0073D0A3 /* ShoppingMallTagView.m */; };
|
||||||
@@ -700,13 +710,10 @@
|
|||||||
4CD19E702E9CDF980069DAA0 /* emoji_118@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4CD19D142E9CDF980069DAA0 /* emoji_118@2x.png */; };
|
4CD19E702E9CDF980069DAA0 /* emoji_118@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4CD19D142E9CDF980069DAA0 /* emoji_118@2x.png */; };
|
||||||
4CD19E712E9CDF980069DAA0 /* emoji_21@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4CD19CB32E9CDF980069DAA0 /* emoji_21@2x.png */; };
|
4CD19E712E9CDF980069DAA0 /* emoji_21@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4CD19CB32E9CDF980069DAA0 /* emoji_21@2x.png */; };
|
||||||
4CD19E722E9CDF980069DAA0 /* UIButton+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D692E9CDF980069DAA0 /* UIButton+MSRTL.m */; };
|
4CD19E722E9CDF980069DAA0 /* UIButton+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D692E9CDF980069DAA0 /* UIButton+MSRTL.m */; };
|
||||||
4CD19E732E9CDF980069DAA0 /* XPShareItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D7A2E9CDF980069DAA0 /* XPShareItem.m */; };
|
|
||||||
4CD19E742E9CDF980069DAA0 /* TTNewAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DA02E9CDF980069DAA0 /* TTNewAlertView.m */; };
|
4CD19E742E9CDF980069DAA0 /* TTNewAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DA02E9CDF980069DAA0 /* TTNewAlertView.m */; };
|
||||||
4CD19E752E9CDF980069DAA0 /* QPhotoImageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D5B2E9CDF980069DAA0 /* QPhotoImageModel.m */; };
|
4CD19E752E9CDF980069DAA0 /* QPhotoImageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D5B2E9CDF980069DAA0 /* QPhotoImageModel.m */; };
|
||||||
4CD19E762E9CDF980069DAA0 /* XPShareInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D782E9CDF980069DAA0 /* XPShareInfoModel.m */; };
|
|
||||||
4CD19E772E9CDF980069DAA0 /* UITextView+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D732E9CDF980069DAA0 /* UITextView+MSRTL.m */; };
|
4CD19E772E9CDF980069DAA0 /* UITextView+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D732E9CDF980069DAA0 /* UITextView+MSRTL.m */; };
|
||||||
4CD19E782E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D672E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m */; };
|
4CD19E782E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D672E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m */; };
|
||||||
4CD19E792E9CDF980069DAA0 /* XPShareItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D7D2E9CDF980069DAA0 /* XPShareItemCell.m */; };
|
|
||||||
4CD19E7A2E9CDF980069DAA0 /* SexAgeLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DC42E9CDF980069DAA0 /* SexAgeLabel.m */; };
|
4CD19E7A2E9CDF980069DAA0 /* SexAgeLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DC42E9CDF980069DAA0 /* SexAgeLabel.m */; };
|
||||||
4CD19E7B2E9CDF980069DAA0 /* QKeyboardManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D592E9CDF980069DAA0 /* QKeyboardManager.m */; };
|
4CD19E7B2E9CDF980069DAA0 /* QKeyboardManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D592E9CDF980069DAA0 /* QKeyboardManager.m */; };
|
||||||
4CD19E7C2E9CDF980069DAA0 /* TTPopupService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D982E9CDF980069DAA0 /* TTPopupService.m */; };
|
4CD19E7C2E9CDF980069DAA0 /* TTPopupService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D982E9CDF980069DAA0 /* TTPopupService.m */; };
|
||||||
@@ -735,7 +742,6 @@
|
|||||||
4CD19E932E9CDF980069DAA0 /* NetImageConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DAC2E9CDF980069DAA0 /* NetImageConfig.m */; };
|
4CD19E932E9CDF980069DAA0 /* NetImageConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DAC2E9CDF980069DAA0 /* NetImageConfig.m */; };
|
||||||
4CD19E942E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DA62E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m */; };
|
4CD19E942E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19DA62E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m */; };
|
||||||
4CD19E952E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D632E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m */; };
|
4CD19E952E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D632E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m */; };
|
||||||
4CD19E962E9CDF980069DAA0 /* XPShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D802E9CDF980069DAA0 /* XPShareView.m */; };
|
|
||||||
4CD19E972E9CDF980069DAA0 /* QEmotion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D452E9CDF980069DAA0 /* QEmotion.m */; };
|
4CD19E972E9CDF980069DAA0 /* QEmotion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D452E9CDF980069DAA0 /* QEmotion.m */; };
|
||||||
4CD19E982E9CDF980069DAA0 /* AdvertiseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19C952E9CDF980069DAA0 /* AdvertiseModel.m */; };
|
4CD19E982E9CDF980069DAA0 /* AdvertiseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19C952E9CDF980069DAA0 /* AdvertiseModel.m */; };
|
||||||
4CD19E992E9CDF980069DAA0 /* XPSVGAPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D832E9CDF980069DAA0 /* XPSVGAPlayer.m */; };
|
4CD19E992E9CDF980069DAA0 /* XPSVGAPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD19D832E9CDF980069DAA0 /* XPSVGAPlayer.m */; };
|
||||||
@@ -884,7 +890,7 @@
|
|||||||
54FFD3832C9BD12600DE61E5 /* 5.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37F2C9BD12600DE61E5 /* 5.svga */; };
|
54FFD3832C9BD12600DE61E5 /* 5.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37F2C9BD12600DE61E5 /* 5.svga */; };
|
||||||
54FFD3842C9BD12600DE61E5 /* 3.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37D2C9BD12600DE61E5 /* 3.svga */; };
|
54FFD3842C9BD12600DE61E5 /* 3.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37D2C9BD12600DE61E5 /* 3.svga */; };
|
||||||
54FFD3852C9BD12600DE61E5 /* 2.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37C2C9BD12600DE61E5 /* 2.svga */; };
|
54FFD3852C9BD12600DE61E5 /* 2.svga in Resources */ = {isa = PBXBuildFile; fileRef = 54FFD37C2C9BD12600DE61E5 /* 2.svga */; };
|
||||||
73FFADDC93E195344047A2EC /* Pods_YuMi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CACF623970097D653132D69A /* Pods_YuMi.framework */; };
|
6996748A711C8E6931880AD0 /* Pods_YuMi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3148BBD005110C1B57D04595 /* Pods_YuMi.framework */; };
|
||||||
9B0086C627BA392B0032BD2B /* AnchorStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C527BA392B0032BD2B /* AnchorStageView.m */; };
|
9B0086C627BA392B0032BD2B /* AnchorStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C527BA392B0032BD2B /* AnchorStageView.m */; };
|
||||||
9B0086CA27BA4F570032BD2B /* AnchorMicroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C927BA4F570032BD2B /* AnchorMicroView.m */; };
|
9B0086CA27BA4F570032BD2B /* AnchorMicroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0086C927BA4F570032BD2B /* AnchorMicroView.m */; };
|
||||||
9B044DA0282D32F700DE4859 /* MicroInviteExtModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B044D9F282D32F700DE4859 /* MicroInviteExtModel.m */; };
|
9B044DA0282D32F700DE4859 /* MicroInviteExtModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B044D9F282D32F700DE4859 /* MicroInviteExtModel.m */; };
|
||||||
@@ -1652,7 +1658,6 @@
|
|||||||
E8F63CB4298B563D00B338BA /* Api+SayHello.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CB3298B563D00B338BA /* Api+SayHello.m */; };
|
E8F63CB4298B563D00B338BA /* Api+SayHello.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CB3298B563D00B338BA /* Api+SayHello.m */; };
|
||||||
E8F63CB7298B566D00B338BA /* XPSessionSayHelloPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CB6298B566D00B338BA /* XPSessionSayHelloPresenter.m */; };
|
E8F63CB7298B566D00B338BA /* XPSessionSayHelloPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CB6298B566D00B338BA /* XPSessionSayHelloPresenter.m */; };
|
||||||
E8F63CBB298B648300B338BA /* SessionSayHelloListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CBA298B648300B338BA /* SessionSayHelloListModel.m */; };
|
E8F63CBB298B648300B338BA /* SessionSayHelloListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F63CBA298B648300B338BA /* SessionSayHelloListModel.m */; };
|
||||||
E8F65C1F286998C9009BB5B9 /* XPMineShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F65C1E286998C9009BB5B9 /* XPMineShareViewController.m */; };
|
|
||||||
E8F65C222869A36F009BB5B9 /* ContentShareMonentsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F65C212869A36F009BB5B9 /* ContentShareMonentsModel.m */; };
|
E8F65C222869A36F009BB5B9 /* ContentShareMonentsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E8F65C212869A36F009BB5B9 /* ContentShareMonentsModel.m */; };
|
||||||
F1D8556F2931FC86008C418F /* XPRoomYearActivityView.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D8556E2931FC86008C418F /* XPRoomYearActivityView.m */; };
|
F1D8556F2931FC86008C418F /* XPRoomYearActivityView.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D8556E2931FC86008C418F /* XPRoomYearActivityView.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@@ -2431,13 +2436,12 @@
|
|||||||
23FF42782AA6E19C0055733C /* HomeMenuSourceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeMenuSourceModel.m; sourceTree = "<group>"; };
|
23FF42782AA6E19C0055733C /* HomeMenuSourceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeMenuSourceModel.m; sourceTree = "<group>"; };
|
||||||
23FF428C2AAB2D3A0055733C /* XPCandyTreeBuyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPCandyTreeBuyView.h; sourceTree = "<group>"; };
|
23FF428C2AAB2D3A0055733C /* XPCandyTreeBuyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPCandyTreeBuyView.h; sourceTree = "<group>"; };
|
||||||
23FF428D2AAB2D3A0055733C /* XPCandyTreeBuyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPCandyTreeBuyView.m; sourceTree = "<group>"; };
|
23FF428D2AAB2D3A0055733C /* XPCandyTreeBuyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPCandyTreeBuyView.m; sourceTree = "<group>"; };
|
||||||
|
3148BBD005110C1B57D04595 /* Pods_YuMi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YuMi.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4C0642722E97BD6D00BAF413 /* EPMineHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMineHeaderView.h; sourceTree = "<group>"; };
|
4C0642722E97BD6D00BAF413 /* EPMineHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMineHeaderView.h; sourceTree = "<group>"; };
|
||||||
4C0642732E97BD6D00BAF413 /* EPMineHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMineHeaderView.m; sourceTree = "<group>"; };
|
4C0642732E97BD6D00BAF413 /* EPMineHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMineHeaderView.m; sourceTree = "<group>"; };
|
||||||
4C0642792E97BD6D00BAF413 /* EPMomentCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMomentCell.h; sourceTree = "<group>"; };
|
4C0642792E97BD6D00BAF413 /* EPMomentCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMomentCell.h; sourceTree = "<group>"; };
|
||||||
4C06427A2E97BD6D00BAF413 /* EPMomentCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMomentCell.m; sourceTree = "<group>"; };
|
4C06427A2E97BD6D00BAF413 /* EPMomentCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMomentCell.m; sourceTree = "<group>"; };
|
||||||
4C0642842E97BD9500BAF413 /* APIConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIConfig.swift; sourceTree = "<group>"; };
|
4C0642842E97BD9500BAF413 /* APIConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIConfig.swift; sourceTree = "<group>"; };
|
||||||
4C0642862E97BDA300BAF413 /* GlobalEventManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalEventManager.h; sourceTree = "<group>"; };
|
|
||||||
4C0642872E97BDA300BAF413 /* GlobalEventManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GlobalEventManager.m; sourceTree = "<group>"; };
|
|
||||||
4C0642892E97BDC900BAF413 /* YuMi-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YuMi-Bridging-Header.h"; sourceTree = "<group>"; };
|
4C0642892E97BDC900BAF413 /* YuMi-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YuMi-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
4C06428A2E98DC5F00BAF413 /* EPTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPTabBarController.swift; sourceTree = "<group>"; };
|
4C06428A2E98DC5F00BAF413 /* EPTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPTabBarController.swift; sourceTree = "<group>"; };
|
||||||
4C06428F2E98DC8700BAF413 /* EPMomentViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMomentViewController.h; sourceTree = "<group>"; };
|
4C06428F2E98DC8700BAF413 /* EPMomentViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMomentViewController.h; sourceTree = "<group>"; };
|
||||||
@@ -2480,6 +2484,16 @@
|
|||||||
4C1392952D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RechargerTransferHistoryViewController.m; sourceTree = "<group>"; };
|
4C1392952D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RechargerTransferHistoryViewController.m; sourceTree = "<group>"; };
|
||||||
4C13929B2D70441500A6DFB5 /* giftgift.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = giftgift.mp4; sourceTree = "<group>"; };
|
4C13929B2D70441500A6DFB5 /* giftgift.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = giftgift.mp4; sourceTree = "<group>"; };
|
||||||
4C1392A02D71675900A6DFB5 /* coincoin.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = coincoin.mp4; sourceTree = "<group>"; };
|
4C1392A02D71675900A6DFB5 /* coincoin.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = coincoin.mp4; sourceTree = "<group>"; };
|
||||||
|
4C14398B2EA62D3C0037B074 /* EPClientAPIBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPClientAPIBridge.h; sourceTree = "<group>"; };
|
||||||
|
4C14398C2EA62D3C0037B074 /* EPClientAPIBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPClientAPIBridge.m; sourceTree = "<group>"; };
|
||||||
|
4C14398E2EA62D8C0037B074 /* EPConfigStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPConfigStorage.h; sourceTree = "<group>"; };
|
||||||
|
4C14398F2EA62DD30037B074 /* EPConfigManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPConfigManager.swift; sourceTree = "<group>"; };
|
||||||
|
4C1439902EA62DD30037B074 /* EPConfigStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPConfigStorage.m; sourceTree = "<group>"; };
|
||||||
|
4C1439932EA630490037B074 /* EPConfigAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPConfigAPI.swift; sourceTree = "<group>"; };
|
||||||
|
4C1439962EA635EB0037B074 /* EPNIMConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPNIMConfig.h; sourceTree = "<group>"; };
|
||||||
|
4C1439972EA635EB0037B074 /* EPNIMConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPNIMConfig.m; sourceTree = "<group>"; };
|
||||||
|
4C1439982EA635EB0037B074 /* EPNIMManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPNIMManager.h; sourceTree = "<group>"; };
|
||||||
|
4C1439992EA635EB0037B074 /* EPNIMManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPNIMManager.m; sourceTree = "<group>"; };
|
||||||
4C1892972CF84349004D4426 /* RoomCahtCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomCahtCell.h; sourceTree = "<group>"; };
|
4C1892972CF84349004D4426 /* RoomCahtCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomCahtCell.h; sourceTree = "<group>"; };
|
||||||
4C1892982CF84349004D4426 /* RoomCahtCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomCahtCell.m; sourceTree = "<group>"; };
|
4C1892982CF84349004D4426 /* RoomCahtCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomCahtCell.m; sourceTree = "<group>"; };
|
||||||
4C1A14192DCB4AB700B6D0CA /* ChatFaceVo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChatFaceVo.h; sourceTree = "<group>"; };
|
4C1A14192DCB4AB700B6D0CA /* ChatFaceVo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChatFaceVo.h; sourceTree = "<group>"; };
|
||||||
@@ -2527,6 +2541,11 @@
|
|||||||
4C5527BB2D1BDCDE00833FFD /* RoomLevelInfoModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomLevelInfoModel.m; sourceTree = "<group>"; };
|
4C5527BB2D1BDCDE00833FFD /* RoomLevelInfoModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomLevelInfoModel.m; sourceTree = "<group>"; };
|
||||||
4C5527BD2D1C099500833FFD /* RoomResourceManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomResourceManager.h; sourceTree = "<group>"; };
|
4C5527BD2D1C099500833FFD /* RoomResourceManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomResourceManager.h; sourceTree = "<group>"; };
|
||||||
4C5527BE2D1C099500833FFD /* RoomResourceManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomResourceManager.m; sourceTree = "<group>"; };
|
4C5527BE2D1C099500833FFD /* RoomResourceManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomResourceManager.m; sourceTree = "<group>"; };
|
||||||
|
4C59C0F72EA2508F00D1F7BD /* EPBaseListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPBaseListViewController.swift; sourceTree = "<group>"; };
|
||||||
|
4C59C0F82EA2508F00D1F7BD /* EPFriendFollowingFans.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPFriendFollowingFans.swift; sourceTree = "<group>"; };
|
||||||
|
4C59C0F92EA2508F00D1F7BD /* EPMessageListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPMessageListVC.swift; sourceTree = "<group>"; };
|
||||||
|
4C59C0FA2EA2508F00D1F7BD /* EPMessageMainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPMessageMainViewController.swift; sourceTree = "<group>"; };
|
||||||
|
4C59C0FB2EA2508F00D1F7BD /* EPMessageSegmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPMessageSegmentView.swift; sourceTree = "<group>"; };
|
||||||
4C5C37212D0C1C7900BA9AB8 /* RegionListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegionListViewController.h; sourceTree = "<group>"; };
|
4C5C37212D0C1C7900BA9AB8 /* RegionListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegionListViewController.h; sourceTree = "<group>"; };
|
||||||
4C5C37222D0C1C7900BA9AB8 /* RegionListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RegionListViewController.m; sourceTree = "<group>"; };
|
4C5C37222D0C1C7900BA9AB8 /* RegionListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RegionListViewController.m; sourceTree = "<group>"; };
|
||||||
4C6C92BE2D1172D9000A4693 /* RegionListInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegionListInfo.h; sourceTree = "<group>"; };
|
4C6C92BE2D1172D9000A4693 /* RegionListInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegionListInfo.h; sourceTree = "<group>"; };
|
||||||
@@ -2913,14 +2932,6 @@
|
|||||||
4CD19D732E9CDF980069DAA0 /* UITextView+MSRTL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UITextView+MSRTL.m"; sourceTree = "<group>"; };
|
4CD19D732E9CDF980069DAA0 /* UITextView+MSRTL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UITextView+MSRTL.m"; sourceTree = "<group>"; };
|
||||||
4CD19D742E9CDF980069DAA0 /* YYLabel+MSRTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YYLabel+MSRTL.h"; sourceTree = "<group>"; };
|
4CD19D742E9CDF980069DAA0 /* YYLabel+MSRTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YYLabel+MSRTL.h"; sourceTree = "<group>"; };
|
||||||
4CD19D752E9CDF980069DAA0 /* YYLabel+MSRTL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "YYLabel+MSRTL.m"; sourceTree = "<group>"; };
|
4CD19D752E9CDF980069DAA0 /* YYLabel+MSRTL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "YYLabel+MSRTL.m"; sourceTree = "<group>"; };
|
||||||
4CD19D772E9CDF980069DAA0 /* XPShareInfoModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPShareInfoModel.h; sourceTree = "<group>"; };
|
|
||||||
4CD19D782E9CDF980069DAA0 /* XPShareInfoModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPShareInfoModel.m; sourceTree = "<group>"; };
|
|
||||||
4CD19D792E9CDF980069DAA0 /* XPShareItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPShareItem.h; sourceTree = "<group>"; };
|
|
||||||
4CD19D7A2E9CDF980069DAA0 /* XPShareItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPShareItem.m; sourceTree = "<group>"; };
|
|
||||||
4CD19D7C2E9CDF980069DAA0 /* XPShareItemCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPShareItemCell.h; sourceTree = "<group>"; };
|
|
||||||
4CD19D7D2E9CDF980069DAA0 /* XPShareItemCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPShareItemCell.m; sourceTree = "<group>"; };
|
|
||||||
4CD19D7F2E9CDF980069DAA0 /* XPShareView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPShareView.h; sourceTree = "<group>"; };
|
|
||||||
4CD19D802E9CDF980069DAA0 /* XPShareView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPShareView.m; sourceTree = "<group>"; };
|
|
||||||
4CD19D822E9CDF980069DAA0 /* XPSVGAPlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSVGAPlayer.h; sourceTree = "<group>"; };
|
4CD19D822E9CDF980069DAA0 /* XPSVGAPlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSVGAPlayer.h; sourceTree = "<group>"; };
|
||||||
4CD19D832E9CDF980069DAA0 /* XPSVGAPlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSVGAPlayer.m; sourceTree = "<group>"; };
|
4CD19D832E9CDF980069DAA0 /* XPSVGAPlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSVGAPlayer.m; sourceTree = "<group>"; };
|
||||||
4CD19D852E9CDF980069DAA0 /* XPSwitch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSwitch.h; sourceTree = "<group>"; };
|
4CD19D852E9CDF980069DAA0 /* XPSwitch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSwitch.h; sourceTree = "<group>"; };
|
||||||
@@ -2982,8 +2993,8 @@
|
|||||||
4CD19EAD2E9CDFC30069DAA0 /* EPLoginInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPLoginInputView.swift; sourceTree = "<group>"; };
|
4CD19EAD2E9CDFC30069DAA0 /* EPLoginInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPLoginInputView.swift; sourceTree = "<group>"; };
|
||||||
4CD19EB02E9D12600069DAA0 /* EPEditSettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPEditSettingViewController.swift; sourceTree = "<group>"; };
|
4CD19EB02E9D12600069DAA0 /* EPEditSettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPEditSettingViewController.swift; sourceTree = "<group>"; };
|
||||||
4CD19EB22E9D141A0069DAA0 /* EPMineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMineViewController.h; sourceTree = "<group>"; };
|
4CD19EB22E9D141A0069DAA0 /* EPMineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPMineViewController.h; sourceTree = "<group>"; };
|
||||||
4CD19EB62E9D15000069DAA0 /* EPAboutUsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPAboutUsViewController.swift; sourceTree = "<group>"; };
|
|
||||||
4CD19EB32E9D141A0069DAA0 /* EPMineViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMineViewController.m; sourceTree = "<group>"; };
|
4CD19EB32E9D141A0069DAA0 /* EPMineViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPMineViewController.m; sourceTree = "<group>"; };
|
||||||
|
4CD19EB62E9D15000069DAA0 /* EPAboutUsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPAboutUsViewController.swift; sourceTree = "<group>"; };
|
||||||
4CD401452E7183A8003F5009 /* XPPartyRoomItemCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPPartyRoomItemCollectionViewCell.h; sourceTree = "<group>"; };
|
4CD401452E7183A8003F5009 /* XPPartyRoomItemCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPPartyRoomItemCollectionViewCell.h; sourceTree = "<group>"; };
|
||||||
4CD401462E7183A8003F5009 /* XPPartyRoomItemCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPPartyRoomItemCollectionViewCell.m; sourceTree = "<group>"; };
|
4CD401462E7183A8003F5009 /* XPPartyRoomItemCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPPartyRoomItemCollectionViewCell.m; sourceTree = "<group>"; };
|
||||||
4CD401482E718E36003F5009 /* XPBlankRoomModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPBlankRoomModel.h; sourceTree = "<group>"; };
|
4CD401482E718E36003F5009 /* XPBlankRoomModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPBlankRoomModel.h; sourceTree = "<group>"; };
|
||||||
@@ -3209,7 +3220,7 @@
|
|||||||
54FFD37D2C9BD12600DE61E5 /* 3.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 3.svga; sourceTree = "<group>"; };
|
54FFD37D2C9BD12600DE61E5 /* 3.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 3.svga; sourceTree = "<group>"; };
|
||||||
54FFD37E2C9BD12600DE61E5 /* 4.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 4.svga; sourceTree = "<group>"; };
|
54FFD37E2C9BD12600DE61E5 /* 4.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 4.svga; sourceTree = "<group>"; };
|
||||||
54FFD37F2C9BD12600DE61E5 /* 5.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 5.svga; sourceTree = "<group>"; };
|
54FFD37F2C9BD12600DE61E5 /* 5.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = 5.svga; sourceTree = "<group>"; };
|
||||||
7DB00EC07F1D0ADFF900B38D /* Pods-YuMi.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.debug.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.debug.xcconfig"; sourceTree = "<group>"; };
|
56B26C27109C1DD2002D0624 /* Pods-YuMi.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.release.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
9B0086C427BA392B0032BD2B /* AnchorStageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnchorStageView.h; sourceTree = "<group>"; };
|
9B0086C427BA392B0032BD2B /* AnchorStageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnchorStageView.h; sourceTree = "<group>"; };
|
||||||
9B0086C527BA392B0032BD2B /* AnchorStageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnchorStageView.m; sourceTree = "<group>"; };
|
9B0086C527BA392B0032BD2B /* AnchorStageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnchorStageView.m; sourceTree = "<group>"; };
|
||||||
9B0086C827BA4F570032BD2B /* AnchorMicroView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnchorMicroView.h; sourceTree = "<group>"; };
|
9B0086C827BA4F570032BD2B /* AnchorMicroView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnchorMicroView.h; sourceTree = "<group>"; };
|
||||||
@@ -3495,8 +3506,6 @@
|
|||||||
9BFE0D912899042600F53C24 /* XPTaskCompleteTipView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPTaskCompleteTipView.m; sourceTree = "<group>"; };
|
9BFE0D912899042600F53C24 /* XPTaskCompleteTipView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPTaskCompleteTipView.m; sourceTree = "<group>"; };
|
||||||
9BFE992C288142FD009DA429 /* RoomClassifyModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomClassifyModel.h; sourceTree = "<group>"; };
|
9BFE992C288142FD009DA429 /* RoomClassifyModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomClassifyModel.h; sourceTree = "<group>"; };
|
||||||
9BFE992D288142FD009DA429 /* RoomClassifyModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomClassifyModel.m; sourceTree = "<group>"; };
|
9BFE992D288142FD009DA429 /* RoomClassifyModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomClassifyModel.m; sourceTree = "<group>"; };
|
||||||
B66633E061B1B34177CD011C /* Pods-YuMi.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.release.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
CACF623970097D653132D69A /* Pods_YuMi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YuMi.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
E801273E27E323C800BAC3F2 /* XPRoomPKViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomPKViewController.h; sourceTree = "<group>"; };
|
E801273E27E323C800BAC3F2 /* XPRoomPKViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomPKViewController.h; sourceTree = "<group>"; };
|
||||||
E801273F27E323C800BAC3F2 /* XPRoomPKViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomPKViewController.m; sourceTree = "<group>"; };
|
E801273F27E323C800BAC3F2 /* XPRoomPKViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomPKViewController.m; sourceTree = "<group>"; };
|
||||||
E801274127E323E500BAC3F2 /* XPRoomPKPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomPKPresenter.h; sourceTree = "<group>"; };
|
E801274127E323E500BAC3F2 /* XPRoomPKPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomPKPresenter.h; sourceTree = "<group>"; };
|
||||||
@@ -4799,10 +4808,9 @@
|
|||||||
E8F63CB8298B5F3D00B338BA /* XPSessionSayHelloProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSessionSayHelloProtocol.h; sourceTree = "<group>"; };
|
E8F63CB8298B5F3D00B338BA /* XPSessionSayHelloProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSessionSayHelloProtocol.h; sourceTree = "<group>"; };
|
||||||
E8F63CB9298B648300B338BA /* SessionSayHelloListModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SessionSayHelloListModel.h; sourceTree = "<group>"; };
|
E8F63CB9298B648300B338BA /* SessionSayHelloListModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SessionSayHelloListModel.h; sourceTree = "<group>"; };
|
||||||
E8F63CBA298B648300B338BA /* SessionSayHelloListModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SessionSayHelloListModel.m; sourceTree = "<group>"; };
|
E8F63CBA298B648300B338BA /* SessionSayHelloListModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SessionSayHelloListModel.m; sourceTree = "<group>"; };
|
||||||
E8F65C1D286998C9009BB5B9 /* XPMineShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMineShareViewController.h; sourceTree = "<group>"; };
|
|
||||||
E8F65C1E286998C9009BB5B9 /* XPMineShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMineShareViewController.m; sourceTree = "<group>"; };
|
|
||||||
E8F65C202869A36F009BB5B9 /* ContentShareMonentsModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentShareMonentsModel.h; sourceTree = "<group>"; };
|
E8F65C202869A36F009BB5B9 /* ContentShareMonentsModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentShareMonentsModel.h; sourceTree = "<group>"; };
|
||||||
E8F65C212869A36F009BB5B9 /* ContentShareMonentsModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentShareMonentsModel.m; sourceTree = "<group>"; };
|
E8F65C212869A36F009BB5B9 /* ContentShareMonentsModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContentShareMonentsModel.m; sourceTree = "<group>"; };
|
||||||
|
ECF5B2AAE493057A3DBCCFAF /* Pods-YuMi.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.debug.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
F1D8556D2931FC86008C418F /* XPRoomYearActivityView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomYearActivityView.h; sourceTree = "<group>"; };
|
F1D8556D2931FC86008C418F /* XPRoomYearActivityView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomYearActivityView.h; sourceTree = "<group>"; };
|
||||||
F1D8556E2931FC86008C418F /* XPRoomYearActivityView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomYearActivityView.m; sourceTree = "<group>"; };
|
F1D8556E2931FC86008C418F /* XPRoomYearActivityView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomYearActivityView.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@@ -4821,11 +4829,11 @@
|
|||||||
237701082BCF73CE00D661F1 /* Security.framework in Frameworks */,
|
237701082BCF73CE00D661F1 /* Security.framework in Frameworks */,
|
||||||
4CD15D922D7EC2AC00D9279F /* CoreTelephony.framework in Frameworks */,
|
4CD15D922D7EC2AC00D9279F /* CoreTelephony.framework in Frameworks */,
|
||||||
234489082AC3C5DA0070E5D5 /* SudMGP.framework in Frameworks */,
|
234489082AC3C5DA0070E5D5 /* SudMGP.framework in Frameworks */,
|
||||||
73FFADDC93E195344047A2EC /* Pods_YuMi.framework in Frameworks */,
|
|
||||||
186A531926FC592100D67B2C /* libresolv.tbd in Frameworks */,
|
186A531926FC592100D67B2C /* libresolv.tbd in Frameworks */,
|
||||||
E87888F42738C30E00BF1D57 /* StoreKit.framework in Frameworks */,
|
E87888F42738C30E00BF1D57 /* StoreKit.framework in Frameworks */,
|
||||||
9BA8A47727C60DF7000365A3 /* AVFoundation.framework in Frameworks */,
|
9BA8A47727C60DF7000365A3 /* AVFoundation.framework in Frameworks */,
|
||||||
9BA8A47527C60D9F000365A3 /* AudioToolbox.framework in Frameworks */,
|
9BA8A47527C60D9F000365A3 /* AudioToolbox.framework in Frameworks */,
|
||||||
|
6996748A711C8E6931880AD0 /* Pods_YuMi.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -6473,6 +6481,8 @@
|
|||||||
4C0642922E98EF0A00BAF413 /* E-P */ = {
|
4C0642922E98EF0A00BAF413 /* E-P */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4C14399B2EA635EB0037B074 /* SDKManager */,
|
||||||
|
4C59C0FC2EA2508F00D1F7BD /* NewMessage */,
|
||||||
4CD19C852E9CB31C0069DAA0 /* NewLogin */,
|
4CD19C852E9CB31C0069DAA0 /* NewLogin */,
|
||||||
4C1E98C22E9A45160031AE79 /* Common */,
|
4C1E98C22E9A45160031AE79 /* Common */,
|
||||||
4C0642752E97BD6D00BAF413 /* NewMine */,
|
4C0642752E97BD6D00BAF413 /* NewMine */,
|
||||||
@@ -6492,6 +6502,25 @@
|
|||||||
path = Services;
|
path = Services;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4C14399A2EA635EB0037B074 /* NIMSDK */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4C1439962EA635EB0037B074 /* EPNIMConfig.h */,
|
||||||
|
4C1439972EA635EB0037B074 /* EPNIMConfig.m */,
|
||||||
|
4C1439982EA635EB0037B074 /* EPNIMManager.h */,
|
||||||
|
4C1439992EA635EB0037B074 /* EPNIMManager.m */,
|
||||||
|
);
|
||||||
|
path = NIMSDK;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
4C14399B2EA635EB0037B074 /* SDKManager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4C14399A2EA635EB0037B074 /* NIMSDK */,
|
||||||
|
);
|
||||||
|
path = SDKManager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4C1E98BE2E9A3A540031AE79 /* Services */ = {
|
4C1E98BE2E9A3A540031AE79 /* Services */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -6504,6 +6533,12 @@
|
|||||||
4C1E98C22E9A45160031AE79 /* Common */ = {
|
4C1E98C22E9A45160031AE79 /* Common */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4C1439932EA630490037B074 /* EPConfigAPI.swift */,
|
||||||
|
4C14398F2EA62DD30037B074 /* EPConfigManager.swift */,
|
||||||
|
4C1439902EA62DD30037B074 /* EPConfigStorage.m */,
|
||||||
|
4C14398E2EA62D8C0037B074 /* EPConfigStorage.h */,
|
||||||
|
4C14398B2EA62D3C0037B074 /* EPClientAPIBridge.h */,
|
||||||
|
4C14398C2EA62D3C0037B074 /* EPClientAPIBridge.m */,
|
||||||
4C1E98C72E9A4DFD0031AE79 /* EPQCloudConfig.swift */,
|
4C1E98C72E9A4DFD0031AE79 /* EPQCloudConfig.swift */,
|
||||||
4C1E98C82E9A4DFD0031AE79 /* EPSDKManager.swift */,
|
4C1E98C82E9A4DFD0031AE79 /* EPSDKManager.swift */,
|
||||||
4C1E98C02E9A45160031AE79 /* EPImageUploader.swift */,
|
4C1E98C02E9A45160031AE79 /* EPImageUploader.swift */,
|
||||||
@@ -6532,6 +6567,18 @@
|
|||||||
path = GZIP;
|
path = GZIP;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4C59C0FC2EA2508F00D1F7BD /* NewMessage */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4C59C0F72EA2508F00D1F7BD /* EPBaseListViewController.swift */,
|
||||||
|
4C59C0F82EA2508F00D1F7BD /* EPFriendFollowingFans.swift */,
|
||||||
|
4C59C0F92EA2508F00D1F7BD /* EPMessageListVC.swift */,
|
||||||
|
4C59C0FA2EA2508F00D1F7BD /* EPMessageMainViewController.swift */,
|
||||||
|
4C59C0FB2EA2508F00D1F7BD /* EPMessageSegmentView.swift */,
|
||||||
|
);
|
||||||
|
path = NewMessage;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4C7989F02D195293006AE07B /* RoomMode */ = {
|
4C7989F02D195293006AE07B /* RoomMode */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -6937,37 +6984,6 @@
|
|||||||
path = MSRTL;
|
path = MSRTL;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
4CD19D7B2E9CDF980069DAA0 /* Model */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
4CD19D772E9CDF980069DAA0 /* XPShareInfoModel.h */,
|
|
||||||
4CD19D782E9CDF980069DAA0 /* XPShareInfoModel.m */,
|
|
||||||
4CD19D792E9CDF980069DAA0 /* XPShareItem.h */,
|
|
||||||
4CD19D7A2E9CDF980069DAA0 /* XPShareItem.m */,
|
|
||||||
);
|
|
||||||
path = Model;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4CD19D7E2E9CDF980069DAA0 /* View */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
4CD19D7C2E9CDF980069DAA0 /* XPShareItemCell.h */,
|
|
||||||
4CD19D7D2E9CDF980069DAA0 /* XPShareItemCell.m */,
|
|
||||||
);
|
|
||||||
path = View;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4CD19D812E9CDF980069DAA0 /* ShareView */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
4CD19D7B2E9CDF980069DAA0 /* Model */,
|
|
||||||
4CD19D7E2E9CDF980069DAA0 /* View */,
|
|
||||||
4CD19D7F2E9CDF980069DAA0 /* XPShareView.h */,
|
|
||||||
4CD19D802E9CDF980069DAA0 /* XPShareView.m */,
|
|
||||||
);
|
|
||||||
path = ShareView;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4CD19D842E9CDF980069DAA0 /* SVGA */ = {
|
4CD19D842E9CDF980069DAA0 /* SVGA */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -7120,7 +7136,6 @@
|
|||||||
4CD19C9A2E9CDF980069DAA0 /* Adbvertise */,
|
4CD19C9A2E9CDF980069DAA0 /* Adbvertise */,
|
||||||
4CD19D612E9CDF980069DAA0 /* InputView */,
|
4CD19D612E9CDF980069DAA0 /* InputView */,
|
||||||
4CD19D762E9CDF980069DAA0 /* MSRTL */,
|
4CD19D762E9CDF980069DAA0 /* MSRTL */,
|
||||||
4CD19D812E9CDF980069DAA0 /* ShareView */,
|
|
||||||
4CD19D842E9CDF980069DAA0 /* SVGA */,
|
4CD19D842E9CDF980069DAA0 /* SVGA */,
|
||||||
4CD19D872E9CDF980069DAA0 /* SwitchView */,
|
4CD19D872E9CDF980069DAA0 /* SwitchView */,
|
||||||
4CD19DA42E9CDF980069DAA0 /* TTPopup */,
|
4CD19DA42E9CDF980069DAA0 /* TTPopup */,
|
||||||
@@ -7965,7 +7980,7 @@
|
|||||||
23E56B3B2B03564B00C8DAC9 /* CoreTelephony.framework */,
|
23E56B3B2B03564B00C8DAC9 /* CoreTelephony.framework */,
|
||||||
E87888F32738C30E00BF1D57 /* StoreKit.framework */,
|
E87888F32738C30E00BF1D57 /* StoreKit.framework */,
|
||||||
186A531826FC591100D67B2C /* libresolv.tbd */,
|
186A531826FC591100D67B2C /* libresolv.tbd */,
|
||||||
CACF623970097D653132D69A /* Pods_YuMi.framework */,
|
3148BBD005110C1B57D04595 /* Pods_YuMi.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -7973,8 +7988,8 @@
|
|||||||
D09C770DC30B9BAAEAFC7945 /* Pods */ = {
|
D09C770DC30B9BAAEAFC7945 /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7DB00EC07F1D0ADFF900B38D /* Pods-YuMi.debug.xcconfig */,
|
ECF5B2AAE493057A3DBCCFAF /* Pods-YuMi.debug.xcconfig */,
|
||||||
B66633E061B1B34177CD011C /* Pods-YuMi.release.xcconfig */,
|
56B26C27109C1DD2002D0624 /* Pods-YuMi.release.xcconfig */,
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -8337,8 +8352,6 @@
|
|||||||
E81C279926EB64BA0031E639 /* Global */ = {
|
E81C279926EB64BA0031E639 /* Global */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4C0642862E97BDA300BAF413 /* GlobalEventManager.h */,
|
|
||||||
4C0642872E97BDA300BAF413 /* GlobalEventManager.m */,
|
|
||||||
4C84A9C92E602B1A002C10FC /* BuglyManager.h */,
|
4C84A9C92E602B1A002C10FC /* BuglyManager.h */,
|
||||||
4C84A9CA2E602B1A002C10FC /* BuglyManager.m */,
|
4C84A9CA2E602B1A002C10FC /* BuglyManager.m */,
|
||||||
E81C279A26EB65560031E639 /* YUMIMacroUitls.h */,
|
E81C279A26EB65560031E639 /* YUMIMacroUitls.h */,
|
||||||
@@ -10512,8 +10525,6 @@
|
|||||||
E896EFA12771AE9400AD2CC1 /* XPMineFriendViewController.m */,
|
E896EFA12771AE9400AD2CC1 /* XPMineFriendViewController.m */,
|
||||||
E84CBCDF28436D3C00D43221 /* XPMineContactViewController.h */,
|
E84CBCDF28436D3C00D43221 /* XPMineContactViewController.h */,
|
||||||
E84CBCE028436D3C00D43221 /* XPMineContactViewController.m */,
|
E84CBCE028436D3C00D43221 /* XPMineContactViewController.m */,
|
||||||
E8F65C1D286998C9009BB5B9 /* XPMineShareViewController.h */,
|
|
||||||
E8F65C1E286998C9009BB5B9 /* XPMineShareViewController.m */,
|
|
||||||
E84CBCE2284372D800D43221 /* XPRoomHalfMessageView.h */,
|
E84CBCE2284372D800D43221 /* XPRoomHalfMessageView.h */,
|
||||||
E84CBCE3284372D800D43221 /* XPRoomHalfMessageView.m */,
|
E84CBCE3284372D800D43221 /* XPRoomHalfMessageView.m */,
|
||||||
E8DAC5AA2858305A00012CFD /* XPRoomMessageBubbleView.h */,
|
E8DAC5AA2858305A00012CFD /* XPRoomMessageBubbleView.h */,
|
||||||
@@ -11634,14 +11645,14 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 189DD54226DE255600AB55B1 /* Build configuration list for PBXNativeTarget "YuMi" */;
|
buildConfigurationList = 189DD54226DE255600AB55B1 /* Build configuration list for PBXNativeTarget "YuMi" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
1865B406E358C680125F108D /* [CP] Check Pods Manifest.lock */,
|
1BE44CE1939801EC8D8A3B98 /* [CP] Check Pods Manifest.lock */,
|
||||||
189DD52526DE255300AB55B1 /* Sources */,
|
189DD52526DE255300AB55B1 /* Sources */,
|
||||||
189DD52626DE255300AB55B1 /* Frameworks */,
|
189DD52626DE255300AB55B1 /* Frameworks */,
|
||||||
189DD52726DE255300AB55B1 /* Resources */,
|
189DD52726DE255300AB55B1 /* Resources */,
|
||||||
8311720C3643AC2030B96510 /* [CP] Embed Pods Frameworks */,
|
|
||||||
4C25F8F9E2D1F501119C383D /* [CP] Copy Pods Resources */,
|
|
||||||
18E7B21326E8CD220064BC9B /* Embed Frameworks */,
|
18E7B21326E8CD220064BC9B /* Embed Frameworks */,
|
||||||
232C43E62AB0754700D4B2ED /* CopyFiles */,
|
232C43E62AB0754700D4B2ED /* CopyFiles */,
|
||||||
|
5D1CA1F69A65602D6A906867 /* [CP] Embed Pods Frameworks */,
|
||||||
|
86EC598DD301B1F442E90F99 /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -11937,7 +11948,7 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
1865B406E358C680125F108D /* [CP] Check Pods Manifest.lock */ = {
|
1BE44CE1939801EC8D8A3B98 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
@@ -11959,28 +11970,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";
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
4C25F8F9E2D1F501119C383D /* [CP] Copy Pods Resources */ = {
|
5D1CA1F69A65602D6A906867 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-input-files.xcfilelist",
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Copy Pods Resources";
|
|
||||||
outputFileListPaths = (
|
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-output-files.xcfilelist",
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
8311720C3643AC2030B96510 /* [CP] Embed Pods Frameworks */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
@@ -12001,6 +11991,27 @@
|
|||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-frameworks.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
|
86EC598DD301B1F442E90F99 /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-YuMi/Pods-YuMi-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@@ -12011,7 +12022,6 @@
|
|||||||
9BE01ADA289296B500B50299 /* XPDressUpShopPresenter.m in Sources */,
|
9BE01ADA289296B500B50299 /* XPDressUpShopPresenter.m in Sources */,
|
||||||
E8751E6628A6465A0056EF44 /* XPSailingRankSubView.m in Sources */,
|
E8751E6628A6465A0056EF44 /* XPSailingRankSubView.m in Sources */,
|
||||||
9B2EA7C32804052E00ED17BF /* AnchorPKMicroView.m in Sources */,
|
9B2EA7C32804052E00ED17BF /* AnchorPKMicroView.m in Sources */,
|
||||||
E8F65C1F286998C9009BB5B9 /* XPMineShareViewController.m in Sources */,
|
|
||||||
E85E7BAB2A4EC99300B6D00A /* XPMineChooseGiveGiftView.m in Sources */,
|
E85E7BAB2A4EC99300B6D00A /* XPMineChooseGiveGiftView.m in Sources */,
|
||||||
E85E7B3D2A4EB0D300B6D00A /* XPGuildIncomeDetailCollectionViewCell.m in Sources */,
|
E85E7B3D2A4EB0D300B6D00A /* XPGuildIncomeDetailCollectionViewCell.m in Sources */,
|
||||||
181D7F1B2726CE2A00B7C059 /* StageView.m in Sources */,
|
181D7F1B2726CE2A00B7C059 /* StageView.m in Sources */,
|
||||||
@@ -12116,13 +12126,10 @@
|
|||||||
E8412FA22779BE8F006E1101 /* XPRoomSettingViewController.m in Sources */,
|
E8412FA22779BE8F006E1101 /* XPRoomSettingViewController.m in Sources */,
|
||||||
E89D60BD271D647A001F8895 /* XPRoomPresenter.m in Sources */,
|
E89D60BD271D647A001F8895 /* XPRoomPresenter.m in Sources */,
|
||||||
4CD19E722E9CDF980069DAA0 /* UIButton+MSRTL.m in Sources */,
|
4CD19E722E9CDF980069DAA0 /* UIButton+MSRTL.m in Sources */,
|
||||||
4CD19E732E9CDF980069DAA0 /* XPShareItem.m in Sources */,
|
|
||||||
4CD19E742E9CDF980069DAA0 /* TTNewAlertView.m in Sources */,
|
4CD19E742E9CDF980069DAA0 /* TTNewAlertView.m in Sources */,
|
||||||
4CD19E752E9CDF980069DAA0 /* QPhotoImageModel.m in Sources */,
|
4CD19E752E9CDF980069DAA0 /* QPhotoImageModel.m in Sources */,
|
||||||
4CD19E762E9CDF980069DAA0 /* XPShareInfoModel.m in Sources */,
|
|
||||||
4CD19E772E9CDF980069DAA0 /* UITextView+MSRTL.m in Sources */,
|
4CD19E772E9CDF980069DAA0 /* UITextView+MSRTL.m in Sources */,
|
||||||
4CD19E782E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m in Sources */,
|
4CD19E782E9CDF980069DAA0 /* NSMutableAttributedString+MSRTL.m in Sources */,
|
||||||
4CD19E792E9CDF980069DAA0 /* XPShareItemCell.m in Sources */,
|
|
||||||
4CD19E7A2E9CDF980069DAA0 /* SexAgeLabel.m in Sources */,
|
4CD19E7A2E9CDF980069DAA0 /* SexAgeLabel.m in Sources */,
|
||||||
4CD19E7B2E9CDF980069DAA0 /* QKeyboardManager.m in Sources */,
|
4CD19E7B2E9CDF980069DAA0 /* QKeyboardManager.m in Sources */,
|
||||||
4CD19E7C2E9CDF980069DAA0 /* TTPopupService.m in Sources */,
|
4CD19E7C2E9CDF980069DAA0 /* TTPopupService.m in Sources */,
|
||||||
@@ -12151,7 +12158,6 @@
|
|||||||
4CD19E932E9CDF980069DAA0 /* NetImageConfig.m in Sources */,
|
4CD19E932E9CDF980069DAA0 /* NetImageConfig.m in Sources */,
|
||||||
4CD19E942E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m in Sources */,
|
4CD19E942E9CDF980069DAA0 /* UIButton+EnlargeTouchArea.m in Sources */,
|
||||||
4CD19E952E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m in Sources */,
|
4CD19E952E9CDF980069DAA0 /* MSBaseRTLFlowLayout.m in Sources */,
|
||||||
4CD19E962E9CDF980069DAA0 /* XPShareView.m in Sources */,
|
|
||||||
4CD19E972E9CDF980069DAA0 /* QEmotion.m in Sources */,
|
4CD19E972E9CDF980069DAA0 /* QEmotion.m in Sources */,
|
||||||
4CD19E982E9CDF980069DAA0 /* AdvertiseModel.m in Sources */,
|
4CD19E982E9CDF980069DAA0 /* AdvertiseModel.m in Sources */,
|
||||||
4CD19E992E9CDF980069DAA0 /* XPSVGAPlayer.m in Sources */,
|
4CD19E992E9CDF980069DAA0 /* XPSVGAPlayer.m in Sources */,
|
||||||
@@ -12562,6 +12568,9 @@
|
|||||||
4C1A141B2DCB4AB700B6D0CA /* ChatFaceVo.m in Sources */,
|
4C1A141B2DCB4AB700B6D0CA /* ChatFaceVo.m in Sources */,
|
||||||
E8664ED627E434D5000171BA /* XPRoomPKRecordViewController.m in Sources */,
|
E8664ED627E434D5000171BA /* XPRoomPKRecordViewController.m in Sources */,
|
||||||
E87E914E2796678D00A7B3F2 /* XPMineDressEmptyTableViewCell.m in Sources */,
|
E87E914E2796678D00A7B3F2 /* XPMineDressEmptyTableViewCell.m in Sources */,
|
||||||
|
4C14398D2EA62D3C0037B074 /* EPClientAPIBridge.m in Sources */,
|
||||||
|
4C14399C2EA635EB0037B074 /* EPNIMConfig.m in Sources */,
|
||||||
|
4C14399D2EA635EB0037B074 /* EPNIMManager.m in Sources */,
|
||||||
232EBBFF2BD7A25500E8CEAD /* MSParamsDecode.m in Sources */,
|
232EBBFF2BD7A25500E8CEAD /* MSParamsDecode.m in Sources */,
|
||||||
9B7D804D27537950003DAC0C /* MessageCell.m in Sources */,
|
9B7D804D27537950003DAC0C /* MessageCell.m in Sources */,
|
||||||
23E9EAA62A84C97C00B792F2 /* XPMineUserInfoTagVC.m in Sources */,
|
23E9EAA62A84C97C00B792F2 /* XPMineUserInfoTagVC.m in Sources */,
|
||||||
@@ -12885,6 +12894,7 @@
|
|||||||
E8751E5928A62A390056EF44 /* Api+Sailing.m in Sources */,
|
E8751E5928A62A390056EF44 /* Api+Sailing.m in Sources */,
|
||||||
E897ABFF28AF39B4003B3587 /* XPSailingAnimationView.m in Sources */,
|
E897ABFF28AF39B4003B3587 /* XPSailingAnimationView.m in Sources */,
|
||||||
E885D5362977CE28004DC088 /* SessionSettingModel.m in Sources */,
|
E885D5362977CE28004DC088 /* SessionSettingModel.m in Sources */,
|
||||||
|
4C1439942EA630490037B074 /* EPConfigAPI.swift in Sources */,
|
||||||
9BE01AE128937DBC00B50299 /* XPDressUpShopCardViewController.m in Sources */,
|
9BE01AE128937DBC00B50299 /* XPDressUpShopCardViewController.m in Sources */,
|
||||||
E896EFA22771AE9400AD2CC1 /* XPMineFriendViewController.m in Sources */,
|
E896EFA22771AE9400AD2CC1 /* XPMineFriendViewController.m in Sources */,
|
||||||
1427218D29A75F6F00C7C423 /* HTTPRedirectResponse.m in Sources */,
|
1427218D29A75F6F00C7C423 /* HTTPRedirectResponse.m in Sources */,
|
||||||
@@ -12962,7 +12972,6 @@
|
|||||||
E85E7B162A4EB0D200B6D00A /* GuildInfoModel.m in Sources */,
|
E85E7B162A4EB0D200B6D00A /* GuildInfoModel.m in Sources */,
|
||||||
E885D53C2977FBFD004DC088 /* MessageTimeView.m in Sources */,
|
E885D53C2977FBFD004DC088 /* MessageTimeView.m in Sources */,
|
||||||
E8AC723A26F49AAE007D6E91 /* XPMineNotifyStatus.m in Sources */,
|
E8AC723A26F49AAE007D6E91 /* XPMineNotifyStatus.m in Sources */,
|
||||||
4C0642882E97BDA300BAF413 /* GlobalEventManager.m in Sources */,
|
|
||||||
E87DF50E2A42CF15009C1185 /* HomeLiveRoomModel.m in Sources */,
|
E87DF50E2A42CF15009C1185 /* HomeLiveRoomModel.m in Sources */,
|
||||||
E8F6135F291E274E00E12650 /* NSArray+Safe.m in Sources */,
|
E8F6135F291E274E00E12650 /* NSArray+Safe.m in Sources */,
|
||||||
4C44BD5D2D151B5C00F321FA /* RoomSideMenu.m in Sources */,
|
4C44BD5D2D151B5C00F321FA /* RoomSideMenu.m in Sources */,
|
||||||
@@ -13068,6 +13077,11 @@
|
|||||||
E87AE7FC277AAC450037823A /* XPRoomTagPresenter.m in Sources */,
|
E87AE7FC277AAC450037823A /* XPRoomTagPresenter.m in Sources */,
|
||||||
E85E7B652A4EC35A00B6D00A /* XPExchangeDiamondsModel.m in Sources */,
|
E85E7B652A4EC35A00B6D00A /* XPExchangeDiamondsModel.m in Sources */,
|
||||||
E878894C273A607C00BF1D57 /* XPGiftUserCollectionViewCell.m in Sources */,
|
E878894C273A607C00BF1D57 /* XPGiftUserCollectionViewCell.m in Sources */,
|
||||||
|
4C59C0FD2EA2508F00D1F7BD /* EPFriendFollowingFans.swift in Sources */,
|
||||||
|
4C59C0FE2EA2508F00D1F7BD /* EPMessageSegmentView.swift in Sources */,
|
||||||
|
4C59C0FF2EA2508F00D1F7BD /* EPMessageMainViewController.swift in Sources */,
|
||||||
|
4C59C1002EA2508F00D1F7BD /* EPBaseListViewController.swift in Sources */,
|
||||||
|
4C59C1012EA2508F00D1F7BD /* EPMessageListVC.swift in Sources */,
|
||||||
23E9E9A72A80F1C300B792F2 /* XPNewMineHallIncomeVC.m in Sources */,
|
23E9E9A72A80F1C300B792F2 /* XPNewMineHallIncomeVC.m in Sources */,
|
||||||
2331C1712A5EB71000E1D940 /* XPNobleCenterTableHeadView.m in Sources */,
|
2331C1712A5EB71000E1D940 /* XPNobleCenterTableHeadView.m in Sources */,
|
||||||
181D7F212727D9DB00B7C059 /* SocialStageView.m in Sources */,
|
181D7F212727D9DB00B7C059 /* SocialStageView.m in Sources */,
|
||||||
@@ -13140,6 +13154,8 @@
|
|||||||
2331C1742A5EB71000E1D940 /* XPNobleCenterResidueView.m in Sources */,
|
2331C1742A5EB71000E1D940 /* XPNobleCenterResidueView.m in Sources */,
|
||||||
4C0A5B842E02675300955219 /* MedalsCollectionViewCell.m in Sources */,
|
4C0A5B842E02675300955219 /* MedalsCollectionViewCell.m in Sources */,
|
||||||
E80E2377299A47F60013FD40 /* AESUtils.m in Sources */,
|
E80E2377299A47F60013FD40 /* AESUtils.m in Sources */,
|
||||||
|
4C1439912EA62DD30037B074 /* EPConfigManager.swift in Sources */,
|
||||||
|
4C1439922EA62DD30037B074 /* EPConfigStorage.m in Sources */,
|
||||||
E81060E229876E9100B772F0 /* MessageImageModel.m in Sources */,
|
E81060E229876E9100B772F0 /* MessageImageModel.m in Sources */,
|
||||||
E839533F276A0CDB00CF2F24 /* XPMineNameplateTableViewCell.m in Sources */,
|
E839533F276A0CDB00CF2F24 /* XPMineNameplateTableViewCell.m in Sources */,
|
||||||
E80E09AE2A41336500CD2BE7 /* XPWebViewNavView.m in Sources */,
|
E80E09AE2A41336500CD2BE7 /* XPWebViewNavView.m in Sources */,
|
||||||
@@ -13457,6 +13473,7 @@
|
|||||||
189DD54026DE255600AB55B1 /* Debug */ = {
|
189DD54026DE255600AB55B1 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -13516,6 +13533,7 @@
|
|||||||
189DD54126DE255600AB55B1 /* Release */ = {
|
189DD54126DE255600AB55B1 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -13568,7 +13586,7 @@
|
|||||||
};
|
};
|
||||||
189DD54326DE255600AB55B1 /* Debug */ = {
|
189DD54326DE255600AB55B1 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7DB00EC07F1D0ADFF900B38D /* Pods-YuMi.debug.xcconfig */;
|
baseConfigurationReference = ECF5B2AAE493057A3DBCCFAF /* Pods-YuMi.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
APP_DISPLAY_NAME = "E-Party DEBUG";
|
APP_DISPLAY_NAME = "E-Party DEBUG";
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
@@ -13583,12 +13601,8 @@
|
|||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/YuMi/Main/RTC/Library",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Modules/YMRTC/Library",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Resources/Client",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Library",
|
"$(PROJECT_DIR)/YuMi/Library",
|
||||||
"$(PROJECT_DIR)/YuMi/Tools",
|
"$(PROJECT_DIR)/YuMi/Tools",
|
||||||
"$(PROJECT_DIR)/YuMi/Tools/TencentOpenApiSDK",
|
|
||||||
);
|
);
|
||||||
GCC_PREFIX_HEADER = YuMi/Structure/PrefixHeader.pch;
|
GCC_PREFIX_HEADER = YuMi/Structure/PrefixHeader.pch;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
@@ -13628,10 +13642,6 @@
|
|||||||
"\"AVKit\"",
|
"\"AVKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"Accelerate\"",
|
"\"Accelerate\"",
|
||||||
"\"-framework\"",
|
|
||||||
"\"AppAuth\"",
|
|
||||||
"-framework",
|
|
||||||
"\"AppleAccountConnector\"",
|
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"AssetsLibrary\"",
|
"\"AssetsLibrary\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
@@ -13661,16 +13671,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"CoreText\"",
|
"\"CoreText\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"FBAEMKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKCoreKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKCoreKit_Basics\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKLoginKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKShareKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FFPopup\"",
|
"\"FFPopup\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"FLAnimatedImage\"",
|
"\"FLAnimatedImage\"",
|
||||||
@@ -13679,12 +13679,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"GKCycleScrollView\"",
|
"\"GKCycleScrollView\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"GTMAppAuth\"",
|
|
||||||
"-framework",
|
|
||||||
"\"GTMSessionFetcher\"",
|
|
||||||
"-framework",
|
|
||||||
"\"GoogleSignIn\"",
|
|
||||||
"-framework",
|
|
||||||
"\"IQKeyboardManager\"",
|
"\"IQKeyboardManager\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ImageIO\"",
|
"\"ImageIO\"",
|
||||||
@@ -13703,8 +13697,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"MJRefresh\"",
|
"\"MJRefresh\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"MOBFoundation\"",
|
|
||||||
"-framework",
|
|
||||||
"\"MarqueeLabel\"",
|
"\"MarqueeLabel\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"Masonry\"",
|
"\"Masonry\"",
|
||||||
@@ -13715,8 +13707,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"MetalPerformanceShaders\"",
|
"\"MetalPerformanceShaders\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"MobLinkPro\"",
|
|
||||||
"-framework",
|
|
||||||
"\"MobileCoreServices\"",
|
"\"MobileCoreServices\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"NIMNOS\"",
|
"\"NIMNOS\"",
|
||||||
@@ -13737,8 +13727,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"QGVAPlayer\"",
|
"\"QGVAPlayer\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"QimeiSDK\"",
|
|
||||||
"-framework",
|
|
||||||
"\"QuartzCore\"",
|
"\"QuartzCore\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ReactiveObjC\"",
|
"\"ReactiveObjC\"",
|
||||||
@@ -13763,12 +13751,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"Security\"",
|
"\"Security\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ShareSDK\"",
|
|
||||||
"-framework",
|
|
||||||
"\"ShareSDKConnector\"",
|
|
||||||
"-framework",
|
|
||||||
"\"ShareSDKExtension\"",
|
|
||||||
"-framework",
|
|
||||||
"\"StoreKit\"",
|
"\"StoreKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"SystemConfiguration\"",
|
"\"SystemConfiguration\"",
|
||||||
@@ -13787,10 +13769,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"UIKit\"",
|
"\"UIKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"UMCommon\"",
|
|
||||||
"-framework",
|
|
||||||
"\"UMDevice\"",
|
|
||||||
"-framework",
|
|
||||||
"\"VideoToolbox\"",
|
"\"VideoToolbox\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"YXArtemis\"",
|
"\"YXArtemis\"",
|
||||||
@@ -13830,7 +13808,7 @@
|
|||||||
};
|
};
|
||||||
189DD54426DE255600AB55B1 /* Release */ = {
|
189DD54426DE255600AB55B1 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = B66633E061B1B34177CD011C /* Pods-YuMi.release.xcconfig */;
|
baseConfigurationReference = 56B26C27109C1DD2002D0624 /* Pods-YuMi.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
APP_DISPLAY_NAME = "E-Party";
|
APP_DISPLAY_NAME = "E-Party";
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
@@ -13844,12 +13822,8 @@
|
|||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/YuMi/Main/RTC/Library",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Modules/YMRTC/Library",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Resources/Client",
|
|
||||||
"$(PROJECT_DIR)/YuMi/Library",
|
"$(PROJECT_DIR)/YuMi/Library",
|
||||||
"$(PROJECT_DIR)/YuMi/Tools",
|
"$(PROJECT_DIR)/YuMi/Tools",
|
||||||
"$(PROJECT_DIR)/YuMi/Tools/TencentOpenApiSDK",
|
|
||||||
);
|
);
|
||||||
GCC_PREFIX_HEADER = YuMi/Structure/PrefixHeader.pch;
|
GCC_PREFIX_HEADER = YuMi/Structure/PrefixHeader.pch;
|
||||||
INFOPLIST_FILE = YuMi/Info.plist;
|
INFOPLIST_FILE = YuMi/Info.plist;
|
||||||
@@ -13878,10 +13852,6 @@
|
|||||||
"\"AVKit\"",
|
"\"AVKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"Accelerate\"",
|
"\"Accelerate\"",
|
||||||
"\"-framework\"",
|
|
||||||
"\"AppAuth\"",
|
|
||||||
"-framework",
|
|
||||||
"\"AppleAccountConnector\"",
|
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"AssetsLibrary\"",
|
"\"AssetsLibrary\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
@@ -13911,16 +13881,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"CoreText\"",
|
"\"CoreText\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"FBAEMKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKCoreKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKCoreKit_Basics\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKLoginKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FBSDKShareKit\"",
|
|
||||||
"-framework",
|
|
||||||
"\"FFPopup\"",
|
"\"FFPopup\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"FLAnimatedImage\"",
|
"\"FLAnimatedImage\"",
|
||||||
@@ -13929,12 +13889,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"GKCycleScrollView\"",
|
"\"GKCycleScrollView\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"GTMAppAuth\"",
|
|
||||||
"-framework",
|
|
||||||
"\"GTMSessionFetcher\"",
|
|
||||||
"-framework",
|
|
||||||
"\"GoogleSignIn\"",
|
|
||||||
"-framework",
|
|
||||||
"\"IQKeyboardManager\"",
|
"\"IQKeyboardManager\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ImageIO\"",
|
"\"ImageIO\"",
|
||||||
@@ -13953,8 +13907,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"MJRefresh\"",
|
"\"MJRefresh\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"MOBFoundation\"",
|
|
||||||
"-framework",
|
|
||||||
"\"MarqueeLabel\"",
|
"\"MarqueeLabel\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"Masonry\"",
|
"\"Masonry\"",
|
||||||
@@ -13965,8 +13917,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"MetalPerformanceShaders\"",
|
"\"MetalPerformanceShaders\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"MobLinkPro\"",
|
|
||||||
"-framework",
|
|
||||||
"\"MobileCoreServices\"",
|
"\"MobileCoreServices\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"NIMNOS\"",
|
"\"NIMNOS\"",
|
||||||
@@ -13987,8 +13937,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"QGVAPlayer\"",
|
"\"QGVAPlayer\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"QimeiSDK\"",
|
|
||||||
"-framework",
|
|
||||||
"\"QuartzCore\"",
|
"\"QuartzCore\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ReactiveObjC\"",
|
"\"ReactiveObjC\"",
|
||||||
@@ -14013,12 +13961,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"Security\"",
|
"\"Security\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"ShareSDK\"",
|
|
||||||
"-framework",
|
|
||||||
"\"ShareSDKConnector\"",
|
|
||||||
"-framework",
|
|
||||||
"\"ShareSDKExtension\"",
|
|
||||||
"-framework",
|
|
||||||
"\"StoreKit\"",
|
"\"StoreKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"SystemConfiguration\"",
|
"\"SystemConfiguration\"",
|
||||||
@@ -14037,10 +13979,6 @@
|
|||||||
"-framework",
|
"-framework",
|
||||||
"\"UIKit\"",
|
"\"UIKit\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"UMCommon\"",
|
|
||||||
"-framework",
|
|
||||||
"\"UMDevice\"",
|
|
||||||
"-framework",
|
|
||||||
"\"VideoToolbox\"",
|
"\"VideoToolbox\"",
|
||||||
"-framework",
|
"-framework",
|
||||||
"\"YXArtemis\"",
|
"\"YXArtemis\"",
|
||||||
|
@@ -8,10 +8,8 @@
|
|||||||
#import "AppDelegate+ThirdConfig.h"
|
#import "AppDelegate+ThirdConfig.h"
|
||||||
///Third
|
///Third
|
||||||
#import <NIMSDK/NIMSDK.h>
|
#import <NIMSDK/NIMSDK.h>
|
||||||
#import <ShareSDK/ShareSDK.h>
|
|
||||||
#import <UserNotifications/UNUserNotificationCenter.h>
|
#import <UserNotifications/UNUserNotificationCenter.h>
|
||||||
#import <UserNotifications/UserNotifications.h>
|
#import <UserNotifications/UserNotifications.h>
|
||||||
#import <MOBFoundation/MobSDK+Privacy.h>
|
|
||||||
///Tool
|
///Tool
|
||||||
#import "YUMIConstant.h"
|
#import "YUMIConstant.h"
|
||||||
#import "CustomAttachmentDecoder.h"
|
#import "CustomAttachmentDecoder.h"
|
||||||
@@ -40,7 +38,6 @@ UIKIT_EXTERN NSString * adImageName;
|
|||||||
/// 初始化一些第三方配置
|
/// 初始化一些第三方配置
|
||||||
- (void)initThirdConfig{
|
- (void)initThirdConfig{
|
||||||
[self setLanguage];
|
[self setLanguage];
|
||||||
[self configShareSDK];
|
|
||||||
[self configNIMSDK];
|
[self configNIMSDK];
|
||||||
[self configBugly];
|
[self configBugly];
|
||||||
[self registerNot];
|
[self registerNot];
|
||||||
@@ -123,24 +120,6 @@ UIKIT_EXTERN NSString * adImageName;
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)configShareSDK {
|
|
||||||
|
|
||||||
// [PILineLoginManager registerLine];
|
|
||||||
|
|
||||||
[ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) {
|
|
||||||
///faceBook
|
|
||||||
// [platformsRegister setupFacebookWithAppkey:@"1266232494209868" appSecret:@"c9b170b383f8be9cdf118823b8632821" displayName:YMLocalizedString(@"AppDelegate_ThirdConfig0")];
|
|
||||||
[platformsRegister setupLineAuthType:SSDKAuthorizeTypeBoth];
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSString *isUpload = [[NSUserDefaults standardUserDefaults]valueForKey:@"kMobLinkUploadPrivacy"];
|
|
||||||
if (isUpload == nil){
|
|
||||||
[MobSDK uploadPrivacyPermissionStatus:YES onResult:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setValue:@"YES" forKey:@"kMobLinkUploadPrivacy"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - 表情
|
#pragma mark - 表情
|
||||||
- (void)initEmojiData {
|
- (void)initEmojiData {
|
||||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||||
|
@@ -6,15 +6,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <CoreData/CoreData.h>
|
|
||||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
@property (strong, nonatomic) UIWindow *window;
|
@property (strong, nonatomic) UIWindow *window;
|
||||||
@property(nonatomic,strong,readonly)NSManagedObjectContext *managedObjectContext;
|
|
||||||
@property(nonatomic,strong,readonly)NSManagedObjectModel *managedObjectModel;
|
|
||||||
@property(nonatomic,strong,readonly)NSPersistentStoreCoordinator *persistentStoreCoordinator;
|
|
||||||
|
|
||||||
- (void)saveContext;
|
|
||||||
- (NSURL *)applicationDocumentsDirectory;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -7,30 +7,20 @@
|
|||||||
|
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import <UMCommon/UMCommon.h>
|
|
||||||
#import <MobLinkPro/MobLink.h>
|
|
||||||
#import <MobLinkPro/MLSDKScene.h>
|
|
||||||
#import "TabbarViewController.h"
|
|
||||||
#import "BaseNavigationController.h"
|
#import "BaseNavigationController.h"
|
||||||
#import "AppDelegate+ThirdConfig.h"
|
|
||||||
#import <NIMSDK/NIMSDK.h>
|
|
||||||
#import <AppTrackingTransparency/AppTrackingTransparency.h>
|
#import <AppTrackingTransparency/AppTrackingTransparency.h>
|
||||||
#import "ClientConfig.h"
|
#import "ClientConfig.h"
|
||||||
#import <GoogleSignIn/GoogleSignIn.h>
|
|
||||||
#import <GoogleSignIn/GoogleSignIn.h>
|
|
||||||
#import "LoginViewController.h"
|
|
||||||
#import "AccountModel.h"
|
#import "AccountModel.h"
|
||||||
#import "YuMi-swift.h"
|
#import "YuMi-swift.h"
|
||||||
#import "SessionViewController.h"
|
|
||||||
#import "LoginFullInfoViewController.h"
|
|
||||||
#import "UIView+VAP.h"
|
#import "UIView+VAP.h"
|
||||||
#import "SocialShareManager.h"
|
#import "SocialShareManager.h"
|
||||||
#import "EPSignatureColorGuideView.h"
|
#import "EPSignatureColorGuideView.h"
|
||||||
#import "EPEmotionColorStorage.h"
|
#import "EPEmotionColorStorage.h"
|
||||||
|
#import "EPNIMManager.h"
|
||||||
|
|
||||||
UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||||
|
|
||||||
@interface AppDelegate ()<IMLSDKRestoreDelegate>
|
@interface AppDelegate ()
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -65,63 +55,51 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
|
|||||||
self.window.rootViewController = launchScreenVC;
|
self.window.rootViewController = launchScreenVC;
|
||||||
[self.window makeKeyAndVisible];
|
[self.window makeKeyAndVisible];
|
||||||
|
|
||||||
[VAPView registerHWDLog:qg_VAP_Logger_handler];
|
[self setupUIAppearance];
|
||||||
|
|
||||||
///初始化一些 sdk配置
|
[self setupConfig];
|
||||||
[self initThirdConfig];
|
|
||||||
[self initUM:application launchOptions:launchOptions];
|
|
||||||
|
|
||||||
@kWeakify(self);
|
|
||||||
[[ClientConfig shareConfig] clientConfig:^{
|
|
||||||
@kStrongify(self);
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[self loadMainPage];
|
|
||||||
[self setupLaunchADView];
|
|
||||||
});
|
|
||||||
}];
|
|
||||||
|
|
||||||
if (@available(iOS 15, *)) {
|
|
||||||
[[UITableView appearance] setSectionHeaderTopPadding:0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Helper Methods
|
- (void)setupUIAppearance {
|
||||||
|
if (@available(iOS 15, *)) {
|
||||||
/// 获取 keyWindow(iOS 13+ 兼容)
|
[[UITableView appearance] setSectionHeaderTopPadding:0];
|
||||||
- (UIWindow *)getKeyWindow {
|
|
||||||
// iOS 13+ 使用 connectedScenes 获取 window
|
|
||||||
if (@available(iOS 13.0, *)) {
|
|
||||||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
|
||||||
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
|
||||||
for (UIWindow *window in scene.windows) {
|
|
||||||
if (window.isKeyWindow) {
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 如果没有 keyWindow,返回第一个 window
|
|
||||||
return scene.windows.firstObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
- (void)setupConfig {
|
||||||
#pragma clang diagnostic push
|
// 冷启动配置:client/init → client/config,由 EPConfigManager 统一调度
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
@kWeakify(self);
|
||||||
return [UIApplication sharedApplication].keyWindow;
|
[[EPConfigManager shared] startColdBootWithOnSuccess:^{
|
||||||
#pragma clang diagnostic pop
|
@kStrongify(self);
|
||||||
}
|
if (!self) return;
|
||||||
|
|
||||||
- (void)initUM:(UIApplication *)application
|
// 配置成功,初始化 NIMSDK 并进入主页面
|
||||||
launchOptions:(NSDictionary *)launchOptions {
|
@kWeakify(self);
|
||||||
// 只有同意过了隐私协议 才初始化
|
[[EPNIMManager sharedManager] initializeWithCompletion:^(NSError * _Nullable error) {
|
||||||
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"kYouMinumbernnagna"]) {
|
@kStrongify(self);
|
||||||
///初始化友盟
|
if (!self) return;
|
||||||
[UMConfigure initWithAppkey:@"6434c6dfd64e686139618269"
|
|
||||||
channel:@"appstore"];
|
if (error) {
|
||||||
|
NSLog(@"[AppDelegate] NIMSDK 初始化失败: %@", error);
|
||||||
|
} else {
|
||||||
|
NSLog(@"[AppDelegate] NIMSDK 初始化成功");
|
||||||
}
|
}
|
||||||
[MobLink setDelegate:self];
|
// 无论 NIMSDK 是否成功,都进入主页面
|
||||||
|
[self loadMainPage];
|
||||||
|
}];
|
||||||
|
} onFailure:^(NSString * _Nonnull errorMessage) {
|
||||||
|
@kStrongify(self);
|
||||||
|
if (!self) return;
|
||||||
|
|
||||||
|
// 配置失败,显示错误提示
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:YMLocalizedString(@"提示")
|
||||||
|
message:errorMessage
|
||||||
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:YMLocalizedString(@"确定") style:UIAlertActionStyleDefault handler:nil]];
|
||||||
|
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadMainPage {
|
- (void)loadMainPage {
|
||||||
@@ -139,17 +117,21 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ClientConfig shareConfig] clientInit];
|
[self ignoreVAPLog];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)ignoreVAPLog {
|
||||||
|
[VAPView registerHWDLog:qg_VAP_Logger_handler];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查并显示专属颜色引导页
|
/// 检查并显示专属颜色引导页
|
||||||
- (void)checkAndShowSignatureColorGuide {
|
- (void)checkAndShowSignatureColorGuide {
|
||||||
UIWindow *keyWindow = [self getKeyWindow];
|
UIWindow *keyWindow = kWindow;
|
||||||
if (!keyWindow) return;
|
if (!keyWindow) return;
|
||||||
|
|
||||||
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
|
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
|
||||||
|
|
||||||
#if DEBUG
|
#if 0
|
||||||
// Debug 环境:总是显示引导页
|
// Debug 环境:总是显示引导页
|
||||||
NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO");
|
NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO");
|
||||||
|
|
||||||
@@ -191,47 +173,21 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
|
|||||||
[[BaseNavigationController alloc] initWithRootViewController:lvc];
|
[[BaseNavigationController alloc] initWithRootViewController:lvc];
|
||||||
navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
|
navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
self.window.rootViewController = navigationController;
|
self.window.rootViewController = navigationController;
|
||||||
|
|
||||||
// 旧代码保留注释(便于回滚)
|
|
||||||
// LoginViewController *lvc = [[LoginViewController alloc] init];
|
|
||||||
// BaseNavigationController * navigationController = [[BaseNavigationController alloc] initWithRootViewController:lvc];
|
|
||||||
// navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
||||||
// self.window.rootViewController = navigationController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)toHomeTabbarPage {
|
- (void)toHomeTabbarPage {
|
||||||
// ========== 白牌版本:使用新的 EPTabBarController ==========
|
|
||||||
EPTabBarController *epTabBar = [EPTabBarController create];
|
EPTabBarController *epTabBar = [EPTabBarController create];
|
||||||
[epTabBar refreshTabBarWithIsLogin:YES];
|
[epTabBar refreshTabBarWithIsLogin:YES];
|
||||||
|
|
||||||
UIWindow *window = [self getKeyWindow];
|
UIWindow *window = kWindow;
|
||||||
if (window) {
|
if (window) {
|
||||||
window.rootViewController = epTabBar;
|
window.rootViewController = epTabBar;
|
||||||
[window makeKeyAndVisible];
|
[window makeKeyAndVisible];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"[AppDelegate] 自动登录后已切换到白牌 TabBar:EPTabBarController");
|
|
||||||
|
|
||||||
// ========== 原代码(已注释) ==========
|
|
||||||
/*
|
|
||||||
TabbarViewController *vc = [[TabbarViewController alloc] init];
|
|
||||||
BaseNavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:vc];
|
|
||||||
self.window.rootViewController = navigationController;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)IMLSDKWillRestoreScene:(MLSDKScene *)scene
|
|
||||||
Restore:(void (^)(BOOL, RestoreStyle))restoreHandler {
|
|
||||||
NSString *inviteCode = scene.params[@"inviteCode"];
|
|
||||||
if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
|
|
||||||
ClientConfig *config = [ClientConfig shareConfig];
|
|
||||||
config.inviteCode = inviteCode;
|
|
||||||
}
|
|
||||||
restoreHandler(YES, MLDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||||
NSInteger count = [NIMSDK sharedSDK].conversationManager.allUnreadCount;
|
NSInteger count = [[EPNIMManager sharedManager] allUnreadCount];
|
||||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
|
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,8 +223,8 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
|
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
|
||||||
// 上传devicetoken至云信服务器。
|
// 上传 deviceToken 至云信服务器(统一走 EPNIMManager)
|
||||||
[[NIMSDK sharedSDK] updateApnsToken:deviceToken ];
|
[[EPNIMManager sharedManager] updateApnsToken:deviceToken];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
|
||||||
@@ -300,124 +256,9 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
|
|||||||
|
|
||||||
///URL Scheme跳转
|
///URL Scheme跳转
|
||||||
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
|
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
|
||||||
|
// TODO: 在 EPTabbar 中补充 [SocialShareManager sharedManager] setHandleJumpToRoom
|
||||||
[[SocialShareManager sharedManager] handleURL:url];
|
[[SocialShareManager sharedManager] handleURL:url];
|
||||||
|
return YES;
|
||||||
return [GIDSignIn.sharedInstance handleURL:url];
|
|
||||||
}
|
|
||||||
|
|
||||||
//- (void)__oldApplicationOpenURLMethod:(NSURL *)url {
|
|
||||||
// NSString *text = [url query];
|
|
||||||
// if(text.length){
|
|
||||||
// NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
|
|
||||||
// NSArray *paramArray = [text componentsSeparatedByString:@"&"];
|
|
||||||
// for (NSString *param in paramArray) {
|
|
||||||
// if (param && param.length) {
|
|
||||||
// NSArray *parArr = [param componentsSeparatedByString:@"="];
|
|
||||||
// if (parArr.count == 2) {
|
|
||||||
// [paramsDict setObject:parArr[1] forKey:parArr[0]];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if(paramsDict[@"type"] != nil){
|
|
||||||
// NSInteger type = [paramsDict[@"type"] integerValue];
|
|
||||||
// if (type == 2) {
|
|
||||||
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
|
||||||
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"uid":uid}];
|
|
||||||
// ClientConfig *config = [ClientConfig shareConfig];
|
|
||||||
// config.roomId = uid;
|
|
||||||
// }else if(type == 7){
|
|
||||||
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
|
||||||
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":uid}];
|
|
||||||
// ClientConfig *config = [ClientConfig shareConfig];
|
|
||||||
// config.chatId = uid;
|
|
||||||
// }else if (type == 8){
|
|
||||||
// NSString *inviteCode = paramsDict[@"inviteCode"];
|
|
||||||
// if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
|
|
||||||
// ClientConfig *config = [ClientConfig shareConfig];
|
|
||||||
// config.inviteCode = inviteCode;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//// return YES;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
#pragma mark - Core Data stack
|
|
||||||
@synthesize managedObjectContext = _managedObjectContext;
|
|
||||||
@synthesize managedObjectModel = _managedObjectModel;
|
|
||||||
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
|
|
||||||
|
|
||||||
-(NSURL *)applicationDocumentsDirectory{
|
|
||||||
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSManagedObjectModel *)managedObjectModel {
|
|
||||||
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
|
|
||||||
if (_managedObjectModel != nil) {
|
|
||||||
return _managedObjectModel;
|
|
||||||
}
|
|
||||||
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"_1_______" withExtension:@"momd"];
|
|
||||||
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
|
|
||||||
return _managedObjectModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
|
|
||||||
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
|
|
||||||
if (_persistentStoreCoordinator != nil) {
|
|
||||||
return _persistentStoreCoordinator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the coordinator and store
|
|
||||||
|
|
||||||
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
|
|
||||||
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"_1_______.sqlite"];
|
|
||||||
NSError *error = nil;
|
|
||||||
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
|
|
||||||
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
|
|
||||||
// Report any error we got.
|
|
||||||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
|
||||||
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
|
|
||||||
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
|
|
||||||
dict[NSUnderlyingErrorKey] = error;
|
|
||||||
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
|
|
||||||
// Replace this with code to handle the error appropriately.
|
|
||||||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
|
||||||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _persistentStoreCoordinator;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (NSManagedObjectContext *)managedObjectContext {
|
|
||||||
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
|
|
||||||
if (_managedObjectContext != nil) {
|
|
||||||
return _managedObjectContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
|
|
||||||
if (!coordinator) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
|
||||||
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
|
|
||||||
return _managedObjectContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Core Data Saving support
|
|
||||||
|
|
||||||
- (void)saveContext {
|
|
||||||
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
|
|
||||||
if (managedObjectContext != nil) {
|
|
||||||
NSError *error = nil;
|
|
||||||
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
|
|
||||||
// Replace this implementation with code to handle the error appropriately.
|
|
||||||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
|
||||||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -38,8 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@property (nonatomic, copy) NSString *__nullable chatId;
|
@property (nonatomic, copy) NSString *__nullable chatId;
|
||||||
///用户id,推送跳转到聊天页面
|
///用户id,推送跳转到聊天页面
|
||||||
@property (nonatomic, copy) NSString *__nullable pushChatId;
|
@property (nonatomic, copy) NSString *__nullable pushChatId;
|
||||||
///邀请码,从外面进来会进入注册页面,并自动填写这个邀请码
|
|
||||||
@property(nonatomic,copy) NSString *inviteCode;
|
|
||||||
///表情---
|
///表情---
|
||||||
@property (nonatomic, copy) NSString *version;
|
@property (nonatomic, copy) NSString *version;
|
||||||
@property (nonatomic, copy) NSString *zipMd5;
|
@property (nonatomic, copy) NSString *zipMd5;
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareModel.h
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2021/11/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
typedef NS_ENUM(NSUInteger, ShareType) {
|
|
||||||
///分享房间
|
|
||||||
ShareType_Room = 1,
|
|
||||||
///分享h5
|
|
||||||
ShareType_H5 = 2,
|
|
||||||
///大转盘 目前没用到
|
|
||||||
ShareType_User_Draw = 888,
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface XPShareInfoModel : PIBaseModel
|
|
||||||
///分享的标题
|
|
||||||
@property (nonatomic,copy) NSString *shareTitle;
|
|
||||||
///分享的内容
|
|
||||||
@property (nonatomic,copy) NSString *shareContent;
|
|
||||||
///分享的地址
|
|
||||||
@property (nonatomic,copy) NSString *shareUrl;
|
|
||||||
///分享图片
|
|
||||||
@property (nonatomic,copy) NSString *shareImageUrl;
|
|
||||||
///分享图片
|
|
||||||
@property (nonatomic,copy) UIImage *shareImage;
|
|
||||||
///分享的类型
|
|
||||||
@property (nonatomic,assign) ShareType type;
|
|
||||||
///分享类型,1微信好友,2微信朋友圈,3QQ好友,4QQ空间
|
|
||||||
@property (nonatomic,assign) NSInteger shareType;
|
|
||||||
///分享房间的uid
|
|
||||||
@property (nonatomic,assign) NSInteger roomUid;
|
|
||||||
#pragma mark - 动态分享
|
|
||||||
///被分享动态的那个人
|
|
||||||
@property (nonatomic,copy) NSString *uid;
|
|
||||||
///动态分享
|
|
||||||
@property (nonatomic,copy) NSString *dynamicId;
|
|
||||||
///话题id
|
|
||||||
@property (nonatomic,copy) NSString *worldId;
|
|
||||||
///封面
|
|
||||||
@property (nonatomic,copy) NSString *imageUrl;
|
|
||||||
///名称
|
|
||||||
@property (nonatomic,copy) NSString *nick;
|
|
||||||
///发布者的uid
|
|
||||||
@property (nonatomic,copy) NSString *publishUid;
|
|
||||||
///内容
|
|
||||||
@property (nonatomic,copy) NSString *content;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
@@ -1,12 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareModel.m
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2021/11/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "XPShareInfoModel.h"
|
|
||||||
|
|
||||||
@implementation XPShareInfoModel
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareItem.h
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2021/11/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
typedef enum : NSUInteger {
|
|
||||||
///微信好友
|
|
||||||
XPShareItemTagWeChat = 1,
|
|
||||||
///微信朋友圈
|
|
||||||
XPShareItemTagMoments,
|
|
||||||
///QQ好友
|
|
||||||
XPShareItemTagQQ,
|
|
||||||
///QQ空间
|
|
||||||
XPShareItemTagQQZone,
|
|
||||||
///LIne
|
|
||||||
XPShareItemTagLine,
|
|
||||||
///FaceBook
|
|
||||||
XPShareItemTagFaceBook,
|
|
||||||
///复制链接
|
|
||||||
XPShareItemTagCopyLink,
|
|
||||||
///应用好友
|
|
||||||
XPShareItemTagAppFriends,
|
|
||||||
///保存到相册
|
|
||||||
XPShareItemTagAppSaveAlbum,
|
|
||||||
} XPShareItemTag;
|
|
||||||
|
|
||||||
@interface XPShareItem : NSObject
|
|
||||||
@property(nonatomic,assign) BOOL isShareInvite;
|
|
||||||
@property (nonatomic, copy) NSString *inviteTitle;
|
|
||||||
@property (nonatomic, copy) NSString *title;
|
|
||||||
@property (nonatomic, copy) NSString *imageName;
|
|
||||||
@property (nonatomic, copy) NSString *disableImageName;
|
|
||||||
@property (nonatomic, assign) BOOL disable;
|
|
||||||
@property (nonatomic, assign) XPShareItemTag type;
|
|
||||||
|
|
||||||
+ (instancetype)itemWitTag:(XPShareItemTag)itemTag title:(NSString *)title imageName:(NSString *)imageName disableImageName:(NSString *)disableImageName;
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
@@ -1,23 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareItem.m
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2021/11/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "XPShareItem.h"
|
|
||||||
|
|
||||||
@implementation XPShareItem
|
|
||||||
|
|
||||||
+ (instancetype)itemWitTag:(XPShareItemTag)itemTag title:(NSString *)title imageName:(NSString *)imageName disableImageName:(NSString *)disableImageName {
|
|
||||||
XPShareItem *item = [[self alloc] init];
|
|
||||||
item.type = itemTag;
|
|
||||||
item.title = title;
|
|
||||||
item.imageName = imageName;
|
|
||||||
item.disableImageName = disableImageName;
|
|
||||||
item.disable = NO;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,16 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareItemCell.h
|
|
||||||
// YMRoomMoudle
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2022/9/2.
|
|
||||||
// Copyright © 2023 YUMI. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
#import "XPShareItem.h"
|
|
||||||
|
|
||||||
@interface XPShareItemCell : UICollectionViewCell
|
|
||||||
|
|
||||||
@property (nonatomic, strong) XPShareItem *shareItem;
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,78 +0,0 @@
|
|||||||
//
|
|
||||||
// YMShareItemCell.m
|
|
||||||
// YMRoomMoudle
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2022/9/2.
|
|
||||||
// Copyright © 2023 YUMI. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "XPShareItemCell.h"
|
|
||||||
#import "DJDKMIMOMColor.h"
|
|
||||||
#import <Masonry/Masonry.h>
|
|
||||||
|
|
||||||
@interface XPShareItemCell()
|
|
||||||
|
|
||||||
@property (nonatomic, strong) UIImageView *iconImageView;
|
|
||||||
@property (nonatomic, strong) UILabel *titleLabel;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation XPShareItemCell
|
|
||||||
|
|
||||||
#pragma mark - Life Style
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame{
|
|
||||||
if (self=[super initWithFrame:frame]) {
|
|
||||||
[self initSubViews];
|
|
||||||
[self initSubViewConstraints];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
#pragma mark - Private Method
|
|
||||||
- (void)initSubViews{
|
|
||||||
[self.contentView addSubview:self.iconImageView];
|
|
||||||
[self.contentView addSubview:self.titleLabel];
|
|
||||||
|
|
||||||
}
|
|
||||||
- (void)initSubViewConstraints{
|
|
||||||
CGFloat wh = 30;
|
|
||||||
[self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.width.height.equalTo(@(wh));
|
|
||||||
make.top.equalTo(self.contentView);
|
|
||||||
make.centerX.equalTo(self.contentView);
|
|
||||||
}];
|
|
||||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.trailing.leading.equalTo(self.contentView).inset(5);
|
|
||||||
make.top.equalTo(self.iconImageView.mas_bottom).offset(10);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Getters And Setters
|
|
||||||
- (void)setShareItem:(XPShareItem *)shareItem{
|
|
||||||
_shareItem = shareItem;
|
|
||||||
self.userInteractionEnabled = shareItem.disable;
|
|
||||||
if (!shareItem.disable) {
|
|
||||||
self.iconImageView.image = [UIImage imageNamed:shareItem.disableImageName];
|
|
||||||
}else{
|
|
||||||
self.iconImageView.image = [UIImage imageNamed:shareItem.imageName];
|
|
||||||
}
|
|
||||||
self.titleLabel.text = shareItem.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (UIImageView *)iconImageView{
|
|
||||||
if (!_iconImageView) {
|
|
||||||
_iconImageView = [[UIImageView alloc] init];
|
|
||||||
}
|
|
||||||
return _iconImageView;
|
|
||||||
}
|
|
||||||
- (UILabel *)titleLabel{
|
|
||||||
if (!_titleLabel) {
|
|
||||||
_titleLabel = [[UILabel alloc] init];
|
|
||||||
_titleLabel.textColor = [DJDKMIMOMColor alertMessageColor];
|
|
||||||
_titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Medium" size:12];
|
|
||||||
_titleLabel.numberOfLines = 2;
|
|
||||||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
|
||||||
}
|
|
||||||
return _titleLabel;
|
|
||||||
}
|
|
||||||
@end
|
|
@@ -1,34 +0,0 @@
|
|||||||
//
|
|
||||||
// XCShareView.h
|
|
||||||
// XCRoomMoudle
|
|
||||||
//
|
|
||||||
// Created by KevinWang on 2018/9/2.
|
|
||||||
// Copyright © 2018年 YiZhuan. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
#import "XPShareItem.h"
|
|
||||||
#import "XPShareInfoModel.h"
|
|
||||||
|
|
||||||
@class XPShareView;
|
|
||||||
@protocol XCShareViewDelegate <NSObject>
|
|
||||||
@optional
|
|
||||||
///点击保存图片到相册
|
|
||||||
- (void)shareView:(XPShareView *)shareView savePhoto:(XPShareInfoModel *)shareInfo;
|
|
||||||
///点了取消分享
|
|
||||||
- (void)shareViewDidClickCancel:(XPShareView *)shareView;
|
|
||||||
///分享成功
|
|
||||||
- (void)shareView:(XPShareView *)shareView didSuccess:(XPShareInfoModel *)shareInfo;
|
|
||||||
///分享失败
|
|
||||||
- (void)shareView:(XPShareView *)shareView shareFail:(NSString *)message;
|
|
||||||
@end;
|
|
||||||
|
|
||||||
@interface XPShareView : UIView
|
|
||||||
|
|
||||||
@property (nonatomic, weak) id<XCShareViewDelegate> delegate;
|
|
||||||
@property (nonatomic,assign) BOOL isFromWebVeiw;
|
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWithItems:(NSArray<XPShareItem *> *)items itemSize:(CGSize)itemSize shareInfo:(XPShareInfoModel *)shareInfo;
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,329 +0,0 @@
|
|||||||
//
|
|
||||||
// XCShareView.m
|
|
||||||
// XCRoomMoudle
|
|
||||||
//
|
|
||||||
// Created by KevinWang on 2018/9/2.
|
|
||||||
// Copyright © 2018年 YiZhuan. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "XPShareView.h"
|
|
||||||
///Third
|
|
||||||
#import <Masonry/Masonry.h>
|
|
||||||
#import <ShareSDK/ShareSDK.h>
|
|
||||||
#import <ShareSDKExtension/ShareSDK+Extension.h>
|
|
||||||
#import <FBSDKShareKit/FBSDKShareKit.h>
|
|
||||||
#import "XCCurrentVCStackManager.h"
|
|
||||||
///Tool
|
|
||||||
#import "TTPopup.h"
|
|
||||||
|
|
||||||
///View
|
|
||||||
#import "XPShareItemCell.h"
|
|
||||||
#import "XPMineShareViewController.h"
|
|
||||||
#import "ClientConfig.h"
|
|
||||||
|
|
||||||
@interface XPShareView()<UICollectionViewDataSource,UICollectionViewDelegate,FBSDKSharingDelegate>
|
|
||||||
///取消
|
|
||||||
@property (nonatomic, strong) UIButton *cancleButton;
|
|
||||||
///列表
|
|
||||||
@property (nonatomic, strong) UICollectionView *collectionView;
|
|
||||||
///数据源
|
|
||||||
@property (nonatomic, strong) NSArray<XPShareItem *> *items;
|
|
||||||
///item的大小
|
|
||||||
@property (nonatomic,assign) CGSize itemSize;
|
|
||||||
///分享的内容
|
|
||||||
@property (nonatomic,strong) XPShareInfoModel *shareInfo;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation XPShareView
|
|
||||||
|
|
||||||
#pragma mark - Life Style
|
|
||||||
- (instancetype)initWithItems:(NSArray<XPShareItem *> *)items itemSize:(CGSize)itemSize shareInfo:(XPShareInfoModel *)shareInfo {
|
|
||||||
if (self = [super init]) {
|
|
||||||
for (XPShareItem * item in items) {
|
|
||||||
if (item.type == XPShareItemTagAppFriends || item.type == XPShareItemTagCopyLink) {
|
|
||||||
item.disable = YES;
|
|
||||||
} else {
|
|
||||||
item.disable = [self isInstallClient:[self getSharePlatformType:item.type]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.items = [NSMutableArray arrayWithArray:items];
|
|
||||||
self.itemSize =itemSize;
|
|
||||||
self.shareInfo = shareInfo;
|
|
||||||
[self initSubViews];
|
|
||||||
[self initSubViewConstraints];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Private Method
|
|
||||||
- (void)initSubViews {
|
|
||||||
[self addSubview:self.collectionView];
|
|
||||||
[self addSubview:self.cancleButton];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)initSubViewConstraints {
|
|
||||||
|
|
||||||
CGFloat collectionWidth = KScreenWidth - 15 * 2;
|
|
||||||
///一行有几个
|
|
||||||
int numberLine = collectionWidth / self.itemSize.width;
|
|
||||||
int page = self.items.count % numberLine > 0 ? (int)self.items.count / numberLine + 1 : (int)self.items.count / numberLine;
|
|
||||||
CGFloat collectionHeight = page * self.itemSize.height + 20 + (page-1) * 10 + 10;
|
|
||||||
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.top.mas_equalTo(self);
|
|
||||||
make.height.mas_equalTo(collectionHeight);
|
|
||||||
make.leading.trailing.mas_equalTo(self).inset(15);
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self.cancleButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.height.mas_equalTo(45);
|
|
||||||
make.leading.trailing.mas_equalTo(self.collectionView);
|
|
||||||
make.top.mas_equalTo(self.collectionView.mas_bottom).offset(15);
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.width.mas_equalTo(KScreenWidth);
|
|
||||||
make.bottom.mas_equalTo(self.cancleButton.mas_bottom).offset(30);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (BOOL)isInstallClient:(SSDKPlatformType)platform {
|
|
||||||
return [ShareSDK isClientInstalled:platform];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (SSDKPlatformType)getSharePlatformType:(XPShareItemTag)itemTag {
|
|
||||||
SSDKPlatformType type;
|
|
||||||
switch (itemTag) {
|
|
||||||
case XPShareItemTagFaceBook:
|
|
||||||
type = SSDKPlatformTypeFacebook;
|
|
||||||
break;
|
|
||||||
case XPShareItemTagLine:
|
|
||||||
type = SSDKPlatformTypeLine;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = SSDKPlatformTypeUnknown;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - UICollectionViewDelegate
|
|
||||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
|
|
||||||
return self.items.count;
|
|
||||||
}
|
|
||||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
|
|
||||||
XPShareItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPShareItemCell class]) forIndexPath:indexPath];
|
|
||||||
XPShareItem * item = [self.items xpSafeObjectAtIndex:indexPath.item];
|
|
||||||
item.disable = YES;
|
|
||||||
cell.shareItem = item;
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
|
|
||||||
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
|
|
||||||
|
|
||||||
NSMutableDictionary *shareParams = [NSMutableDictionary dictionary];
|
|
||||||
NSString * title = [self.shareInfo shareTitle].length > 0 ? self.shareInfo.shareTitle : @"";
|
|
||||||
NSString * content = self.shareInfo.shareContent.length > 0 ? self.shareInfo.shareContent : @"";
|
|
||||||
NSString * urlString = self.shareInfo.shareUrl.length > 0 ?self.shareInfo.shareUrl : @"";
|
|
||||||
if ([urlString containsString:@"?"]){
|
|
||||||
urlString = [NSString stringWithFormat:@"%@&lang=%@",urlString,[NSBundle uploadLanguageText]];
|
|
||||||
}else{
|
|
||||||
urlString = [NSString stringWithFormat:@"%@?lang=%@",urlString,[NSBundle uploadLanguageText]];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString *encodedUrl = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
|
||||||
|
|
||||||
XPShareItem * item = [self.items xpSafeObjectAtIndex:indexPath.item];
|
|
||||||
if (item == nil){
|
|
||||||
[TTPopup dismiss];
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
if (item.type == XPShareItemTagAppSaveAlbum){
|
|
||||||
[TTPopup dismiss];
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:savePhoto:)]){
|
|
||||||
[self.delegate shareView:self savePhoto:self.shareInfo];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (item.type == XPShareItemTagAppFriends) {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
XPMineShareViewController * shareVC = [[XPMineShareViewController alloc] init];
|
|
||||||
shareVC.shareType = MineShareType_Monents;
|
|
||||||
shareVC.shareInfo = self.shareInfo;
|
|
||||||
[[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:shareVC animated:YES];
|
|
||||||
return;
|
|
||||||
} else if(item.type == XPShareItemTagCopyLink) {
|
|
||||||
NSString * urlString = self.shareInfo.shareUrl;
|
|
||||||
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
||||||
[pasteboard setString:urlString];
|
|
||||||
[XNDJTDDLoadingTool showSuccessWithMessage:YMLocalizedString(@"XPShareView0")];
|
|
||||||
|
|
||||||
[TTPopup dismiss];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if([self isInstallClient:[self getSharePlatformType:item.type]] == NO){
|
|
||||||
[XNDJTDDLoadingTool showErrorWithMessage:YMLocalizedString(@"XPShareView9")];
|
|
||||||
[TTPopup dismiss];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加类型安全检查,防止NSTaggedPointerString错误
|
|
||||||
if ([self.shareInfo isKindOfClass:[XPShareInfoModel class]] && [item isKindOfClass:[XPShareItem class]]) {
|
|
||||||
self.shareInfo.shareType = item.type;
|
|
||||||
} else {
|
|
||||||
NSLog(@"警告:self.shareInfo不是XPShareInfoModel类型,而是%@类型", NSStringFromClass([self.shareInfo class]));
|
|
||||||
[TTPopup dismiss];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSDKPlatformType platformType = SSDKPlatformTypeCopy;
|
|
||||||
|
|
||||||
if (item.type == XPShareItemTagLine) {
|
|
||||||
title = YMLocalizedString(@"XPShareView1");
|
|
||||||
platformType = SSDKPlatformTypeLine;
|
|
||||||
if (![ShareSDK isClientInstalled:platformType]) {
|
|
||||||
[XNDJTDDLoadingTool showErrorWithMessage:YMLocalizedString(@"XPShareView2")];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSString*contentKey= [encodedUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet];
|
|
||||||
NSString*contentType =@"text";
|
|
||||||
NSString*urlString = [NSString stringWithFormat:@"line://msg/%@/%@",contentType, contentKey];
|
|
||||||
|
|
||||||
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:urlString] options:@{} completionHandler:^(BOOL success) {
|
|
||||||
|
|
||||||
}];
|
|
||||||
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:didSuccess:)]) {
|
|
||||||
[self.delegate shareView:self didSuccess:self.shareInfo];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
if(item.type == XPShareItemTagFaceBook){
|
|
||||||
FBSDKShareLinkContent*linkContent = [[FBSDKShareLinkContent alloc]init];
|
|
||||||
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
|
|
||||||
linkContent.contentURL= [NSURL URLWithString:urlString];
|
|
||||||
linkContent.quote = content;
|
|
||||||
FBSDKShareDialog *shareDialog = [[FBSDKShareDialog alloc]initWithViewController:[XCCurrentVCStackManager shareManager].getCurrentVC content:linkContent delegate:self];
|
|
||||||
// 需要指定模式,否则会调起web分享
|
|
||||||
shareDialog.mode = FBSDKShareDialogModeNative;
|
|
||||||
if (![shareDialog canShow]) {
|
|
||||||
shareDialog.mode = FBSDKShareDialogModeWeb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[shareDialog show];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ShareSDK share:platformType parameters:shareParams onStateChanged:^(SSDKResponseState state, NSDictionary *userData, SSDKContentEntity *contentEntity, NSError *error) {
|
|
||||||
switch (state) {
|
|
||||||
case SSDKResponseStateSuccess:
|
|
||||||
{
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:didSuccess:)]) {
|
|
||||||
[self.delegate shareView:self didSuccess:self.shareInfo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SSDKResponseStateFail:
|
|
||||||
{
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:shareFail:)]) {
|
|
||||||
[self.delegate shareView:self shareFail:YMLocalizedString(@"XPShareView5")];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SSDKResponseStateCancel:
|
|
||||||
{
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:shareFail:)]) {
|
|
||||||
[self.delegate shareView:self shareFail:YMLocalizedString(@"XPShareView6")];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
#pragma mark - FBSDKSharingDelegate
|
|
||||||
/// Sent to the delegate when sharing completes without error or cancellation.
|
|
||||||
/// @param sharer The sharer that completed.
|
|
||||||
/// @param results The results from the sharer. This may be nil or empty.
|
|
||||||
- (void)sharer:(id <FBSDKSharing> _Nonnull)sharer didCompleteWithResults:(NSDictionary<NSString *, id> * _Nonnull)results{
|
|
||||||
NSString *postId = results[@"postId"];
|
|
||||||
FBSDKShareDialog *dialog = (FBSDKShareDialog *)sharer;
|
|
||||||
if (dialog.mode == FBSDKShareDialogModeBrowser && (postId == nil || [postId isEqualToString:@""])) {
|
|
||||||
// 如果使用webview分享的,但postId是空的,
|
|
||||||
// 这种情况是用户点击了『完成』按钮,并没有真的分享
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:shareFail:)]) {
|
|
||||||
[self.delegate shareView:self shareFail:YMLocalizedString(@"XPShareView6")];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:didSuccess:)]) {
|
|
||||||
[self.delegate shareView:self didSuccess:self.shareInfo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Sent to the delegate when the sharer encounters an error.
|
|
||||||
/// @param sharer The sharer that completed.
|
|
||||||
/// @param error The error.
|
|
||||||
- (void)sharer:(id <FBSDKSharing> _Nonnull)sharer didFailWithError:(NSError * _Nonnull)error{
|
|
||||||
FBSDKShareDialog *dialog = (FBSDKShareDialog *)sharer;
|
|
||||||
if (error == nil && dialog.mode == FBSDKShareDialogModeNative) {
|
|
||||||
// 如果使用原生登录失败,但error为空,那是因为用户没有安装Facebook app
|
|
||||||
// 重设dialog的mode,再次弹出对话框
|
|
||||||
dialog.mode = FBSDKShareDialogModeBrowser;
|
|
||||||
[dialog show];
|
|
||||||
} else {
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:shareFail:)]) {
|
|
||||||
[self.delegate shareView:self shareFail:YMLocalizedString(@"XPShareView5")];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Sent to the delegate when the sharer is cancelled.
|
|
||||||
/// @param sharer The sharer that completed.
|
|
||||||
- (void)sharerDidCancel:(id <FBSDKSharing> _Nonnull)sharer{
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareView:shareFail:)]) {
|
|
||||||
[self.delegate shareView:self shareFail:YMLocalizedString(@"XPShareView6")];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#pragma mark - Event Response
|
|
||||||
- (void)cancleButtonDidClck:(UIButton *)button{
|
|
||||||
if (self.delegate && [self.delegate respondsToSelector:@selector(shareViewDidClickCancel:)]) {
|
|
||||||
[self.delegate shareViewDidClickCancel:self];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Getters And Setters
|
|
||||||
- (UICollectionView *)collectionView{
|
|
||||||
if (!_collectionView) {
|
|
||||||
MSBaseRTLFlowLayout *layout = [[MSBaseRTLFlowLayout alloc] init];
|
|
||||||
layout.itemSize = self.itemSize;
|
|
||||||
layout.minimumInteritemSpacing = 0;
|
|
||||||
layout.minimumLineSpacing = 10;
|
|
||||||
layout.sectionInset = UIEdgeInsetsMake(20, 0, 10, 0);
|
|
||||||
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
|
|
||||||
_collectionView.backgroundColor = [UIColor whiteColor];
|
|
||||||
_collectionView.dataSource = self;
|
|
||||||
_collectionView.delegate = self;
|
|
||||||
_collectionView.layer.masksToBounds = YES;
|
|
||||||
_collectionView.layer.cornerRadius = 15;
|
|
||||||
[_collectionView registerClass:[XPShareItemCell class] forCellWithReuseIdentifier:NSStringFromClass([XPShareItemCell class])];
|
|
||||||
}
|
|
||||||
return _collectionView;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIButton *)cancleButton{
|
|
||||||
if (!_cancleButton) {
|
|
||||||
_cancleButton = [[UIButton alloc] init];
|
|
||||||
[_cancleButton setBackgroundColor:[UIColor whiteColor]];
|
|
||||||
[_cancleButton setTitle:YMLocalizedString(@"XPShareView7") forState:UIControlStateNormal];
|
|
||||||
_cancleButton.titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Medium" size:15];
|
|
||||||
_cancleButton.layer.masksToBounds = YES;
|
|
||||||
_cancleButton.layer.cornerRadius = 45/2;
|
|
||||||
[_cancleButton setTitleColor:[DJDKMIMOMColor textThirdColor] forState:UIControlStateNormal];
|
|
||||||
[_cancleButton addTarget:self action:@selector(cancleButtonDidClck:) forControlEvents:UIControlEventTouchUpInside];
|
|
||||||
}
|
|
||||||
return _cancleButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
26
YuMi/E-P/Common/EPClientAPIBridge.h
Normal file
26
YuMi/E-P/Common/EPClientAPIBridge.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// EPClientAPIBridge.h
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Deprecated: replaced by Swift EPConfigAPI
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// Bridge to wrap existing Objective-C APIs for Swift consumers
|
||||||
|
__attribute__((deprecated("Use EPConfigAPI (Swift) instead")))
|
||||||
|
@interface EPClientAPIBridge : NSObject
|
||||||
|
|
||||||
|
/// Call Api.clientInitConfig and forward raw dictionary and status
|
||||||
|
+ (void)clientInit:(void(^)(NSDictionary * _Nullable data, NSInteger code, NSString * _Nullable msg))completion;
|
||||||
|
|
||||||
|
/// Call ClientConfig.clientConfig; returns code 200 on success (no payload)
|
||||||
|
+ (void)clientConfig:(void(^)(NSDictionary * _Nullable data, NSInteger code, NSString * _Nullable msg))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
|
36
YuMi/E-P/Common/EPClientAPIBridge.m
Normal file
36
YuMi/E-P/Common/EPClientAPIBridge.m
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// EPClientAPIBridge.m
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Objective-C to Swift bridge for client init/config APIs
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "EPClientAPIBridge.h"
|
||||||
|
#import "Api+Main.h"
|
||||||
|
#import "ClientConfig.h"
|
||||||
|
#import "BaseModel.h"
|
||||||
|
|
||||||
|
@implementation EPClientAPIBridge
|
||||||
|
|
||||||
|
+ (void)clientInit:(void(^)(NSDictionary * _Nullable data, NSInteger code, NSString * _Nullable msg))completion {
|
||||||
|
if (!completion) { return; }
|
||||||
|
[Api clientInitConfig:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
|
||||||
|
NSDictionary *payload = nil;
|
||||||
|
if (code == 200 && data.data && [data.data isKindOfClass:[NSDictionary class]]) {
|
||||||
|
payload = (NSDictionary *)data.data;
|
||||||
|
}
|
||||||
|
completion(payload, code, msg);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)clientConfig:(void(^)(NSDictionary * _Nullable data, NSInteger code, NSString * _Nullable msg))completion {
|
||||||
|
if (!completion) { return; }
|
||||||
|
// ClientConfig.clientConfig only has a finish block with no parameters; treat success as code 200
|
||||||
|
[[ClientConfig shareConfig] clientConfig:^{
|
||||||
|
completion(nil, 200, nil);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
37
YuMi/E-P/Common/EPConfigAPI.swift
Normal file
37
YuMi/E-P/Common/EPConfigAPI.swift
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// EPConfigAPI.swift
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Thin Swift wrapper aligning EP module naming, for client/init & client/config
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc final class EPConfigAPI: NSObject {
|
||||||
|
|
||||||
|
/// GET client/init — returns payload dictionary when code == 200
|
||||||
|
@objc static func clientInit(
|
||||||
|
completion: @escaping (_ data: [String: Any]?, _ code: Int, _ msg: String?) -> Void
|
||||||
|
) {
|
||||||
|
Api.clientInitConfig { baseModel, code, msg in
|
||||||
|
var dict: [String: Any]? = nil
|
||||||
|
if code == 200, let payload = baseModel?.data as? [String: Any] {
|
||||||
|
dict = payload
|
||||||
|
}
|
||||||
|
completion(dict, Int(code), msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GET client/config — treat success as code 200 (no payload)
|
||||||
|
@objc static func clientConfig(
|
||||||
|
completion: @escaping (_ data: [String: Any]?, _ code: Int, _ msg: String?) -> Void
|
||||||
|
) {
|
||||||
|
// ClientConfig has + (instancetype)shareConfig; bridged to Swift as .share()
|
||||||
|
// If the symbol differs, adjust to your Swift name (e.g., shareConfig()).
|
||||||
|
ClientConfig.share().clientConfig {
|
||||||
|
completion(nil, 200, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
133
YuMi/E-P/Common/EPConfigManager.swift
Normal file
133
YuMi/E-P/Common/EPConfigManager.swift
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
//
|
||||||
|
// EPConfigManager.swift
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Cold boot configuration manager for client/init and client/config flows
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc final class EPConfigManager: NSObject {
|
||||||
|
@objc static let shared = EPConfigManager()
|
||||||
|
|
||||||
|
// MARK: - State
|
||||||
|
@objc private(set) var isInitReady: Bool = false
|
||||||
|
@objc private(set) var isConfigReady: Bool = false
|
||||||
|
@objc private(set) var isUsingPersistedInit: Bool = false
|
||||||
|
|
||||||
|
// 原始数据(向后兼容)
|
||||||
|
@objc private(set) var initModelRaw: [String: Any]? = nil
|
||||||
|
@objc private(set) var configModelRaw: [String: Any]? = nil
|
||||||
|
|
||||||
|
// 强类型模型
|
||||||
|
@objc private(set) var clientDataModel: ClientDataModel? = nil
|
||||||
|
|
||||||
|
private var hasStarted = false
|
||||||
|
|
||||||
|
// 回调闭包
|
||||||
|
private var successCallback: (() -> Void)?
|
||||||
|
private var failureCallback: ((String) -> Void)?
|
||||||
|
|
||||||
|
// MARK: - Public API
|
||||||
|
@objc(startColdBootWithOnSuccess:onFailure:)
|
||||||
|
func startColdBoot(
|
||||||
|
onSuccess: @escaping () -> Void,
|
||||||
|
onFailure: @escaping (String) -> Void
|
||||||
|
) {
|
||||||
|
guard !hasStarted else {
|
||||||
|
// 如果已经启动过,根据当前状态直接回调
|
||||||
|
if isInitReady && isConfigReady {
|
||||||
|
onSuccess()
|
||||||
|
} else if !isInitReady {
|
||||||
|
onFailure("配置初始化失败")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hasStarted = true
|
||||||
|
|
||||||
|
// 保存回调
|
||||||
|
self.successCallback = onSuccess
|
||||||
|
self.failureCallback = onFailure
|
||||||
|
|
||||||
|
runClientInitWithRetry(maxRetry: 5, interval: 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Flow
|
||||||
|
private func runClientInitWithRetry(maxRetry: Int, interval: TimeInterval) {
|
||||||
|
attemptClientInit(remaining: maxRetry, interval: interval)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func attemptClientInit(remaining: Int, interval: TimeInterval) {
|
||||||
|
EPConfigAPI.clientInit { [weak self] data, code, msg in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if code == 200, let dict = data {
|
||||||
|
self.onInitSuccess(dict)
|
||||||
|
self.runClientConfig()
|
||||||
|
} else if remaining > 0 {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
|
||||||
|
self.attemptClientInit(remaining: remaining - 1, interval: interval)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.onInitExhausted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func onInitSuccess(_ dict: [String: Any]) {
|
||||||
|
// 1. 转换为强类型模型
|
||||||
|
let model = ClientDataModel.model(withJSON: dict)
|
||||||
|
self.clientDataModel = model
|
||||||
|
|
||||||
|
// 2. 更新 ClientConfig(保持现有代码兼容)
|
||||||
|
ClientConfig.share().configInfo = model
|
||||||
|
|
||||||
|
// 3. 持久化原始字典(避免模型变更时数据失效)
|
||||||
|
_ = EPConfigStorage.saveInit(dict)
|
||||||
|
|
||||||
|
// 4. 更新状态
|
||||||
|
isUsingPersistedInit = false
|
||||||
|
initModelRaw = dict
|
||||||
|
isInitReady = true
|
||||||
|
|
||||||
|
// 5. 继续执行 client/config
|
||||||
|
runClientConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func onInitExhausted() {
|
||||||
|
if let persistedDict = EPConfigStorage.loadInit() as? [String: Any] {
|
||||||
|
// 使用持久化数据
|
||||||
|
let model = ClientDataModel.model(withJSON: persistedDict)
|
||||||
|
self.clientDataModel = model
|
||||||
|
ClientConfig.share().configInfo = model
|
||||||
|
|
||||||
|
isUsingPersistedInit = true
|
||||||
|
initModelRaw = persistedDict
|
||||||
|
isInitReady = true
|
||||||
|
|
||||||
|
// 尝试获取最新配置
|
||||||
|
runClientConfig()
|
||||||
|
} else {
|
||||||
|
// 无持久化数据,调用失败回调
|
||||||
|
failureCallback?("网络异常,请稍后重新启动应用")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func runClientConfig() {
|
||||||
|
EPConfigAPI.clientConfig { [weak self] data, code, msg in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if code == 200 {
|
||||||
|
// client/config 成功,标记完成并调用成功回调
|
||||||
|
self.isConfigReady = true
|
||||||
|
self.successCallback?()
|
||||||
|
} else {
|
||||||
|
// client/config 失败,但 init 已成功,仍可继续
|
||||||
|
self.isConfigReady = true
|
||||||
|
self.successCallback?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除 Notification 扩展,不再需要
|
||||||
|
|
||||||
|
|
27
YuMi/E-P/Common/EPConfigStorage.h
Normal file
27
YuMi/E-P/Common/EPConfigStorage.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// EPConfigStorage.h
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Lightweight persistence for client/init data
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface EPConfigStorage : NSObject
|
||||||
|
|
||||||
|
/// Save init payload dictionary to disk (Application Support)
|
||||||
|
+ (BOOL)saveInit:(NSDictionary *)dict;
|
||||||
|
|
||||||
|
/// Load init payload dictionary from disk; returns nil if missing/invalid
|
||||||
|
+ (NSDictionary * _Nullable)loadInit;
|
||||||
|
|
||||||
|
/// Remove persisted init payload
|
||||||
|
+ (BOOL)clearInit;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
|
62
YuMi/E-P/Common/EPConfigStorage.m
Normal file
62
YuMi/E-P/Common/EPConfigStorage.m
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// EPConfigStorage.m
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// Lightweight persistence for client/init data
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "EPConfigStorage.h"
|
||||||
|
|
||||||
|
@implementation EPConfigStorage
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
|
||||||
|
+ (BOOL)saveInit:(NSDictionary *)dict {
|
||||||
|
if (![dict isKindOfClass:[NSDictionary class]]) { return NO; }
|
||||||
|
NSMutableDictionary *wrapped = [dict mutableCopy];
|
||||||
|
wrapped[@"_version"] = @1;
|
||||||
|
wrapped[@"_timestamp"] = @((long long)([[NSDate date] timeIntervalSince1970]));
|
||||||
|
NSData *data = [NSJSONSerialization dataWithJSONObject:wrapped options:0 error:nil];
|
||||||
|
if (!data) { return NO; }
|
||||||
|
NSString *path = [self initPath];
|
||||||
|
NSError *error = nil;
|
||||||
|
NSFileManager *fm = [NSFileManager defaultManager];
|
||||||
|
NSString *dir = [path stringByDeletingLastPathComponent];
|
||||||
|
if (![fm fileExistsAtPath:dir]) {
|
||||||
|
[fm createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:&error];
|
||||||
|
if (error) { return NO; }
|
||||||
|
}
|
||||||
|
return [data writeToFile:path atomically:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary * _Nullable)loadInit {
|
||||||
|
NSString *path = [self initPath];
|
||||||
|
NSData *data = [NSData dataWithContentsOfFile:path];
|
||||||
|
if (!data) { return nil; }
|
||||||
|
id obj = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
||||||
|
if (![obj isKindOfClass:[NSDictionary class]]) { return nil; }
|
||||||
|
return (NSDictionary *)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)clearInit {
|
||||||
|
NSString *path = [self initPath];
|
||||||
|
NSFileManager *fm = [NSFileManager defaultManager];
|
||||||
|
if (![fm fileExistsAtPath:path]) { return YES; }
|
||||||
|
NSError *error = nil;
|
||||||
|
[fm removeItemAtPath:path error:&error];
|
||||||
|
return (error == nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Helpers
|
||||||
|
|
||||||
|
+ (NSString *)initPath {
|
||||||
|
NSArray<NSURL *> *urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
|
||||||
|
NSURL *dirURL = urls.firstObject;
|
||||||
|
if (!dirURL) { dirURL = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject]]; }
|
||||||
|
NSURL *fileURL = [dirURL URLByAppendingPathComponent:@"ep_config_init.json"];
|
||||||
|
return fileURL.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
27
YuMi/E-P/Common/EPSDKManager+NIM.swift
Normal file
27
YuMi/E-P/Common/EPSDKManager+NIM.swift
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// EPSDKManager+NIM.swift
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc extension EPSDKManager {
|
||||||
|
/// 初始化 NIMSDK(从 ClientConfig 获取 nimKey)
|
||||||
|
@objc func initializeNIMSDK(completion: ((NSError?) -> Void)? = nil) {
|
||||||
|
EPNIMManager.shared().initialize { error in
|
||||||
|
completion?(error as NSError?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 上传 APNS token 到 NIM
|
||||||
|
@objc func updateNIMApnsToken(_ deviceToken: Data) {
|
||||||
|
EPNIMManager.shared().updateApnsToken(deviceToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取 NIM 未读数
|
||||||
|
@objc func nimUnreadCount() -> Int {
|
||||||
|
return Int(EPNIMManager.shared().allUnreadCount())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@@ -41,8 +41,8 @@ import UIKit
|
|||||||
let epTabBar = EPTabBarController.create()
|
let epTabBar = EPTabBarController.create()
|
||||||
epTabBar.refreshTabBarWithIsLogin(true)
|
epTabBar.refreshTabBarWithIsLogin(true)
|
||||||
|
|
||||||
// 设置为根控制器
|
// 设置为根控制器(统一从 ObjC inline 函数获取)
|
||||||
if let window = getKeyWindow() {
|
if let window = kGetKeyWindow() {
|
||||||
window.rootViewController = epTabBar
|
window.rootViewController = epTabBar
|
||||||
window.makeKeyAndVisible()
|
window.makeKeyAndVisible()
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ import UIKit
|
|||||||
let epTabBar = EPTabBarController.create()
|
let epTabBar = EPTabBarController.create()
|
||||||
epTabBar.refreshTabBarWithIsLogin(true)
|
epTabBar.refreshTabBarWithIsLogin(true)
|
||||||
|
|
||||||
if let window = getKeyWindow() {
|
if let window = kGetKeyWindow() {
|
||||||
window.rootViewController = epTabBar
|
window.rootViewController = epTabBar
|
||||||
window.makeKeyAndVisible()
|
window.makeKeyAndVisible()
|
||||||
|
|
||||||
@@ -87,27 +87,7 @@ import UIKit
|
|||||||
|
|
||||||
// MARK: - Helper Methods
|
// MARK: - Helper Methods
|
||||||
|
|
||||||
/// 获取 keyWindow(iOS 13+ 兼容)
|
// Swift 侧不再重复实现 keyWindow 获取,统一调用 ObjC inline 函数 kGetKeyWindow()
|
||||||
private static func getKeyWindow() -> UIWindow? {
|
|
||||||
if #available(iOS 13.0, *) {
|
|
||||||
for windowScene in UIApplication.shared.connectedScenes {
|
|
||||||
if let windowScene = windowScene as? UIWindowScene,
|
|
||||||
windowScene.activationState == .foregroundActive {
|
|
||||||
for window in windowScene.windows {
|
|
||||||
if window.isKeyWindow {
|
|
||||||
return window
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 如果没有 keyWindow,返回第一个 window
|
|
||||||
return windowScene.windows.first
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
|
||||||
return UIApplication.shared.keyWindow
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 检查并显示专属颜色引导页
|
/// 检查并显示专属颜色引导页
|
||||||
private static func checkAndShowSignatureColorGuide(in window: UIWindow) {
|
private static func checkAndShowSignatureColorGuide(in window: UIWindow) {
|
||||||
|
54
YuMi/E-P/NewMessage/EPBaseListViewController.swift
Normal file
54
YuMi/E-P/NewMessage/EPBaseListViewController.swift
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// EPBaseListViewController.swift
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
// A lightweight table-view base class used by EP Message subpages.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SnapKit
|
||||||
|
|
||||||
|
class EPBaseListViewController<Cell: UITableViewCell>: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
||||||
|
let tableView = UITableView(frame: .zero, style: .plain)
|
||||||
|
var itemsCount: Int = 0 { didSet { tableView.reloadData() } }
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
view.backgroundColor = UIColor(named: "ep.background.dark") ?? UIColor.black.withAlphaComponent(0.9)
|
||||||
|
|
||||||
|
tableView.backgroundColor = .clear
|
||||||
|
tableView.separatorStyle = .none
|
||||||
|
tableView.showsVerticalScrollIndicator = false
|
||||||
|
tableView.dataSource = self
|
||||||
|
tableView.delegate = self
|
||||||
|
tableView.rowHeight = 72
|
||||||
|
tableView.contentInsetAdjustmentBehavior = .never
|
||||||
|
tableView.keyboardDismissMode = .onDrag
|
||||||
|
tableView.register(Cell.self, forCellReuseIdentifier: "cell")
|
||||||
|
|
||||||
|
view.addSubview(tableView)
|
||||||
|
tableView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalTo(view.safeAreaLayoutGuide)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UITableViewDataSource
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return itemsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
|
||||||
|
cell.backgroundColor = .clear
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Helpers
|
||||||
|
func simulateItems(_ count: Int) {
|
||||||
|
itemsCount = count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
126
YuMi/E-P/NewMessage/EPFriendFollowingFans.swift
Normal file
126
YuMi/E-P/NewMessage/EPFriendFollowingFans.swift
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class EPFriendListVC: EPBaseListViewController<EPUserBriefCell> {
|
||||||
|
override func viewDidLoad() { super.viewDidLoad(); simulateItems(6) }
|
||||||
|
}
|
||||||
|
|
||||||
|
final class EPFollowingListVC: EPBaseListViewController<EPUserBriefCell> {
|
||||||
|
override func viewDidLoad() { super.viewDidLoad(); simulateItems(10) }
|
||||||
|
}
|
||||||
|
|
||||||
|
final class EPFansListVC: EPBaseListViewController<EPUserBriefCell> {
|
||||||
|
override func viewDidLoad() { super.viewDidLoad(); simulateItems(12) }
|
||||||
|
}
|
||||||
|
|
||||||
|
final class EPUserBriefCell: UITableViewCell {
|
||||||
|
private let avatar = UIImageView()
|
||||||
|
private let nameLabel = UILabel()
|
||||||
|
private let subtitleLabel = UILabel()
|
||||||
|
private let followButton = EPFollowButton()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
setup()
|
||||||
|
}
|
||||||
|
required init?(coder: NSCoder) { super.init(coder: coder); setup() }
|
||||||
|
|
||||||
|
private func setup() {
|
||||||
|
selectionStyle = .none
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
avatar.contentMode = .scaleAspectFill
|
||||||
|
avatar.layer.cornerRadius = 24
|
||||||
|
avatar.layer.masksToBounds = true
|
||||||
|
avatar.image = UIImage(named: "pi_login_new_logo")
|
||||||
|
|
||||||
|
nameLabel.font = .systemFont(ofSize: 20, weight: .semibold)
|
||||||
|
nameLabel.textColor = .white
|
||||||
|
nameLabel.text = "Momoyy"
|
||||||
|
|
||||||
|
subtitleLabel.font = .systemFont(ofSize: 16)
|
||||||
|
subtitleLabel.textColor = UIColor.white.withAlphaComponent(0.6)
|
||||||
|
subtitleLabel.text = "Welcome to play"
|
||||||
|
|
||||||
|
contentView.addSubview(avatar)
|
||||||
|
contentView.addSubview(nameLabel)
|
||||||
|
contentView.addSubview(subtitleLabel)
|
||||||
|
contentView.addSubview(followButton)
|
||||||
|
|
||||||
|
avatar.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
followButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
avatar.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||||
|
avatar.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
|
avatar.widthAnchor.constraint(equalToConstant: 48),
|
||||||
|
avatar.heightAnchor.constraint(equalToConstant: 48),
|
||||||
|
|
||||||
|
nameLabel.leadingAnchor.constraint(equalTo: avatar.trailingAnchor, constant: 12),
|
||||||
|
nameLabel.topAnchor.constraint(equalTo: avatar.topAnchor, constant: -2),
|
||||||
|
|
||||||
|
subtitleLabel.leadingAnchor.constraint(equalTo: nameLabel.leadingAnchor),
|
||||||
|
subtitleLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 6),
|
||||||
|
|
||||||
|
followButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
|
||||||
|
followButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
|
followButton.widthAnchor.constraint(equalToConstant: 120),
|
||||||
|
followButton.heightAnchor.constraint(equalToConstant: 40)
|
||||||
|
])
|
||||||
|
|
||||||
|
followButton.setFollowed(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class EPFollowButton: UIButton {
|
||||||
|
private var isFollowedState: Bool = false
|
||||||
|
|
||||||
|
override init(frame: CGRect) { super.init(frame: frame); setup() }
|
||||||
|
required init?(coder: NSCoder) { super.init(coder: coder); setup() }
|
||||||
|
|
||||||
|
private func setup() {
|
||||||
|
titleLabel?.font = .systemFont(ofSize: 18, weight: .semibold)
|
||||||
|
layer.cornerRadius = 20
|
||||||
|
layer.masksToBounds = true
|
||||||
|
addTarget(self, action: #selector(onTap), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFollowed(_ followed: Bool) {
|
||||||
|
isFollowedState = followed
|
||||||
|
if followed {
|
||||||
|
setTitle("Followed", for: .normal)
|
||||||
|
backgroundColor = .clear
|
||||||
|
layer.borderWidth = 1
|
||||||
|
layer.borderColor = UIColor.systemPurple.withAlphaComponent(0.6).cgColor
|
||||||
|
setTitleColor(UIColor.systemPurple.withAlphaComponent(0.9), for: .normal)
|
||||||
|
} else {
|
||||||
|
setTitle("Follow", for: .normal)
|
||||||
|
layer.borderWidth = 0
|
||||||
|
setTitleColor(.white, for: .normal)
|
||||||
|
setGradientBackground()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func onTap() { setFollowed(!isFollowedState) }
|
||||||
|
|
||||||
|
private func setGradientBackground() {
|
||||||
|
let gradient = CAGradientLayer()
|
||||||
|
gradient.colors = [UIColor.systemPink.cgColor, UIColor.systemPurple.cgColor]
|
||||||
|
gradient.startPoint = CGPoint(x: 0, y: 0.5)
|
||||||
|
gradient.endPoint = CGPoint(x: 1, y: 0.5)
|
||||||
|
gradient.frame = bounds
|
||||||
|
gradient.cornerRadius = layer.cornerRadius
|
||||||
|
layer.sublayers?.removeAll(where: { $0 is CAGradientLayer })
|
||||||
|
layer.insertSublayer(gradient, at: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
if !isFollowedState { setGradientBackground() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
90
YuMi/E-P/NewMessage/EPMessageListVC.swift
Normal file
90
YuMi/E-P/NewMessage/EPMessageListVC.swift
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class EPMessageListVC: EPBaseListViewController<EPMessageCell> {
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
simulateItems(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Cell
|
||||||
|
final class EPMessageCell: UITableViewCell {
|
||||||
|
private let avatar = UIImageView()
|
||||||
|
private let nameLabel = UILabel()
|
||||||
|
private let subtitleLabel = UILabel()
|
||||||
|
private let timeLabel = UILabel()
|
||||||
|
private let unreadView = UILabel()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
setup()
|
||||||
|
}
|
||||||
|
required init?(coder: NSCoder) { super.init(coder: coder); setup() }
|
||||||
|
|
||||||
|
private func setup() {
|
||||||
|
selectionStyle = .none
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
avatar.contentMode = .scaleAspectFill
|
||||||
|
avatar.layer.cornerRadius = 24
|
||||||
|
avatar.layer.masksToBounds = true
|
||||||
|
avatar.image = UIImage(named: "pi_login_new_logo")
|
||||||
|
|
||||||
|
nameLabel.font = .systemFont(ofSize: 20, weight: .semibold)
|
||||||
|
nameLabel.textColor = .white
|
||||||
|
nameLabel.text = "Momoyy"
|
||||||
|
|
||||||
|
subtitleLabel.font = .systemFont(ofSize: 16)
|
||||||
|
subtitleLabel.textColor = UIColor.white.withAlphaComponent(0.6)
|
||||||
|
subtitleLabel.text = "Nice to meet you"
|
||||||
|
|
||||||
|
timeLabel.font = .systemFont(ofSize: 14)
|
||||||
|
timeLabel.textColor = UIColor.white.withAlphaComponent(0.5)
|
||||||
|
timeLabel.text = "11:03"
|
||||||
|
|
||||||
|
unreadView.backgroundColor = UIColor.systemRed
|
||||||
|
unreadView.textColor = .white
|
||||||
|
unreadView.font = .systemFont(ofSize: 12, weight: .bold)
|
||||||
|
unreadView.textAlignment = .center
|
||||||
|
unreadView.layer.cornerRadius = 12
|
||||||
|
unreadView.layer.masksToBounds = true
|
||||||
|
unreadView.text = "99+"
|
||||||
|
|
||||||
|
contentView.addSubview(avatar)
|
||||||
|
contentView.addSubview(nameLabel)
|
||||||
|
contentView.addSubview(subtitleLabel)
|
||||||
|
contentView.addSubview(timeLabel)
|
||||||
|
contentView.addSubview(unreadView)
|
||||||
|
|
||||||
|
avatar.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
timeLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
unreadView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
avatar.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||||
|
avatar.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
|
avatar.widthAnchor.constraint(equalToConstant: 48),
|
||||||
|
avatar.heightAnchor.constraint(equalToConstant: 48),
|
||||||
|
|
||||||
|
nameLabel.leadingAnchor.constraint(equalTo: avatar.trailingAnchor, constant: 12),
|
||||||
|
nameLabel.topAnchor.constraint(equalTo: avatar.topAnchor, constant: -2),
|
||||||
|
|
||||||
|
subtitleLabel.leadingAnchor.constraint(equalTo: nameLabel.leadingAnchor),
|
||||||
|
subtitleLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 6),
|
||||||
|
|
||||||
|
timeLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
|
||||||
|
timeLabel.topAnchor.constraint(equalTo: nameLabel.topAnchor),
|
||||||
|
|
||||||
|
unreadView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
|
||||||
|
unreadView.centerYAnchor.constraint(equalTo: subtitleLabel.centerYAnchor),
|
||||||
|
unreadView.widthAnchor.constraint(greaterThanOrEqualToConstant: 40),
|
||||||
|
unreadView.heightAnchor.constraint(equalToConstant: 24)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
92
YuMi/E-P/NewMessage/EPMessageMainViewController.swift
Normal file
92
YuMi/E-P/NewMessage/EPMessageMainViewController.swift
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import UIKit
|
||||||
|
import SnapKit
|
||||||
|
|
||||||
|
final class EPMessageMainViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
|
||||||
|
// 外部回调:未读数变化
|
||||||
|
var unreadCountDidChange: ((Int)->Void)?
|
||||||
|
|
||||||
|
private let segment = EPMessageSegmentView()
|
||||||
|
private let pageVC = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
|
||||||
|
|
||||||
|
private lazy var pages: [UIViewController] = {
|
||||||
|
return [
|
||||||
|
EPMessageListVC(),
|
||||||
|
EPFriendListVC(),
|
||||||
|
EPFollowingListVC(),
|
||||||
|
EPFansListVC()
|
||||||
|
]
|
||||||
|
}()
|
||||||
|
|
||||||
|
private var currentIndex: Int = 0
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
view.backgroundColor = UIColor.black.withAlphaComponent(0.92)
|
||||||
|
title = YMLocalizedString("XPSessionMainViewController0")
|
||||||
|
|
||||||
|
setupSegment()
|
||||||
|
setupPageVC()
|
||||||
|
|
||||||
|
// 模拟未读变化(后续接入桥接器)
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
|
||||||
|
self?.unreadCountDidChange?(12)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupSegment() {
|
||||||
|
view.addSubview(segment)
|
||||||
|
segment.snp.makeConstraints { make in
|
||||||
|
make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(8)
|
||||||
|
make.leading.trailing.equalToSuperview().inset(20)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
}
|
||||||
|
segment.didSelect = { [weak self] index in
|
||||||
|
self?.setPage(index: index, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupPageVC() {
|
||||||
|
addChild(pageVC)
|
||||||
|
view.addSubview(pageVC.view)
|
||||||
|
pageVC.view.backgroundColor = .clear
|
||||||
|
pageVC.view.snp.makeConstraints { make in
|
||||||
|
make.top.equalTo(segment.snp.bottom).offset(8)
|
||||||
|
make.leading.trailing.bottom.equalTo(view.safeAreaLayoutGuide)
|
||||||
|
}
|
||||||
|
pageVC.didMove(toParent: self)
|
||||||
|
pageVC.dataSource = self
|
||||||
|
pageVC.delegate = self
|
||||||
|
pageVC.setViewControllers([pages[0]], direction: .forward, animated: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setPage(index: Int, animated: Bool) {
|
||||||
|
guard index != currentIndex, index >= 0, index < pages.count else { return }
|
||||||
|
let direction: UIPageViewController.NavigationDirection = index > currentIndex ? .forward : .reverse
|
||||||
|
pageVC.setViewControllers([pages[index]], direction: direction, animated: animated)
|
||||||
|
currentIndex = index
|
||||||
|
segment.select(index: index, animated: animated)
|
||||||
|
title = segment.titles[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UIPageViewControllerDataSource
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||||
|
guard let idx = pages.firstIndex(of: viewController), idx > 0 else { return nil }
|
||||||
|
return pages[idx - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||||
|
guard let idx = pages.firstIndex(of: viewController), idx < pages.count - 1 else { return nil }
|
||||||
|
return pages[idx + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
|
||||||
|
guard completed, let vc = pageViewController.viewControllers?.first, let idx = pages.firstIndex(of: vc) else { return }
|
||||||
|
currentIndex = idx
|
||||||
|
segment.select(index: idx, animated: true)
|
||||||
|
title = segment.titles[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
84
YuMi/E-P/NewMessage/EPMessageSegmentView.swift
Normal file
84
YuMi/E-P/NewMessage/EPMessageSegmentView.swift
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
// A simple segmented control with underline indicator for four tabs
|
||||||
|
import UIKit
|
||||||
|
import SnapKit
|
||||||
|
|
||||||
|
final class EPMessageSegmentView: UIView {
|
||||||
|
enum Segment: Int, CaseIterable { case message=0, friend, following, fans }
|
||||||
|
|
||||||
|
var titles: [String] = [
|
||||||
|
YMLocalizedString("XPSessionMainViewController0"),
|
||||||
|
YMLocalizedString("XPSessionMainViewController1"),
|
||||||
|
YMLocalizedString("XPSessionMainViewController2"),
|
||||||
|
YMLocalizedString("XPSessionMainViewController3")
|
||||||
|
]
|
||||||
|
|
||||||
|
var didSelect: ((Int)->Void)?
|
||||||
|
|
||||||
|
private var buttons: [UIButton] = []
|
||||||
|
private let indicator = UIView()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
setup()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) { super.init(coder: coder); setup() }
|
||||||
|
|
||||||
|
private func setup() {
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
let stack = UIStackView()
|
||||||
|
stack.axis = .horizontal
|
||||||
|
stack.alignment = .fill
|
||||||
|
stack.distribution = .fillEqually
|
||||||
|
stack.spacing = 0
|
||||||
|
addSubview(stack)
|
||||||
|
stack.snp.makeConstraints { $0.edges.equalToSuperview() }
|
||||||
|
|
||||||
|
for (idx, title) in titles.enumerated() {
|
||||||
|
let b = UIButton(type: .custom)
|
||||||
|
b.tag = idx
|
||||||
|
b.setTitle(title, for: .normal)
|
||||||
|
b.setTitleColor(UIColor.white.withAlphaComponent(0.6), for: .normal)
|
||||||
|
b.setTitleColor(.white, for: .selected)
|
||||||
|
b.titleLabel?.font = .systemFont(ofSize: 24, weight: idx == 0 ? .heavy : .regular)
|
||||||
|
b.addTarget(self, action: #selector(onTap(_:)), for: .touchUpInside)
|
||||||
|
buttons.append(b)
|
||||||
|
stack.addArrangedSubview(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator.backgroundColor = UIColor.systemPink
|
||||||
|
addSubview(indicator)
|
||||||
|
layoutIfNeeded()
|
||||||
|
select(index: 0, animated: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func onTap(_ sender: UIButton) {
|
||||||
|
select(index: sender.tag, animated: true)
|
||||||
|
didSelect?(sender.tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func select(index: Int, animated: Bool) {
|
||||||
|
guard index >= 0 && index < buttons.count else { return }
|
||||||
|
for (i,b) in buttons.enumerated() {
|
||||||
|
b.isSelected = (i == index)
|
||||||
|
b.titleLabel?.font = .systemFont(ofSize: 24, weight: b.isSelected ? .heavy : .regular)
|
||||||
|
}
|
||||||
|
let target = buttons[index]
|
||||||
|
let width = target.bounds.width
|
||||||
|
let y = bounds.height - 4
|
||||||
|
let frame = CGRect(x: CGFloat(index) * width + width*0.15, y: y, width: width*0.7, height: 3)
|
||||||
|
|
||||||
|
if animated {
|
||||||
|
UIView.animate(withDuration: 0.2) {
|
||||||
|
self.indicator.frame = frame
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
indicator.frame = frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,14 +1,10 @@
|
|||||||
//
|
|
||||||
// EPMomentPublishViewController.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-10.
|
// Created by AI on 2025-10-10.
|
||||||
//
|
|
||||||
|
|
||||||
// NOTE: 话题选择功能未实现
|
// NOTE: 话题选择功能未实现
|
||||||
// 旧版本 XPMonentsPublishViewController 包含话题选择 UI (addTopicView)
|
|
||||||
// 但实际业务中话题功能使用率低,新版本暂不实现
|
|
||||||
// 如需实现参考: YuMi/Modules/YMMonents/View/XPMonentsPublishTopicView
|
|
||||||
|
|
||||||
#import "EPMomentPublishViewController.h"
|
#import "EPMomentPublishViewController.h"
|
||||||
#import <Masonry/Masonry.h>
|
#import <Masonry/Masonry.h>
|
||||||
@@ -20,7 +16,7 @@
|
|||||||
#import "EPEmotionColorStorage.h"
|
#import "EPEmotionColorStorage.h"
|
||||||
#import "UIView+GradientLayer.h"
|
#import "UIView+GradientLayer.h"
|
||||||
|
|
||||||
// 发布成功通知
|
|
||||||
NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNotification";
|
NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNotification";
|
||||||
|
|
||||||
@interface EPMomentPublishViewController () <UICollectionViewDataSource, UICollectionViewDelegate, TZImagePickerControllerDelegate, UITextViewDelegate>
|
@interface EPMomentPublishViewController () <UICollectionViewDataSource, UICollectionViewDelegate, TZImagePickerControllerDelegate, UITextViewDelegate>
|
||||||
@@ -37,10 +33,10 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
@property (nonatomic, strong) UIButton *emotionButton;
|
@property (nonatomic, strong) UIButton *emotionButton;
|
||||||
@property (nonatomic, strong) UICollectionView *collectionView;
|
@property (nonatomic, strong) UICollectionView *collectionView;
|
||||||
@property (nonatomic, strong) NSMutableArray<UIImage *> *images;
|
@property (nonatomic, strong) NSMutableArray<UIImage *> *images;
|
||||||
@property (nonatomic, strong) NSMutableArray *selectedAssets; // TZImagePicker 已选资源
|
@property (nonatomic, strong) NSMutableArray *selectedAssets;
|
||||||
@property (nonatomic, copy) NSString *selectedEmotionColor; // 选中的情绪颜色
|
@property (nonatomic, copy) NSString *selectedEmotionColor;
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL hasAddedGradient; // 标记是否已添加渐变背景
|
@property (nonatomic, assign) BOOL hasAddedGradient;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -51,27 +47,27 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
self.view.backgroundColor = [UIColor colorWithRed:0x0C/255.0 green:0x05/255.0 blue:0x27/255.0 alpha:1.0];
|
self.view.backgroundColor = [UIColor colorWithRed:0x0C/255.0 green:0x05/255.0 blue:0x27/255.0 alpha:1.0];
|
||||||
[self setupUI];
|
[self setupUI];
|
||||||
|
|
||||||
// 自动加载用户专属颜色
|
|
||||||
[self loadUserSignatureColor];
|
[self loadUserSignatureColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLayoutSubviews {
|
- (void)viewDidLayoutSubviews {
|
||||||
[super viewDidLayoutSubviews];
|
[super viewDidLayoutSubviews];
|
||||||
|
|
||||||
// 添加渐变背景到发布按钮(只添加一次)
|
|
||||||
if (!self.hasAddedGradient && self.publishButton.bounds.size.width > 0) {
|
if (!self.hasAddedGradient && self.publishButton.bounds.size.width > 0) {
|
||||||
// 使用与登录页面相同的渐变颜色(EPLoginConfig.Colors)
|
|
||||||
// gradientStart: #F854FC, gradientEnd: #500FFF
|
|
||||||
[self.publishButton addGradientBackgroundWithColors:@[
|
[self.publishButton addGradientBackgroundWithColors:@[
|
||||||
[UIColor colorWithRed:0xF8/255.0 green:0x54/255.0 blue:0xFC/255.0 alpha:1.0], // #F854FC
|
[UIColor colorWithRed:0xF8/255.0 green:0x54/255.0 blue:0xFC/255.0 alpha:1.0],
|
||||||
[UIColor colorWithRed:0x50/255.0 green:0x0F/255.0 blue:0xFF/255.0 alpha:1.0] // #500FFF
|
[UIColor colorWithRed:0x50/255.0 green:0x0F/255.0 blue:0xFF/255.0 alpha:1.0]
|
||||||
] startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5) cornerRadius:25];
|
] startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5) cornerRadius:25];
|
||||||
|
|
||||||
self.hasAddedGradient = YES;
|
self.hasAddedGradient = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 加载用户专属颜色作为默认选中
|
|
||||||
- (void)loadUserSignatureColor {
|
- (void)loadUserSignatureColor {
|
||||||
NSString *signatureColor = [EPEmotionColorStorage userSignatureColor];
|
NSString *signatureColor = [EPEmotionColorStorage userSignatureColor];
|
||||||
if (signatureColor) {
|
if (signatureColor) {
|
||||||
@@ -86,7 +82,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
[self.view addSubview:self.contentView];
|
[self.view addSubview:self.contentView];
|
||||||
[self.navView addSubview:self.backButton];
|
[self.navView addSubview:self.backButton];
|
||||||
[self.navView addSubview:self.titleLabel];
|
[self.navView addSubview:self.titleLabel];
|
||||||
// 发布按钮移到底部
|
|
||||||
[self.contentView addSubview:self.textView];
|
[self.contentView addSubview:self.textView];
|
||||||
[self.contentView addSubview:self.limitLabel];
|
[self.contentView addSubview:self.limitLabel];
|
||||||
[self.contentView addSubview:self.lineView];
|
[self.contentView addSubview:self.lineView];
|
||||||
@@ -107,7 +103,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
make.centerX.equalTo(self.navView);
|
make.centerX.equalTo(self.navView);
|
||||||
make.centerY.equalTo(self.backButton);
|
make.centerY.equalTo(self.backButton);
|
||||||
}];
|
}];
|
||||||
// 发布按钮约束移到底部
|
|
||||||
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.view);
|
make.leading.trailing.equalTo(self.view);
|
||||||
make.top.equalTo(self.navView.mas_bottom);
|
make.top.equalTo(self.navView.mas_bottom);
|
||||||
@@ -128,16 +124,14 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
make.height.mas_equalTo(1);
|
make.height.mas_equalTo(1);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 情绪按钮
|
|
||||||
[self.emotionButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.emotionButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.contentView).inset(15);
|
make.leading.trailing.equalTo(self.contentView).inset(15);
|
||||||
make.top.equalTo(self.lineView.mas_bottom).offset(10);
|
make.top.equalTo(self.lineView.mas_bottom).offset(10);
|
||||||
make.height.mas_equalTo(44);
|
make.height.mas_equalTo(44);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 计算显示3行图片所需的高度
|
|
||||||
// itemW = (屏幕宽度 - 左右边距30 - 列间距20) / 3
|
|
||||||
// 总高度 = 3行itemW + 2个行间距(10*2)
|
|
||||||
CGFloat itemW = (KScreenWidth - 15*2 - 10*2)/3.0;
|
CGFloat itemW = (KScreenWidth - 15*2 - 10*2)/3.0;
|
||||||
CGFloat collectionHeight = itemW * 3 + 10 * 2;
|
CGFloat collectionHeight = itemW * 3 + 10 * 2;
|
||||||
|
|
||||||
@@ -147,7 +141,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
make.height.mas_equalTo(collectionHeight);
|
make.height.mas_equalTo(collectionHeight);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 底部发布按钮
|
|
||||||
[self.publishButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.publishButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.view).inset(20);
|
make.leading.trailing.equalTo(self.view).inset(20);
|
||||||
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-20);
|
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-20);
|
||||||
@@ -164,7 +158,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
- (void)onEmotionButtonTapped {
|
- (void)onEmotionButtonTapped {
|
||||||
EPEmotionColorPicker *picker = [[EPEmotionColorPicker alloc] init];
|
EPEmotionColorPicker *picker = [[EPEmotionColorPicker alloc] init];
|
||||||
|
|
||||||
// 预选中当前颜色(如果有)
|
|
||||||
picker.preselectedColor = self.selectedEmotionColor;
|
picker.preselectedColor = self.selectedEmotionColor;
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
@@ -178,10 +172,10 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
|
|
||||||
- (void)updateEmotionButtonAppearance {
|
- (void)updateEmotionButtonAppearance {
|
||||||
if (self.selectedEmotionColor) {
|
if (self.selectedEmotionColor) {
|
||||||
// 显示选中的颜色
|
|
||||||
UIColor *color = [self colorFromHex:self.selectedEmotionColor];
|
UIColor *color = [self colorFromHex:self.selectedEmotionColor];
|
||||||
|
|
||||||
// 创建色块视图
|
|
||||||
UIView *colorDot = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
|
UIView *colorDot = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
|
||||||
colorDot.backgroundColor = color;
|
colorDot.backgroundColor = color;
|
||||||
colorDot.layer.cornerRadius = 10;
|
colorDot.layer.cornerRadius = 10;
|
||||||
@@ -189,7 +183,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
colorDot.layer.borderWidth = 2;
|
colorDot.layer.borderWidth = 2;
|
||||||
colorDot.layer.borderColor = [UIColor whiteColor].CGColor;
|
colorDot.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||||
|
|
||||||
// 转换为 UIImage
|
|
||||||
UIGraphicsBeginImageContextWithOptions(colorDot.bounds.size, NO, 0);
|
UIGraphicsBeginImageContextWithOptions(colorDot.bounds.size, NO, 0);
|
||||||
[colorDot.layer renderInContext:UIGraphicsGetCurrentContext()];
|
[colorDot.layer renderInContext:UIGraphicsGetCurrentContext()];
|
||||||
UIImage *colorDotImage = UIGraphicsGetImageFromCurrentImageContext();
|
UIImage *colorDotImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||||
@@ -197,7 +191,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
|
|
||||||
[self.emotionButton setImage:colorDotImage forState:UIControlStateNormal];
|
[self.emotionButton setImage:colorDotImage forState:UIControlStateNormal];
|
||||||
|
|
||||||
// 获取情绪名称
|
|
||||||
NSString *emotionName = [EPEmotionColorStorage emotionNameForColor:self.selectedEmotionColor];
|
NSString *emotionName = [EPEmotionColorStorage emotionNameForColor:self.selectedEmotionColor];
|
||||||
NSString *title = emotionName
|
NSString *title = emotionName
|
||||||
? [NSString stringWithFormat:@" Selected Emotion: %@", emotionName]
|
? [NSString stringWithFormat:@" Selected Emotion: %@", emotionName]
|
||||||
@@ -212,7 +206,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
- (UIColor *)colorFromHex:(NSString *)hexString {
|
- (UIColor *)colorFromHex:(NSString *)hexString {
|
||||||
unsigned rgbValue = 0;
|
unsigned rgbValue = 0;
|
||||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||||
[scanner setScanLocation:1]; // 跳过 #
|
[scanner setScanLocation:1];
|
||||||
[scanner scanHexInt:&rgbValue];
|
[scanner scanHexInt:&rgbValue];
|
||||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
||||||
green:((rgbValue & 0xFF00) >> 8)/255.0
|
green:((rgbValue & 0xFF00) >> 8)/255.0
|
||||||
@@ -223,20 +217,20 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
- (void)onPublish {
|
- (void)onPublish {
|
||||||
[self.view endEditing:YES];
|
[self.view endEditing:YES];
|
||||||
|
|
||||||
// 验证:文本或图片至少有一项
|
|
||||||
if (self.textView.text.length == 0 && self.images.count == 0) {
|
if (self.textView.text.length == 0 && self.images.count == 0) {
|
||||||
[EPProgressHUD showError:YMLocalizedString(@"publish.content_or_image_required")];
|
[EPProgressHUD showError:YMLocalizedString(@"publish.content_or_image_required")];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建 Swift API Helper
|
|
||||||
EPMomentAPISwiftHelper *apiHelper = [[EPMomentAPISwiftHelper alloc] init];
|
EPMomentAPISwiftHelper *apiHelper = [[EPMomentAPISwiftHelper alloc] init];
|
||||||
|
|
||||||
// 保存情绪颜色用于发布后关联
|
|
||||||
NSString *emotionColorToSave = self.selectedEmotionColor;
|
NSString *emotionColorToSave = self.selectedEmotionColor;
|
||||||
|
|
||||||
if (self.images.count > 0) {
|
if (self.images.count > 0) {
|
||||||
// 有图片:上传后发布(统一入口)
|
|
||||||
[[EPSDKManager shared] uploadImages:self.images
|
[[EPSDKManager shared] uploadImages:self.images
|
||||||
progress:^(NSInteger uploaded, NSInteger total) {
|
progress:^(NSInteger uploaded, NSInteger total) {
|
||||||
[EPProgressHUD showProgress:uploaded total:total];
|
[EPProgressHUD showProgress:uploaded total:total];
|
||||||
@@ -247,11 +241,11 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
content:self.textView.text ?: @""
|
content:self.textView.text ?: @""
|
||||||
resList:resList
|
resList:resList
|
||||||
completion:^{
|
completion:^{
|
||||||
// 保存临时情绪颜色(等待列表刷新后匹配)
|
|
||||||
if (emotionColorToSave) {
|
if (emotionColorToSave) {
|
||||||
[self savePendingEmotionColor:emotionColorToSave];
|
[self savePendingEmotionColor:emotionColorToSave];
|
||||||
}
|
}
|
||||||
// 发送发布成功通知
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:EPMomentPublishSuccessNotification object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:EPMomentPublishSuccessNotification object:nil];
|
||||||
[self dismissViewControllerAnimated:YES completion:nil];
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
} failure:^(NSInteger code, NSString *msg) {
|
} failure:^(NSInteger code, NSString *msg) {
|
||||||
@@ -265,16 +259,16 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
NSLog(@"上传失败: %@", errorMsg);
|
NSLog(@"上传失败: %@", errorMsg);
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
// 纯文本:直接发布
|
|
||||||
[apiHelper publishMomentWithType:@"0"
|
[apiHelper publishMomentWithType:@"0"
|
||||||
content:self.textView.text
|
content:self.textView.text
|
||||||
resList:@[]
|
resList:@[]
|
||||||
completion:^{
|
completion:^{
|
||||||
// 保存临时情绪颜色(等待列表刷新后匹配)
|
|
||||||
if (emotionColorToSave) {
|
if (emotionColorToSave) {
|
||||||
[self savePendingEmotionColor:emotionColorToSave];
|
[self savePendingEmotionColor:emotionColorToSave];
|
||||||
}
|
}
|
||||||
// 发送发布成功通知
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:EPMomentPublishSuccessNotification object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:EPMomentPublishSuccessNotification object:nil];
|
||||||
[self dismissViewControllerAnimated:YES completion:nil];
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
} failure:^(NSInteger code, NSString *msg) {
|
} failure:^(NSInteger code, NSString *msg) {
|
||||||
@@ -284,7 +278,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 保存待处理的情绪颜色(临时存储,供列表刷新后匹配)
|
|
||||||
- (void)savePendingEmotionColor:(NSString *)color {
|
- (void)savePendingEmotionColor:(NSString *)color {
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:color forKey:@"EP_Pending_Emotion_Color"];
|
[[NSUserDefaults standardUserDefaults] setObject:color forKey:@"EP_Pending_Emotion_Color"];
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:@([[NSDate date] timeIntervalSince1970]) forKey:@"EP_Pending_Emotion_Timestamp"];
|
[[NSUserDefaults standardUserDefaults] setObject:@([[NSDate date] timeIntervalSince1970]) forKey:@"EP_Pending_Emotion_Timestamp"];
|
||||||
@@ -294,14 +288,14 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
#pragma mark - UICollectionView
|
#pragma mark - UICollectionView
|
||||||
|
|
||||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||||
return self.images.count + 1; // 最后一个是添加按钮
|
return self.images.count + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ep.publish.cell" forIndexPath:indexPath];
|
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ep.publish.cell" forIndexPath:indexPath];
|
||||||
cell.contentView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.06];
|
cell.contentView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.06];
|
||||||
cell.contentView.layer.cornerRadius = 12;
|
cell.contentView.layer.cornerRadius = 12;
|
||||||
// 清空复用子视图,避免加号被覆盖
|
|
||||||
for (UIView *sub in cell.contentView.subviews) { [sub removeFromSuperview]; }
|
for (UIView *sub in cell.contentView.subviews) { [sub removeFromSuperview]; }
|
||||||
BOOL showAdd = (self.images.count < 9) && (indexPath.item == self.images.count);
|
BOOL showAdd = (self.images.count < 9) && (indexPath.item == self.images.count);
|
||||||
if (showAdd) {
|
if (showAdd) {
|
||||||
@@ -327,15 +321,16 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
TZImagePickerController *picker = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:self];
|
TZImagePickerController *picker = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:self];
|
||||||
picker.allowPickingVideo = NO;
|
picker.allowPickingVideo = NO;
|
||||||
picker.allowTakeVideo = NO;
|
picker.allowTakeVideo = NO;
|
||||||
picker.selectedAssets = self.selectedAssets; // 预选
|
picker.allowCameraLocation = NO; // 禁止请求定位权限
|
||||||
picker.maxImagesCount = 9; // 总上限
|
picker.selectedAssets = self.selectedAssets;
|
||||||
|
picker.maxImagesCount = 9;
|
||||||
[self presentViewController:picker animated:YES completion:nil];
|
[self presentViewController:picker animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - TZImagePickerControllerDelegate
|
#pragma mark - TZImagePickerControllerDelegate
|
||||||
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos {
|
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos {
|
||||||
// 合并选择:在已有基础上追加,最多 9 张
|
|
||||||
for (NSInteger i = 0; i < assets.count; i++) {
|
for (NSInteger i = 0; i < assets.count; i++) {
|
||||||
id asset = assets[i];
|
id asset = assets[i];
|
||||||
UIImage *img = [photos xpSafeObjectAtIndex:i] ?: photos[i];
|
UIImage *img = [photos xpSafeObjectAtIndex:i] ?: photos[i];
|
||||||
@@ -358,12 +353,24 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
#pragma mark - Lazy
|
#pragma mark - Lazy
|
||||||
|
|
||||||
- (UIView *)navView { if (!_navView) { _navView = [UIView new]; _navView.backgroundColor = [UIColor clearColor]; } return _navView; }
|
- (UIView *)navView { if (!_navView) { _navView = [UIView new]; _navView.backgroundColor = [UIColor clearColor]; } return _navView; }
|
||||||
- (UIButton *)backButton { if (!_backButton) { _backButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_backButton setImage:[UIImage imageNamed:@"common_nav_back"] forState:UIControlStateNormal]; [_backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside]; } return _backButton; }
|
- (UIButton *)backButton {
|
||||||
|
if (!_backButton) {
|
||||||
|
_backButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
|
||||||
|
UIImage *backImage = [UIImage systemImageNamed:@"chevron.left"];
|
||||||
|
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:20 weight:UIImageSymbolWeightMedium];
|
||||||
|
backImage = [backImage imageByApplyingSymbolConfiguration:config];
|
||||||
|
[_backButton setImage:backImage forState:UIControlStateNormal];
|
||||||
|
[_backButton setTintColor:[UIColor whiteColor]];
|
||||||
|
[_backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _backButton;
|
||||||
|
}
|
||||||
- (UILabel *)titleLabel {
|
- (UILabel *)titleLabel {
|
||||||
if (!_titleLabel) {
|
if (!_titleLabel) {
|
||||||
_titleLabel = [UILabel new];
|
_titleLabel = [UILabel new];
|
||||||
_titleLabel.text = YMLocalizedString(@"publish.title");
|
_titleLabel.text = YMLocalizedString(@"publish.title");
|
||||||
_titleLabel.textColor = [UIColor whiteColor]; // 白色适配深色背景
|
_titleLabel.textColor = [UIColor whiteColor];
|
||||||
_titleLabel.font = [UIFont systemFontOfSize:17];
|
_titleLabel.font = [UIFont systemFontOfSize:17];
|
||||||
}
|
}
|
||||||
return _titleLabel;
|
return _titleLabel;
|
||||||
@@ -375,8 +382,8 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
[_publishButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
[_publishButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||||
_publishButton.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium];
|
_publishButton.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium];
|
||||||
_publishButton.layer.cornerRadius = 25;
|
_publishButton.layer.cornerRadius = 25;
|
||||||
_publishButton.layer.masksToBounds = NO; // 改为 NO 以便渐变层正常显示
|
_publishButton.layer.masksToBounds = NO;
|
||||||
// 渐变背景将在 viewDidLayoutSubviews 中添加(与登录页面统一)
|
|
||||||
[_publishButton addTarget:self action:@selector(onPublish) forControlEvents:UIControlEventTouchUpInside];
|
[_publishButton addTarget:self action:@selector(onPublish) forControlEvents:UIControlEventTouchUpInside];
|
||||||
}
|
}
|
||||||
return _publishButton;
|
return _publishButton;
|
||||||
@@ -386,9 +393,9 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
if (!_textView) {
|
if (!_textView) {
|
||||||
_textView = [SZTextView new];
|
_textView = [SZTextView new];
|
||||||
_textView.placeholder = @"Enter Content";
|
_textView.placeholder = @"Enter Content";
|
||||||
_textView.textColor = [UIColor whiteColor]; // 白色文本适配深色背景
|
_textView.textColor = [UIColor whiteColor];
|
||||||
_textView.placeholderTextColor = [[UIColor whiteColor] colorWithAlphaComponent:0.4]; // 半透明白色占位符
|
_textView.placeholderTextColor = [[UIColor whiteColor] colorWithAlphaComponent:0.4];
|
||||||
_textView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.08]; // 轻微背景色
|
_textView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.08];
|
||||||
_textView.layer.cornerRadius = 12;
|
_textView.layer.cornerRadius = 12;
|
||||||
_textView.layer.masksToBounds = YES;
|
_textView.layer.masksToBounds = YES;
|
||||||
_textView.font = [UIFont systemFontOfSize:15];
|
_textView.font = [UIFont systemFontOfSize:15];
|
||||||
@@ -400,7 +407,7 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
if (!_limitLabel) {
|
if (!_limitLabel) {
|
||||||
_limitLabel = [UILabel new];
|
_limitLabel = [UILabel new];
|
||||||
_limitLabel.text = @"0/500";
|
_limitLabel.text = @"0/500";
|
||||||
_limitLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6]; // 浅色适配深色背景
|
_limitLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6];
|
||||||
_limitLabel.font = [UIFont systemFontOfSize:12];
|
_limitLabel.font = [UIFont systemFontOfSize:12];
|
||||||
}
|
}
|
||||||
return _limitLabel;
|
return _limitLabel;
|
||||||
@@ -410,11 +417,11 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
if (!_emotionButton) {
|
if (!_emotionButton) {
|
||||||
_emotionButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_emotionButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
[_emotionButton setTitle:@"🎨 Add Emotion" forState:UIControlStateNormal];
|
[_emotionButton setTitle:@"🎨 Add Emotion" forState:UIControlStateNormal];
|
||||||
[_emotionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // 白色文本
|
[_emotionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||||
_emotionButton.titleLabel.font = [UIFont systemFontOfSize:15];
|
_emotionButton.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||||
_emotionButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
|
_emotionButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
|
||||||
_emotionButton.contentEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0);
|
_emotionButton.contentEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0);
|
||||||
_emotionButton.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.08]; // 稍微提亮背景
|
_emotionButton.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.08];
|
||||||
_emotionButton.layer.cornerRadius = 8;
|
_emotionButton.layer.cornerRadius = 8;
|
||||||
_emotionButton.layer.masksToBounds = YES;
|
_emotionButton.layer.masksToBounds = YES;
|
||||||
[_emotionButton addTarget:self action:@selector(onEmotionButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_emotionButton addTarget:self action:@selector(onEmotionButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
@@ -426,5 +433,3 @@ NSString *const EPMomentPublishSuccessNotification = @"EPMomentPublishSuccessNot
|
|||||||
- (NSMutableArray *)selectedAssets { if (!_selectedAssets) { _selectedAssets = [NSMutableArray array]; } return _selectedAssets; }
|
- (NSMutableArray *)selectedAssets { if (!_selectedAssets) { _selectedAssets = [NSMutableArray array]; } return _selectedAssets; }
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
//
|
|
||||||
// EPMomentViewController.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-09.
|
// Created by AI on 2025-10-09.
|
||||||
// Copyright © 2025 YuMi. All rights reserved.
|
// Copyright © 2025 YuMi. All rights reserved.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPMomentViewController.h"
|
#import "EPMomentViewController.h"
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
@@ -18,13 +16,13 @@
|
|||||||
|
|
||||||
// MARK: - UI Components
|
// MARK: - UI Components
|
||||||
|
|
||||||
/// 列表视图(MVVM:View)
|
|
||||||
@property (nonatomic, strong) EPMomentListView *listView;
|
@property (nonatomic, strong) EPMomentListView *listView;
|
||||||
|
|
||||||
/// 顶部图标
|
|
||||||
@property (nonatomic, strong) UIImageView *topIconImageView;
|
@property (nonatomic, strong) UIImageView *topIconImageView;
|
||||||
|
|
||||||
/// 顶部固定文案
|
|
||||||
@property (nonatomic, strong) UILabel *topTipLabel;
|
@property (nonatomic, strong) UILabel *topTipLabel;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -38,24 +36,33 @@
|
|||||||
|
|
||||||
self.title = @"Enjoy your Life Time";
|
self.title = @"Enjoy your Life Time";
|
||||||
|
|
||||||
// 设置 title 为白色
|
|
||||||
[self.navigationController.navigationBar setTitleTextAttributes:@{
|
[self.navigationController.navigationBar setTitleTextAttributes:@{
|
||||||
NSForegroundColorAttributeName: [UIColor whiteColor]
|
NSForegroundColorAttributeName: [UIColor whiteColor]
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[self setupUI];
|
[self setupUI];
|
||||||
[self.listView reloadFirstPage];
|
|
||||||
|
|
||||||
// 监听发布成功通知
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(onMomentPublishSuccess:)
|
selector:@selector(onMomentPublishSuccess:)
|
||||||
name:EPMomentPublishSuccessNotification
|
name:EPMomentPublishSuccessNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
// ✅ 新增:冷启动时延迟检查数据,如果没有数据则自动刷新一次
|
NSLog(@"[EPMomentViewController] 页面加载完成,UI 已设置");
|
||||||
[self scheduleAutoRefreshIfNeeded];
|
}
|
||||||
|
|
||||||
NSLog(@"[EPMomentViewController] 页面加载完成");
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
|
[super viewDidAppear:animated];
|
||||||
|
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
NSLog(@"[EPMomentViewController] 首次 viewDidAppear,延迟 0.3s 后开始加载数据");
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
|
NSLog(@"[EPMomentViewController] 触发首次数据加载");
|
||||||
|
[self.listView reloadFirstPage];
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
@@ -73,7 +80,7 @@
|
|||||||
make.edges.mas_equalTo(self.view);
|
make.edges.mas_equalTo(self.view);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 顶部图标
|
|
||||||
[self.view addSubview:self.topIconImageView];
|
[self.view addSubview:self.topIconImageView];
|
||||||
[self.topIconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.topIconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.centerX.equalTo(self.view);
|
make.centerX.equalTo(self.view);
|
||||||
@@ -81,21 +88,21 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(56, 41));
|
make.size.mas_equalTo(CGSizeMake(56, 41));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 顶部固定文案
|
|
||||||
[self.view addSubview:self.topTipLabel];
|
[self.view addSubview:self.topTipLabel];
|
||||||
[self.topTipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.topTipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.topIconImageView.mas_bottom).offset(14);
|
make.top.equalTo(self.topIconImageView.mas_bottom).offset(14);
|
||||||
make.leading.trailing.equalTo(self.view).inset(20);
|
make.leading.trailing.equalTo(self.view).inset(20);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 列表视图
|
|
||||||
[self.view addSubview:self.listView];
|
[self.view addSubview:self.listView];
|
||||||
[self.listView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.listView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.bottom.equalTo(self.view);
|
make.leading.trailing.bottom.equalTo(self.view);
|
||||||
make.top.equalTo(self.topTipLabel.mas_bottom).offset(8);
|
make.top.equalTo(self.topTipLabel.mas_bottom).offset(8);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 右上角发布按钮
|
|
||||||
UIImage *addIcon = [UIImage imageNamed:@"icon_moment_add"];
|
UIImage *addIcon = [UIImage imageNamed:@"icon_moment_add"];
|
||||||
UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
publishButton.contentMode = UIViewContentModeScaleAspectFit;
|
publishButton.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
@@ -108,26 +115,6 @@
|
|||||||
NSLog(@"[EPMomentViewController] UI 设置完成");
|
NSLog(@"[EPMomentViewController] UI 设置完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不再在 VC 内部直接发请求/维护分页
|
|
||||||
|
|
||||||
// MARK: - Auto Refresh
|
|
||||||
|
|
||||||
/// 延迟检查数据,如果没有数据则自动刷新(解决冷启动数据未加载问题)
|
|
||||||
- (void)scheduleAutoRefreshIfNeeded {
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
||||||
__strong typeof(weakSelf) self = weakSelf;
|
|
||||||
if (!self) return;
|
|
||||||
|
|
||||||
// 检查是否有数据
|
|
||||||
if (self.listView.rawList.count == 0) {
|
|
||||||
NSLog(@"[EPMomentViewController] ⚠️ 冷启动 1 秒后检测到无数据,自动刷新一次");
|
|
||||||
[self.listView reloadFirstPage];
|
|
||||||
} else {
|
|
||||||
NSLog(@"[EPMomentViewController] ✅ 冷启动 1 秒后检测到已有 %lu 条数据,无需刷新", (unsigned long)self.listView.rawList.count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Actions
|
// MARK: - Actions
|
||||||
|
|
||||||
@@ -155,17 +142,16 @@
|
|||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 列表点击回调由 listView 暴露
|
|
||||||
|
|
||||||
// MARK: - Lazy Loading
|
// MARK: - Lazy Loading
|
||||||
|
|
||||||
- (EPMomentListView *)listView {
|
- (EPMomentListView *)listView {
|
||||||
if (!_listView) {
|
if (!_listView) {
|
||||||
_listView = [[EPMomentListView alloc] initWithFrame:CGRectZero];
|
_listView = [[EPMomentListView alloc] initWithFrame:CGRectZero];
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
_listView.onSelectMoment = ^(NSInteger index) {
|
_listView.onSelectMoment = ^(NSInteger index) {
|
||||||
__strong typeof(weakSelf) self = weakSelf;
|
|
||||||
// [self showAlertWithMessage:[NSString stringWithFormat:YMLocalizedString(@"moment.item_clicked"), (long)index]];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return _listView;
|
return _listView;
|
||||||
@@ -190,6 +176,5 @@
|
|||||||
return _topTipLabel;
|
return _topTipLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无数据源属性
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
//
|
|
||||||
// EPEmotionColorStorage.h
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-14.
|
// Created by AI on 2025-10-14.
|
||||||
// 本地情绪颜色存储管理器(基于 UserDefaults)
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@@ -12,47 +9,38 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@interface EPEmotionColorStorage : NSObject
|
@interface EPEmotionColorStorage : NSObject
|
||||||
|
|
||||||
/// 保存动态的情绪颜色
|
|
||||||
/// @param hexColor Hex 格式颜色值,如 #FF0000
|
|
||||||
/// @param dynamicId 动态 ID
|
|
||||||
+ (void)saveColor:(NSString *)hexColor forDynamicId:(NSString *)dynamicId;
|
+ (void)saveColor:(NSString *)hexColor forDynamicId:(NSString *)dynamicId;
|
||||||
|
|
||||||
/// 获取动态关联的情绪颜色
|
|
||||||
/// @param dynamicId 动态 ID
|
|
||||||
/// @return Hex 格式颜色值,若未设置则返回 nil
|
|
||||||
+ (nullable NSString *)colorForDynamicId:(NSString *)dynamicId;
|
+ (nullable NSString *)colorForDynamicId:(NSString *)dynamicId;
|
||||||
|
|
||||||
/// 删除动态的情绪颜色
|
|
||||||
/// @param dynamicId 动态 ID
|
|
||||||
+ (void)removeColorForDynamicId:(NSString *)dynamicId;
|
+ (void)removeColorForDynamicId:(NSString *)dynamicId;
|
||||||
|
|
||||||
/// 获取所有预设情绪颜色(6种基础情绪)
|
|
||||||
/// @return Hex 颜色数组
|
|
||||||
+ (NSArray<NSString *> *)allEmotionColors;
|
+ (NSArray<NSString *> *)allEmotionColors;
|
||||||
|
|
||||||
/// 获取随机情绪颜色(不持久化)
|
|
||||||
+ (NSString *)randomEmotionColor;
|
+ (NSString *)randomEmotionColor;
|
||||||
|
|
||||||
/// 根据颜色值获取情绪名称
|
|
||||||
/// @param hexColor Hex 格式颜色值,如 #FFD700
|
|
||||||
/// @return 情绪名称(如 "Joy"),若未匹配返回 nil
|
|
||||||
+ (nullable NSString *)emotionNameForColor:(NSString *)hexColor;
|
+ (nullable NSString *)emotionNameForColor:(NSString *)hexColor;
|
||||||
|
|
||||||
#pragma mark - User Signature Color
|
#pragma mark - User Signature Color
|
||||||
|
|
||||||
/// 保存用户专属颜色
|
|
||||||
+ (void)saveUserSignatureColor:(NSString *)hexColor;
|
+ (void)saveUserSignatureColor:(NSString *)hexColor;
|
||||||
|
|
||||||
/// 获取用户专属颜色
|
|
||||||
+ (nullable NSString *)userSignatureColor;
|
+ (nullable NSString *)userSignatureColor;
|
||||||
|
|
||||||
/// 是否已设置专属颜色
|
|
||||||
+ (BOOL)hasUserSignatureColor;
|
+ (BOOL)hasUserSignatureColor;
|
||||||
|
|
||||||
/// 清除专属颜色(调试用)
|
|
||||||
+ (void)clearUserSignatureColor;
|
+ (void)clearUserSignatureColor;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPEmotionColorStorage.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-14.
|
// Created by AI on 2025-10-14.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPEmotionColorStorage.h"
|
#import "EPEmotionColorStorage.h"
|
||||||
|
|
||||||
@@ -44,14 +42,14 @@ static NSString *const kUserSignatureTimestampKey = @"EP_User_Signature_Timestam
|
|||||||
|
|
||||||
+ (NSArray<NSString *> *)allEmotionColors {
|
+ (NSArray<NSString *> *)allEmotionColors {
|
||||||
return @[
|
return @[
|
||||||
@"#FFD700", // 喜悦 Joy(金黄)- 降低亮度,更温暖
|
@"#FFD700",
|
||||||
@"#4A90E2", // 悲伤 Sadness(天蓝)- 提高亮度,更柔和
|
@"#4A90E2",
|
||||||
@"#E74C3C", // 愤怒 Anger(珊瑚红)- 降低饱和度
|
@"#E74C3C",
|
||||||
@"#9B59B6", // 恐惧 Fear(紫罗兰)- 稍微提亮
|
@"#9B59B6",
|
||||||
@"#FF9A3D", // 惊讶 Surprise(柔和橙)- 略微调暗
|
@"#FF9A3D",
|
||||||
@"#2ECC71", // 厌恶 Disgust(翡翠绿)- 大幅降低亮度
|
@"#2ECC71",
|
||||||
@"#3498DB", // 信任 Trust(亮蓝)- 清新明亮
|
@"#3498DB",
|
||||||
@"#F39C12" // 期待 Anticipation(琥珀色)- 温暖期待
|
@"#F39C12"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ static NSString *const kUserSignatureTimestampKey = @"EP_User_Signature_Timestam
|
|||||||
NSArray<NSString *> *colors = [self allEmotionColors];
|
NSArray<NSString *> *colors = [self allEmotionColors];
|
||||||
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
||||||
|
|
||||||
// 大小写不敏感比较
|
|
||||||
NSString *upperHex = [hexColor uppercaseString];
|
NSString *upperHex = [hexColor uppercaseString];
|
||||||
for (NSInteger i = 0; i < colors.count; i++) {
|
for (NSInteger i = 0; i < colors.count; i++) {
|
||||||
if ([[colors[i] uppercaseString] isEqualToString:upperHex]) {
|
if ([[colors[i] uppercaseString] isEqualToString:upperHex]) {
|
||||||
@@ -115,4 +113,3 @@ static NSString *const kUserSignatureTimestampKey = @"EP_User_Signature_Timestam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -1,55 +1,47 @@
|
|||||||
//
|
|
||||||
// EPMomentAPISwiftHelper.swift
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-11.
|
// Created by AI on 2025-10-11.
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// 动态 API 封装(Swift 现代化版本)
|
|
||||||
/// 统一封装列表获取和发布功能,完全替代 OC 版本
|
|
||||||
@objc class EPMomentAPISwiftHelper: NSObject {
|
@objc class EPMomentAPISwiftHelper: NSObject {
|
||||||
|
|
||||||
/// 拉取最新动态列表
|
|
||||||
/// - Parameters:
|
|
||||||
/// - nextID: 下一页 ID,首次传空字符串
|
|
||||||
/// - completion: 成功回调 (动态列表, 下一页ID)
|
|
||||||
/// - failure: 失败回调 (错误码, 错误信息)
|
|
||||||
@objc func fetchLatestMomentsWithNextID(
|
@objc func fetchLatestMomentsWithNextID(
|
||||||
_ nextID: String,
|
_ nextID: String,
|
||||||
completion: @escaping ([MomentsInfoModel], String) -> Void,
|
completion: @escaping ([MomentsInfoModel], String) -> Void,
|
||||||
failure: @escaping (Int, String) -> Void
|
failure: @escaping (Int, String) -> Void
|
||||||
) {
|
) {
|
||||||
let pageSize = "20"
|
let pageSize = "20"
|
||||||
let types = "0,2" // 图片+文字
|
let types = "0,2"
|
||||||
|
|
||||||
|
NSLog("[EPMomentAPISwiftHelper] 🔄 开始请求动态列表,nextID=\(nextID.isEmpty ? "(首页)" : nextID)")
|
||||||
|
|
||||||
Api.momentsLatestList({ (data, code, msg) in
|
Api.momentsLatestList({ (data, code, msg) in
|
||||||
|
NSLog("[EPMomentAPISwiftHelper] 📥 收到响应,code=\(code)")
|
||||||
|
|
||||||
if code == 200, let dict = data?.data as? NSDictionary {
|
if code == 200, let dict = data?.data as? NSDictionary {
|
||||||
// 使用 MomentsListInfoModel 序列化响应数据(标准化方式)
|
NSLog("[EPMomentAPISwiftHelper] 📦 开始解析数据字典")
|
||||||
// 参考: XPMomentsLatestPresenter.m line 25 / EPLoginService.swift line 34
|
|
||||||
// Swift 中使用 mj_object(withKeyValues:) 而不是 model(withJSON:)
|
|
||||||
if let listInfo = MomentsListInfoModel.mj_object(withKeyValues: dict) {
|
if let listInfo = MomentsListInfoModel.mj_object(withKeyValues: dict) {
|
||||||
let dynamicList = listInfo.dynamicList
|
let dynamicList = listInfo.dynamicList
|
||||||
let nextDynamicId = listInfo.nextDynamicId
|
let nextDynamicId = listInfo.nextDynamicId
|
||||||
|
NSLog("[EPMomentAPISwiftHelper] ✅ 解析成功,dynamicList.count=\(dynamicList.count), nextDynamicId=\(nextDynamicId)")
|
||||||
completion(dynamicList, nextDynamicId)
|
completion(dynamicList, nextDynamicId)
|
||||||
} else {
|
} else {
|
||||||
// 序列化失败时返回空数据
|
NSLog("[EPMomentAPISwiftHelper] ⚠️ 解析失败,返回空数组")
|
||||||
completion([], "")
|
completion([], "")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
NSLog("[EPMomentAPISwiftHelper] ❌ 请求失败,code=\(code), msg=\(msg ?? "无错误信息")")
|
||||||
failure(Int(code), msg ?? YMLocalizedString("error.request_failed"))
|
failure(Int(code), msg ?? YMLocalizedString("error.request_failed"))
|
||||||
}
|
}
|
||||||
}, dynamicId: nextID, pageSize: pageSize, types: types)
|
}, dynamicId: nextID, pageSize: pageSize, types: types)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 发布动态
|
|
||||||
/// - Parameters:
|
|
||||||
/// - type: "0"=纯文本, "2"=图片
|
|
||||||
/// - content: 文本内容
|
|
||||||
/// - resList: 图片信息数组
|
|
||||||
/// - completion: 成功回调
|
|
||||||
/// - failure: 失败回调 (错误码, 错误信息)
|
|
||||||
@objc func publishMoment(
|
@objc func publishMoment(
|
||||||
type: String,
|
type: String,
|
||||||
content: String,
|
content: String,
|
||||||
@@ -62,10 +54,9 @@ import Foundation
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// worldId 传空字符串(话题功能不实现)
|
|
||||||
// NOTE: 旧版本 XPMonentsPublishViewController 包含话题选择功能
|
// NOTE: 旧版本 XPMonentsPublishViewController 包含话题选择功能
|
||||||
// 但实际业务中话题功能使用率低,新版本暂不实现
|
|
||||||
// 如需实现参考: YuMi/Modules/YMMonents/View/XPMonentsPublishTopicView
|
|
||||||
|
|
||||||
Api.momentsPublish({ (data, code, msg) in
|
Api.momentsPublish({ (data, code, msg) in
|
||||||
if code == 200 {
|
if code == 200 {
|
||||||
@@ -76,14 +67,7 @@ import Foundation
|
|||||||
}, uid: uid, type: type, worldId: "", content: content, resList: resList)
|
}, uid: uid, type: type, worldId: "", content: content, resList: resList)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 点赞/取消点赞动态
|
|
||||||
/// - Parameters:
|
|
||||||
/// - dynamicId: 动态 ID
|
|
||||||
/// - isLike: true=点赞,false=取消点赞
|
|
||||||
/// - likedUid: 动态发布者 UID
|
|
||||||
/// - worldId: 话题 ID
|
|
||||||
/// - completion: 成功回调
|
|
||||||
/// - failure: 失败回调 (错误码, 错误信息)
|
|
||||||
@objc func likeMoment(
|
@objc func likeMoment(
|
||||||
dynamicId: String,
|
dynamicId: String,
|
||||||
isLike: Bool,
|
isLike: Bool,
|
||||||
@@ -109,4 +93,3 @@ import Foundation
|
|||||||
}, dynamicId: dynamicId, uid: uid, status: status, likedUid: likedUid, worldId: worldIdStr)
|
}, dynamicId: dynamicId, uid: uid, status: status, likedUid: likedUid, worldId: worldIdStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPEmotionColorPicker.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-14.
|
// Created by AI on 2025-10-14.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPEmotionColorPicker.h"
|
#import "EPEmotionColorPicker.h"
|
||||||
#import "EPEmotionColorWheelView.h"
|
#import "EPEmotionColorWheelView.h"
|
||||||
@@ -39,27 +37,27 @@
|
|||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
self.backgroundColor = [UIColor clearColor];
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
|
||||||
// 背景遮罩
|
|
||||||
[self addSubview:self.backgroundMask];
|
[self addSubview:self.backgroundMask];
|
||||||
[self.backgroundMask mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.backgroundMask mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.edges.equalTo(self);
|
make.edges.equalTo(self);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 底部卡片容器
|
|
||||||
[self addSubview:self.containerView];
|
[self addSubview:self.containerView];
|
||||||
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.bottom.equalTo(self);
|
make.leading.trailing.bottom.equalTo(self);
|
||||||
make.height.mas_equalTo(450); // 增加高度以适应新布局
|
make.height.mas_equalTo(450);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 标题
|
|
||||||
[self.containerView addSubview:self.titleLabel];
|
[self.containerView addSubview:self.titleLabel];
|
||||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.containerView).offset(20);
|
make.top.equalTo(self.containerView).offset(20);
|
||||||
make.centerX.equalTo(self.containerView);
|
make.centerX.equalTo(self.containerView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Info 按钮(左上角)
|
|
||||||
[self.containerView addSubview:self.infoButton];
|
[self.containerView addSubview:self.infoButton];
|
||||||
[self.infoButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.infoButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self.containerView).offset(16);
|
make.leading.equalTo(self.containerView).offset(16);
|
||||||
@@ -67,7 +65,7 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(28, 28));
|
make.size.mas_equalTo(CGSizeMake(28, 28));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// OK 按钮(右上角)
|
|
||||||
[self.containerView addSubview:self.okButton];
|
[self.containerView addSubview:self.okButton];
|
||||||
[self.okButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.okButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.trailing.equalTo(self.containerView).offset(-16);
|
make.trailing.equalTo(self.containerView).offset(-16);
|
||||||
@@ -75,7 +73,7 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(60, 32));
|
make.size.mas_equalTo(CGSizeMake(60, 32));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 选中状态显示区域
|
|
||||||
[self.containerView addSubview:self.selectedColorView];
|
[self.containerView addSubview:self.selectedColorView];
|
||||||
[self.selectedColorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.selectedColorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.titleLabel.mas_bottom).offset(20);
|
make.top.equalTo(self.titleLabel.mas_bottom).offset(20);
|
||||||
@@ -84,12 +82,12 @@
|
|||||||
make.leading.trailing.equalTo(self.containerView).inset(20);
|
make.leading.trailing.equalTo(self.containerView).inset(20);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 色轮视图(使用共享组件)
|
|
||||||
[self.containerView addSubview:self.colorWheelView];
|
[self.containerView addSubview:self.colorWheelView];
|
||||||
[self.colorWheelView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.colorWheelView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.centerX.equalTo(self.containerView);
|
make.centerX.equalTo(self.containerView);
|
||||||
make.top.equalTo(self.selectedColorView.mas_bottom).offset(20);
|
make.top.equalTo(self.selectedColorView.mas_bottom).offset(20);
|
||||||
make.size.mas_equalTo(CGSizeMake(280, 280)); // 调整尺寸
|
make.size.mas_equalTo(CGSizeMake(280, 280));
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,11 +117,11 @@
|
|||||||
make.edges.equalTo(parentView);
|
make.edges.equalTo(parentView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 初始状态
|
|
||||||
self.backgroundMask.alpha = 0;
|
|
||||||
self.containerView.transform = CGAffineTransformMakeTranslation(0, 450); // 更新动画偏移量
|
|
||||||
|
|
||||||
// 弹出动画
|
self.backgroundMask.alpha = 0;
|
||||||
|
self.containerView.transform = CGAffineTransformMakeTranslation(0, 450);
|
||||||
|
|
||||||
|
|
||||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||||
self.backgroundMask.alpha = 1;
|
self.backgroundMask.alpha = 1;
|
||||||
self.containerView.transform = CGAffineTransformIdentity;
|
self.containerView.transform = CGAffineTransformIdentity;
|
||||||
@@ -133,7 +131,7 @@
|
|||||||
- (void)dismiss {
|
- (void)dismiss {
|
||||||
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
|
||||||
self.backgroundMask.alpha = 0;
|
self.backgroundMask.alpha = 0;
|
||||||
self.containerView.transform = CGAffineTransformMakeTranslation(0, 450); // 更新动画偏移量
|
self.containerView.transform = CGAffineTransformMakeTranslation(0, 450);
|
||||||
} completion:^(BOOL finished) {
|
} completion:^(BOOL finished) {
|
||||||
[self removeFromSuperview];
|
[self removeFromSuperview];
|
||||||
}];
|
}];
|
||||||
@@ -177,12 +175,12 @@
|
|||||||
if (!_infoButton) {
|
if (!_infoButton) {
|
||||||
_infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
|
||||||
// 使用系统 info.circle 图标
|
|
||||||
UIImage *infoIcon = [UIImage systemImageNamed:@"info.circle"];
|
UIImage *infoIcon = [UIImage systemImageNamed:@"info.circle"];
|
||||||
[_infoButton setImage:infoIcon forState:UIControlStateNormal];
|
[_infoButton setImage:infoIcon forState:UIControlStateNormal];
|
||||||
_infoButton.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
|
_infoButton.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
|
||||||
|
|
||||||
// 点击效果
|
|
||||||
[_infoButton addTarget:self action:@selector(onInfoButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_infoButton addTarget:self action:@selector(onInfoButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
}
|
}
|
||||||
return _infoButton;
|
return _infoButton;
|
||||||
@@ -194,11 +192,11 @@
|
|||||||
_selectedColorView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1];
|
_selectedColorView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1];
|
||||||
_selectedColorView.layer.cornerRadius = 25;
|
_selectedColorView.layer.cornerRadius = 25;
|
||||||
_selectedColorView.layer.masksToBounds = YES;
|
_selectedColorView.layer.masksToBounds = YES;
|
||||||
_selectedColorView.hidden = YES; // 初始隐藏
|
_selectedColorView.hidden = YES;
|
||||||
|
|
||||||
|
|
||||||
// 颜色圆点
|
|
||||||
UIView *colorDot = [[UIView alloc] init];
|
UIView *colorDot = [[UIView alloc] init];
|
||||||
colorDot.tag = 100; // 用于后续查找
|
colorDot.tag = 100;
|
||||||
colorDot.layer.cornerRadius = 12;
|
colorDot.layer.cornerRadius = 12;
|
||||||
colorDot.layer.masksToBounds = YES;
|
colorDot.layer.masksToBounds = YES;
|
||||||
[_selectedColorView addSubview:colorDot];
|
[_selectedColorView addSubview:colorDot];
|
||||||
@@ -208,7 +206,7 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(24, 24));
|
make.size.mas_equalTo(CGSizeMake(24, 24));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 情绪名称标签
|
|
||||||
[_selectedColorView addSubview:self.selectedColorLabel];
|
[_selectedColorView addSubview:self.selectedColorLabel];
|
||||||
[self.selectedColorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.selectedColorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(colorDot.mas_trailing).offset(12);
|
make.leading.equalTo(colorDot.mas_trailing).offset(12);
|
||||||
@@ -238,7 +236,7 @@
|
|||||||
_okButton.backgroundColor = [UIColor colorWithRed:0x9B/255.0 green:0x59/255.0 blue:0xB6/255.0 alpha:1.0];
|
_okButton.backgroundColor = [UIColor colorWithRed:0x9B/255.0 green:0x59/255.0 blue:0xB6/255.0 alpha:1.0];
|
||||||
_okButton.layer.cornerRadius = 16;
|
_okButton.layer.cornerRadius = 16;
|
||||||
_okButton.layer.masksToBounds = YES;
|
_okButton.layer.masksToBounds = YES;
|
||||||
_okButton.enabled = NO; // 初始禁用
|
_okButton.enabled = NO;
|
||||||
_okButton.alpha = 0.5;
|
_okButton.alpha = 0.5;
|
||||||
[_okButton addTarget:self action:@selector(onOkButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_okButton addTarget:self action:@selector(onOkButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
}
|
}
|
||||||
@@ -256,41 +254,41 @@
|
|||||||
_colorWheelView.onColorTapped = ^(NSString *hexColor, NSInteger index) {
|
_colorWheelView.onColorTapped = ^(NSString *hexColor, NSInteger index) {
|
||||||
__strong typeof(weakSelf) self = weakSelf;
|
__strong typeof(weakSelf) self = weakSelf;
|
||||||
|
|
||||||
// 保存当前选择
|
|
||||||
self.currentSelectedColor = hexColor;
|
self.currentSelectedColor = hexColor;
|
||||||
self.currentSelectedIndex = index;
|
self.currentSelectedIndex = index;
|
||||||
|
|
||||||
// 更新选中状态显示
|
|
||||||
[self updateSelectedColorDisplay:hexColor index:index];
|
[self updateSelectedColorDisplay:hexColor index:index];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return _colorWheelView;
|
return _colorWheelView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新选中颜色显示
|
|
||||||
- (void)updateSelectedColorDisplay:(NSString *)hexColor index:(NSInteger)index {
|
- (void)updateSelectedColorDisplay:(NSString *)hexColor index:(NSInteger)index {
|
||||||
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
||||||
|
|
||||||
// 显示选中状态区域
|
|
||||||
self.selectedColorView.hidden = NO;
|
self.selectedColorView.hidden = NO;
|
||||||
|
|
||||||
// 更新颜色圆点
|
|
||||||
UIView *colorDot = [self.selectedColorView viewWithTag:100];
|
UIView *colorDot = [self.selectedColorView viewWithTag:100];
|
||||||
colorDot.backgroundColor = [self colorFromHex:hexColor];
|
colorDot.backgroundColor = [self colorFromHex:hexColor];
|
||||||
|
|
||||||
// 更新情绪名称
|
|
||||||
self.selectedColorLabel.text = emotions[index];
|
self.selectedColorLabel.text = emotions[index];
|
||||||
|
|
||||||
// 启用OK按钮
|
|
||||||
self.okButton.enabled = YES;
|
self.okButton.enabled = YES;
|
||||||
self.okButton.alpha = 1.0;
|
self.okButton.alpha = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hex 转 UIColor
|
|
||||||
- (UIColor *)colorFromHex:(NSString *)hexString {
|
- (UIColor *)colorFromHex:(NSString *)hexString {
|
||||||
unsigned rgbValue = 0;
|
unsigned rgbValue = 0;
|
||||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||||
[scanner setScanLocation:1]; // 跳过 #
|
[scanner setScanLocation:1];
|
||||||
[scanner scanHexInt:&rgbValue];
|
[scanner scanHexInt:&rgbValue];
|
||||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
||||||
green:((rgbValue & 0xFF00) >> 8)/255.0
|
green:((rgbValue & 0xFF00) >> 8)/255.0
|
||||||
@@ -299,4 +297,3 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPEmotionColorWheelView.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-15.
|
// Created by AI on 2025-10-15.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPEmotionColorWheelView.h"
|
#import "EPEmotionColorWheelView.h"
|
||||||
#import "EPEmotionColorStorage.h"
|
#import "EPEmotionColorStorage.h"
|
||||||
@@ -11,7 +9,7 @@
|
|||||||
@interface EPEmotionColorWheelView ()
|
@interface EPEmotionColorWheelView ()
|
||||||
|
|
||||||
@property (nonatomic, strong) NSMutableArray<UIButton *> *colorButtons;
|
@property (nonatomic, strong) NSMutableArray<UIButton *> *colorButtons;
|
||||||
@property (nonatomic, assign) NSInteger selectedIndex; // 当前选中的索引
|
@property (nonatomic, assign) NSInteger selectedIndex;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -21,7 +19,7 @@
|
|||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame {
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
if (self = [super initWithFrame:frame]) {
|
if (self = [super initWithFrame:frame]) {
|
||||||
// 默认配置
|
|
||||||
_radius = 80.0;
|
_radius = 80.0;
|
||||||
_buttonSize = 50.0;
|
_buttonSize = 50.0;
|
||||||
_colorButtons = [NSMutableArray array];
|
_colorButtons = [NSMutableArray array];
|
||||||
@@ -34,7 +32,7 @@
|
|||||||
- (void)layoutSubviews {
|
- (void)layoutSubviews {
|
||||||
[super layoutSubviews];
|
[super layoutSubviews];
|
||||||
|
|
||||||
// 如果色轮还未创建,自动创建
|
|
||||||
if (self.colorButtons.count == 0) {
|
if (self.colorButtons.count == 0) {
|
||||||
[self createColorButtons];
|
[self createColorButtons];
|
||||||
}
|
}
|
||||||
@@ -45,13 +43,13 @@
|
|||||||
- (void)reloadWithPreselectedColor:(NSString *)color {
|
- (void)reloadWithPreselectedColor:(NSString *)color {
|
||||||
self.preselectedColor = color;
|
self.preselectedColor = color;
|
||||||
|
|
||||||
// 清除旧按钮
|
|
||||||
for (UIButton *btn in self.colorButtons) {
|
for (UIButton *btn in self.colorButtons) {
|
||||||
[btn removeFromSuperview];
|
[btn removeFromSuperview];
|
||||||
}
|
}
|
||||||
[self.colorButtons removeAllObjects];
|
[self.colorButtons removeAllObjects];
|
||||||
|
|
||||||
// 重新创建
|
|
||||||
[self createColorButtons];
|
[self createColorButtons];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +64,7 @@
|
|||||||
CGFloat centerY = CGRectGetHeight(self.bounds) / 2.0;
|
CGFloat centerY = CGRectGetHeight(self.bounds) / 2.0;
|
||||||
|
|
||||||
for (NSInteger i = 0; i < colors.count; i++) {
|
for (NSInteger i = 0; i < colors.count; i++) {
|
||||||
// 从顶部开始,顺时针排列
|
|
||||||
CGFloat angle = angleStep * i - M_PI_2;
|
CGFloat angle = angleStep * i - M_PI_2;
|
||||||
CGFloat x = centerX + self.radius * cos(angle) - self.buttonSize / 2.0;
|
CGFloat x = centerX + self.radius * cos(angle) - self.buttonSize / 2.0;
|
||||||
CGFloat y = centerY + self.radius * sin(angle) - self.buttonSize / 2.0;
|
CGFloat y = centerY + self.radius * sin(angle) - self.buttonSize / 2.0;
|
||||||
@@ -81,13 +79,13 @@
|
|||||||
button.tag = i;
|
button.tag = i;
|
||||||
[button addTarget:self action:@selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
|
[button addTarget:self action:@selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
|
||||||
// 如果是预选中颜色,添加选中态标识
|
|
||||||
if (self.preselectedColor && [colors[i] isEqualToString:self.preselectedColor]) {
|
if (self.preselectedColor && [colors[i] isEqualToString:self.preselectedColor]) {
|
||||||
button.layer.borderWidth = 5.0; // 加粗边框
|
button.layer.borderWidth = 5.0;
|
||||||
button.transform = CGAffineTransformMakeScale(1.1, 1.1); // 稍微放大
|
button.transform = CGAffineTransformMakeScale(1.1, 1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加阴影效果
|
|
||||||
button.layer.shadowColor = [self colorFromHex:colors[i]].CGColor;
|
button.layer.shadowColor = [self colorFromHex:colors[i]].CGColor;
|
||||||
button.layer.shadowOffset = CGSizeMake(0, 2);
|
button.layer.shadowOffset = CGSizeMake(0, 2);
|
||||||
button.layer.shadowOpacity = 0.6;
|
button.layer.shadowOpacity = 0.6;
|
||||||
@@ -103,10 +101,10 @@
|
|||||||
NSInteger index = sender.tag;
|
NSInteger index = sender.tag;
|
||||||
self.selectedIndex = index;
|
self.selectedIndex = index;
|
||||||
|
|
||||||
// 更新选中状态
|
|
||||||
[self updateSelectionState];
|
[self updateSelectionState];
|
||||||
|
|
||||||
// 执行回调(仅用于更新UI,不直接确认选择)
|
|
||||||
NSArray<NSString *> *colors = [EPEmotionColorStorage allEmotionColors];
|
NSArray<NSString *> *colors = [EPEmotionColorStorage allEmotionColors];
|
||||||
NSString *selectedColor = colors[index];
|
NSString *selectedColor = colors[index];
|
||||||
if (self.onColorTapped) {
|
if (self.onColorTapped) {
|
||||||
@@ -114,16 +112,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新选中状态
|
|
||||||
- (void)updateSelectionState {
|
- (void)updateSelectionState {
|
||||||
for (NSInteger i = 0; i < self.colorButtons.count; i++) {
|
for (NSInteger i = 0; i < self.colorButtons.count; i++) {
|
||||||
UIButton *button = self.colorButtons[i];
|
UIButton *button = self.colorButtons[i];
|
||||||
if (i == self.selectedIndex) {
|
if (i == self.selectedIndex) {
|
||||||
// 选中状态:加粗边框,稍微放大
|
|
||||||
button.layer.borderWidth = 5.0;
|
button.layer.borderWidth = 5.0;
|
||||||
button.transform = CGAffineTransformMakeScale(1.1, 1.1);
|
button.transform = CGAffineTransformMakeScale(1.1, 1.1);
|
||||||
} else {
|
} else {
|
||||||
// 未选中状态:正常边框,正常大小
|
|
||||||
button.layer.borderWidth = 3.0;
|
button.layer.borderWidth = 3.0;
|
||||||
button.transform = CGAffineTransformIdentity;
|
button.transform = CGAffineTransformIdentity;
|
||||||
}
|
}
|
||||||
@@ -135,7 +133,7 @@
|
|||||||
- (UIColor *)colorFromHex:(NSString *)hexString {
|
- (UIColor *)colorFromHex:(NSString *)hexString {
|
||||||
unsigned rgbValue = 0;
|
unsigned rgbValue = 0;
|
||||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||||
[scanner setScanLocation:1]; // 跳过 #
|
[scanner setScanLocation:1];
|
||||||
[scanner scanHexInt:&rgbValue];
|
[scanner scanHexInt:&rgbValue];
|
||||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
||||||
green:((rgbValue & 0xFF00) >> 8)/255.0
|
green:((rgbValue & 0xFF00) >> 8)/255.0
|
||||||
@@ -144,4 +142,3 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPEmotionInfoView.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-16.
|
// Created by AI on 2025-10-16.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPEmotionInfoView.h"
|
#import "EPEmotionInfoView.h"
|
||||||
#import <Masonry/Masonry.h>
|
#import <Masonry/Masonry.h>
|
||||||
@@ -33,13 +31,13 @@
|
|||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
self.backgroundColor = [UIColor clearColor];
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
|
||||||
// 背景遮罩
|
|
||||||
[self addSubview:self.backgroundMask];
|
[self addSubview:self.backgroundMask];
|
||||||
[self.backgroundMask mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.backgroundMask mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.edges.equalTo(self);
|
make.edges.equalTo(self);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 内容容器
|
|
||||||
[self addSubview:self.contentContainer];
|
[self addSubview:self.contentContainer];
|
||||||
[self.contentContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.contentContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.center.equalTo(self);
|
make.center.equalTo(self);
|
||||||
@@ -47,14 +45,14 @@
|
|||||||
make.height.mas_lessThanOrEqualTo(500);
|
make.height.mas_lessThanOrEqualTo(500);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 标题
|
|
||||||
[self.contentContainer addSubview:self.titleLabel];
|
[self.contentContainer addSubview:self.titleLabel];
|
||||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.contentContainer).offset(24);
|
make.top.equalTo(self.contentContainer).offset(24);
|
||||||
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 滚动视图
|
|
||||||
[self.contentContainer addSubview:self.scrollView];
|
[self.contentContainer addSubview:self.scrollView];
|
||||||
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.titleLabel.mas_bottom).offset(16);
|
make.top.equalTo(self.titleLabel.mas_bottom).offset(16);
|
||||||
@@ -62,14 +60,14 @@
|
|||||||
make.height.mas_lessThanOrEqualTo(320);
|
make.height.mas_lessThanOrEqualTo(320);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 内容文本
|
|
||||||
[self.scrollView addSubview:self.contentLabel];
|
[self.scrollView addSubview:self.contentLabel];
|
||||||
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.edges.equalTo(self.scrollView);
|
make.edges.equalTo(self.scrollView);
|
||||||
make.width.equalTo(self.scrollView);
|
make.width.equalTo(self.scrollView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 关闭按钮
|
|
||||||
[self.contentContainer addSubview:self.closeButton];
|
[self.contentContainer addSubview:self.closeButton];
|
||||||
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.scrollView.mas_bottom).offset(20);
|
make.top.equalTo(self.scrollView.mas_bottom).offset(20);
|
||||||
@@ -98,12 +96,12 @@
|
|||||||
make.edges.equalTo(parentView);
|
make.edges.equalTo(parentView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 初始状态
|
|
||||||
self.backgroundMask.alpha = 0;
|
self.backgroundMask.alpha = 0;
|
||||||
self.contentContainer.alpha = 0;
|
self.contentContainer.alpha = 0;
|
||||||
self.contentContainer.transform = CGAffineTransformMakeScale(0.9, 0.9);
|
self.contentContainer.transform = CGAffineTransformMakeScale(0.9, 0.9);
|
||||||
|
|
||||||
// 弹出动画
|
|
||||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||||
self.backgroundMask.alpha = 1;
|
self.backgroundMask.alpha = 1;
|
||||||
self.contentContainer.alpha = 1;
|
self.contentContainer.alpha = 1;
|
||||||
@@ -170,7 +168,7 @@
|
|||||||
_contentLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
|
_contentLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
|
||||||
_contentLabel.font = [UIFont systemFontOfSize:15];
|
_contentLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
|
||||||
// 普拉奇克情绪轮说明文本
|
|
||||||
NSString *content = @"Based on Plutchik's Wheel of Emotions, we use 8 core colors to represent fundamental human emotions:\n\n"
|
NSString *content = @"Based on Plutchik's Wheel of Emotions, we use 8 core colors to represent fundamental human emotions:\n\n"
|
||||||
"🟡 Joy (Gold)\n"
|
"🟡 Joy (Gold)\n"
|
||||||
"Represents happiness, delight, and cheerfulness. Like sunshine warming your heart.\n\n"
|
"Represents happiness, delight, and cheerfulness. Like sunshine warming your heart.\n\n"
|
||||||
@@ -210,4 +208,3 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
//
|
|
||||||
// NewMomentCell.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-09.
|
// Created by AI on 2025-10-09.
|
||||||
// Copyright © 2025 YuMi. All rights reserved.
|
// Copyright © 2025 YuMi. All rights reserved.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPMomentCell.h"
|
#import "EPMomentCell.h"
|
||||||
#import "MomentsInfoModel.h"
|
#import "MomentsInfoModel.h"
|
||||||
@@ -12,52 +10,50 @@
|
|||||||
#import "NetImageView.h"
|
#import "NetImageView.h"
|
||||||
#import "EPEmotionColorStorage.h"
|
#import "EPEmotionColorStorage.h"
|
||||||
#import "SDPhotoBrowser.h"
|
#import "SDPhotoBrowser.h"
|
||||||
#import "YuMi-Swift.h" // Swift 互操作
|
#import "YuMi-Swift.h"
|
||||||
|
|
||||||
@interface EPMomentCell () <SDPhotoBrowserDelegate>
|
@interface EPMomentCell () <SDPhotoBrowserDelegate>
|
||||||
|
|
||||||
// MARK: - UI Components
|
// MARK: - UI Components
|
||||||
|
|
||||||
/// 卡片容器
|
|
||||||
@property (nonatomic, strong) UIView *cardView;
|
@property (nonatomic, strong) UIView *cardView;
|
||||||
|
|
||||||
/// 彩色背景层(毛玻璃下方)
|
|
||||||
@property (nonatomic, strong) UIView *colorBackgroundView;
|
@property (nonatomic, strong) UIView *colorBackgroundView;
|
||||||
|
|
||||||
/// 毛玻璃效果视图
|
|
||||||
@property (nonatomic, strong) UIVisualEffectView *blurEffectView;
|
@property (nonatomic, strong) UIVisualEffectView *blurEffectView;
|
||||||
|
|
||||||
/// 头像(网络)
|
|
||||||
@property (nonatomic, strong) NetImageView *avatarImageView;
|
@property (nonatomic, strong) NetImageView *avatarImageView;
|
||||||
|
|
||||||
/// 用户名
|
|
||||||
@property (nonatomic, strong) UILabel *nameLabel;
|
@property (nonatomic, strong) UILabel *nameLabel;
|
||||||
|
|
||||||
/// 时间标签
|
|
||||||
@property (nonatomic, strong) UILabel *timeLabel;
|
@property (nonatomic, strong) UILabel *timeLabel;
|
||||||
|
|
||||||
/// 内容标签
|
|
||||||
@property (nonatomic, strong) UILabel *contentLabel;
|
@property (nonatomic, strong) UILabel *contentLabel;
|
||||||
|
|
||||||
/// 图片容器(九宫格)
|
|
||||||
@property (nonatomic, strong) UIView *imagesContainer;
|
@property (nonatomic, strong) UIView *imagesContainer;
|
||||||
@property (nonatomic, strong) NSMutableArray<NetImageView *> *imageViews;
|
@property (nonatomic, strong) NSMutableArray<NetImageView *> *imageViews;
|
||||||
|
|
||||||
/// 底部操作栏
|
|
||||||
@property (nonatomic, strong) UIView *actionBar;
|
@property (nonatomic, strong) UIView *actionBar;
|
||||||
|
|
||||||
/// 点赞按钮
|
|
||||||
@property (nonatomic, strong) UIButton *likeButton;
|
@property (nonatomic, strong) UIButton *likeButton;
|
||||||
|
|
||||||
/// 评论按钮
|
|
||||||
@property (nonatomic, strong) UIButton *commentButton;
|
@property (nonatomic, strong) UIButton *commentButton;
|
||||||
|
|
||||||
// 分享按钮已移除
|
|
||||||
|
|
||||||
/// 当前数据模型
|
|
||||||
@property (nonatomic, strong) MomentsInfoModel *currentModel;
|
@property (nonatomic, strong) MomentsInfoModel *currentModel;
|
||||||
|
|
||||||
/// API Helper (Swift 版本)
|
|
||||||
@property (nonatomic, strong) EPMomentAPISwiftHelper *apiHelper;
|
@property (nonatomic, strong) EPMomentAPISwiftHelper *apiHelper;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -78,7 +74,7 @@
|
|||||||
// MARK: - Setup UI
|
// MARK: - Setup UI
|
||||||
|
|
||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
// 卡片容器(圆角矩形 + 阴影)
|
|
||||||
[self.contentView addSubview:self.cardView];
|
[self.contentView addSubview:self.cardView];
|
||||||
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.contentView).inset(15);
|
make.leading.trailing.equalTo(self.contentView).inset(15);
|
||||||
@@ -86,19 +82,19 @@
|
|||||||
make.bottom.equalTo(self.contentView).offset(-8).priority(UILayoutPriorityRequired - 1);
|
make.bottom.equalTo(self.contentView).offset(-8).priority(UILayoutPriorityRequired - 1);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 彩色背景层(最底层)
|
|
||||||
[self.cardView addSubview:self.colorBackgroundView];
|
[self.cardView addSubview:self.colorBackgroundView];
|
||||||
[self.colorBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.colorBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.edges.equalTo(self.cardView);
|
make.edges.equalTo(self.cardView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 毛玻璃效果视图(在彩色背景层之上)
|
|
||||||
[self.cardView addSubview:self.blurEffectView];
|
[self.cardView addSubview:self.blurEffectView];
|
||||||
[self.blurEffectView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.blurEffectView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.edges.equalTo(self.cardView);
|
make.edges.equalTo(self.cardView);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 头像(
|
|
||||||
[self.blurEffectView.contentView addSubview:self.avatarImageView];
|
[self.blurEffectView.contentView addSubview:self.avatarImageView];
|
||||||
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self.cardView).offset(15);
|
make.leading.equalTo(self.cardView).offset(15);
|
||||||
@@ -106,7 +102,7 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(40, 40));
|
make.size.mas_equalTo(CGSizeMake(40, 40));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 用户名
|
|
||||||
[self.blurEffectView.contentView addSubview:self.nameLabel];
|
[self.blurEffectView.contentView addSubview:self.nameLabel];
|
||||||
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self.avatarImageView.mas_trailing).offset(10);
|
make.leading.equalTo(self.avatarImageView.mas_trailing).offset(10);
|
||||||
@@ -114,7 +110,7 @@
|
|||||||
make.trailing.equalTo(self.cardView).offset(-15);
|
make.trailing.equalTo(self.cardView).offset(-15);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 时间
|
|
||||||
[self.blurEffectView.contentView addSubview:self.timeLabel];
|
[self.blurEffectView.contentView addSubview:self.timeLabel];
|
||||||
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self.nameLabel);
|
make.leading.equalTo(self.nameLabel);
|
||||||
@@ -122,32 +118,32 @@
|
|||||||
make.trailing.equalTo(self.cardView).offset(-15);
|
make.trailing.equalTo(self.cardView).offset(-15);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 内容
|
|
||||||
[self.blurEffectView.contentView addSubview:self.contentLabel];
|
[self.blurEffectView.contentView addSubview:self.contentLabel];
|
||||||
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.cardView).inset(15);
|
make.leading.trailing.equalTo(self.cardView).inset(15);
|
||||||
make.top.equalTo(self.avatarImageView.mas_bottom).offset(12);
|
make.top.equalTo(self.avatarImageView.mas_bottom).offset(12);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 图片九宫格
|
|
||||||
[self.blurEffectView.contentView addSubview:self.imagesContainer];
|
[self.blurEffectView.contentView addSubview:self.imagesContainer];
|
||||||
[self.imagesContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.imagesContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.cardView).inset(15);
|
make.leading.trailing.equalTo(self.cardView).inset(15);
|
||||||
make.top.equalTo(self.contentLabel.mas_bottom).offset(12);
|
make.top.equalTo(self.contentLabel.mas_bottom).offset(12);
|
||||||
make.height.mas_equalTo(0); // 初始高度为0,renderImages 时会 remakeConstraints
|
make.height.mas_equalTo(0);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 底部操作栏
|
|
||||||
[self.blurEffectView.contentView addSubview:self.actionBar];
|
[self.blurEffectView.contentView addSubview:self.actionBar];
|
||||||
[self.actionBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.actionBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.trailing.equalTo(self.cardView);
|
make.leading.trailing.equalTo(self.cardView);
|
||||||
make.top.equalTo(self.imagesContainer.mas_bottom).offset(12);
|
make.top.equalTo(self.imagesContainer.mas_bottom).offset(12);
|
||||||
make.height.mas_equalTo(50);
|
make.height.mas_equalTo(50);
|
||||||
// 设置较高优先级,确保底部约束生效
|
|
||||||
make.bottom.equalTo(self.cardView).offset(-8).priority(UILayoutPriorityRequired - 2);
|
make.bottom.equalTo(self.cardView).offset(-8).priority(UILayoutPriorityRequired - 2);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 点赞按钮(居左显示,评论功能已隐藏)
|
|
||||||
[self.actionBar addSubview:self.likeButton];
|
[self.actionBar addSubview:self.likeButton];
|
||||||
[self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self.actionBar);
|
make.leading.equalTo(self.actionBar);
|
||||||
@@ -161,19 +157,19 @@
|
|||||||
- (void)configureWithModel:(MomentsInfoModel *)model {
|
- (void)configureWithModel:(MomentsInfoModel *)model {
|
||||||
self.currentModel = model;
|
self.currentModel = model;
|
||||||
|
|
||||||
// 配置用户名
|
|
||||||
self.nameLabel.text = model.nick ?: YMLocalizedString(@"user.anonymous");
|
self.nameLabel.text = model.nick ?: YMLocalizedString(@"user.anonymous");
|
||||||
|
|
||||||
// 配置时间(将时间戳转换为 MM/dd 格式)
|
|
||||||
self.timeLabel.text = [self formatTimestampToDate:model.publishTime];
|
self.timeLabel.text = [self formatTimestampToDate:model.publishTime];
|
||||||
|
|
||||||
// 配置内容
|
|
||||||
self.contentLabel.text = model.content ?: @"";
|
self.contentLabel.text = model.content ?: @"";
|
||||||
|
|
||||||
// 配置图片九宫格
|
|
||||||
[self renderImages:model.dynamicResList];
|
[self renderImages:model.dynamicResList];
|
||||||
|
|
||||||
// 配置点赞按钮状态和数字
|
|
||||||
NSInteger likeCnt = MAX(0, model.likeCount.integerValue);
|
NSInteger likeCnt = MAX(0, model.likeCount.integerValue);
|
||||||
self.likeButton.selected = model.isLike;
|
self.likeButton.selected = model.isLike;
|
||||||
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCnt] forState:UIControlStateNormal];
|
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCnt] forState:UIControlStateNormal];
|
||||||
@@ -181,16 +177,16 @@
|
|||||||
|
|
||||||
self.avatarImageView.imageUrl = model.avatar;
|
self.avatarImageView.imageUrl = model.avatar;
|
||||||
|
|
||||||
// 配置情绪颜色 border 和 shadow
|
|
||||||
[self applyEmotionColorEffect:model.emotionColor];
|
[self applyEmotionColorEffect:model.emotionColor];
|
||||||
|
|
||||||
// 确保布局完成后 cell 高度正确
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 应用情绪颜色视觉效果(Background + Shadow)
|
|
||||||
- (void)applyEmotionColorEffect:(NSString *)emotionColorHex {
|
- (void)applyEmotionColorEffect:(NSString *)emotionColorHex {
|
||||||
// 获取颜色(已在列表加载时处理,这里直接使用)
|
|
||||||
if (!emotionColorHex) {
|
if (!emotionColorHex) {
|
||||||
NSLog(@"[EPMomentCell] 警告:emotionColorHex 为 nil");
|
NSLog(@"[EPMomentCell] 警告:emotionColorHex 为 nil");
|
||||||
return;
|
return;
|
||||||
@@ -198,24 +194,24 @@
|
|||||||
|
|
||||||
UIColor *color = [self colorFromHex:emotionColorHex];
|
UIColor *color = [self colorFromHex:emotionColorHex];
|
||||||
|
|
||||||
// 移除边框
|
|
||||||
self.cardView.layer.borderWidth = 0;
|
self.cardView.layer.borderWidth = 0;
|
||||||
|
|
||||||
// 设置彩色背景(50% 透明度,在毛玻璃下方)
|
|
||||||
self.colorBackgroundView.backgroundColor = [color colorWithAlphaComponent:0.5];
|
self.colorBackgroundView.backgroundColor = [color colorWithAlphaComponent:0.5];
|
||||||
|
|
||||||
// 设置 shadow(使用情绪颜色)
|
|
||||||
self.cardView.layer.shadowColor = color.CGColor;
|
self.cardView.layer.shadowColor = color.CGColor;
|
||||||
self.cardView.layer.shadowOffset = CGSizeMake(0, 2);
|
self.cardView.layer.shadowOffset = CGSizeMake(0, 2);
|
||||||
self.cardView.layer.shadowOpacity = 0.5;
|
self.cardView.layer.shadowOpacity = 0.5;
|
||||||
self.cardView.layer.shadowRadius = 16.0;
|
self.cardView.layer.shadowRadius = 16.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hex 转 UIColor
|
|
||||||
- (UIColor *)colorFromHex:(NSString *)hexString {
|
- (UIColor *)colorFromHex:(NSString *)hexString {
|
||||||
unsigned rgbValue = 0;
|
unsigned rgbValue = 0;
|
||||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||||
[scanner setScanLocation:1]; // 跳过 #
|
[scanner setScanLocation:1];
|
||||||
[scanner scanHexInt:&rgbValue];
|
[scanner scanHexInt:&rgbValue];
|
||||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
||||||
green:((rgbValue & 0xFF00) >> 8)/255.0
|
green:((rgbValue & 0xFF00) >> 8)/255.0
|
||||||
@@ -226,7 +222,7 @@
|
|||||||
// MARK: - Images Grid
|
// MARK: - Images Grid
|
||||||
|
|
||||||
- (void)renderImages:(NSArray *)resList {
|
- (void)renderImages:(NSArray *)resList {
|
||||||
// 清理旧视图
|
|
||||||
for (UIView *iv in self.imageViews) { [iv removeFromSuperview]; }
|
for (UIView *iv in self.imageViews) { [iv removeFromSuperview]; }
|
||||||
[self.imageViews removeAllObjects];
|
[self.imageViews removeAllObjects];
|
||||||
if (resList.count == 0) {
|
if (resList.count == 0) {
|
||||||
@@ -236,14 +232,14 @@
|
|||||||
make.height.mas_equalTo(0);
|
make.height.mas_equalTo(0);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 强制触发布局更新
|
|
||||||
[self.contentView setNeedsLayout];
|
[self.contentView setNeedsLayout];
|
||||||
[self.contentView layoutIfNeeded];
|
[self.contentView layoutIfNeeded];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NSInteger columns = 3;
|
NSInteger columns = 3;
|
||||||
CGFloat spacing = 6.0;
|
CGFloat spacing = 6.0;
|
||||||
CGFloat totalWidth = [UIScreen mainScreen].bounds.size.width - 30 - 30; // 左右各 15 内边距,再减卡片左右 15
|
CGFloat totalWidth = [UIScreen mainScreen].bounds.size.width - 30 - 30;
|
||||||
CGFloat itemW = floor((totalWidth - spacing * (columns - 1)) / columns);
|
CGFloat itemW = floor((totalWidth - spacing * (columns - 1)) / columns);
|
||||||
|
|
||||||
for (NSInteger i = 0; i < resList.count && i < 9; i++) {
|
for (NSInteger i = 0; i < resList.count && i < 9; i++) {
|
||||||
@@ -255,9 +251,9 @@
|
|||||||
iv.layer.masksToBounds = YES;
|
iv.layer.masksToBounds = YES;
|
||||||
iv.contentMode = UIViewContentModeScaleAspectFill;
|
iv.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
iv.userInteractionEnabled = YES;
|
iv.userInteractionEnabled = YES;
|
||||||
iv.tag = i; // 用于识别点击的图片索引
|
iv.tag = i;
|
||||||
|
|
||||||
|
|
||||||
// 添加点击手势
|
|
||||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageTapped:)];
|
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageTapped:)];
|
||||||
[iv addGestureRecognizer:tap];
|
[iv addGestureRecognizer:tap];
|
||||||
|
|
||||||
@@ -270,7 +266,7 @@
|
|||||||
make.top.equalTo(self.imagesContainer).offset((itemW + spacing) * row);
|
make.top.equalTo(self.imagesContainer).offset((itemW + spacing) * row);
|
||||||
make.size.mas_equalTo(CGSizeMake(itemW, itemW));
|
make.size.mas_equalTo(CGSizeMake(itemW, itemW));
|
||||||
}];
|
}];
|
||||||
// 绑定网络图片
|
|
||||||
NSString *url = nil;
|
NSString *url = nil;
|
||||||
id item = resList[i];
|
id item = resList[i];
|
||||||
if ([item isKindOfClass:[NSDictionary class]]) {
|
if ([item isKindOfClass:[NSDictionary class]]) {
|
||||||
@@ -289,18 +285,18 @@
|
|||||||
make.height.mas_equalTo(height);
|
make.height.mas_equalTo(height);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 强制触发布局更新,确保 cell 高度正确计算
|
|
||||||
[self.contentView setNeedsLayout];
|
[self.contentView setNeedsLayout];
|
||||||
[self.contentView layoutIfNeeded];
|
[self.contentView layoutIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 格式化时间戳为 MM/dd 格式
|
|
||||||
- (NSString *)formatTimestampToDate:(NSString *)timestampString {
|
- (NSString *)formatTimestampToDate:(NSString *)timestampString {
|
||||||
if (!timestampString || timestampString.length == 0) {
|
if (!timestampString || timestampString.length == 0) {
|
||||||
return @"";
|
return @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将字符串转换为时间戳(毫秒)
|
|
||||||
NSTimeInterval timestamp = [timestampString doubleValue] / 1000.0;
|
NSTimeInterval timestamp = [timestampString doubleValue] / 1000.0;
|
||||||
|
|
||||||
if (timestamp <= 0) {
|
if (timestamp <= 0) {
|
||||||
@@ -314,7 +310,7 @@
|
|||||||
return [formatter stringFromDate:date];
|
return [formatter stringFromDate:date];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 格式化时间戳为相对时间
|
|
||||||
- (NSString *)formatTimeInterval:(NSInteger)timestamp {
|
- (NSString *)formatTimeInterval:(NSInteger)timestamp {
|
||||||
if (timestamp <= 0) return YMLocalizedString(@"time.just_now");
|
if (timestamp <= 0) return YMLocalizedString(@"time.just_now");
|
||||||
|
|
||||||
@@ -340,20 +336,20 @@
|
|||||||
- (void)onLikeButtonTapped {
|
- (void)onLikeButtonTapped {
|
||||||
if (!self.currentModel) return;
|
if (!self.currentModel) return;
|
||||||
|
|
||||||
// 如果已点赞,执行取消点赞
|
|
||||||
if (self.currentModel.isLike) {
|
if (self.currentModel.isLike) {
|
||||||
[self performLikeAction:NO];
|
[self performLikeAction:NO];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审核中的动态不可点赞
|
|
||||||
if (self.currentModel.status == 0) {
|
if (self.currentModel.status == 0) {
|
||||||
NSLog(@"[EPMomentCell] 动态审核中,无法点赞");
|
NSLog(@"[EPMomentCell] 动态审核中,无法点赞");
|
||||||
// TODO: 可选择显示提示 Toast
|
// TODO: 可选择显示提示 Toast
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行点赞
|
|
||||||
[self performLikeAction:YES];
|
[self performLikeAction:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +360,7 @@
|
|||||||
NSString *likedUid = self.currentModel.uid;
|
NSString *likedUid = self.currentModel.uid;
|
||||||
long worldId = self.currentModel.worldId;
|
long worldId = self.currentModel.worldId;
|
||||||
|
|
||||||
// 使用 Swift API Helper
|
|
||||||
@kWeakify(self);
|
@kWeakify(self);
|
||||||
[self.apiHelper likeMomentWithDynamicId:dynamicId
|
[self.apiHelper likeMomentWithDynamicId:dynamicId
|
||||||
isLike:isLike
|
isLike:isLike
|
||||||
@@ -372,14 +368,14 @@
|
|||||||
worldId:worldId
|
worldId:worldId
|
||||||
completion:^{
|
completion:^{
|
||||||
@kStrongify(self);
|
@kStrongify(self);
|
||||||
// 更新点赞状态
|
|
||||||
self.currentModel.isLike = isLike;
|
self.currentModel.isLike = isLike;
|
||||||
NSInteger likeCount = [self.currentModel.likeCount integerValue];
|
NSInteger likeCount = [self.currentModel.likeCount integerValue];
|
||||||
likeCount += isLike ? 1 : -1;
|
likeCount += isLike ? 1 : -1;
|
||||||
likeCount = MAX(0, likeCount); // 防止负数
|
likeCount = MAX(0, likeCount);
|
||||||
self.currentModel.likeCount = @(likeCount).stringValue;
|
self.currentModel.likeCount = @(likeCount).stringValue;
|
||||||
|
|
||||||
// 更新 UI
|
|
||||||
self.likeButton.selected = self.currentModel.isLike;
|
self.likeButton.selected = self.currentModel.isLike;
|
||||||
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCount] forState:UIControlStateNormal];
|
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCount] forState:UIControlStateNormal];
|
||||||
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCount] forState:UIControlStateSelected];
|
[self.likeButton setTitle:[NSString stringWithFormat:@" %ld", (long)likeCount] forState:UIControlStateSelected];
|
||||||
@@ -390,10 +386,6 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 评论功能已隐藏
|
|
||||||
// - (void)onCommentButtonTapped {
|
|
||||||
// NSLog(@"[EPMomentCell] 评论");
|
|
||||||
// }
|
|
||||||
|
|
||||||
- (void)onImageTapped:(UITapGestureRecognizer *)gesture {
|
- (void)onImageTapped:(UITapGestureRecognizer *)gesture {
|
||||||
if (!self.currentModel || !self.currentModel.dynamicResList.count) return;
|
if (!self.currentModel || !self.currentModel.dynamicResList.count) return;
|
||||||
@@ -436,9 +428,9 @@
|
|||||||
- (UIView *)cardView {
|
- (UIView *)cardView {
|
||||||
if (!_cardView) {
|
if (!_cardView) {
|
||||||
_cardView = [[UIView alloc] init];
|
_cardView = [[UIView alloc] init];
|
||||||
_cardView.backgroundColor = [UIColor clearColor]; // 透明背景,颜色由 colorBackgroundView 提供
|
_cardView.backgroundColor = [UIColor clearColor];
|
||||||
_cardView.layer.cornerRadius = 12; // 圆角
|
_cardView.layer.cornerRadius = 12;
|
||||||
// Shadow 将由 applyEmotionColorEffect 动态设置
|
|
||||||
_cardView.layer.masksToBounds = NO;
|
_cardView.layer.masksToBounds = NO;
|
||||||
}
|
}
|
||||||
return _cardView;
|
return _cardView;
|
||||||
@@ -507,7 +499,7 @@
|
|||||||
- (UIView *)actionBar {
|
- (UIView *)actionBar {
|
||||||
if (!_actionBar) {
|
if (!_actionBar) {
|
||||||
_actionBar = [[UIView alloc] init];
|
_actionBar = [[UIView alloc] init];
|
||||||
_actionBar.backgroundColor = [UIColor clearColor]; // 半透明白色,与毛玻璃效果搭配
|
_actionBar.backgroundColor = [UIColor clearColor];
|
||||||
}
|
}
|
||||||
return _actionBar;
|
return _actionBar;
|
||||||
}
|
}
|
||||||
@@ -526,7 +518,7 @@
|
|||||||
return _likeButton;
|
return _likeButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 评论按钮已移除
|
|
||||||
- (UIButton *)commentButton {
|
- (UIButton *)commentButton {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPMomentListView.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-10.
|
// Created by AI on 2025-10-10.
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import "EPMomentListView.h"
|
#import "EPMomentListView.h"
|
||||||
@@ -34,7 +32,7 @@
|
|||||||
_api = [[EPMomentAPISwiftHelper alloc] init];
|
_api = [[EPMomentAPISwiftHelper alloc] init];
|
||||||
_mutableRawList = [NSMutableArray array];
|
_mutableRawList = [NSMutableArray array];
|
||||||
_sourceType = EPMomentListSourceTypeRecommend;
|
_sourceType = EPMomentListSourceTypeRecommend;
|
||||||
_isLocalMode = NO; // 明确初始化为网络模式
|
_isLocalMode = NO;
|
||||||
|
|
||||||
[self addSubview:self.tableView];
|
[self addSubview:self.tableView];
|
||||||
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
@@ -49,8 +47,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)reloadFirstPage {
|
- (void)reloadFirstPage {
|
||||||
|
NSLog(@"[EPMomentListView] 📄 开始刷新第一页,isLocalMode=%d", self.isLocalMode);
|
||||||
|
|
||||||
if (self.isLocalMode) {
|
if (self.isLocalMode) {
|
||||||
// 本地模式:调用外部刷新回调
|
|
||||||
if (self.refreshCallback) {
|
if (self.refreshCallback) {
|
||||||
self.refreshCallback();
|
self.refreshCallback();
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 网络模式:重新请求第一页
|
|
||||||
self.nextID = @"";
|
self.nextID = @"";
|
||||||
[self.mutableRawList removeAllObjects];
|
[self.mutableRawList removeAllObjects];
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
[self.mutableRawList addObjectsFromArray:dynamicInfo];
|
[self.mutableRawList addObjectsFromArray:dynamicInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏加载更多 footer
|
|
||||||
self.tableView.mj_footer.hidden = YES;
|
self.tableView.mj_footer.hidden = YES;
|
||||||
|
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
@@ -84,20 +84,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)requestNextPage {
|
- (void)requestNextPage {
|
||||||
if (self.isLoading) return;
|
if (self.isLoading) {
|
||||||
|
NSLog(@"[EPMomentListView] ⚠️ 已有加载任务进行中,跳过本次请求");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[EPMomentListView] 🌐 发起网络请求,nextID=%@", self.nextID.length > 0 ? self.nextID : @"(首页)");
|
||||||
self.isLoading = YES;
|
self.isLoading = YES;
|
||||||
|
|
||||||
@kWeakify(self);
|
@kWeakify(self);
|
||||||
[self.api fetchLatestMomentsWithNextID:self.nextID
|
[self.api fetchLatestMomentsWithNextID:self.nextID
|
||||||
completion:^(NSArray<MomentsInfoModel *> * _Nonnull list, NSString * _Nonnull nextMomentID) {
|
completion:^(NSArray<MomentsInfoModel *> * _Nonnull list, NSString * _Nonnull nextMomentID) {
|
||||||
@kStrongify(self);
|
@kStrongify(self);
|
||||||
|
NSLog(@"[EPMomentListView] ✅ 请求成功,获得 %lu 条数据", (unsigned long)list.count);
|
||||||
[self endLoading];
|
[self endLoading];
|
||||||
if (list.count > 0) {
|
if (list.count > 0) {
|
||||||
// 处理情绪颜色
|
|
||||||
[self processEmotionColors:list isFirstPage:(self.nextID.length == 0)];
|
[self processEmotionColors:list isFirstPage:(self.nextID.length == 0)];
|
||||||
|
|
||||||
self.nextID = nextMomentID;
|
self.nextID = nextMomentID;
|
||||||
[self.mutableRawList addObjectsFromArray:list];
|
[self.mutableRawList addObjectsFromArray:list];
|
||||||
|
[self removeEmptyState];
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
if (nextMomentID.length > 0) {
|
if (nextMomentID.length > 0) {
|
||||||
[self.tableView.mj_footer endRefreshing];
|
[self.tableView.mj_footer endRefreshing];
|
||||||
@@ -105,13 +112,21 @@
|
|||||||
[self.tableView.mj_footer endRefreshingWithNoMoreData];
|
[self.tableView.mj_footer endRefreshingWithNoMoreData];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 返回空数据:显示 "no more data" 状态
|
NSLog(@"[EPMomentListView] ⚠️ 返回数据为空");
|
||||||
|
if (self.mutableRawList.count == 0) {
|
||||||
|
[self showEmptyStateWithMessage:YMLocalizedString(@"common.no_data")];
|
||||||
|
}
|
||||||
[self.tableView.mj_footer endRefreshingWithNoMoreData];
|
[self.tableView.mj_footer endRefreshingWithNoMoreData];
|
||||||
}
|
}
|
||||||
} failure:^(NSInteger code, NSString * _Nonnull msg) {
|
} failure:^(NSInteger code, NSString * _Nonnull msg) {
|
||||||
@kStrongify(self);
|
@kStrongify(self);
|
||||||
|
NSLog(@"[EPMomentListView] ❌ 请求失败,code=%ld, msg=%@", (long)code, msg);
|
||||||
[self endLoading];
|
[self endLoading];
|
||||||
// TODO: 完全没有数据情况下,后续补充数据异常页面
|
|
||||||
|
|
||||||
|
if (self.mutableRawList.count == 0) {
|
||||||
|
[self showEmptyStateWithMessage:msg ?: YMLocalizedString(@"error.request_failed")];
|
||||||
|
}
|
||||||
[self.tableView.mj_footer endRefreshing];
|
[self.tableView.mj_footer endRefreshing];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@@ -121,25 +136,48 @@
|
|||||||
[self.refreshControl endRefreshing];
|
[self.refreshControl endRefreshing];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理动态的情绪颜色(从 UserDefaults 匹配 + 处理临时颜色)
|
|
||||||
|
- (void)showEmptyStateWithMessage:(NSString *)message {
|
||||||
|
UILabel *emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||||
|
emptyLabel.text = [NSString stringWithFormat:@"%@\n\n%@", message, YMLocalizedString(@"common.pull_to_retry")];
|
||||||
|
emptyLabel.textColor = [UIColor whiteColor];
|
||||||
|
emptyLabel.textAlignment = NSTextAlignmentCenter;
|
||||||
|
emptyLabel.numberOfLines = 0;
|
||||||
|
emptyLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
emptyLabel.tag = 9999;
|
||||||
|
|
||||||
|
|
||||||
|
[[self.tableView viewWithTag:9999] removeFromSuperview];
|
||||||
|
[self.tableView addSubview:emptyLabel];
|
||||||
|
[emptyLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.center.equalTo(self.tableView);
|
||||||
|
make.leading.trailing.equalTo(self.tableView).inset(40);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeEmptyState {
|
||||||
|
[[self.tableView viewWithTag:9999] removeFromSuperview];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)processEmotionColors:(NSArray<MomentsInfoModel *> *)list isFirstPage:(BOOL)isFirstPage {
|
- (void)processEmotionColors:(NSArray<MomentsInfoModel *> *)list isFirstPage:(BOOL)isFirstPage {
|
||||||
// 检查是否有待处理的临时情绪颜色
|
|
||||||
NSString *pendingColor = [[NSUserDefaults standardUserDefaults] stringForKey:@"EP_Pending_Emotion_Color"];
|
NSString *pendingColor = [[NSUserDefaults standardUserDefaults] stringForKey:@"EP_Pending_Emotion_Color"];
|
||||||
NSNumber *pendingTimestamp = [[NSUserDefaults standardUserDefaults] objectForKey:@"EP_Pending_Emotion_Timestamp"];
|
NSNumber *pendingTimestamp = [[NSUserDefaults standardUserDefaults] objectForKey:@"EP_Pending_Emotion_Timestamp"];
|
||||||
|
|
||||||
for (NSInteger i = 0; i < list.count; i++) {
|
for (NSInteger i = 0; i < list.count; i++) {
|
||||||
MomentsInfoModel *model = list[i];
|
MomentsInfoModel *model = list[i];
|
||||||
|
|
||||||
// 优先检查临时颜色(仅第一页第一条)
|
|
||||||
if (isFirstPage && i == 0 && pendingColor && pendingTimestamp) {
|
if (isFirstPage && i == 0 && pendingColor && pendingTimestamp) {
|
||||||
// 检查时间戳(5秒内有效,避免误匹配)
|
|
||||||
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
|
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
|
||||||
NSTimeInterval pending = pendingTimestamp.doubleValue;
|
NSTimeInterval pending = pendingTimestamp.doubleValue;
|
||||||
if ((now - pending) < 5.0) {
|
if ((now - pending) < 5.0) {
|
||||||
model.emotionColor = pendingColor;
|
model.emotionColor = pendingColor;
|
||||||
// 保存到持久化存储
|
|
||||||
[EPEmotionColorStorage saveColor:pendingColor forDynamicId:model.dynamicId];
|
[EPEmotionColorStorage saveColor:pendingColor forDynamicId:model.dynamicId];
|
||||||
// 清除临时数据
|
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"EP_Pending_Emotion_Color"];
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"EP_Pending_Emotion_Color"];
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"EP_Pending_Emotion_Timestamp"];
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"EP_Pending_Emotion_Timestamp"];
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
@@ -147,12 +185,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从持久化存储中匹配
|
|
||||||
NSString *savedColor = [EPEmotionColorStorage colorForDynamicId:model.dynamicId];
|
NSString *savedColor = [EPEmotionColorStorage colorForDynamicId:model.dynamicId];
|
||||||
if (savedColor) {
|
if (savedColor) {
|
||||||
model.emotionColor = savedColor;
|
model.emotionColor = savedColor;
|
||||||
} else {
|
} else {
|
||||||
// 无保存颜色,生成随机颜色并立即持久化
|
|
||||||
NSString *randomColor = [EPEmotionColorStorage randomEmotionColor];
|
NSString *randomColor = [EPEmotionColorStorage randomEmotionColor];
|
||||||
model.emotionColor = randomColor;
|
model.emotionColor = randomColor;
|
||||||
[EPEmotionColorStorage saveColor:randomColor forDynamicId:model.dynamicId];
|
[EPEmotionColorStorage saveColor:randomColor forDynamicId:model.dynamicId];
|
||||||
@@ -190,7 +228,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||||
// 本地模式下不触发加载更多
|
|
||||||
if (self.isLocalMode) return;
|
if (self.isLocalMode) return;
|
||||||
|
|
||||||
CGFloat offsetY = scrollView.contentOffset.y;
|
CGFloat offsetY = scrollView.contentOffset.y;
|
||||||
@@ -213,13 +251,13 @@
|
|||||||
_tableView.estimatedRowHeight = 200;
|
_tableView.estimatedRowHeight = 200;
|
||||||
_tableView.rowHeight = UITableViewAutomaticDimension;
|
_tableView.rowHeight = UITableViewAutomaticDimension;
|
||||||
_tableView.showsVerticalScrollIndicator = NO;
|
_tableView.showsVerticalScrollIndicator = NO;
|
||||||
// 底部留出更高空间,避免被悬浮 TabBar 遮挡
|
|
||||||
_tableView.contentInset = UIEdgeInsetsMake(10, 0, 120, 0);
|
_tableView.contentInset = UIEdgeInsetsMake(10, 0, 120, 0);
|
||||||
_tableView.scrollIndicatorInsets = UIEdgeInsetsMake(10, 0, 120, 0);
|
_tableView.scrollIndicatorInsets = UIEdgeInsetsMake(10, 0, 120, 0);
|
||||||
[_tableView registerClass:[EPMomentCell class] forCellReuseIdentifier:@"NewMomentCell"];
|
[_tableView registerClass:[EPMomentCell class] forCellReuseIdentifier:@"NewMomentCell"];
|
||||||
_tableView.refreshControl = self.refreshControl;
|
_tableView.refreshControl = self.refreshControl;
|
||||||
|
|
||||||
// MJRefresh Footer - 加载更多
|
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
||||||
__strong typeof(weakSelf) self = weakSelf;
|
__strong typeof(weakSelf) self = weakSelf;
|
||||||
@@ -231,7 +269,7 @@
|
|||||||
[self.tableView.mj_footer endRefreshing];
|
[self.tableView.mj_footer endRefreshing];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
// 设置白色文字和指示器
|
|
||||||
footer.stateLabel.textColor = [UIColor whiteColor];
|
footer.stateLabel.textColor = [UIColor whiteColor];
|
||||||
footer.loadingView.color = [UIColor whiteColor];
|
footer.loadingView.color = [UIColor whiteColor];
|
||||||
_tableView.mj_footer = footer;
|
_tableView.mj_footer = footer;
|
||||||
@@ -242,12 +280,10 @@
|
|||||||
- (UIRefreshControl *)refreshControl {
|
- (UIRefreshControl *)refreshControl {
|
||||||
if (!_refreshControl) {
|
if (!_refreshControl) {
|
||||||
_refreshControl = [[UIRefreshControl alloc] init];
|
_refreshControl = [[UIRefreshControl alloc] init];
|
||||||
_refreshControl.tintColor = [UIColor whiteColor]; // 白色加载指示器
|
_refreshControl.tintColor = [UIColor whiteColor];
|
||||||
[_refreshControl addTarget:self action:@selector(reloadFirstPage) forControlEvents:UIControlEventValueChanged];
|
[_refreshControl addTarget:self action:@selector(reloadFirstPage) forControlEvents:UIControlEventValueChanged];
|
||||||
}
|
}
|
||||||
return _refreshControl;
|
return _refreshControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
//
|
|
||||||
// EPSignatureColorGuideView.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-15.
|
// Created by AI on 2025-10-15.
|
||||||
//
|
|
||||||
|
|
||||||
#import "EPSignatureColorGuideView.h"
|
#import "EPSignatureColorGuideView.h"
|
||||||
#import "EPEmotionColorWheelView.h"
|
#import "EPEmotionColorWheelView.h"
|
||||||
@@ -22,7 +20,7 @@
|
|||||||
@property (nonatomic, strong) EPEmotionColorWheelView *colorWheelView;
|
@property (nonatomic, strong) EPEmotionColorWheelView *colorWheelView;
|
||||||
@property (nonatomic, strong) UIButton *confirmButton;
|
@property (nonatomic, strong) UIButton *confirmButton;
|
||||||
@property (nonatomic, strong) UIButton *skipButton;
|
@property (nonatomic, strong) UIButton *skipButton;
|
||||||
@property (nonatomic, copy) NSString *selectedColor; // 当前选中的颜色
|
@property (nonatomic, copy) NSString *selectedColor;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupUI {
|
- (void)setupUI {
|
||||||
// 渐变背景
|
|
||||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||||
gradientLayer.colors = @[
|
gradientLayer.colors = @[
|
||||||
(id)[UIColor colorWithRed:0x1a/255.0 green:0x09/255.0 blue:0x33/255.0 alpha:1.0].CGColor,
|
(id)[UIColor colorWithRed:0x1a/255.0 green:0x09/255.0 blue:0x33/255.0 alpha:1.0].CGColor,
|
||||||
@@ -49,29 +47,30 @@
|
|||||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||||
self.gradientLayer = gradientLayer;
|
self.gradientLayer = gradientLayer;
|
||||||
|
|
||||||
// 内容容器
|
|
||||||
[self addSubview:self.contentContainer];
|
[self addSubview:self.contentContainer];
|
||||||
[self.contentContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.contentContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.center.equalTo(self);
|
make.top.equalTo(self).offset(100);
|
||||||
make.leading.trailing.equalTo(self).inset(30);
|
make.leading.trailing.equalTo(self).inset(30);
|
||||||
|
make.bottom.lessThanOrEqualTo(self).offset(-30);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 标题
|
|
||||||
[self.contentContainer addSubview:self.titleLabel];
|
[self.contentContainer addSubview:self.titleLabel];
|
||||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.contentContainer);
|
make.top.equalTo(self.contentContainer);
|
||||||
make.centerX.equalTo(self.contentContainer);
|
make.centerX.equalTo(self.contentContainer);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 副标题
|
|
||||||
[self.contentContainer addSubview:self.subtitleLabel];
|
[self.contentContainer addSubview:self.subtitleLabel];
|
||||||
[self.subtitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.subtitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.titleLabel.mas_bottom).offset(12);
|
make.top.equalTo(self.titleLabel.mas_bottom).offset(8);
|
||||||
make.centerX.equalTo(self.contentContainer);
|
make.centerX.equalTo(self.contentContainer);
|
||||||
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Info 按钮(左上角,与 Skip 按钮对齐)
|
|
||||||
[self addSubview:self.infoButton];
|
[self addSubview:self.infoButton];
|
||||||
[self.infoButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.infoButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(self).offset(20);
|
make.leading.equalTo(self).offset(20);
|
||||||
@@ -79,33 +78,34 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(36, 36));
|
make.size.mas_equalTo(CGSizeMake(36, 36));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 选中状态显示区域
|
|
||||||
[self.contentContainer addSubview:self.selectedColorView];
|
[self.contentContainer addSubview:self.selectedColorView];
|
||||||
[self.selectedColorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.selectedColorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.subtitleLabel.mas_bottom).offset(30);
|
make.top.equalTo(self.subtitleLabel.mas_bottom).offset(20);
|
||||||
make.centerX.equalTo(self.contentContainer);
|
make.centerX.equalTo(self.contentContainer);
|
||||||
make.height.mas_equalTo(60);
|
make.height.mas_equalTo(60);
|
||||||
make.leading.trailing.equalTo(self.contentContainer).inset(40);
|
make.leading.trailing.equalTo(self.contentContainer).inset(40);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 色轮视图(使用共享组件)
|
|
||||||
[self.contentContainer addSubview:self.colorWheelView];
|
[self.contentContainer addSubview:self.colorWheelView];
|
||||||
[self.colorWheelView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.colorWheelView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.selectedColorView.mas_bottom).offset(30);
|
make.top.equalTo(self.selectedColorView.mas_bottom).offset(20);
|
||||||
make.centerX.equalTo(self.contentContainer);
|
make.centerX.equalTo(self.contentContainer);
|
||||||
make.size.mas_equalTo(CGSizeMake(360, 360)); // 从280x280增加到360x360
|
CGFloat wheelSize = MIN(300, [UIScreen mainScreen].bounds.size.width - 80);
|
||||||
|
make.size.mas_equalTo(CGSizeMake(wheelSize, wheelSize));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 确认按钮
|
|
||||||
[self.contentContainer addSubview:self.confirmButton];
|
[self.contentContainer addSubview:self.confirmButton];
|
||||||
[self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.colorWheelView.mas_bottom).offset(50);
|
make.top.equalTo(self.colorWheelView.mas_bottom).offset(30);
|
||||||
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
make.leading.trailing.equalTo(self.contentContainer).inset(20);
|
||||||
make.height.mas_equalTo(56);
|
make.height.mas_equalTo(56);
|
||||||
make.bottom.equalTo(self.contentContainer);
|
make.bottom.equalTo(self.contentContainer);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Skip 按钮(右上角,初始隐藏)
|
|
||||||
[self addSubview:self.skipButton];
|
[self addSubview:self.skipButton];
|
||||||
[self.skipButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.skipButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self).offset(60);
|
make.top.equalTo(self).offset(60);
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
- (void)layoutSubviews {
|
- (void)layoutSubviews {
|
||||||
[super layoutSubviews];
|
[super layoutSubviews];
|
||||||
// 更新渐变层 frame
|
|
||||||
self.gradientLayer.frame = self.bounds;
|
self.gradientLayer.frame = self.bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,22 +125,22 @@
|
|||||||
- (void)onConfirmButtonTapped {
|
- (void)onConfirmButtonTapped {
|
||||||
if (!self.selectedColor) return;
|
if (!self.selectedColor) return;
|
||||||
|
|
||||||
// 执行回调
|
|
||||||
if (self.onColorConfirmed) {
|
if (self.onColorConfirmed) {
|
||||||
self.onColorConfirmed(self.selectedColor);
|
self.onColorConfirmed(self.selectedColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭引导页
|
|
||||||
[self dismiss];
|
[self dismiss];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onSkipButtonTapped {
|
- (void)onSkipButtonTapped {
|
||||||
// 执行 skip 回调
|
|
||||||
if (self.onSkipTapped) {
|
if (self.onSkipTapped) {
|
||||||
self.onSkipTapped();
|
self.onSkipTapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭引导页
|
|
||||||
[self dismiss];
|
[self dismiss];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,14 +161,14 @@
|
|||||||
make.edges.equalTo(window);
|
make.edges.equalTo(window);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 控制 Skip 按钮显示
|
|
||||||
self.skipButton.hidden = !showSkip;
|
self.skipButton.hidden = !showSkip;
|
||||||
|
|
||||||
// 初始状态
|
|
||||||
self.alpha = 0;
|
self.alpha = 0;
|
||||||
self.contentContainer.transform = CGAffineTransformMakeScale(0.8, 0.8);
|
self.contentContainer.transform = CGAffineTransformMakeScale(0.8, 0.8);
|
||||||
|
|
||||||
// 显示动画
|
|
||||||
[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||||
self.alpha = 1.0;
|
self.alpha = 1.0;
|
||||||
self.contentContainer.transform = CGAffineTransformIdentity;
|
self.contentContainer.transform = CGAffineTransformIdentity;
|
||||||
@@ -223,11 +223,11 @@
|
|||||||
_selectedColorView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.15];
|
_selectedColorView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.15];
|
||||||
_selectedColorView.layer.cornerRadius = 30;
|
_selectedColorView.layer.cornerRadius = 30;
|
||||||
_selectedColorView.layer.masksToBounds = YES;
|
_selectedColorView.layer.masksToBounds = YES;
|
||||||
_selectedColorView.hidden = YES; // 初始隐藏
|
_selectedColorView.hidden = YES;
|
||||||
|
|
||||||
|
|
||||||
// 颜色圆点
|
|
||||||
UIView *colorDot = [[UIView alloc] init];
|
UIView *colorDot = [[UIView alloc] init];
|
||||||
colorDot.tag = 100; // 用于后续查找
|
colorDot.tag = 100;
|
||||||
colorDot.layer.cornerRadius = 16;
|
colorDot.layer.cornerRadius = 16;
|
||||||
colorDot.layer.masksToBounds = YES;
|
colorDot.layer.masksToBounds = YES;
|
||||||
[_selectedColorView addSubview:colorDot];
|
[_selectedColorView addSubview:colorDot];
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
make.size.mas_equalTo(CGSizeMake(32, 32));
|
make.size.mas_equalTo(CGSizeMake(32, 32));
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 情绪名称标签
|
|
||||||
[_selectedColorView addSubview:self.selectedColorLabel];
|
[_selectedColorView addSubview:self.selectedColorLabel];
|
||||||
[self.selectedColorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.selectedColorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.leading.equalTo(colorDot.mas_trailing).offset(16);
|
make.leading.equalTo(colorDot.mas_trailing).offset(16);
|
||||||
@@ -261,20 +261,21 @@
|
|||||||
- (EPEmotionColorWheelView *)colorWheelView {
|
- (EPEmotionColorWheelView *)colorWheelView {
|
||||||
if (!_colorWheelView) {
|
if (!_colorWheelView) {
|
||||||
_colorWheelView = [[EPEmotionColorWheelView alloc] init];
|
_colorWheelView = [[EPEmotionColorWheelView alloc] init];
|
||||||
_colorWheelView.radius = 100.0;
|
CGFloat wheelSize = MIN(300, [UIScreen mainScreen].bounds.size.width - 80);
|
||||||
_colorWheelView.buttonSize = 54.0;
|
_colorWheelView.radius = wheelSize / 3.0;
|
||||||
|
_colorWheelView.buttonSize = 48.0;
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
_colorWheelView.onColorTapped = ^(NSString *hexColor, NSInteger index) {
|
_colorWheelView.onColorTapped = ^(NSString *hexColor, NSInteger index) {
|
||||||
__strong typeof(weakSelf) self = weakSelf;
|
__strong typeof(weakSelf) self = weakSelf;
|
||||||
|
|
||||||
// 保存选中的颜色
|
|
||||||
self.selectedColor = hexColor;
|
self.selectedColor = hexColor;
|
||||||
|
|
||||||
// 更新选中状态显示
|
|
||||||
[self updateSelectedColorDisplay:hexColor index:index];
|
[self updateSelectedColorDisplay:hexColor index:index];
|
||||||
|
|
||||||
// 启用确认按钮
|
|
||||||
self.confirmButton.enabled = YES;
|
self.confirmButton.enabled = YES;
|
||||||
self.confirmButton.alpha = 1.0;
|
self.confirmButton.alpha = 1.0;
|
||||||
};
|
};
|
||||||
@@ -282,26 +283,26 @@
|
|||||||
return _colorWheelView;
|
return _colorWheelView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新选中颜色显示
|
|
||||||
- (void)updateSelectedColorDisplay:(NSString *)hexColor index:(NSInteger)index {
|
- (void)updateSelectedColorDisplay:(NSString *)hexColor index:(NSInteger)index {
|
||||||
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
NSArray<NSString *> *emotions = @[@"Joy", @"Sadness", @"Anger", @"Fear", @"Surprise", @"Disgust", @"Trust", @"Anticipation"];
|
||||||
|
|
||||||
// 显示选中状态区域
|
|
||||||
self.selectedColorView.hidden = NO;
|
self.selectedColorView.hidden = NO;
|
||||||
|
|
||||||
// 更新颜色圆点
|
|
||||||
UIView *colorDot = [self.selectedColorView viewWithTag:100];
|
UIView *colorDot = [self.selectedColorView viewWithTag:100];
|
||||||
colorDot.backgroundColor = [self colorFromHex:hexColor];
|
colorDot.backgroundColor = [self colorFromHex:hexColor];
|
||||||
|
|
||||||
// 更新情绪名称
|
|
||||||
self.selectedColorLabel.text = emotions[index];
|
self.selectedColorLabel.text = emotions[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hex 转 UIColor
|
|
||||||
- (UIColor *)colorFromHex:(NSString *)hexString {
|
- (UIColor *)colorFromHex:(NSString *)hexString {
|
||||||
unsigned rgbValue = 0;
|
unsigned rgbValue = 0;
|
||||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||||
[scanner setScanLocation:1]; // 跳过 #
|
[scanner setScanLocation:1];
|
||||||
[scanner scanHexInt:&rgbValue];
|
[scanner scanHexInt:&rgbValue];
|
||||||
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0
|
||||||
green:((rgbValue & 0xFF00) >> 8)/255.0
|
green:((rgbValue & 0xFF00) >> 8)/255.0
|
||||||
@@ -318,7 +319,7 @@
|
|||||||
_confirmButton.layer.cornerRadius = 28;
|
_confirmButton.layer.cornerRadius = 28;
|
||||||
_confirmButton.layer.masksToBounds = YES;
|
_confirmButton.layer.masksToBounds = YES;
|
||||||
|
|
||||||
// 渐变背景
|
|
||||||
CAGradientLayer *gradient = [CAGradientLayer layer];
|
CAGradientLayer *gradient = [CAGradientLayer layer];
|
||||||
gradient.colors = @[
|
gradient.colors = @[
|
||||||
(id)[UIColor colorWithRed:0x9B/255.0 green:0x59/255.0 blue:0xB6/255.0 alpha:1.0].CGColor,
|
(id)[UIColor colorWithRed:0x9B/255.0 green:0x59/255.0 blue:0xB6/255.0 alpha:1.0].CGColor,
|
||||||
@@ -326,12 +327,12 @@
|
|||||||
];
|
];
|
||||||
gradient.startPoint = CGPointMake(0, 0);
|
gradient.startPoint = CGPointMake(0, 0);
|
||||||
gradient.endPoint = CGPointMake(1, 0);
|
gradient.endPoint = CGPointMake(1, 0);
|
||||||
gradient.frame = CGRectMake(0, 0, 1000, 56); // 宽度设大一点
|
gradient.frame = CGRectMake(0, 0, 1000, 56);
|
||||||
[_confirmButton.layer insertSublayer:gradient atIndex:0];
|
[_confirmButton.layer insertSublayer:gradient atIndex:0];
|
||||||
|
|
||||||
[_confirmButton addTarget:self action:@selector(onConfirmButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_confirmButton addTarget:self action:@selector(onConfirmButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
|
||||||
// 初始禁用状态
|
|
||||||
_confirmButton.enabled = NO;
|
_confirmButton.enabled = NO;
|
||||||
_confirmButton.alpha = 0.5;
|
_confirmButton.alpha = 0.5;
|
||||||
}
|
}
|
||||||
@@ -342,12 +343,12 @@
|
|||||||
if (!_infoButton) {
|
if (!_infoButton) {
|
||||||
_infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
|
||||||
// 使用系统 info.circle 图标
|
|
||||||
UIImage *infoIcon = [UIImage systemImageNamed:@"info.circle"];
|
UIImage *infoIcon = [UIImage systemImageNamed:@"info.circle"];
|
||||||
[_infoButton setImage:infoIcon forState:UIControlStateNormal];
|
[_infoButton setImage:infoIcon forState:UIControlStateNormal];
|
||||||
_infoButton.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
|
_infoButton.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
|
||||||
|
|
||||||
// 点击效果
|
|
||||||
[_infoButton addTarget:self action:@selector(onInfoButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_infoButton addTarget:self action:@selector(onInfoButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
}
|
}
|
||||||
return _infoButton;
|
return _infoButton;
|
||||||
@@ -363,10 +364,9 @@
|
|||||||
_skipButton.layer.cornerRadius = 18;
|
_skipButton.layer.cornerRadius = 18;
|
||||||
_skipButton.layer.masksToBounds = YES;
|
_skipButton.layer.masksToBounds = YES;
|
||||||
[_skipButton addTarget:self action:@selector(onSkipButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
[_skipButton addTarget:self action:@selector(onSkipButtonTapped) forControlEvents:UIControlEventTouchUpInside];
|
||||||
_skipButton.hidden = YES; // 默认隐藏
|
_skipButton.hidden = YES;
|
||||||
}
|
}
|
||||||
return _skipButton;
|
return _skipButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@@ -1,33 +1,27 @@
|
|||||||
//
|
|
||||||
// EPTabBarController.swift
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-09.
|
// Created by AI on 2025-10-09.
|
||||||
// Copyright © 2025 YuMi. All rights reserved.
|
// Copyright © 2025 YuMi. All rights reserved.
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import SnapKit
|
import SnapKit
|
||||||
|
|
||||||
/// EP 系列 TabBar 控制器
|
|
||||||
/// 悬浮设计 + 液态玻璃效果,只包含 Moment 和 Mine 两个 Tab
|
|
||||||
@objc class EPTabBarController: UITabBarController {
|
@objc class EPTabBarController: UITabBarController {
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
|
||||||
/// 全局事件管理器
|
|
||||||
private var globalEventManager: GlobalEventManager?
|
|
||||||
|
|
||||||
/// 是否已登录
|
|
||||||
private var isLoggedIn: Bool = false
|
private var isLoggedIn: Bool = false
|
||||||
|
|
||||||
/// 自定义悬浮 TabBar 容器
|
|
||||||
private var customTabBarView: UIView!
|
private var customTabBarView: UIView!
|
||||||
|
|
||||||
/// 毛玻璃背景视图
|
|
||||||
private var tabBarBackgroundView: UIVisualEffectView!
|
private var tabBarBackgroundView: UIVisualEffectView!
|
||||||
|
|
||||||
/// Tab 按钮数组
|
|
||||||
private var tabButtons: [UIButton] = []
|
private var tabButtons: [UIButton] = []
|
||||||
|
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
@@ -35,49 +29,47 @@ import SnapKit
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
// 测试域名配置
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
APIConfig.testEncryption()
|
APIConfig.testEncryption()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 隐藏原生 TabBar
|
|
||||||
self.tabBar.isHidden = true
|
self.tabBar.isHidden = true
|
||||||
|
|
||||||
// 设置 delegate 以完全控制切换行为
|
|
||||||
self.delegate = self
|
self.delegate = self
|
||||||
|
|
||||||
// ✅ 启动时验证 ticket(与 OC 版本保持一致)
|
|
||||||
performAutoLogin()
|
performAutoLogin()
|
||||||
|
|
||||||
setupCustomFloatingTabBar()
|
setupCustomFloatingTabBar()
|
||||||
setupGlobalManagers()
|
|
||||||
setupInitialViewControllers()
|
setupInitialViewControllers()
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 悬浮 TabBar 初始化完成")
|
NSLog("[EPTabBarController] 悬浮 TabBar 初始化完成")
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
globalEventManager?.removeAllDelegates()
|
|
||||||
NSLog("[EPTabBarController] 已释放")
|
NSLog("[EPTabBarController] 已释放")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
|
|
||||||
/// 设置自定义悬浮 TabBar
|
|
||||||
private func setupCustomFloatingTabBar() {
|
private func setupCustomFloatingTabBar() {
|
||||||
// 创建悬浮容器
|
|
||||||
customTabBarView = UIView()
|
customTabBarView = UIView()
|
||||||
customTabBarView.translatesAutoresizingMaskIntoConstraints = false
|
customTabBarView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
customTabBarView.backgroundColor = .clear
|
customTabBarView.backgroundColor = .clear
|
||||||
view.addSubview(customTabBarView)
|
view.addSubview(customTabBarView)
|
||||||
|
|
||||||
// 液态玻璃/毛玻璃效果
|
|
||||||
let effect: UIVisualEffect
|
let effect: UIVisualEffect
|
||||||
if #available(iOS 26.0, *) {
|
if #available(iOS 26.0, *) {
|
||||||
// iOS 26+ 使用液态玻璃(Material)
|
|
||||||
effect = UIGlassEffect()
|
effect = UIGlassEffect()
|
||||||
} else {
|
} else {
|
||||||
// iOS 13-17 使用毛玻璃
|
|
||||||
effect = UIBlurEffect(style: .systemMaterial)
|
effect = UIBlurEffect(style: .systemMaterial)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,13 +78,13 @@ import SnapKit
|
|||||||
tabBarBackgroundView.layer.cornerRadius = 28
|
tabBarBackgroundView.layer.cornerRadius = 28
|
||||||
tabBarBackgroundView.layer.masksToBounds = true
|
tabBarBackgroundView.layer.masksToBounds = true
|
||||||
|
|
||||||
// 添加边框
|
|
||||||
tabBarBackgroundView.layer.borderWidth = 0.5
|
tabBarBackgroundView.layer.borderWidth = 0.5
|
||||||
tabBarBackgroundView.layer.borderColor = UIColor.white.withAlphaComponent(0.2).cgColor
|
tabBarBackgroundView.layer.borderColor = UIColor.white.withAlphaComponent(0.2).cgColor
|
||||||
|
|
||||||
customTabBarView.addSubview(tabBarBackgroundView)
|
customTabBarView.addSubview(tabBarBackgroundView)
|
||||||
|
|
||||||
// 简化的布局约束(类似 Masonry 风格)
|
|
||||||
customTabBarView.snp.makeConstraints { make in
|
customTabBarView.snp.makeConstraints { make in
|
||||||
make.leading.equalTo(view).offset(16)
|
make.leading.equalTo(view).offset(16)
|
||||||
make.trailing.equalTo(view).offset(-16)
|
make.trailing.equalTo(view).offset(-16)
|
||||||
@@ -104,13 +96,13 @@ import SnapKit
|
|||||||
make.edges.equalTo(customTabBarView)
|
make.edges.equalTo(customTabBarView)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 Tab 按钮
|
|
||||||
setupTabButtons()
|
setupTabButtons()
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 悬浮 TabBar 设置完成")
|
NSLog("[EPTabBarController] 悬浮 TabBar 设置完成")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置 Tab 按钮
|
|
||||||
private func setupTabButtons() {
|
private func setupTabButtons() {
|
||||||
let momentButton = createTabButton(
|
let momentButton = createTabButton(
|
||||||
normalImage: "tab_moment_off",
|
normalImage: "tab_moment_off",
|
||||||
@@ -118,13 +110,19 @@ import SnapKit
|
|||||||
tag: 0
|
tag: 0
|
||||||
)
|
)
|
||||||
|
|
||||||
let mineButton = createTabButton(
|
let messageButton = createTabButton(
|
||||||
normalImage: "tab_mine_off",
|
normalImage: "tab_message_off",
|
||||||
selectedImage: "tab_mine_on",
|
selectedImage: "tab_message_on",
|
||||||
tag: 1
|
tag: 1
|
||||||
)
|
)
|
||||||
|
|
||||||
tabButtons = [momentButton, mineButton]
|
let mineButton = createTabButton(
|
||||||
|
normalImage: "tab_mine_off",
|
||||||
|
selectedImage: "tab_mine_on",
|
||||||
|
tag: 2
|
||||||
|
)
|
||||||
|
|
||||||
|
tabButtons = [momentButton, messageButton, mineButton]
|
||||||
|
|
||||||
let stackView = UIStackView(arrangedSubviews: tabButtons)
|
let stackView = UIStackView(arrangedSubviews: tabButtons)
|
||||||
stackView.axis = .horizontal
|
stackView.axis = .horizontal
|
||||||
@@ -140,23 +138,23 @@ import SnapKit
|
|||||||
make.bottom.equalTo(tabBarBackgroundView).offset(-8)
|
make.bottom.equalTo(tabBarBackgroundView).offset(-8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认选中第一个
|
|
||||||
updateTabButtonStates(selectedIndex: 0)
|
updateTabButtonStates(selectedIndex: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 创建 Tab 按钮
|
|
||||||
private func createTabButton(normalImage: String, selectedImage: String, tag: Int) -> UIButton {
|
private func createTabButton(normalImage: String, selectedImage: String, tag: Int) -> UIButton {
|
||||||
let button = UIButton(type: .custom)
|
let button = UIButton(type: .custom)
|
||||||
button.tag = tag
|
button.tag = tag
|
||||||
button.adjustsImageWhenHighlighted = false // 禁用高亮效果,避免闪烁
|
button.adjustsImageWhenHighlighted = false
|
||||||
|
|
||||||
|
|
||||||
// 尝试设置自定义图片,如果不存在则使用 SF Symbols
|
|
||||||
if let normalImg = UIImage(named: normalImage), let selectedImg = UIImage(named: selectedImage) {
|
if let normalImg = UIImage(named: normalImage), let selectedImg = UIImage(named: selectedImage) {
|
||||||
// 正确设置:分别为 normal 和 selected 状态设置图片
|
|
||||||
button.setImage(normalImg, for: .normal)
|
button.setImage(normalImg, for: .normal)
|
||||||
button.setImage(selectedImg, for: .selected)
|
button.setImage(selectedImg, for: .selected)
|
||||||
} else {
|
} else {
|
||||||
// 使用 SF Symbols 作为备用
|
|
||||||
let fallbackIcons = ["sparkles", "person.circle"]
|
let fallbackIcons = ["sparkles", "person.circle"]
|
||||||
let iconName = fallbackIcons[tag]
|
let iconName = fallbackIcons[tag]
|
||||||
let imageConfig = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium)
|
let imageConfig = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium)
|
||||||
@@ -167,14 +165,14 @@ import SnapKit
|
|||||||
button.tintColor = .white.withAlphaComponent(0.6)
|
button.tintColor = .white.withAlphaComponent(0.6)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 图片渲染模式
|
|
||||||
button.imageView?.contentMode = .scaleAspectFit
|
button.imageView?.contentMode = .scaleAspectFit
|
||||||
|
|
||||||
// 移除标题
|
|
||||||
button.setTitle(nil, for: .normal)
|
button.setTitle(nil, for: .normal)
|
||||||
button.setTitle(nil, for: .selected)
|
button.setTitle(nil, for: .selected)
|
||||||
|
|
||||||
// 设置图片大小约束
|
|
||||||
button.imageView?.snp.makeConstraints { make in
|
button.imageView?.snp.makeConstraints { make in
|
||||||
make.size.equalTo(28)
|
make.size.equalTo(28)
|
||||||
}
|
}
|
||||||
@@ -183,105 +181,90 @@ import SnapKit
|
|||||||
return button
|
return button
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab 按钮点击事件
|
|
||||||
@objc private func tabButtonTapped(_ sender: UIButton) {
|
@objc private func tabButtonTapped(_ sender: UIButton) {
|
||||||
let newIndex = sender.tag
|
let newIndex = sender.tag
|
||||||
|
|
||||||
// 如果点击的是当前已选中的 tab,不做任何操作
|
|
||||||
if newIndex == selectedIndex {
|
if newIndex == selectedIndex {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先更新按钮状态
|
|
||||||
updateTabButtonStates(selectedIndex: newIndex)
|
updateTabButtonStates(selectedIndex: newIndex)
|
||||||
|
|
||||||
// 禁用 UITabBarController 的默认切换动画,避免闪烁
|
|
||||||
UIView.performWithoutAnimation {
|
UIView.performWithoutAnimation {
|
||||||
selectedIndex = newIndex
|
selectedIndex = newIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
let tabNames = [YMLocalizedString("tab.moment"), YMLocalizedString("tab.mine")]
|
let tabNames = [YMLocalizedString("tab.moment"),
|
||||||
|
YMLocalizedString("tab.message"),
|
||||||
|
YMLocalizedString("tab.mine")]
|
||||||
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[newIndex])")
|
NSLog("[EPTabBarController] 选中 Tab: \(tabNames[newIndex])")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新 Tab 按钮状态
|
|
||||||
private func updateTabButtonStates(selectedIndex: Int) {
|
private func updateTabButtonStates(selectedIndex: Int) {
|
||||||
// 禁用按钮交互,避免快速点击
|
|
||||||
tabButtons.forEach { $0.isUserInteractionEnabled = false }
|
tabButtons.forEach { $0.isUserInteractionEnabled = false }
|
||||||
|
|
||||||
for (index, button) in tabButtons.enumerated() {
|
for (index, button) in tabButtons.enumerated() {
|
||||||
let isSelected = (index == selectedIndex)
|
let isSelected = (index == selectedIndex)
|
||||||
|
|
||||||
// 直接设置 isSelected 属性即可,图片会自动切换
|
|
||||||
button.isSelected = isSelected
|
button.isSelected = isSelected
|
||||||
|
|
||||||
// SF Symbols 的情况需要手动更新 tintColor
|
|
||||||
if button.currentImage?.isSymbolImage == true {
|
if button.currentImage?.isSymbolImage == true {
|
||||||
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
button.tintColor = isSelected ? .white : .white.withAlphaComponent(0.6)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中状态缩放动画
|
|
||||||
UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseOut], animations: {
|
UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseOut], animations: {
|
||||||
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
button.transform = isSelected ? CGAffineTransform(scaleX: 1.1, y: 1.1) : .identity
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 延迟恢复按钮交互
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
|
||||||
self.tabButtons.forEach { $0.isUserInteractionEnabled = true }
|
self.tabButtons.forEach { $0.isUserInteractionEnabled = true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置全局管理器
|
|
||||||
private func setupGlobalManagers() {
|
|
||||||
globalEventManager = GlobalEventManager.shared()
|
|
||||||
globalEventManager?.setupSDKDelegates()
|
|
||||||
|
|
||||||
// TODO: v0.2 版本暂时禁用房间最小化视图(无房间功能)
|
|
||||||
// 后续版本可通过 Build Configuration 或版本号判断是否启用
|
|
||||||
/*
|
|
||||||
if let containerView = view {
|
|
||||||
globalEventManager?.setupRoomMiniView(on: containerView)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 注册社交分享回调
|
|
||||||
globalEventManager?.registerSocialShareCallback()
|
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 全局管理器设置完成(v0.2 - 无 MiniRoom)")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 设置初始 ViewController(未登录状态)
|
|
||||||
private func setupInitialViewControllers() {
|
private func setupInitialViewControllers() {
|
||||||
// TODO: 暂时使用空白页面占位
|
// 三栏占位(Moment | Message | Mine)
|
||||||
let blankVC1 = UIViewController()
|
let momentVC = UIViewController()
|
||||||
blankVC1.view.backgroundColor = .white
|
momentVC.view.backgroundColor = .systemBlue
|
||||||
blankVC1.tabBarItem = createTabBarItem(
|
momentVC.title = "Moment"
|
||||||
title: YMLocalizedString("tab.moment"),
|
let momentNav = UINavigationController(rootViewController: momentVC)
|
||||||
normalImage: "tab_moment_normal",
|
momentNav.tabBarItem = createTabBarItem(title: YMLocalizedString("tab.moment"), normalImage: "tab_moment_normal", selectedImage: "tab_moment_selected")
|
||||||
selectedImage: "tab_moment_selected"
|
|
||||||
)
|
|
||||||
|
|
||||||
let blankVC2 = UIViewController()
|
let messageVC = EPMessageMainViewController()
|
||||||
blankVC2.view.backgroundColor = .white
|
messageVC.title = "Message"
|
||||||
blankVC2.tabBarItem = createTabBarItem(
|
let messageNav = UINavigationController(rootViewController: messageVC)
|
||||||
title: YMLocalizedString("tab.mine"),
|
messageNav.tabBarItem = createTabBarItem(title: YMLocalizedString("tab.message"), normalImage: "tab_message_normal", selectedImage: "tab_message_selected")
|
||||||
normalImage: "tab_mine_normal",
|
|
||||||
selectedImage: "tab_mine_selected"
|
|
||||||
)
|
|
||||||
|
|
||||||
viewControllers = [blankVC1, blankVC2]
|
// 角标绑定
|
||||||
|
messageVC.unreadCountDidChange = { [weak self] c in
|
||||||
|
let value: String? = c > 0 ? (c > 99 ? "99+" : "\(c)") : nil
|
||||||
|
self?.viewControllers?[1].tabBarItem.badgeValue = value
|
||||||
|
}
|
||||||
|
|
||||||
|
let mineVC = UIViewController()
|
||||||
|
mineVC.view.backgroundColor = .systemGreen
|
||||||
|
mineVC.title = "Mine"
|
||||||
|
let mineNav = UINavigationController(rootViewController: mineVC)
|
||||||
|
mineNav.tabBarItem = createTabBarItem(title: YMLocalizedString("tab.mine"), normalImage: "tab_mine_normal", selectedImage: "tab_mine_selected")
|
||||||
|
|
||||||
|
viewControllers = [momentNav, messageNav, mineNav]
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
|
|
||||||
NSLog("[EPTabBarController] 初始 ViewControllers 设置完成")
|
NSLog("[EPTabBarController] 初始 ViewControllers 设置完成")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 创建 TabBarItem
|
|
||||||
/// - Parameters:
|
|
||||||
/// - title: 标题
|
|
||||||
/// - normalImage: 未选中图标名称
|
|
||||||
/// - selectedImage: 选中图标名称
|
|
||||||
/// - Returns: UITabBarItem
|
|
||||||
private func createTabBarItem(title: String, normalImage: String, selectedImage: String) -> UITabBarItem {
|
private func createTabBarItem(title: String, normalImage: String, selectedImage: String) -> UITabBarItem {
|
||||||
let item = UITabBarItem(
|
let item = UITabBarItem(
|
||||||
title: title,
|
title: title,
|
||||||
@@ -293,8 +276,7 @@ import SnapKit
|
|||||||
|
|
||||||
// MARK: - Public Methods
|
// MARK: - Public Methods
|
||||||
|
|
||||||
/// 登录成功后刷新 TabBar
|
|
||||||
/// - Parameter isLogin: 是否已登录
|
|
||||||
func refreshTabBar(isLogin: Bool) {
|
func refreshTabBar(isLogin: Bool) {
|
||||||
isLoggedIn = isLogin
|
isLoggedIn = isLogin
|
||||||
|
|
||||||
@@ -307,12 +289,8 @@ import SnapKit
|
|||||||
NSLog("[EPTabBarController] TabBar 已刷新,登录状态: \(isLogin)")
|
NSLog("[EPTabBarController] TabBar 已刷新,登录状态: \(isLogin)")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置登录后的 ViewControllers
|
|
||||||
private func setupLoggedInViewControllers() {
|
private func setupLoggedInViewControllers() {
|
||||||
// 只在 viewControllers 为空或不是正确类型时才创建
|
|
||||||
if viewControllers?.count != 2 ||
|
|
||||||
!(viewControllers?[0] is UINavigationController) ||
|
|
||||||
!(viewControllers?[1] is UINavigationController) {
|
|
||||||
|
|
||||||
// 创建动态页
|
// 创建动态页
|
||||||
let momentVC = EPMomentViewController()
|
let momentVC = EPMomentViewController()
|
||||||
@@ -324,6 +302,20 @@ import SnapKit
|
|||||||
selectedImage: "tab_moment_selected"
|
selectedImage: "tab_moment_selected"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 创建消息页(Swift UIKit 容器)
|
||||||
|
let messageVC = EPMessageMainViewController()
|
||||||
|
let messageNav = createTransparentNavigationController(
|
||||||
|
rootViewController: messageVC,
|
||||||
|
tabTitle: YMLocalizedString("tab.message"),
|
||||||
|
normalImage: "tab_message_normal",
|
||||||
|
selectedImage: "tab_message_selected"
|
||||||
|
)
|
||||||
|
// 角标绑定
|
||||||
|
messageVC.unreadCountDidChange = { [weak self] c in
|
||||||
|
let value: String? = c > 0 ? (c > 99 ? "99+" : "\(c)") : nil
|
||||||
|
self?.viewControllers?[1].tabBarItem.badgeValue = value
|
||||||
|
}
|
||||||
|
|
||||||
// 创建我的页
|
// 创建我的页
|
||||||
let mineVC = EPMineViewController()
|
let mineVC = EPMineViewController()
|
||||||
mineVC.title = YMLocalizedString("tab.mine")
|
mineVC.title = YMLocalizedString("tab.mine")
|
||||||
@@ -334,20 +326,13 @@ import SnapKit
|
|||||||
selectedImage: "tab_mine_selected"
|
selectedImage: "tab_mine_selected"
|
||||||
)
|
)
|
||||||
|
|
||||||
viewControllers = [momentNav, mineNav]
|
viewControllers = [momentNav, messageNav, mineNav]
|
||||||
NSLog("[EPTabBarController] 登录后 ViewControllers 创建完成 - Moment & Mine")
|
NSLog("[EPTabBarController] 登录后 ViewControllers 创建完成 - Moment & Message & Mine")
|
||||||
}
|
|
||||||
|
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 创建透明导航控制器(统一配置)
|
|
||||||
/// - Parameters:
|
|
||||||
/// - rootViewController: 根视图控制器
|
|
||||||
/// - tabTitle: TabBar 标题
|
|
||||||
/// - normalImage: 未选中图标
|
|
||||||
/// - selectedImage: 选中图标
|
|
||||||
/// - Returns: 配置好的 UINavigationController
|
|
||||||
private func createTransparentNavigationController(
|
private func createTransparentNavigationController(
|
||||||
rootViewController: UIViewController,
|
rootViewController: UIViewController,
|
||||||
tabTitle: String,
|
tabTitle: String,
|
||||||
@@ -365,7 +350,7 @@ import SnapKit
|
|||||||
selectedImage: selectedImage
|
selectedImage: selectedImage
|
||||||
)
|
)
|
||||||
|
|
||||||
// 设置 delegate 以监听页面切换
|
|
||||||
nav.delegate = self
|
nav.delegate = self
|
||||||
|
|
||||||
return nav
|
return nav
|
||||||
@@ -373,7 +358,7 @@ import SnapKit
|
|||||||
|
|
||||||
// MARK: - TabBar Visibility Control
|
// MARK: - TabBar Visibility Control
|
||||||
|
|
||||||
/// 显示悬浮 TabBar
|
|
||||||
private func showCustomTabBar(animated: Bool = true) {
|
private func showCustomTabBar(animated: Bool = true) {
|
||||||
guard customTabBarView.isHidden else { return }
|
guard customTabBarView.isHidden else { return }
|
||||||
|
|
||||||
@@ -392,7 +377,7 @@ import SnapKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 隐藏悬浮 TabBar
|
|
||||||
private func hideCustomTabBar(animated: Bool = true) {
|
private func hideCustomTabBar(animated: Bool = true) {
|
||||||
guard !customTabBarView.isHidden else { return }
|
guard !customTabBarView.isHidden else { return }
|
||||||
|
|
||||||
@@ -419,18 +404,18 @@ extension EPTabBarController: UITabBarControllerDelegate {
|
|||||||
NSLog("[EPTabBarController] 选中 Tab: \(item.title ?? "Unknown")")
|
NSLog("[EPTabBarController] 选中 Tab: \(item.title ?? "Unknown")")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 禁用系统默认的切换动画
|
|
||||||
func tabBarController(_ tabBarController: UITabBarController,
|
func tabBarController(_ tabBarController: UITabBarController,
|
||||||
animationControllerForTransitionFrom fromVC: UIViewController,
|
animationControllerForTransitionFrom fromVC: UIViewController,
|
||||||
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||||
// 返回 nil 表示不使用动画
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 完全控制是否允许切换
|
|
||||||
func tabBarController(_ tabBarController: UITabBarController,
|
func tabBarController(_ tabBarController: UITabBarController,
|
||||||
shouldSelect viewController: UIViewController) -> Bool {
|
shouldSelect viewController: UIViewController) -> Bool {
|
||||||
// 允许切换,但通过返回 nil 的 animationController 来禁用动画
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,15 +428,15 @@ extension EPTabBarController: UINavigationControllerDelegate {
|
|||||||
willShow viewController: UIViewController,
|
willShow viewController: UIViewController,
|
||||||
animated: Bool) {
|
animated: Bool) {
|
||||||
|
|
||||||
// 判断是否是根页面(一级页面)
|
|
||||||
let isRootViewController = navigationController.viewControllers.count == 1
|
let isRootViewController = navigationController.viewControllers.count == 1
|
||||||
|
|
||||||
if isRootViewController {
|
if isRootViewController {
|
||||||
// 一级页面:显示 TabBar
|
|
||||||
showCustomTabBar(animated: animated)
|
showCustomTabBar(animated: animated)
|
||||||
NSLog("[EPTabBarController] 显示 TabBar - 根页面")
|
NSLog("[EPTabBarController] 显示 TabBar - 根页面")
|
||||||
} else {
|
} else {
|
||||||
// 二级及以上页面:隐藏 TabBar
|
|
||||||
hideCustomTabBar(animated: animated)
|
hideCustomTabBar(animated: animated)
|
||||||
NSLog("[EPTabBarController] 隐藏 TabBar - 子页面 (层级: \(navigationController.viewControllers.count))")
|
NSLog("[EPTabBarController] 隐藏 TabBar - 子页面 (层级: \(navigationController.viewControllers.count))")
|
||||||
}
|
}
|
||||||
@@ -462,16 +447,16 @@ extension EPTabBarController: UINavigationControllerDelegate {
|
|||||||
|
|
||||||
extension EPTabBarController {
|
extension EPTabBarController {
|
||||||
|
|
||||||
/// 自动登录:验证 ticket 有效性(与 OC MainPresenter.autoLogin 保持一致)
|
|
||||||
private func performAutoLogin() {
|
private func performAutoLogin() {
|
||||||
// 1. 检查账号信息
|
|
||||||
guard let accountModel = AccountInfoStorage.instance().getCurrentAccountInfo() else {
|
guard let accountModel = AccountInfoStorage.instance().getCurrentAccountInfo() else {
|
||||||
NSLog("[EPTabBarController] ⚠️ 账号信息不存在,跳转到登录页")
|
NSLog("[EPTabBarController] ⚠️ 账号信息不存在,跳转到登录页")
|
||||||
handleTokenInvalid()
|
handleTokenInvalid()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查 uid 和 access_token
|
|
||||||
let uid = accountModel.uid
|
let uid = accountModel.uid
|
||||||
let accessToken = accountModel.access_token
|
let accessToken = accountModel.access_token
|
||||||
|
|
||||||
@@ -481,14 +466,14 @@ extension EPTabBarController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 检查 ticket 是否已存在(内存缓存)
|
|
||||||
let existingTicket = AccountInfoStorage.instance().getTicket() ?? ""
|
let existingTicket = AccountInfoStorage.instance().getTicket() ?? ""
|
||||||
if !existingTicket.isEmpty {
|
if !existingTicket.isEmpty {
|
||||||
NSLog("[EPTabBarController] ✅ Ticket 已存在,自动登录成功")
|
NSLog("[EPTabBarController] ✅ Ticket 已存在,自动登录成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Ticket 不存在,请求新的 ticket
|
|
||||||
NSLog("[EPTabBarController] 🔄 Ticket 不存在,正在请求...")
|
NSLog("[EPTabBarController] 🔄 Ticket 不存在,正在请求...")
|
||||||
let loginService = EPLoginService()
|
let loginService = EPLoginService()
|
||||||
|
|
||||||
@@ -498,28 +483,28 @@ extension EPTabBarController {
|
|||||||
} failure: { [weak self] code, msg in
|
} failure: { [weak self] code, msg in
|
||||||
NSLog("[EPTabBarController] ❌ Ticket 请求失败 (\(code)): \(msg)")
|
NSLog("[EPTabBarController] ❌ Ticket 请求失败 (\(code)): \(msg)")
|
||||||
|
|
||||||
// ⚠️ Ticket 失败,强制退出登录(与 OC MainPresenter 保持一致)
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self?.handleTokenInvalid()
|
self?.handleTokenInvalid()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理 Token 失效:清空数据并跳转到登录页
|
|
||||||
private func handleTokenInvalid() {
|
private func handleTokenInvalid() {
|
||||||
NSLog("[EPTabBarController] ⚠️ Token 失效,清空账号数据...")
|
NSLog("[EPTabBarController] ⚠️ Token 失效,清空账号数据...")
|
||||||
|
|
||||||
// 1. 清空账号信息
|
|
||||||
AccountInfoStorage.instance().saveAccountInfo(nil)
|
AccountInfoStorage.instance().saveAccountInfo(nil)
|
||||||
AccountInfoStorage.instance().saveTicket("")
|
AccountInfoStorage.instance().saveTicket("")
|
||||||
|
|
||||||
// 2. 跳转到登录页
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
let loginVC = EPLoginViewController()
|
let loginVC = EPLoginViewController()
|
||||||
let nav = BaseNavigationController(rootViewController: loginVC)
|
let nav = BaseNavigationController(rootViewController: loginVC)
|
||||||
nav.modalPresentationStyle = .fullScreen
|
nav.modalPresentationStyle = .fullScreen
|
||||||
|
|
||||||
// 获取 keyWindow(iOS 13+ 兼容)
|
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
for scene in UIApplication.shared.connectedScenes {
|
for scene in UIApplication.shared.connectedScenes {
|
||||||
if let windowScene = scene as? UIWindowScene,
|
if let windowScene = scene as? UIWindowScene,
|
||||||
@@ -546,12 +531,12 @@ extension EPTabBarController {
|
|||||||
|
|
||||||
extension EPTabBarController {
|
extension EPTabBarController {
|
||||||
|
|
||||||
/// OC 兼容:创建实例的工厂方法
|
|
||||||
@objc static func create() -> EPTabBarController {
|
@objc static func create() -> EPTabBarController {
|
||||||
return EPTabBarController()
|
return EPTabBarController()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OC 兼容:刷新 TabBar 方法
|
|
||||||
@objc func refreshTabBarWithIsLogin(_ isLogin: Bool) {
|
@objc func refreshTabBarWithIsLogin(_ isLogin: Bool) {
|
||||||
refreshTabBar(isLogin: isLogin)
|
refreshTabBar(isLogin: isLogin)
|
||||||
}
|
}
|
||||||
|
29
YuMi/E-P/SDKManager/NIMSDK/EPNIMConfig.h
Normal file
29
YuMi/E-P/SDKManager/NIMSDK/EPNIMConfig.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// EPNIMConfig.h
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// NIMSDK 配置模型(从 ClientConfig 派生)
|
||||||
|
@interface EPNIMConfig : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *appKey;
|
||||||
|
@property (nonatomic, copy) NSString *apnsCername;
|
||||||
|
@property (nonatomic, assign) BOOL shouldConsiderRevokedMessageUnreadCount;
|
||||||
|
@property (nonatomic, assign) BOOL shouldSyncStickTopSessionInfos;
|
||||||
|
@property (nonatomic, assign) BOOL enabledHttpsForInfo;
|
||||||
|
@property (nonatomic, assign) BOOL enabledHttpsForMessage;
|
||||||
|
@property (nonatomic, assign) NSInteger cdnTrackInterval;
|
||||||
|
@property (nonatomic, assign) NSInteger chatroomMessageReceiveMinInterval;
|
||||||
|
|
||||||
|
/// 从 ClientConfig 创建配置;若缺失 nimKey 则返回 nil
|
||||||
|
+ (instancetype _Nullable)configFromClientConfig;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
|
39
YuMi/E-P/SDKManager/NIMSDK/EPNIMConfig.m
Normal file
39
YuMi/E-P/SDKManager/NIMSDK/EPNIMConfig.m
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// EPNIMConfig.m
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "EPNIMConfig.h"
|
||||||
|
#import "ClientConfig.h"
|
||||||
|
#import "YUMIConstant.h"
|
||||||
|
|
||||||
|
@implementation EPNIMConfig
|
||||||
|
|
||||||
|
+ (instancetype _Nullable)configFromClientConfig {
|
||||||
|
ClientConfig *client = [ClientConfig shareConfig];
|
||||||
|
if (client.configInfo == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
NSString *nimKey = client.configInfo.nimKey;
|
||||||
|
if (nimKey.length == 0) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
EPNIMConfig *cfg = [[EPNIMConfig alloc] init];
|
||||||
|
cfg.appKey = nimKey;
|
||||||
|
#ifdef DEBUG
|
||||||
|
cfg.apnsCername = @"pikoDevelopPush";
|
||||||
|
#else
|
||||||
|
cfg.apnsCername = @"newPiko";
|
||||||
|
#endif
|
||||||
|
cfg.shouldConsiderRevokedMessageUnreadCount = YES;
|
||||||
|
cfg.shouldSyncStickTopSessionInfos = YES;
|
||||||
|
cfg.enabledHttpsForInfo = YES;
|
||||||
|
cfg.enabledHttpsForMessage = YES;
|
||||||
|
cfg.cdnTrackInterval = 0;
|
||||||
|
cfg.chatroomMessageReceiveMinInterval = 50;
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
26
YuMi/E-P/SDKManager/NIMSDK/EPNIMManager.h
Normal file
26
YuMi/E-P/SDKManager/NIMSDK/EPNIMManager.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// EPNIMManager.h
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface EPNIMManager : NSObject
|
||||||
|
|
||||||
|
+ (instancetype)sharedManager;
|
||||||
|
|
||||||
|
- (void)initializeWithCompletion:(void(^ _Nullable)(NSError * _Nullable error))completion;
|
||||||
|
|
||||||
|
- (void)updateApnsToken:(NSData *)deviceToken;
|
||||||
|
|
||||||
|
- (NSInteger)allUnreadCount;
|
||||||
|
|
||||||
|
- (BOOL)isInitialized;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
|
61
YuMi/E-P/SDKManager/NIMSDK/EPNIMManager.m
Normal file
61
YuMi/E-P/SDKManager/NIMSDK/EPNIMManager.m
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// EPNIMManager.m
|
||||||
|
// YuMi
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "EPNIMManager.h"
|
||||||
|
#import "EPNIMConfig.h"
|
||||||
|
#import <NIMSDK/NIMSDK.h>
|
||||||
|
#import "CustomAttachmentDecoder.h"
|
||||||
|
|
||||||
|
@interface EPNIMManager ()
|
||||||
|
@property (nonatomic, assign) BOOL initialized;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation EPNIMManager
|
||||||
|
|
||||||
|
+ (instancetype)sharedManager {
|
||||||
|
static EPNIMManager *s;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{ s = [EPNIMManager new]; });
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initializeWithCompletion:(void(^ _Nullable)(NSError * _Nullable error))completion {
|
||||||
|
if (self.initialized) {
|
||||||
|
if (completion) completion(nil);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EPNIMConfig *cfg = [EPNIMConfig configFromClientConfig];
|
||||||
|
if (!cfg) {
|
||||||
|
if (completion) {
|
||||||
|
completion([NSError errorWithDomain:@"EPNIM" code:-1001 userInfo:@{NSLocalizedDescriptionKey:@"ClientConfig not ready or nimKey missing"}]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NIMSDKOption *option = [NIMSDKOption optionWithAppKey:cfg.appKey];
|
||||||
|
option.apnsCername = cfg.apnsCername;
|
||||||
|
[[NIMSDK sharedSDK] registerWithOption:option];
|
||||||
|
[NIMCustomObject registerCustomDecoder:[[CustomAttachmentDecoder alloc] init]];
|
||||||
|
[NIMSDKConfig sharedConfig].shouldConsiderRevokedMessageUnreadCount = cfg.shouldConsiderRevokedMessageUnreadCount;
|
||||||
|
[[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:cfg.shouldSyncStickTopSessionInfos];
|
||||||
|
[NIMSDKConfig sharedConfig].enabledHttpsForInfo = cfg.enabledHttpsForInfo;
|
||||||
|
[NIMSDKConfig sharedConfig].enabledHttpsForMessage = cfg.enabledHttpsForMessage;
|
||||||
|
[NIMSDKConfig sharedConfig].cdnTrackInterval = cfg.cdnTrackInterval;
|
||||||
|
[NIMSDKConfig sharedConfig].chatroomMessageReceiveMinInterval = cfg.chatroomMessageReceiveMinInterval;
|
||||||
|
self.initialized = YES;
|
||||||
|
if (completion) completion(nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateApnsToken:(NSData *)deviceToken {
|
||||||
|
if (!deviceToken) return;
|
||||||
|
[[NIMSDK sharedSDK] updateApnsToken:deviceToken];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)allUnreadCount { return [NIMSDK sharedSDK].conversationManager.allUnreadCount; }
|
||||||
|
|
||||||
|
- (BOOL)isInitialized { return self.initialized; }
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
@@ -1,71 +0,0 @@
|
|||||||
//
|
|
||||||
// GlobalEventManager.h
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-09.
|
|
||||||
// Copyright © 2025 YuMi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
/// 全局事件管理器
|
|
||||||
/// 负责处理原 TabBar 中的全局逻辑(SDK 代理、房间最小化、通知等)
|
|
||||||
@interface GlobalEventManager : NSObject
|
|
||||||
|
|
||||||
/// 单例
|
|
||||||
+ (instancetype)shared;
|
|
||||||
|
|
||||||
// MARK: - SDK Delegates Setup
|
|
||||||
|
|
||||||
/// 设置所有第三方 SDK 的代理
|
|
||||||
- (void)setupSDKDelegates;
|
|
||||||
|
|
||||||
/// 移除所有代理(dealloc 时调用)
|
|
||||||
- (void)removeAllDelegates;
|
|
||||||
|
|
||||||
// MARK: - Room Mini View
|
|
||||||
|
|
||||||
/// 设置房间最小化视图
|
|
||||||
/// @param containerView 父视图(通常是 TabBar 的 view)
|
|
||||||
- (void)setupRoomMiniViewOn:(UIView *)containerView;
|
|
||||||
|
|
||||||
/// 处理房间最小化通知
|
|
||||||
/// @param userInfo 通知携带的数据
|
|
||||||
- (void)handleRoomMini:(NSDictionary * _Nullable)userInfo;
|
|
||||||
|
|
||||||
/// 隐藏房间最小化视图
|
|
||||||
- (void)hideRoomMiniView;
|
|
||||||
|
|
||||||
// MARK: - Global Notifications
|
|
||||||
|
|
||||||
/// 处理配置重载通知
|
|
||||||
- (void)handleConfigReload;
|
|
||||||
|
|
||||||
/// 处理新用户充值通知
|
|
||||||
- (void)handleNewUserRecharge;
|
|
||||||
|
|
||||||
/// 处理主播卡片通知
|
|
||||||
/// @param notification 通知对象
|
|
||||||
- (void)handleAnchorCard:(NSNotification * _Nullable)notification;
|
|
||||||
|
|
||||||
/// 处理语言切换通知
|
|
||||||
/// @param notification 通知对象
|
|
||||||
- (void)handleLanguageSwitch:(NSNotification * _Nullable)notification;
|
|
||||||
|
|
||||||
// MARK: - User Info
|
|
||||||
|
|
||||||
/// 获取用户信息成功后的处理
|
|
||||||
/// @param userInfo 用户信息模型
|
|
||||||
- (void)handleUserInfoSuccess:(id)userInfo;
|
|
||||||
|
|
||||||
// MARK: - Social Share
|
|
||||||
|
|
||||||
/// 注册社交分享回调
|
|
||||||
- (void)registerSocialShareCallback;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
@@ -1,242 +0,0 @@
|
|||||||
//
|
|
||||||
// GlobalEventManager.m
|
|
||||||
// YuMi
|
|
||||||
//
|
|
||||||
// Created by AI on 2025-10-09.
|
|
||||||
// Copyright © 2025 YuMi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "GlobalEventManager.h"
|
|
||||||
#import "XPMiniRoomView.h"
|
|
||||||
#import "RoomBoomManager.h"
|
|
||||||
#import "PublicRoomManager.h"
|
|
||||||
#import "XPSkillCardPlayerManager.h"
|
|
||||||
#import "SocialShareManager.h"
|
|
||||||
#import "YUMIConstant.h"
|
|
||||||
#import <NIMSDK/NIMSDK.h>
|
|
||||||
|
|
||||||
@interface GlobalEventManager () <NIMLoginManagerDelegate, NIMChatManagerDelegate, NIMSystemNotificationManagerDelegate, NIMBroadcastManagerDelegate>
|
|
||||||
|
|
||||||
// MARK: - Private Properties
|
|
||||||
|
|
||||||
/// 房间最小化视图
|
|
||||||
@property (nonatomic, strong) XPMiniRoomView *miniRoomView;
|
|
||||||
|
|
||||||
/// 配置重载回调
|
|
||||||
@property (nonatomic, copy) void(^configReloadCallback)(void);
|
|
||||||
|
|
||||||
/// 新用户充值回调
|
|
||||||
@property (nonatomic, copy) void(^newUserRechargeCallback)(void);
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation GlobalEventManager
|
|
||||||
|
|
||||||
// MARK: - Lifecycle
|
|
||||||
|
|
||||||
+ (instancetype)shared {
|
|
||||||
static GlobalEventManager *instance = nil;
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
instance = [[GlobalEventManager alloc] init];
|
|
||||||
});
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)init {
|
|
||||||
if (self = [super init]) {
|
|
||||||
[self setupNotificationObservers];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
[self removeAllDelegates];
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - SDK Delegates Setup
|
|
||||||
|
|
||||||
- (void)setupSDKDelegates {
|
|
||||||
// NIMSDK 代理设置
|
|
||||||
[[NIMSDK sharedSDK].loginManager addDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].chatManager addDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].systemNotificationManager addDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].broadcastManager addDelegate:self];
|
|
||||||
|
|
||||||
// RoomBoomManager 回调注册
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
[[RoomBoomManager sharedManager] registerBoomBanner:^(id sth) {
|
|
||||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
||||||
if (!strongSelf) return;
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
// 检查用户是否在房间中
|
|
||||||
if ([XPSkillCardPlayerManager shareInstance].isInRoom) {
|
|
||||||
NSLog(@"[GlobalEventManager] 收到 RoomBoom 通知");
|
|
||||||
// TODO: 显示 Boom Banner
|
|
||||||
// [RoomBoomBannerAnimation display:window with:sth tapToRoom:YES complete:^{}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} target:self];
|
|
||||||
|
|
||||||
NSLog(@"[GlobalEventManager] SDK 代理设置完成");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeAllDelegates {
|
|
||||||
[[NIMSDK sharedSDK].loginManager removeDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].chatManager removeDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].systemNotificationManager removeDelegate:self];
|
|
||||||
[[NIMSDK sharedSDK].broadcastManager removeDelegate:self];
|
|
||||||
[[RoomBoomManager sharedManager] removeEventListenerForTarget:self];
|
|
||||||
|
|
||||||
NSLog(@"[GlobalEventManager] 所有代理已移除");
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Room Mini View
|
|
||||||
|
|
||||||
- (void)setupRoomMiniViewOn:(UIView *)containerView {
|
|
||||||
if (!self.miniRoomView) {
|
|
||||||
self.miniRoomView = [[XPMiniRoomView alloc] init];
|
|
||||||
}
|
|
||||||
[containerView addSubview:self.miniRoomView];
|
|
||||||
NSLog(@"[GlobalEventManager] 房间最小化视图已添加");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleRoomMini:(NSDictionary *)userInfo {
|
|
||||||
if (self.miniRoomView) {
|
|
||||||
// TODO: 处理房间最小化逻辑
|
|
||||||
NSLog(@"[GlobalEventManager] 处理房间最小化: %@", userInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)hideRoomMiniView {
|
|
||||||
if (self.miniRoomView) {
|
|
||||||
[self.miniRoomView hiddenRoomMiniView];
|
|
||||||
NSLog(@"[GlobalEventManager] 房间最小化视图已隐藏");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Notification Observers
|
|
||||||
|
|
||||||
- (void)setupNotificationObservers {
|
|
||||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
||||||
|
|
||||||
// 房间最小化通知
|
|
||||||
[center addObserver:self
|
|
||||||
selector:@selector(onRoomMiniNotification:)
|
|
||||||
name:kRoomMiniNotificationKey
|
|
||||||
object:nil];
|
|
||||||
|
|
||||||
// 配置重载通知
|
|
||||||
[center addObserver:self
|
|
||||||
selector:@selector(onConfigReloadNotification:)
|
|
||||||
name:@"reloadAfterLoadConfig"
|
|
||||||
object:nil];
|
|
||||||
|
|
||||||
// 语言切换通知
|
|
||||||
[center addObserver:self
|
|
||||||
selector:@selector(onLanguageSwitchNotification:)
|
|
||||||
name:@"kSwitchLanguage"
|
|
||||||
object:nil];
|
|
||||||
|
|
||||||
NSLog(@"[GlobalEventManager] 通知监听已设置");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onRoomMiniNotification:(NSNotification *)notification {
|
|
||||||
[self handleRoomMini:notification.userInfo];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onConfigReloadNotification:(NSNotification *)notification {
|
|
||||||
[self handleConfigReload];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onLanguageSwitchNotification:(NSNotification *)notification {
|
|
||||||
[self handleLanguageSwitch:notification];
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Global Notifications Handler
|
|
||||||
|
|
||||||
- (void)handleConfigReload {
|
|
||||||
NSLog(@"[GlobalEventManager] 配置重载");
|
|
||||||
if (self.configReloadCallback) {
|
|
||||||
self.configReloadCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleNewUserRecharge {
|
|
||||||
NSLog(@"[GlobalEventManager] 新用户充值");
|
|
||||||
if (self.newUserRechargeCallback) {
|
|
||||||
self.newUserRechargeCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleAnchorCard:(NSNotification *)notification {
|
|
||||||
NSLog(@"[GlobalEventManager] 主播卡片通知: %@", notification.userInfo);
|
|
||||||
// TODO: 实现主播卡片逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleLanguageSwitch:(NSNotification *)notification {
|
|
||||||
NSLog(@"[GlobalEventManager] 语言切换: %@", notification.userInfo);
|
|
||||||
// TODO: 实现语言切换逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - User Info
|
|
||||||
|
|
||||||
- (void)handleUserInfoSuccess:(id)userInfo {
|
|
||||||
NSLog(@"[GlobalEventManager] 用户信息获取成功");
|
|
||||||
|
|
||||||
// 更新各个 Manager 的用户信息
|
|
||||||
if ([userInfo respondsToSelector:@selector(uid)]) {
|
|
||||||
[[PublicRoomManager sharedManager] initialize];
|
|
||||||
[[PublicRoomManager sharedManager] updateUserInfo:userInfo];
|
|
||||||
[[RoomBoomManager sharedManager] saveUserInfo:userInfo];
|
|
||||||
[[XPSkillCardPlayerManager shareInstance] setUserInfoModel:userInfo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Social Share
|
|
||||||
|
|
||||||
- (void)registerSocialShareCallback {
|
|
||||||
// 延迟 2 秒检查社交分享
|
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
||||||
[[SocialShareManager sharedManager] checkSocialShareItem];
|
|
||||||
NSLog(@"[GlobalEventManager] 社交分享回调已注册");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - NIMSDK Delegate Methods
|
|
||||||
|
|
||||||
#pragma mark - NIMLoginManagerDelegate
|
|
||||||
|
|
||||||
- (void)onLogin:(NIMLoginStep)step {
|
|
||||||
NSLog(@"[GlobalEventManager] NIMSDK 登录步骤: %ld", (long)step);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onKickout:(NIMKickReason)code clientType:(NIMLoginClientType)clientType {
|
|
||||||
NSLog(@"[GlobalEventManager] NIMSDK 被踢出: reason=%ld, clientType=%ld", (long)code, (long)clientType);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)onAutoLoginFailed:(NSError *)error {
|
|
||||||
NSLog(@"[GlobalEventManager] NIMSDK 自动登录失败: %@", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - NIMChatManagerDelegate
|
|
||||||
|
|
||||||
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
|
|
||||||
NSLog(@"[GlobalEventManager] 收到 %lu 条消息", (unsigned long)messages.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - NIMSystemNotificationManagerDelegate
|
|
||||||
|
|
||||||
- (void)onReceiveSystemNotification:(NIMSystemNotification *)notification {
|
|
||||||
NSLog(@"[GlobalEventManager] 收到系统通知: %@", notification.notificationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - NIMBroadcastManagerDelegate
|
|
||||||
|
|
||||||
- (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)message {
|
|
||||||
NSLog(@"[GlobalEventManager] 收到广播消息: %@", message.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
///一些宏
|
///一些宏
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
#import "../Tools/Bundle/NSBundle+Localizable.h"
|
#import "../Tools/Bundle/NSBundle+Localizable.h"
|
||||||
|
|
||||||
#ifndef YUMIMacroUitls_h
|
#ifndef YUMIMacroUitls_h
|
||||||
@@ -49,26 +50,35 @@ isPhoneXSeries = [[UIApplication sharedApplication] delegate].window.safeAreaIns
|
|||||||
#define kWeakify(o) try{}@finally{} __weak typeof(o) o##Weak = o;
|
#define kWeakify(o) try{}@finally{} __weak typeof(o) o##Weak = o;
|
||||||
#define kStrongify(o) autoreleasepool{} __strong typeof(o) o = o##Weak;
|
#define kStrongify(o) autoreleasepool{} __strong typeof(o) o = o##Weak;
|
||||||
|
|
||||||
// 兼容 iOS 13+ 的 keyWindow 获取
|
/// 兼容 iOS 13+ 的 keyWindow 获取(Swift & ObjC 通用)
|
||||||
#define kWindow ({\
|
/// 使用此函数统一获取 keyWindow,避免在各处重复实现
|
||||||
UIWindow *window = nil;\
|
/// 自动处理 iOS 13+ 的 UIWindowScene 和旧版本的兼容性
|
||||||
if (@available(iOS 13.0, *)) {\
|
static inline __attribute__((unused)) UIWindow * _Nullable kGetKeyWindow(void) {
|
||||||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {\
|
UIWindow *window = nil;
|
||||||
if (scene.activationState == UISceneActivationStateForegroundActive) {\
|
if (@available(iOS 13.0, *)) {
|
||||||
for (UIWindow *w in scene.windows) {\
|
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
||||||
if (w.isKeyWindow) {\
|
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
||||||
window = w;\
|
for (UIWindow *w in scene.windows) {
|
||||||
break;\
|
if (w.isKeyWindow) {
|
||||||
}\
|
return w;
|
||||||
}\
|
}
|
||||||
if (window) break;\
|
}
|
||||||
}\
|
if (scene.windows.firstObject) {
|
||||||
}\
|
return scene.windows.firstObject;
|
||||||
} else {\
|
}
|
||||||
window = [UIApplication sharedApplication].keyWindow;\
|
}
|
||||||
}\
|
}
|
||||||
window;\
|
} else {
|
||||||
})
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
window = [UIApplication sharedApplication].keyWindow;
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容旧代码:保留宏入口
|
||||||
|
#define kWindow kGetKeyWindow()
|
||||||
|
|
||||||
#define kImage(image) [UIImage imageNamed:image]
|
#define kImage(image) [UIImage imageNamed:image]
|
||||||
|
|
||||||
|
@@ -94,7 +94,7 @@
|
|||||||
|
|
||||||
// 设置为根控制器(不需要 NavigationController 包装)
|
// 设置为根控制器(不需要 NavigationController 包装)
|
||||||
|
|
||||||
[self getKeyWindow].rootViewController = newTabBar;
|
kWindow.rootViewController = newTabBar;
|
||||||
|
|
||||||
// 登录成功并进入主页后,启动首充监控
|
// 登录成功并进入主页后,启动首充监控
|
||||||
[[FirstRechargeManager sharedManager] startMonitoring];
|
[[FirstRechargeManager sharedManager] startMonitoring];
|
||||||
@@ -120,30 +120,4 @@
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Helper Methods
|
|
||||||
|
|
||||||
/// 获取 keyWindow(iOS 13+ 兼容)
|
|
||||||
+ (UIWindow *)getKeyWindow {
|
|
||||||
// iOS 13+ 使用 connectedScenes 获取 window
|
|
||||||
if (@available(iOS 13.0, *)) {
|
|
||||||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
|
||||||
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
|
||||||
for (UIWindow *window in scene.windows) {
|
|
||||||
if (window.isKeyWindow) {
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 如果没有 keyWindow,返回第一个 window
|
|
||||||
return scene.windows.firstObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
return [UIApplication sharedApplication].keyWindow;
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@@ -7,9 +7,6 @@
|
|||||||
|
|
||||||
#import "BaseMvpPresenter.h"
|
#import "BaseMvpPresenter.h"
|
||||||
#import "YUMINNNN.h"
|
#import "YUMINNNN.h"
|
||||||
#import <GoogleSignIn/GoogleSignIn.h>
|
|
||||||
#import <GoogleSignIn/GIDGoogleUser.h>
|
|
||||||
#import <GoogleSignIn/GoogleSignIn-umbrella.h>
|
|
||||||
|
|
||||||
@class FeedBackConfigModel;
|
@class FeedBackConfigModel;
|
||||||
|
|
||||||
@@ -19,18 +16,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
- (void)phoneQuickLogin:(NSString *)accessToken token:(NSString*) token;
|
- (void)phoneQuickLogin:(NSString *)accessToken token:(NSString*) token;
|
||||||
|
|
||||||
|
|
||||||
/// 第三方登录
|
|
||||||
/// @param type 登录的类型
|
|
||||||
- (void)thirdLoginWithType:(ThirdLoginType)type;
|
|
||||||
|
|
||||||
///第三方登录,谷歌登录
|
|
||||||
-(void)thirdLoginByGoogleWithPresentingViewController:(UIViewController *)presentingViewController configuration:(GIDConfiguration *)configuration;
|
|
||||||
///第三方登录,fb登录
|
|
||||||
-(void)thirdLoginByFBWithPresentingViewController:(UIViewController *)presentingViewController;
|
|
||||||
///第三方登录,line登录
|
|
||||||
-(void)thirdLoginByLine:(UIViewController *)presentingViewController;
|
|
||||||
|
|
||||||
/// 获取手机的验证码
|
/// 获取手机的验证码
|
||||||
/// @param phone 手机号
|
/// @param phone 手机号
|
||||||
/// @param type 类型
|
/// @param type 类型
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
#import "LoginPresenter.h"
|
#import "LoginPresenter.h"
|
||||||
///Third
|
///Third
|
||||||
#import <ReactiveObjC/ReactiveObjC.h>
|
#import <ReactiveObjC/ReactiveObjC.h>
|
||||||
#import <ShareSDK/ShareSDK.h>
|
|
||||||
///APi
|
///APi
|
||||||
#import "Api+Login.h"
|
#import "Api+Login.h"
|
||||||
///Tool
|
///Tool
|
||||||
@@ -56,75 +55,7 @@ static NSString *clinet_s = @"uyzjdhds";
|
|||||||
/// 第三方登录
|
/// 第三方登录
|
||||||
/// @param type 登录的类型
|
/// @param type 登录的类型
|
||||||
- (void)thirdLoginWithType:(ThirdLoginType)type{
|
- (void)thirdLoginWithType:(ThirdLoginType)type{
|
||||||
|
// TODO: 后续补充 Apple Login
|
||||||
SSDKPlatformType platformType;
|
|
||||||
switch (type) {
|
|
||||||
case ThirdLoginType_FB:
|
|
||||||
platformType = SSDKPlatformTypeFacebook;
|
|
||||||
break;
|
|
||||||
case ThirdLoginType_Line:
|
|
||||||
platformType = SSDKPlatformTypeLine;
|
|
||||||
break;
|
|
||||||
case ThirdLoginType_Apple:
|
|
||||||
platformType = SSDKPlatformTypeAppleAccount;
|
|
||||||
break;
|
|
||||||
case ThirdLoginType_Gmail:
|
|
||||||
platformType = SSDKPlatformTypeGooglePlus;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
platformType = SSDKPlatformTypeAppleAccount;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
NSDictionary * settings;
|
|
||||||
if (type == SSDKPlatformTypeFacebook) {
|
|
||||||
settings = @{@"isBrowser":@(YES)};
|
|
||||||
}
|
|
||||||
@kWeakify(self);
|
|
||||||
[ShareSDK cancelAuthorize:platformType result:nil];
|
|
||||||
[ShareSDK authorize:platformType
|
|
||||||
settings:settings
|
|
||||||
onStateChanged:^(SSDKResponseState state, SSDKUser *user, NSError *error) {
|
|
||||||
@kStrongify(self);
|
|
||||||
if (state == SSDKResponseStateSuccess) {///成功
|
|
||||||
ThirdUserInfo * userInfo = [[ThirdUserInfo alloc] init];
|
|
||||||
NSString * openid = @"";
|
|
||||||
NSString * access_token = user.credential.token.length > 0 ? user.credential.token : @"";
|
|
||||||
NSString * unionid = @"";
|
|
||||||
if (platformType == SSDKPlatformTypeLine) {
|
|
||||||
openid = user.credential.uid.length > 0 ? user.credential.uid : user.uid;
|
|
||||||
unionid = user.credential.uid.length > 0 ? user.credential.uid : user.uid;
|
|
||||||
userInfo.userName = user.nickname;
|
|
||||||
userInfo.avatarUrl = user.icon;
|
|
||||||
} else if (platformType == SSDKPlatformTypeFacebook) { //微信登录
|
|
||||||
openid = user.credential.uid.length > 0 ? user.credential.uid : user.uid;;
|
|
||||||
unionid = user.credential.uid.length > 0 ? user.credential.uid : user.uid;;
|
|
||||||
userInfo.userName = user.nickname;
|
|
||||||
userInfo.avatarUrl = user.icon;
|
|
||||||
} else if (platformType == SSDKPlatformTypeAppleAccount) { //苹果登录
|
|
||||||
// openid = user.credential.token;
|
|
||||||
unionid = [user.credential rawData][@"user"];
|
|
||||||
NSString * familyName = [user.credential rawData][@"fullName"][@"familyName"];
|
|
||||||
NSString * givenName = [user.credential rawData][@"fullName"][@"givenName"];
|
|
||||||
if (familyName.length > 0 && givenName.length> 0) {
|
|
||||||
userInfo.userName = [NSString stringWithFormat:@"%@%@", familyName, givenName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unionid == nil) {
|
|
||||||
unionid = @"";
|
|
||||||
}
|
|
||||||
openid = unionid;
|
|
||||||
userInfo.openid = openid;
|
|
||||||
userInfo.access_token = access_token;
|
|
||||||
userInfo.unionid = unionid;
|
|
||||||
///保存一下第三方的值
|
|
||||||
[AccountInfoStorage instance].thirdUserInfo = userInfo;
|
|
||||||
[self loginWithThirdPartWithType:type];
|
|
||||||
} else if(state == SSDKResponseStateCancel) {///取消
|
|
||||||
[[self getView] showErrorToast:YMLocalizedString(@"LoginPresenter0")];
|
|
||||||
} else if (state == SSDKResponseStateFail) {///失败
|
|
||||||
[[self getView] showErrorToast:YMLocalizedString(@"LoginPresenter1")];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
-(void)loginWithThirdPartWithType:(ThirdLoginType)type{
|
-(void)loginWithThirdPartWithType:(ThirdLoginType)type{
|
||||||
[XNDJTDDLoadingTool showOnlyView:kWindow];
|
[XNDJTDDLoadingTool showOnlyView:kWindow];
|
||||||
@@ -154,68 +85,6 @@ static NSString *clinet_s = @"uyzjdhds";
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-(void)thirdLoginByLine:(UIViewController *)presentingViewController {
|
|
||||||
|
|
||||||
}
|
|
||||||
-(void)thirdLoginByFBWithPresentingViewController:(UIViewController *)presentingViewController {
|
|
||||||
|
|
||||||
}
|
|
||||||
-(void)thirdLoginByGoogleWithPresentingViewController:(UIViewController *)presentingViewController configuration:(GIDConfiguration *)configuration{
|
|
||||||
@kWeakify(self);
|
|
||||||
[GIDSignIn sharedInstance].configuration = configuration;
|
|
||||||
[GIDSignIn.sharedInstance signInWithPresentingViewController:presentingViewController
|
|
||||||
completion:^(GIDSignInResult * _Nullable signInResult, NSError * _Nullable error) {
|
|
||||||
@kStrongify(self);
|
|
||||||
if (error) {
|
|
||||||
if (error.code == kGIDSignInErrorCodeCanceled){
|
|
||||||
[[self getView] showErrorToast:YMLocalizedString(@"LoginPresenter0")];
|
|
||||||
}else{
|
|
||||||
[[self getView] showErrorToast:YMLocalizedString(@"LoginPresenter1")];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ThirdUserInfo * userInfo = [[ThirdUserInfo alloc] init];
|
|
||||||
NSString * openid = signInResult.user.userID;
|
|
||||||
NSString * access_token = signInResult.user.idToken.tokenString.length > 0 ? signInResult.user.idToken.tokenString : @"";
|
|
||||||
NSString * unionid = signInResult.user.userID;
|
|
||||||
userInfo.userName = signInResult.user.profile.name;
|
|
||||||
userInfo.avatarUrl = [[signInResult.user.profile imageURLWithDimension:60] absoluteString];
|
|
||||||
userInfo.openid = openid;
|
|
||||||
userInfo.access_token = access_token;
|
|
||||||
userInfo.unionid = unionid;
|
|
||||||
///保存一下第三方的值
|
|
||||||
[AccountInfoStorage instance].thirdUserInfo = userInfo;
|
|
||||||
[self loginWithThirdGoogle];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)loginWithThirdGoogle{
|
|
||||||
[XNDJTDDLoadingTool showOnlyView:kWindow];
|
|
||||||
NSString * openid = [AccountInfoStorage instance].thirdUserInfo.openid;
|
|
||||||
NSString * access_token = [AccountInfoStorage instance].thirdUserInfo.access_token;
|
|
||||||
NSString * unionid = [AccountInfoStorage instance].thirdUserInfo.unionid;
|
|
||||||
@kWeakify(self);
|
|
||||||
[Api loginWithThirdPart:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
|
|
||||||
@kStrongify(self);
|
|
||||||
[XNDJTDDLoadingTool hideOnlyView:kWindow];
|
|
||||||
AccountModel * model = [AccountModel modelWithDictionary:data.data];
|
|
||||||
if (model != nil) {
|
|
||||||
[[AccountInfoStorage instance] saveAccountInfo:model];
|
|
||||||
[[self getView] loginThirdPartSuccess];
|
|
||||||
}
|
|
||||||
}fail:^(NSInteger code, NSString * _Nullable msg) {
|
|
||||||
@kStrongify(self);
|
|
||||||
[XNDJTDDLoadingTool hideOnlyView:kWindow];
|
|
||||||
if (msg.length == 0) {
|
|
||||||
[[self getView] showErrorToast:YMLocalizedString(@"LoginPresenter1")];
|
|
||||||
}
|
|
||||||
} showLoading:YES errorToast:YES]
|
|
||||||
openid:openid
|
|
||||||
unionid:unionid
|
|
||||||
access_token:access_token
|
|
||||||
type:[NSString stringWithFormat:@"%lu", (unsigned long)ThirdLoginType_Gmail]];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 获取手机的验证码
|
/// 获取手机的验证码
|
||||||
/// @param phone 手机号
|
/// @param phone 手机号
|
||||||
/// @param type 类型
|
/// @param type 类型
|
||||||
|
@@ -96,11 +96,6 @@
|
|||||||
[self initSubViewConstraints];
|
[self initSubViewConstraints];
|
||||||
[self initEvents];
|
[self initEvents];
|
||||||
[self loadAllRegions];
|
[self loadAllRegions];
|
||||||
ClientConfig *config = [ClientConfig shareConfig];
|
|
||||||
if (config.inviteCode.length > 0){
|
|
||||||
self.inviteCode = config.inviteCode;
|
|
||||||
config.inviteCode = @"";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 防止進入後還有 loading
|
// 防止進入後還有 loading
|
||||||
[XNDJTDDLoadingTool hideHUD];
|
[XNDJTDDLoadingTool hideHUD];
|
||||||
|
@@ -20,9 +20,7 @@ NSString * const HadAgreePrivacy = @"HadAgreePrivacy";
|
|||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, LoginType) {
|
typedef NS_ENUM(NSUInteger, LoginType) {
|
||||||
LoginType_ID = 101,
|
LoginType_ID = 101,
|
||||||
LoginType_Email = 102,
|
LoginType_Email = 102
|
||||||
LoginType_Google = 103,
|
|
||||||
LoginType_Apple = 104
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface LoginViewController () <LoginProtocol>
|
@interface LoginViewController () <LoginProtocol>
|
||||||
@@ -33,9 +31,6 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
|||||||
@property(nonatomic, strong) YYLabel *policyLabel;
|
@property(nonatomic, strong) YYLabel *policyLabel;
|
||||||
@property(nonatomic, strong) UIView *policyTips;
|
@property(nonatomic, strong) UIView *policyTips;
|
||||||
|
|
||||||
///谷歌登录配置
|
|
||||||
@property (nonatomic,strong) GIDConfiguration *configuration;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation LoginViewController
|
@implementation LoginViewController
|
||||||
@@ -163,8 +158,6 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
|||||||
UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
|
UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
|
||||||
idBUtton,
|
idBUtton,
|
||||||
[self entrcyButton:LoginType_Email tapSelector:@selector(didTapEntrcyButton:)],
|
[self entrcyButton:LoginType_Email tapSelector:@selector(didTapEntrcyButton:)],
|
||||||
[self entrcyButton:LoginType_Google tapSelector:@selector(didTapEntrcyButton:)],
|
|
||||||
[self entrcyButton:LoginType_Apple tapSelector:@selector(didTapEntrcyButton:)],
|
|
||||||
]];
|
]];
|
||||||
stackView.axis = UILayoutConstraintAxisVertical;
|
stackView.axis = UILayoutConstraintAxisVertical;
|
||||||
stackView.distribution = UIStackViewDistributionFillEqually;
|
stackView.distribution = UIStackViewDistributionFillEqually;
|
||||||
@@ -204,16 +197,6 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
|||||||
[icon setImage:kImage(@"login_page_mail")];
|
[icon setImage:kImage(@"login_page_mail")];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LoginType_Google:{
|
|
||||||
[button setTitle:YMLocalizedString(@"XPLoginViewController13") forState:UIControlStateNormal];
|
|
||||||
[icon setImage:kImage(@"login_gmail")];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LoginType_Apple:{
|
|
||||||
[button setTitle:YMLocalizedString(@"XPLoginViewController12") forState:UIControlStateNormal];
|
|
||||||
[icon setImage:kImage(@"mine_noble_center_apple")];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -258,29 +241,20 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoginTypesViewController *vc = [[LoginTypesViewController alloc] init];
|
||||||
|
|
||||||
switch (sender.tag) {
|
switch (sender.tag) {
|
||||||
case LoginType_ID:{
|
case LoginType_ID:
|
||||||
LoginTypesViewController *vc = [[LoginTypesViewController alloc] init];
|
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
|
||||||
[vc updateLoginType:LoginDisplayType_id];
|
[vc updateLoginType:LoginDisplayType_id];
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case LoginType_Email: {
|
case LoginType_Email:
|
||||||
LoginTypesViewController *vc = [[LoginTypesViewController alloc] init];
|
|
||||||
[self.navigationController pushViewController:vc animated:YES];
|
|
||||||
[vc updateLoginType:LoginDisplayType_email];
|
[vc updateLoginType:LoginDisplayType_email];
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LoginType_Google:
|
|
||||||
[self.presenter thirdLoginByGoogleWithPresentingViewController:self
|
|
||||||
configuration:self.configuration];
|
|
||||||
break;
|
|
||||||
case LoginType_Apple:
|
|
||||||
[self.presenter thirdLoginWithType:ThirdLoginType_Apple];
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self.navigationController pushViewController:vc animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didTapFeedback {
|
- (void)didTapFeedback {
|
||||||
@@ -412,18 +386,6 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
|||||||
return _policyTips;
|
return _policyTips;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GIDConfiguration *)configuration{
|
|
||||||
if (!_configuration){
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
static NSString *decryptedNumber;
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
decryptedNumber = [AESUtils aesDecrypt:@"ScLBu7ctIiyGCKPro3Jj6XMdsdCCpNT9L4wyjHEF+bguqubkXNSayFBGMKmoDwe1hjfAc958XSaBdMyEaFXLO38Bwq3xURYVNpgEM4b14zg="];
|
|
||||||
});
|
|
||||||
_configuration = [[GIDConfiguration alloc] initWithClientID:decryptedNumber];
|
|
||||||
}
|
|
||||||
return _configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIImageView *)logoImageView {
|
- (UIImageView *)logoImageView {
|
||||||
if (!_logoImageView) {
|
if (!_logoImageView) {
|
||||||
_logoImageView = [[UIImageView alloc] initWithImage:kImage(@"login_page_logo")];
|
_logoImageView = [[UIImageView alloc] initWithImage:kImage(@"login_page_logo")];
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// YMMineShareViewController.h
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2022/6/27.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "BaseViewController.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
@class XPShareInfoModel;
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, MineShareType) {
|
|
||||||
///分享动态
|
|
||||||
MineShareType_Monents = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface XPMineShareViewController : BaseViewController
|
|
||||||
@property (nonatomic,strong) XPShareInfoModel *shareInfo;
|
|
||||||
///分享的类型
|
|
||||||
@property (nonatomic,assign) MineShareType shareType;
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
@@ -1,232 +0,0 @@
|
|||||||
//
|
|
||||||
// YMMineShareViewController.m
|
|
||||||
// YUMI
|
|
||||||
//
|
|
||||||
// Created by YUMI on 2022/6/27.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "XPMineShareViewController.h"
|
|
||||||
///Third
|
|
||||||
#import <Masonry/Masonry.h>
|
|
||||||
#import <NIMSDK/NIMSDK.h>
|
|
||||||
#import <JXCategoryView/JXCategoryView.h>
|
|
||||||
#import <JXCategoryView/JXCategoryListContainerView.h>
|
|
||||||
///Tool
|
|
||||||
#import "DJDKMIMOMColor.h"
|
|
||||||
#import "YUMIMacroUitls.h"
|
|
||||||
#import "TTPopup.h"
|
|
||||||
///Model
|
|
||||||
#import "XPShareInfoModel.h"
|
|
||||||
#import "FansInfoModel.h"
|
|
||||||
#import "UserInfoModel.h"
|
|
||||||
#import "AttachMentModel.h"
|
|
||||||
#import "ContentShareMonentsModel.h"
|
|
||||||
///View
|
|
||||||
#import "SessionViewController.h"
|
|
||||||
#import "SessionListViewController.h"
|
|
||||||
#import "XPMineFriendViewController.h"
|
|
||||||
#import "XPMineAttentionViewController.h"
|
|
||||||
#import "XPMineFansViewController.h"
|
|
||||||
@interface XPMineShareViewController ()<JXCategoryViewDelegate,JXCategoryListContainerViewDelegate, XPMineAttentionViewControllerDelegate, XPMineFansViewControllerDelegate, XPMineFriendViewControllerDelegate>
|
|
||||||
///标题
|
|
||||||
@property (nonatomic,strong) NSArray<NSString *> *titles;
|
|
||||||
///滑块
|
|
||||||
@property (nonatomic,strong) JXCategoryTitleView *titleView;
|
|
||||||
@property (nonatomic, strong) JXCategoryListContainerView *listContainerView;
|
|
||||||
///好友
|
|
||||||
@property (nonatomic,strong) XPMineFriendViewController *friendVC;
|
|
||||||
///关注
|
|
||||||
@property (nonatomic,strong) XPMineAttentionViewController *attentionVC;
|
|
||||||
///粉丝
|
|
||||||
@property (nonatomic,strong) XPMineFansViewController *fansVC;
|
|
||||||
///回话的id
|
|
||||||
@property (nonatomic,copy) NSString *sessionId;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation XPMineShareViewController
|
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
|
||||||
[super viewDidLoad];
|
|
||||||
[self initSubViews];
|
|
||||||
[self initSubViewConstraints];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Private Method
|
|
||||||
- (void)initSubViews {
|
|
||||||
self.title = YMLocalizedString(@"XPMineShareViewController0");
|
|
||||||
[self.view addSubview:self.titleView];
|
|
||||||
[self.view addSubview:self.listContainerView];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)initSubViewConstraints {
|
|
||||||
[self.titleView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.leading.trailing.top.mas_equalTo(self.view);
|
|
||||||
make.height.mas_equalTo(50);
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self.listContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.leading.trailing.bottom.mas_equalTo(self.view);
|
|
||||||
make.top.mas_equalTo(self.titleView.mas_bottom);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendCustomMessage:(AttachmentModel *)attachment {
|
|
||||||
NIMMessage *message = [[NIMMessage alloc]init];
|
|
||||||
NIMCustomObject *object = [[NIMCustomObject alloc] init];
|
|
||||||
object.attachment = attachment;
|
|
||||||
message.messageObject = object;
|
|
||||||
NIMSessionType sessionType = NIMSessionTypeP2P;
|
|
||||||
//构造会话
|
|
||||||
NIMSession *session = [NIMSession session:self.sessionId type:sessionType];
|
|
||||||
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareToUser:(NSString *)nick {
|
|
||||||
NSString * title;
|
|
||||||
AttachmentModel * attachment = [[AttachmentModel alloc] init];
|
|
||||||
|
|
||||||
// 添加类型安全检查
|
|
||||||
if (![self.shareInfo isKindOfClass:[XPShareInfoModel class]]) {
|
|
||||||
NSLog(@"警告:self.shareInfo不是XPShareInfoModel类型,而是%@类型", NSStringFromClass([self.shareInfo class]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self.shareType) {
|
|
||||||
case MineShareType_Monents:
|
|
||||||
{
|
|
||||||
title = [NSString stringWithFormat:YMLocalizedString(@"XPMineShareViewController1"), nick];
|
|
||||||
attachment.first = CustomMessageType_Monents;
|
|
||||||
attachment.second = Custom_Message_Sub_Monents_Share;
|
|
||||||
ContentShareMonentsModel * shareInfo = [[ContentShareMonentsModel alloc] init];
|
|
||||||
shareInfo.imageUrl = self.shareInfo.imageUrl;
|
|
||||||
shareInfo.nick = self.shareInfo.nick;
|
|
||||||
shareInfo.content = self.shareInfo.content;
|
|
||||||
shareInfo.dynamicId= self.shareInfo.dynamicId;
|
|
||||||
shareInfo.routerValue = self.shareInfo.dynamicId;
|
|
||||||
shareInfo.routerType = 50;
|
|
||||||
attachment.data = shareInfo.model2dictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (title.length > 0) {
|
|
||||||
[TTPopup alertWithMessage:title confirmHandler:^{
|
|
||||||
[self sendCustomMessage:attachment];
|
|
||||||
} cancelHandler:^{
|
|
||||||
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - JXCategoryListContainerViewDelegate
|
|
||||||
- (NSInteger)numberOfListsInlistContainerView:(JXCategoryListContainerView *)listContainerView {
|
|
||||||
return self.titles.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据下标 index 返回对应遵守并实现 `JXCategoryListContentViewDelegate` 协议的列表实例
|
|
||||||
- (id<JXCategoryListContentViewDelegate>)listContainerView:(JXCategoryListContainerView *)listContainerView initListForIndex:(NSInteger)index {
|
|
||||||
if (index == 0) {
|
|
||||||
return self.friendVC;
|
|
||||||
} else if(index == 1) {
|
|
||||||
return self.fansVC;
|
|
||||||
} else {
|
|
||||||
return self.attentionVC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - XPMineAttentionViewControllerDelegate
|
|
||||||
///点击了关注的某个人
|
|
||||||
- (void)xPMineAttentionViewController:(XPMineAttentionViewController *)viewController didSelectItem:(FansInfoModel *)userInfo {
|
|
||||||
self.sessionId = userInfo.uid;
|
|
||||||
[self shareToUser:userInfo.nick];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - XPMineFansViewControllerDelegate
|
|
||||||
///点击了粉丝
|
|
||||||
- (void)xPMineFansViewController:(XPMineFansViewController *)view didSelectItem:(FansInfoModel *)userInfo {
|
|
||||||
self.sessionId = userInfo.uid;
|
|
||||||
[self shareToUser:userInfo.nick];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - XPMineFriendViewControllerDelegate
|
|
||||||
///点击了好友
|
|
||||||
- (void)xPMineFriendViewController:(XPMineFriendViewController *)viewController didSelectItem:(UserInfoModel *)userInfo {
|
|
||||||
self.sessionId = [NSString stringWithFormat:@"%ld", userInfo.uid];
|
|
||||||
[self shareToUser:userInfo.nick];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Getters And Setters
|
|
||||||
|
|
||||||
- (JXCategoryListContainerView *)listContainerView {
|
|
||||||
if (!_listContainerView) {
|
|
||||||
_listContainerView = [[JXCategoryListContainerView alloc] initWithType:JXCategoryListContainerType_ScrollView delegate:self];
|
|
||||||
_listContainerView.listCellBackgroundColor = [UIColor clearColor];
|
|
||||||
}
|
|
||||||
return _listContainerView;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray<NSString *> *)titles {
|
|
||||||
if (!_titles) {
|
|
||||||
_titles = @[YMLocalizedString(@"XPMonentsTooBarView3"),YMLocalizedString(@"XPMineContactViewController3"), YMLocalizedString(@"XPMineShareViewController4")];
|
|
||||||
}
|
|
||||||
return _titles;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (JXCategoryTitleView *)titleView {
|
|
||||||
if (!_titleView) {
|
|
||||||
_titleView = [[JXCategoryTitleView alloc] initWithFrame:CGRectZero];
|
|
||||||
_titleView.backgroundColor =[UIColor clearColor];
|
|
||||||
_titleView.titleColor = UIColorFromRGB(0x444444);
|
|
||||||
_titleView.titleSelectedColor = [DJDKMIMOMColor mainTextColor];
|
|
||||||
_titleView.titleFont = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
|
||||||
_titleView.titleSelectedFont = [UIFont systemFontOfSize:18 weight:UIFontWeightHeavy];
|
|
||||||
_titleView.titleLabelAnchorPointStyle = JXCategoryTitleLabelAnchorPointStyleCenter;
|
|
||||||
_titleView.contentScrollViewClickTransitionAnimationEnabled = NO;
|
|
||||||
_titleView.averageCellSpacingEnabled = NO;
|
|
||||||
_titleView.defaultSelectedIndex = 0;
|
|
||||||
_titleView.titles = self.titles;
|
|
||||||
_titleView.delegate = self;
|
|
||||||
_titleView.cellSpacing = 0;
|
|
||||||
_titleView.cellWidth = (CGFloat)KScreenWidth/ 3.0;
|
|
||||||
_titleView.listContainer = self.listContainerView;
|
|
||||||
|
|
||||||
JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
|
|
||||||
lineView.indicatorColor = [DJDKMIMOMColor appMainColor];
|
|
||||||
lineView.indicatorWidth = 8.f;
|
|
||||||
lineView.indicatorHeight = 4.f;
|
|
||||||
lineView.indicatorCornerRadius = 2.f;
|
|
||||||
_titleView.indicators = @[lineView];
|
|
||||||
}
|
|
||||||
return _titleView;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (XPMineAttentionViewController *)attentionVC {
|
|
||||||
if (!_attentionVC) {
|
|
||||||
_attentionVC = [[XPMineAttentionViewController alloc] init];
|
|
||||||
_attentionVC.type = ContactUseingType_Share;
|
|
||||||
_attentionVC.delegate = self;
|
|
||||||
}
|
|
||||||
return _attentionVC;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (XPMineFriendViewController *)friendVC {
|
|
||||||
if (!_friendVC) {
|
|
||||||
_friendVC = [[XPMineFriendViewController alloc] init];
|
|
||||||
_friendVC.type = ContactUseingType_Share;
|
|
||||||
_friendVC.delegate = self;
|
|
||||||
}
|
|
||||||
return _friendVC;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (XPMineFansViewController *)fansVC {
|
|
||||||
if (!_fansVC) {
|
|
||||||
_fansVC = [[XPMineFansViewController alloc] init];
|
|
||||||
_fansVC.type = ContactUseingType_Share;
|
|
||||||
_fansVC.delegate = self;
|
|
||||||
}
|
|
||||||
return _fansVC;
|
|
||||||
}
|
|
||||||
@end
|
|
@@ -472,7 +472,6 @@ XPHomeRecommendOtherRoomViewDelegate>
|
|||||||
header.stateLabel.textColor = [DJDKMIMOMColor secondTextColor];
|
header.stateLabel.textColor = [DJDKMIMOMColor secondTextColor];
|
||||||
header.lastUpdatedTimeLabel.textColor = [DJDKMIMOMColor secondTextColor];
|
header.lastUpdatedTimeLabel.textColor = [DJDKMIMOMColor secondTextColor];
|
||||||
self.pagingView.mainTableView.mj_header = header;
|
self.pagingView.mainTableView.mj_header = header;
|
||||||
[ClientConfig shareConfig].inviteCode = @"";
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(homeVCRefreshComplete) name:@"khomeVCRefreshComplete" object:nil];
|
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(homeVCRefreshComplete) name:@"khomeVCRefreshComplete" object:nil];
|
||||||
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(logOut) name:@"kInLoginVC" object:nil];
|
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(logOut) name:@"kInLoginVC" object:nil];
|
||||||
|
@@ -26,12 +26,11 @@
|
|||||||
///View
|
///View
|
||||||
#import "XPArrangeMicEmptyTableViewCell.h"
|
#import "XPArrangeMicEmptyTableViewCell.h"
|
||||||
#import "XPArrangeMicTableViewCell.h"
|
#import "XPArrangeMicTableViewCell.h"
|
||||||
#import "XPShareView.h"
|
|
||||||
///P
|
///P
|
||||||
#import "XPArrangeMicPresenter.h"
|
#import "XPArrangeMicPresenter.h"
|
||||||
#import "XPArrangeMicProtocol.h"
|
#import "XPArrangeMicProtocol.h"
|
||||||
|
|
||||||
@interface XPArrangeMicViewController ()<UITableViewDelegate, UITableViewDataSource, XPArrangeMicTableViewCellDelegate,XPArrangeMicProtocol,NIMChatManagerDelegate, XCShareViewDelegate>
|
@interface XPArrangeMicViewController ()<UITableViewDelegate, UITableViewDataSource, XPArrangeMicTableViewCellDelegate,XPArrangeMicProtocol,NIMChatManagerDelegate>
|
||||||
///点击消失
|
///点击消失
|
||||||
@property (nonatomic,strong) UIView * topView;
|
@property (nonatomic,strong) UIView * topView;
|
||||||
///内容区域
|
///内容区域
|
||||||
@@ -348,7 +347,7 @@
|
|||||||
if (message.messageType == NIMMessageTypeCustom) {
|
if (message.messageType == NIMMessageTypeCustom) {
|
||||||
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||||
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||||
AttachmentModel * attachment = obj.attachment;
|
AttachmentModel * attachment = (AttachmentModel *)obj.attachment;
|
||||||
if (attachment.first == CustomMessageType_Arrange_Mic) {
|
if (attachment.first == CustomMessageType_Arrange_Mic) {
|
||||||
switch (attachment.second) {
|
switch (attachment.second) {
|
||||||
case Custom_Message_Sub_Room_PK_Empty:
|
case Custom_Message_Sub_Room_PK_Empty:
|
||||||
@@ -553,19 +552,6 @@
|
|||||||
self.titleLabel.textAlignment = NSTextAlignmentCenter;
|
self.titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - XCShareViewDelegate
|
|
||||||
- (void)shareView:(XPShareView *)shareView shareFail:(NSString *)message {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
[self showErrorToast:message];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareView:(XPShareView *)shareView didSuccess:(XPShareInfoModel *)shareInfo{
|
|
||||||
[TTPopup dismiss];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareViewDidClickCancel:(XPShareView *)shareView {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - XPArrangeMicTableViewCellDelegate
|
#pragma mark - XPArrangeMicTableViewCellDelegate
|
||||||
- (void)xPArrangeMicTableViewCell:(XPArrangeMicTableViewCell *)view inviteUser:(ArrangeMicUserModel *)userInfo {
|
- (void)xPArrangeMicTableViewCell:(XPArrangeMicTableViewCell *)view inviteUser:(ArrangeMicUserModel *)userInfo {
|
||||||
@@ -664,24 +650,24 @@
|
|||||||
self.userInfo.isManager = NO;
|
self.userInfo.isManager = NO;
|
||||||
#endif
|
#endif
|
||||||
if (self.userInfo.isManager) {
|
if (self.userInfo.isManager) {
|
||||||
XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"];
|
// XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"];
|
||||||
XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"];
|
// XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"];
|
||||||
XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"RoomHeaderView3") imageName:@"share_copy_link" disableImageName:@"share_copy_link"];
|
// XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"RoomHeaderView3") imageName:@"share_copy_link" disableImageName:@"share_copy_link"];
|
||||||
NSArray * items = @[wechat,cycle, qq];
|
// NSArray * items = @[wechat,cycle, qq];
|
||||||
XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init];
|
// XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init];
|
||||||
shareInfo.shareTitle = self.userInfo.roomTitle;
|
// shareInfo.shareTitle = self.userInfo.roomTitle;
|
||||||
shareInfo.shareContent = self.userInfo.nick;
|
// shareInfo.shareContent = self.userInfo.nick;
|
||||||
shareInfo.shareImageUrl = self.userInfo.roomAvatar;
|
// shareInfo.shareImageUrl = self.userInfo.roomAvatar;
|
||||||
shareInfo.type = ShareType_Room;
|
// shareInfo.type = ShareType_Room;
|
||||||
shareInfo.roomUid = self.userInfo.roomUid.integerValue;
|
// shareInfo.roomUid = self.userInfo.roomUid.integerValue;
|
||||||
NSString * uid = [AccountInfoStorage instance].getUid;
|
// NSString * uid = [AccountInfoStorage instance].getUid;
|
||||||
NSString * urlString = [NSString stringWithFormat:@"%@/%@?shareUid=%@&uid=%@&room_name=%@&room_id=%@&room_avatar=%@&share_name=%@",[HttpRequestHelper getHostUrl],URLWithType(kShareRoomURL),uid,self.userInfo.roomUid,self.userInfo.nick,self.userInfo.roomId,self.userInfo.roomAvatar,self.userInfo.nick];
|
// NSString * urlString = [NSString stringWithFormat:@"%@/%@?shareUid=%@&uid=%@&room_name=%@&room_id=%@&room_avatar=%@&share_name=%@",[HttpRequestHelper getHostUrl],URLWithType(kShareRoomURL),uid,self.userInfo.roomUid,self.userInfo.nick,self.userInfo.roomId,self.userInfo.roomAvatar,self.userInfo.nick];
|
||||||
shareInfo.shareUrl = urlString;
|
// shareInfo.shareUrl = urlString;
|
||||||
CGFloat margin = 15;
|
// CGFloat margin = 15;
|
||||||
CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65);
|
// CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65);
|
||||||
XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo];
|
// XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo];
|
||||||
shareView.delegate = self;
|
// shareView.delegate = self;
|
||||||
[TTPopup popupView:shareView style:TTPopupStyleActionSheet];
|
// [TTPopup popupView:shareView style:TTPopupStyleActionSheet];
|
||||||
} else {
|
} else {
|
||||||
if (self.arrangeMicInfo.myPos.integerValue > 0) {
|
if (self.arrangeMicInfo.myPos.integerValue > 0) {
|
||||||
[TTPopup alertWithMessage:YMLocalizedString(@"XPArrangeMicViewController19") confirmHandler:^{
|
[TTPopup alertWithMessage:YMLocalizedString(@"XPArrangeMicViewController19") confirmHandler:^{
|
||||||
|
@@ -65,7 +65,7 @@ static XPCoreDataManager *manager = nil;
|
|||||||
* URL:要保存的文件路径
|
* URL:要保存的文件路径
|
||||||
* options:参数信息 一般无需设置
|
* options:参数信息 一般无需设置
|
||||||
*/
|
*/
|
||||||
NSURL *url = [[self getDocumnetUrlpath] URLByAppendingPathComponent:@"sqlit.db" isDirectory:true];
|
NSURL *url = [[self getDocumnetUrlpath] URLByAppendingPathComponent:@"sqlit.db" isDirectory:NO];
|
||||||
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];
|
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];
|
||||||
}
|
}
|
||||||
return _persistentStoreCoordinator;
|
return _persistentStoreCoordinator;
|
||||||
|
@@ -20,8 +20,7 @@
|
|||||||
/// 初始化配置
|
/// 初始化配置
|
||||||
/// @param complection 完成
|
/// @param complection 完成
|
||||||
+ (void)clientInitConfig:(HttpRequestHelperCompletion)complection {
|
+ (void)clientInitConfig:(HttpRequestHelperCompletion)complection {
|
||||||
NSString * fang = [NSString stringFromBase64String:@"Y2xpZW50L2luaXQ="];///client/init
|
[HttpRequestHelper request:@"client/init" method:HttpRequestHelperMethodGET params:@{} completion:complection];
|
||||||
[HttpRequestHelper request:fang method:HttpRequestHelperMethodGET params:@{} completion:complection];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)clientConfig:(HttpRequestHelperCompletion)completion {
|
+ (void)clientConfig:(HttpRequestHelperCompletion)completion {
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#import "YUMIMacroUitls.h"
|
#import "YUMIMacroUitls.h"
|
||||||
#import "YYUtility.h"
|
#import "YYUtility.h"
|
||||||
#import "HttpRequestHelper.h"
|
#import "HttpRequestHelper.h"
|
||||||
#import "XPShareView.h"
|
|
||||||
#import "TTPopup.h"
|
#import "TTPopup.h"
|
||||||
#import <Masonry/Masonry.h>
|
#import <Masonry/Masonry.h>
|
||||||
#import <MJExtension/MJExtension.h>
|
#import <MJExtension/MJExtension.h>
|
||||||
@@ -79,15 +78,11 @@ typedef NS_ENUM(NSUInteger, RightNavigationPushType){
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface XPWebViewController () <WKNavigationDelegate, WKScriptMessageHandler, XCShareViewDelegate,XPWebViewNavViewDelegate>
|
@interface XPWebViewController () <WKNavigationDelegate, WKScriptMessageHandler, XPWebViewNavViewDelegate>
|
||||||
@property (nonatomic,strong) WalletInfoModel *model ;
|
@property (nonatomic,strong) WalletInfoModel *model ;
|
||||||
//@property (strong, nonatomic) WKWebView *webview;
|
//@property (strong, nonatomic) WKWebView *webview;
|
||||||
@property (strong, nonatomic) UIProgressView *progressView;
|
@property (strong, nonatomic) UIProgressView *progressView;
|
||||||
@property (nonatomic, strong) WKUserContentController *pi_userContentController;
|
@property (nonatomic, strong) WKUserContentController *pi_userContentController;
|
||||||
///分享的内容
|
|
||||||
@property (nonatomic,copy) NSDictionary *shareDic;
|
|
||||||
///分享的内容
|
|
||||||
@property (nonatomic,copy) NSDictionary *savePhotoDic;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
@property (nonatomic,strong) XPWebViewNavView *navView;
|
@property (nonatomic,strong) XPWebViewNavView *navView;
|
||||||
@@ -389,8 +384,7 @@ NSString * const kJSShowShareCallBack = @"showShareAction";
|
|||||||
} else if ([message.body isKindOfClass:[NSString class]]) {
|
} else if ([message.body isKindOfClass:[NSString class]]) {
|
||||||
body = [message.body toJSONObject];
|
body = [message.body toJSONObject];
|
||||||
}
|
}
|
||||||
self.shareDic = body[@"data"];
|
// 分享功能已移除
|
||||||
[self showSharePanel];
|
|
||||||
}
|
}
|
||||||
} else if ([message.name isEqualToString:kJSGetUid]) {
|
} else if ([message.name isEqualToString:kJSGetUid]) {
|
||||||
NSString *uid = [[AccountInfoStorage instance] getUid];
|
NSString *uid = [[AccountInfoStorage instance] getUid];
|
||||||
@@ -570,7 +564,7 @@ NSString * const kJSShowShareCallBack = @"showShareAction";
|
|||||||
if ([type isEqualToString:@"2"]){
|
if ([type isEqualToString:@"2"]){
|
||||||
[self saveImageToPhotoAlbum:bodyDic];
|
[self saveImageToPhotoAlbum:bodyDic];
|
||||||
}else if ([type isEqualToString:@"1"]){
|
}else if ([type isEqualToString:@"1"]){
|
||||||
self.savePhotoDic = bodyDic;
|
// self.savePhotoDic = bodyDic;
|
||||||
[self showShareSavePhote];
|
[self showShareSavePhote];
|
||||||
}
|
}
|
||||||
} else if([message.name isEqualToString:kJSGoToExchangeGold]){
|
} else if([message.name isEqualToString:kJSGoToExchangeGold]){
|
||||||
@@ -726,7 +720,7 @@ NSString * const kJSShowShareCallBack = @"showShareAction";
|
|||||||
#pragma mark - 分享
|
#pragma mark - 分享
|
||||||
- (void)initNav:(NSDictionary *)response{
|
- (void)initNav:(NSDictionary *)response{
|
||||||
if(!response || ![response isKindOfClass:[NSDictionary class]])return;
|
if(!response || ![response isKindOfClass:[NSDictionary class]])return;
|
||||||
self.shareDic = response[@"data"];
|
// self.shareDic = response[@"data"];
|
||||||
if ([response[@"type"] intValue]== RightNavigationPushType_Web) {
|
if ([response[@"type"] intValue]== RightNavigationPushType_Web) {
|
||||||
[self addNavigationItemWithTitles:@[response[@"data"][@"title"]] titleColor:[DJDKMIMOMColor alertTitleColor] isLeft:NO target:self action:@selector(gotoWebView) tags:nil];
|
[self addNavigationItemWithTitles:@[response[@"data"][@"title"]] titleColor:[DJDKMIMOMColor alertTitleColor] isLeft:NO target:self action:@selector(gotoWebView) tags:nil];
|
||||||
}else if ([response[@"type"] intValue]== RightNavigationPushType_Share || [response[@"type"] intValue]== RightNavigationPushType_SharePicture){
|
}else if ([response[@"type"] intValue]== RightNavigationPushType_Share || [response[@"type"] intValue]== RightNavigationPushType_SharePicture){
|
||||||
@@ -736,124 +730,16 @@ NSString * const kJSShowShareCallBack = @"showShareAction";
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)gotoWebView {
|
- (void)gotoWebView {
|
||||||
if (self.shareDic[@"link"]) {
|
// if (self.shareDic[@"link"]) {
|
||||||
XPWebViewController * webVC = [[XPWebViewController alloc] init];
|
// XPWebViewController * webVC = [[XPWebViewController alloc] init];
|
||||||
webVC.url = self.shareDic[@"link"];
|
// webVC.url = self.shareDic[@"link"];
|
||||||
[self.navigationController pushViewController:webVC animated:YES];
|
// [self.navigationController pushViewController:webVC animated:YES];
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
-(void)showShareSavePhote{
|
-(void)showShareSavePhote{
|
||||||
if (self.savePhotoDic.allKeys.count <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSDictionary * dic = self.savePhotoDic;
|
|
||||||
XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init];
|
|
||||||
shareInfo.shareContent = dic[@"shareText"];
|
|
||||||
shareInfo.type = ShareType_H5;
|
|
||||||
shareInfo.uid = [AccountInfoStorage instance].getUid;
|
|
||||||
NSString *urlStr = ((NSString *)dic[@"toUrl"]).length > 0 ? dic[@"toUrl"] : @"";
|
|
||||||
NSString *title = ((NSString *)dic[@"shareTitle"]).length > 0 ? dic[@"shareTitle"] : @"";
|
|
||||||
NSString *shareText = ((NSString *)dic[@"shareText"]).length > 0 ? dic[@"shareText"] : @"";
|
|
||||||
NSString *shareImg = ((NSString *)dic[@"shareImg"]).length > 0 ? dic[@"shareImg"] : @"";
|
|
||||||
shareInfo.shareUrl = [NSString stringWithFormat:@"%@&image=%@&title=%@&subTitle=%@",urlStr,shareImg,title,shareText];
|
|
||||||
XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"];
|
|
||||||
XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"];
|
|
||||||
wechat.isShareInvite = YES;
|
|
||||||
wechat.inviteTitle = title;
|
|
||||||
XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"XPWebViewNavView1") imageName:@"share_copy_link" disableImageName:@"share_copy_link"];
|
|
||||||
XPShareItem *save = [XPShareItem itemWitTag:XPShareItemTagAppSaveAlbum title:YMLocalizedString(@"PIWebViewSavePhotoView4") imageName:@"share_save_icon" disableImageName:@"share_save_icon"];
|
|
||||||
|
|
||||||
NSArray * items = @[wechat,cycle, qq,save];
|
|
||||||
CGFloat margin = 15;
|
|
||||||
CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65);
|
|
||||||
XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo];
|
|
||||||
shareView.delegate = self;
|
|
||||||
|
|
||||||
[TTPopup popupView:shareView style:TTPopupStyleActionSheet];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
- (void)showSharePanel {
|
- (void)showSharePanel {
|
||||||
if (self.shareDic.allKeys.count <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NSDictionary * dic = self.shareDic;
|
|
||||||
XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init];
|
|
||||||
shareInfo.shareTitle = self.shareDic[@"title"];
|
|
||||||
shareInfo.shareContent = dic[@"desc"];
|
|
||||||
shareInfo.shareImageUrl = dic[@"imgUrl"];
|
|
||||||
shareInfo.type = ShareType_H5;
|
|
||||||
shareInfo.uid = [AccountInfoStorage instance].getUid;
|
|
||||||
NSString *urlStr = ((NSString *)dic[@"url"]).length > 0 ? dic[@"url"] : dic[@"showUrl"];
|
|
||||||
if (urlStr.length) {
|
|
||||||
if ([urlStr containsString:@"?"]) {
|
|
||||||
urlStr = [NSString stringWithFormat:@"%@&shareUid=%@",urlStr,[AccountInfoStorage instance].getUid];
|
|
||||||
} else {
|
|
||||||
urlStr = [NSString stringWithFormat:@"%@?shareUid=%@",urlStr,[AccountInfoStorage instance].getUid];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shareInfo.shareUrl = urlStr;
|
|
||||||
XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"];
|
|
||||||
XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"];
|
|
||||||
XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"XPWebViewNavView1") imageName:@"share_copy_link" disableImageName:@"share_copy_link"];
|
|
||||||
XPShareItem *save = [XPShareItem itemWitTag:XPShareItemTagAppSaveAlbum title:YMLocalizedString(@"PIWebViewSavePhotoView4") imageName:@"share_save_icon" disableImageName:@"share_save_icon"];
|
|
||||||
|
|
||||||
NSArray * items = @[wechat,cycle, qq,save];
|
|
||||||
CGFloat margin = 15;
|
|
||||||
CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65);
|
|
||||||
XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo];
|
|
||||||
shareView.delegate = self;
|
|
||||||
|
|
||||||
[TTPopup popupView:shareView style:TTPopupStyleActionSheet];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - XCShareViewDelegate
|
|
||||||
- (void)shareView:(XPShareView *)shareView savePhoto:(XPShareInfoModel *)shareInfo{
|
|
||||||
[self saveImageToPhotoAlbum:self.savePhotoDic];
|
|
||||||
}
|
|
||||||
- (void)shareViewDidClickCancle:(XPShareView *)shareView {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
}
|
|
||||||
- (void)shareView:(XPShareView *)shareView didSuccess:(XPShareInfoModel *)shareInfo {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
|
||||||
NSString *uid = [AccountInfoStorage instance].getUid;
|
|
||||||
NSString *ticket = [AccountInfoStorage instance].getTicket;
|
|
||||||
[params setObject:uid forKey:@"uid"];
|
|
||||||
|
|
||||||
// 添加类型安全检查,防止NSTaggedPointerString错误
|
|
||||||
if ([shareInfo isKindOfClass:[XPShareInfoModel class]]) {
|
|
||||||
[params setObject:@(shareInfo.shareType) forKey:@"shareType"];
|
|
||||||
} else {
|
|
||||||
// 如果不是预期类型,提供默认值
|
|
||||||
[params setObject:@(0) forKey:@"shareType"];
|
|
||||||
NSLog(@"警告:shareInfo不是XPShareInfoModel类型,而是%@类型", NSStringFromClass([shareInfo class]));
|
|
||||||
}
|
|
||||||
|
|
||||||
[params setObject:ticket forKey:@"ticket"];
|
|
||||||
if ([shareInfo isKindOfClass:[XPShareInfoModel class]]) {
|
|
||||||
[params setObject:@(shareInfo.type) forKey:@"sharePageId"];
|
|
||||||
if (shareInfo.shareUrl.length > 0) {
|
|
||||||
[params setObject:shareInfo.shareUrl forKey:@"shareUrl"];
|
|
||||||
}
|
|
||||||
if (shareInfo.roomUid > 0) {
|
|
||||||
[params setObject:@(shareInfo.roomUid) forKey:@"targetUid"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpRequestHelper POST:@"usershare/save" params:params success:^(BaseModel * _Nonnull data) {
|
|
||||||
|
|
||||||
} failure:^(NSInteger resCode, NSString * _Nonnull message) {
|
|
||||||
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareView:(XPShareView *)shareView shareFail:(NSString *)message {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
[self showErrorToast:message];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareViewDidClickCancel:(XPShareView *)shareView {
|
|
||||||
[TTPopup dismiss];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
|
||||||
@@ -911,7 +797,7 @@ NSString * const kJSShowShareCallBack = @"showShareAction";
|
|||||||
configuration.preferences.javaScriptEnabled = YES;
|
configuration.preferences.javaScriptEnabled = YES;
|
||||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
||||||
configuration.preferences.minimumFontSize = 10;
|
configuration.preferences.minimumFontSize = 10;
|
||||||
configuration.selectionGranularity = WKSelectionGranularityCharacter;
|
// configuration.selectionGranularity = WKSelectionGranularityCharacter;
|
||||||
configuration.userContentController = self.pi_userContentController;
|
configuration.userContentController = self.pi_userContentController;
|
||||||
|
|
||||||
CGSize size = [UIScreen mainScreen].bounds.size;
|
CGSize size = [UIScreen mainScreen].bounds.size;
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
// MARK: - Foundation
|
// MARK: - Foundation
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
// MARK: - New Modules (White Label)
|
// MARK: - New Modules
|
||||||
#import "GlobalEventManager.h"
|
#import "EPConfigStorage.h"
|
||||||
#import "EPMomentViewController.h"
|
#import "EPMomentViewController.h"
|
||||||
#import "EPMineViewController.h"
|
#import "EPMineViewController.h"
|
||||||
#import "EPMomentCell.h"
|
#import "EPMomentCell.h"
|
||||||
@@ -79,6 +79,7 @@
|
|||||||
|
|
||||||
// MARK: - Login - Captcha & Config
|
// MARK: - Login - Captcha & Config
|
||||||
#import "ClientConfig.h"
|
#import "ClientConfig.h"
|
||||||
|
#import "ClientDataModel.h"
|
||||||
#import "TTPopup.h"
|
#import "TTPopup.h"
|
||||||
|
|
||||||
// 注意:
|
// 注意:
|
||||||
|
Reference in New Issue
Block a user