diff --git a/xplan-ios.xcodeproj/project.pbxproj b/xplan-ios.xcodeproj/project.pbxproj index e46b9811..c743b092 100644 --- a/xplan-ios.xcodeproj/project.pbxproj +++ b/xplan-ios.xcodeproj/project.pbxproj @@ -123,6 +123,12 @@ 9B2A12E127845DD300CED41B /* XPNobleCenterMyNobleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B2A12E027845DD300CED41B /* XPNobleCenterMyNobleView.m */; }; 9B2A12E427846D7100CED41B /* NobleRechargeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B2A12E327846D7100CED41B /* NobleRechargeModel.m */; }; 9B6B3AAB278C2EA7005551EC /* XPRoomNobleLevelUpView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B6B3AAA278C2EA7005551EC /* XPRoomNobleLevelUpView.m */; }; + 9B33E3CB27D85379003B0E62 /* UploadFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B33E3C927D85379003B0E62 /* UploadFile.m */; }; + 9B33E3CE27D8540C003B0E62 /* XPVoiceCardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B33E3CD27D8540C003B0E62 /* XPVoiceCardViewController.m */; }; + 9B33E3D127D8542D003B0E62 /* CommonFileUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B33E3D027D8542D003B0E62 /* CommonFileUtils.m */; }; + 9B73CD05279A9A6A006AF255 /* XPSkillCardSaveModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B73CD04279A9A6A006AF255 /* XPSkillCardSaveModel.m */; }; + 9B73CD09279A9AA2006AF255 /* XPSkillCardUpdatePropModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B73CD08279A9AA2006AF255 /* XPSkillCardUpdatePropModel.m */; }; + 9B73CD11279AE99B006AF255 /* XPSkillCardListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B73CD10279AE99B006AF255 /* XPSkillCardListCell.m */; }; 9B7B605B27BB53060070BB72 /* XPAnchorAudienceUpMicView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B7B605A27BB53060070BB72 /* XPAnchorAudienceUpMicView.m */; }; 9B7B606227BB96E40070BB72 /* XPRoomAnchorInfoCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B7B606127BB96E40070BB72 /* XPRoomAnchorInfoCardView.m */; }; 9B7B606627BBA0EE0070BB72 /* XPAnchorAttentSendInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B7B606527BBA0EE0070BB72 /* XPAnchorAttentSendInfo.m */; }; @@ -133,11 +139,30 @@ 9B8585D3278837CE00D7D5C6 /* NobleLevelUpModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585D2278837CE00D7D5C6 /* NobleLevelUpModel.m */; }; 9B8585F52788699400D7D5C6 /* FBKVOController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B8585F42788699400D7D5C6 /* FBKVOController.m */; }; 9BA41F2527CBB7950043B11F /* UIColor+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA41F2427CBB7950043B11F /* UIColor+Extension.m */; }; + 9B7D8857279C099C00785A25 /* XPSkillCardListPropCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B7D8856279C099C00785A25 /* XPSkillCardListPropCell.m */; }; + 9B85B6D7279FDABA00A0A1AC /* XPUserCardSkillCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B85B6D6279FDABA00A0A1AC /* XPUserCardSkillCardView.m */; }; + 9B85B6DA279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B85B6D9279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.m */; }; + 9B92A3392797BE4500AD168F /* XPMineSkillTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3382797BE4500AD168F /* XPMineSkillTipView.m */; }; 9B92A33C2797E38100AD168F /* XPMineHeadItemTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A33B2797E38100AD168F /* XPMineHeadItemTableViewCell.m */; }; 9B92A3442797EE6500AD168F /* XPMatchManagePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3432797EE6500AD168F /* XPMatchManagePresenter.m */; }; 9B92A3472797EECD00AD168F /* XPMatchManageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3462797EECD00AD168F /* XPMatchManageViewController.m */; }; 9B92A34A2797F35E00AD168F /* XPMatchManageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3492797F35E00AD168F /* XPMatchManageTableViewCell.m */; }; - 9B92A3392797BE4500AD168F /* XPMineSkillTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3382797BE4500AD168F /* XPMineSkillTipView.m */; }; + 9B92A352279807F300AD168F /* XPSkillCardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A351279807F300AD168F /* XPSkillCardViewController.m */; }; + 9B92A3562798096000AD168F /* XPSkillCardPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3552798096000AD168F /* XPSkillCardPresenter.m */; }; + 9B92A35C27980A2900AD168F /* XPSkillCardHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A35B27980A2900AD168F /* XPSkillCardHeadView.m */; }; + 9B92A36327980DCC00AD168F /* Api+SkillCard.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A36227980DCC00AD168F /* Api+SkillCard.m */; }; + 9B92A3662798132600AD168F /* XPSkillCardTypeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3652798132600AD168F /* XPSkillCardTypeView.m */; }; + 9B92A3692798145000AD168F /* XPSkillCardTypeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A3682798145000AD168F /* XPSkillCardTypeModel.m */; }; + 9B92A36D2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A36C2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.m */; }; + 9B92A37027981F5B00AD168F /* XPSkillCardEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B92A36F27981F5B00AD168F /* XPSkillCardEditViewController.m */; }; + 9B9EEF4E27C8755C006B0EB3 /* XPSkillCardResourcePropModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9EEF4D27C8755C006B0EB3 /* XPSkillCardResourcePropModel.m */; }; + 9B9EEF5427C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9EEF5327C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.m */; }; + 9BA8A47227C5D590000365A3 /* XPVoiceCardCircleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA8A47127C5D590000365A3 /* XPVoiceCardCircleLayer.m */; }; + 9BA8A47527C60D9F000365A3 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BA8A47427C60D9F000365A3 /* AudioToolbox.framework */; }; + 9BA8A47727C60DF7000365A3 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BA8A47627C60DF7000365A3 /* AVFoundation.framework */; }; + 9BA8A47D27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA8A47C27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.m */; }; + 9BA8A48027C65098000365A3 /* XPSkillCardVoiceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA8A47F27C65098000365A3 /* XPSkillCardVoiceView.m */; }; + 9BA8A48327C726E8000365A3 /* ThemeColor+SkillCard.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BA8A48227C726E8000365A3 /* ThemeColor+SkillCard.m */; }; 9BAA5FED277A1BBE007453F3 /* XPPrivacyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BAA5FEC277A1BBE007453F3 /* XPPrivacyViewController.m */; }; 9BAA5FF0277A23F4007453F3 /* XPPermissionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BAA5FEF277A23F4007453F3 /* XPPermissionsViewController.m */; }; 9BB549592782E6A30090CD26 /* XPNobleCenterPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB549582782E6A30090CD26 /* XPNobleCenterPresenter.m */; }; @@ -162,6 +187,11 @@ 9BD63FAB277EE885006EB744 /* Api+RoomRadio.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD63FAA277EE885006EB744 /* Api+RoomRadio.m */; }; 9BD63FAE277EE97A006EB744 /* XPReleaseRadioPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD63FAD277EE97A006EB744 /* XPReleaseRadioPresenter.m */; }; 9BD63FB4277EF1B3006EB744 /* XPReleaseRadioModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BD63FB3277EF1B3006EB744 /* XPReleaseRadioModel.m */; }; + 9BCF58532798FDA1008401A4 /* XPSkillCardModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BCF58522798FDA1008401A4 /* XPSkillCardModel.m */; }; + 9BCF58562798FE86008401A4 /* XPSkillCardPropModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BCF58552798FE86008401A4 /* XPSkillCardPropModel.m */; }; + 9BCF585C279909D7008401A4 /* XPSkillCardEditPropCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BCF585B279909D7008401A4 /* XPSkillCardEditPropCell.m */; }; + 9BCF585F27995363008401A4 /* XPSkillCardSelectPropView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BCF585E27995363008401A4 /* XPSkillCardSelectPropView.m */; }; + 9BCF586227995426008401A4 /* XPSkillCardSelectPropCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BCF586127995426008401A4 /* XPSkillCardSelectPropCell.m */; }; 9BE29A6B27D1BFF700446AB5 /* anchor_room_speak.svga in Resources */ = {isa = PBXBuildFile; fileRef = 9BE29A6927D1BFF700446AB5 /* anchor_room_speak.svga */; }; 9BE29A6D27D210A500446AB5 /* anchor_room_bg.svga in Resources */ = {isa = PBXBuildFile; fileRef = 9BE29A6C27D210A500446AB5 /* anchor_room_bg.svga */; }; 9BEE3D0E27853BD000C83219 /* ThemeColor+NobleCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BEE3D0D27853BD000C83219 /* ThemeColor+NobleCenter.m */; }; @@ -742,6 +772,18 @@ 9B2A12E327846D7100CED41B /* NobleRechargeModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NobleRechargeModel.m; sourceTree = ""; }; 9B6B3AA9278C2EA7005551EC /* XPRoomNobleLevelUpView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomNobleLevelUpView.h; sourceTree = ""; }; 9B6B3AAA278C2EA7005551EC /* XPRoomNobleLevelUpView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomNobleLevelUpView.m; sourceTree = ""; }; + 9B33E3C927D85379003B0E62 /* UploadFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UploadFile.m; sourceTree = ""; }; + 9B33E3CA27D85379003B0E62 /* UploadFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UploadFile.h; sourceTree = ""; }; + 9B33E3CC27D8540C003B0E62 /* XPVoiceCardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPVoiceCardViewController.h; sourceTree = ""; }; + 9B33E3CD27D8540C003B0E62 /* XPVoiceCardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPVoiceCardViewController.m; sourceTree = ""; }; + 9B33E3CF27D8542C003B0E62 /* CommonFileUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonFileUtils.h; sourceTree = ""; }; + 9B33E3D027D8542D003B0E62 /* CommonFileUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommonFileUtils.m; sourceTree = ""; }; + 9B73CD03279A9A6A006AF255 /* XPSkillCardSaveModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardSaveModel.h; sourceTree = ""; }; + 9B73CD04279A9A6A006AF255 /* XPSkillCardSaveModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardSaveModel.m; sourceTree = ""; }; + 9B73CD07279A9AA2006AF255 /* XPSkillCardUpdatePropModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardUpdatePropModel.h; sourceTree = ""; }; + 9B73CD08279A9AA2006AF255 /* XPSkillCardUpdatePropModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardUpdatePropModel.m; sourceTree = ""; }; + 9B73CD0F279AE99B006AF255 /* XPSkillCardListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardListCell.h; sourceTree = ""; }; + 9B73CD10279AE99B006AF255 /* XPSkillCardListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardListCell.m; sourceTree = ""; }; 9B7B605927BB53060070BB72 /* XPAnchorAudienceUpMicView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPAnchorAudienceUpMicView.h; sourceTree = ""; }; 9B7B605A27BB53060070BB72 /* XPAnchorAudienceUpMicView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPAnchorAudienceUpMicView.m; sourceTree = ""; }; 9B7B606027BB96E40070BB72 /* XPRoomAnchorInfoCardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPRoomAnchorInfoCardView.h; sourceTree = ""; }; @@ -762,6 +804,14 @@ 9B8585F42788699400D7D5C6 /* FBKVOController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBKVOController.m; sourceTree = ""; }; 9BA41F2327CBB7950043B11F /* UIColor+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Extension.h"; sourceTree = ""; }; 9BA41F2427CBB7950043B11F /* UIColor+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Extension.m"; sourceTree = ""; }; + 9B7D8855279C099C00785A25 /* XPSkillCardListPropCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardListPropCell.h; sourceTree = ""; }; + 9B7D8856279C099C00785A25 /* XPSkillCardListPropCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardListPropCell.m; sourceTree = ""; }; + 9B85B6D5279FDABA00A0A1AC /* XPUserCardSkillCardView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPUserCardSkillCardView.h; sourceTree = ""; }; + 9B85B6D6279FDABA00A0A1AC /* XPUserCardSkillCardView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPUserCardSkillCardView.m; sourceTree = ""; }; + 9B85B6D8279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPUserCardSkillCollectionViewCell.h; sourceTree = ""; }; + 9B85B6D9279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPUserCardSkillCollectionViewCell.m; sourceTree = ""; }; + 9B92A3372797BE4500AD168F /* XPMineSkillTipView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMineSkillTipView.h; sourceTree = ""; }; + 9B92A3382797BE4500AD168F /* XPMineSkillTipView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMineSkillTipView.m; sourceTree = ""; }; 9B92A33A2797E38100AD168F /* XPMineHeadItemTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMineHeadItemTableViewCell.h; sourceTree = ""; }; 9B92A33B2797E38100AD168F /* XPMineHeadItemTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMineHeadItemTableViewCell.m; sourceTree = ""; }; 9B92A3412797EE1200AD168F /* XPMatchManageProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMatchManageProtocol.h; sourceTree = ""; }; @@ -771,8 +821,37 @@ 9B92A3462797EECD00AD168F /* XPMatchManageViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMatchManageViewController.m; sourceTree = ""; }; 9B92A3482797F35E00AD168F /* XPMatchManageTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMatchManageTableViewCell.h; sourceTree = ""; }; 9B92A3492797F35E00AD168F /* XPMatchManageTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMatchManageTableViewCell.m; sourceTree = ""; }; - 9B92A3372797BE4500AD168F /* XPMineSkillTipView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMineSkillTipView.h; sourceTree = ""; }; - 9B92A3382797BE4500AD168F /* XPMineSkillTipView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMineSkillTipView.m; sourceTree = ""; }; + 9B92A350279807F300AD168F /* XPSkillCardViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardViewController.h; sourceTree = ""; }; + 9B92A351279807F300AD168F /* XPSkillCardViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardViewController.m; sourceTree = ""; }; + 9B92A3542798096000AD168F /* XPSkillCardPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardPresenter.h; sourceTree = ""; }; + 9B92A3552798096000AD168F /* XPSkillCardPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardPresenter.m; sourceTree = ""; }; + 9B92A3572798097500AD168F /* XPSkillCardProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardProtocol.h; sourceTree = ""; }; + 9B92A35A27980A2900AD168F /* XPSkillCardHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardHeadView.h; sourceTree = ""; }; + 9B92A35B27980A2900AD168F /* XPSkillCardHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardHeadView.m; sourceTree = ""; }; + 9B92A36127980DCC00AD168F /* Api+SkillCard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Api+SkillCard.h"; sourceTree = ""; }; + 9B92A36227980DCC00AD168F /* Api+SkillCard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Api+SkillCard.m"; sourceTree = ""; }; + 9B92A3642798132600AD168F /* XPSkillCardTypeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardTypeView.h; sourceTree = ""; }; + 9B92A3652798132600AD168F /* XPSkillCardTypeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardTypeView.m; sourceTree = ""; }; + 9B92A3672798145000AD168F /* XPSkillCardTypeModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardTypeModel.h; sourceTree = ""; }; + 9B92A3682798145000AD168F /* XPSkillCardTypeModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardTypeModel.m; sourceTree = ""; }; + 9B92A36B2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardTypeCollectionViewCell.h; sourceTree = ""; }; + 9B92A36C2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardTypeCollectionViewCell.m; sourceTree = ""; }; + 9B92A36E27981F5B00AD168F /* XPSkillCardEditViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardEditViewController.h; sourceTree = ""; }; + 9B92A36F27981F5B00AD168F /* XPSkillCardEditViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardEditViewController.m; sourceTree = ""; }; + 9B9EEF4C27C8755C006B0EB3 /* XPSkillCardResourcePropModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardResourcePropModel.h; sourceTree = ""; }; + 9B9EEF4D27C8755C006B0EB3 /* XPSkillCardResourcePropModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardResourcePropModel.m; sourceTree = ""; }; + 9B9EEF5227C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardRecordPropModel.h; sourceTree = ""; }; + 9B9EEF5327C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardRecordPropModel.m; sourceTree = ""; }; + 9BA8A47027C5D590000365A3 /* XPVoiceCardCircleLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPVoiceCardCircleLayer.h; sourceTree = ""; }; + 9BA8A47127C5D590000365A3 /* XPVoiceCardCircleLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPVoiceCardCircleLayer.m; sourceTree = ""; }; + 9BA8A47427C60D9F000365A3 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 9BA8A47627C60DF7000365A3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 9BA8A47B27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardUpdatePropDetailModel.h; sourceTree = ""; }; + 9BA8A47C27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardUpdatePropDetailModel.m; sourceTree = ""; }; + 9BA8A47E27C65098000365A3 /* XPSkillCardVoiceView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardVoiceView.h; sourceTree = ""; }; + 9BA8A47F27C65098000365A3 /* XPSkillCardVoiceView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardVoiceView.m; sourceTree = ""; }; + 9BA8A48127C726E8000365A3 /* ThemeColor+SkillCard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ThemeColor+SkillCard.h"; sourceTree = ""; }; + 9BA8A48227C726E8000365A3 /* ThemeColor+SkillCard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ThemeColor+SkillCard.m"; sourceTree = ""; }; 9BAA5FEB277A1BBE007453F3 /* XPPrivacyViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPPrivacyViewController.h; sourceTree = ""; }; 9BAA5FEC277A1BBE007453F3 /* XPPrivacyViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPPrivacyViewController.m; sourceTree = ""; }; 9BAA5FEE277A23F4007453F3 /* XPPermissionsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPPermissionsViewController.h; sourceTree = ""; }; @@ -824,6 +903,16 @@ 9BD63FB1277EF14A006EB744 /* XPReleaseRadioProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPReleaseRadioProtocol.h; sourceTree = ""; }; 9BD63FB2277EF1B3006EB744 /* XPReleaseRadioModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPReleaseRadioModel.h; sourceTree = ""; }; 9BD63FB3277EF1B3006EB744 /* XPReleaseRadioModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPReleaseRadioModel.m; sourceTree = ""; }; + 9BCF58512798FDA1008401A4 /* XPSkillCardModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardModel.h; sourceTree = ""; }; + 9BCF58522798FDA1008401A4 /* XPSkillCardModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardModel.m; sourceTree = ""; }; + 9BCF58542798FE86008401A4 /* XPSkillCardPropModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardPropModel.h; sourceTree = ""; }; + 9BCF58552798FE86008401A4 /* XPSkillCardPropModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardPropModel.m; sourceTree = ""; }; + 9BCF585A279909D7008401A4 /* XPSkillCardEditPropCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardEditPropCell.h; sourceTree = ""; }; + 9BCF585B279909D7008401A4 /* XPSkillCardEditPropCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardEditPropCell.m; sourceTree = ""; }; + 9BCF585D27995363008401A4 /* XPSkillCardSelectPropView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardSelectPropView.h; sourceTree = ""; }; + 9BCF585E27995363008401A4 /* XPSkillCardSelectPropView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardSelectPropView.m; sourceTree = ""; }; + 9BCF586027995426008401A4 /* XPSkillCardSelectPropCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPSkillCardSelectPropCell.h; sourceTree = ""; }; + 9BCF586127995426008401A4 /* XPSkillCardSelectPropCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPSkillCardSelectPropCell.m; sourceTree = ""; }; 9BE29A6927D1BFF700446AB5 /* anchor_room_speak.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = anchor_room_speak.svga; sourceTree = ""; }; 9BE29A6C27D210A500446AB5 /* anchor_room_bg.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = anchor_room_bg.svga; sourceTree = ""; }; 9BEE3D0C27853BD000C83219 /* ThemeColor+NobleCenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ThemeColor+NobleCenter.h"; sourceTree = ""; }; @@ -1529,12 +1618,14 @@ E87888F42738C30E00BF1D57 /* StoreKit.framework in Frameworks */, 186A52E026FC559200D67B2C /* SecurityGuardSDK.framework in Frameworks */, 18E7B25D26E8D4490064BC9B /* fluttertoast.xcframework in Frameworks */, + 9BA8A47727C60DF7000365A3 /* AVFoundation.framework in Frameworks */, 186A52E226FC559200D67B2C /* RPSDK.framework in Frameworks */, 186A52E126FC559200D67B2C /* SGSecurityBody.framework in Frameworks */, 18E7B25926E8D4440064BC9B /* flutter_boost.xcframework in Frameworks */, 184863472721715C005FC5DC /* ZegoAudioRoom.framework in Frameworks */, 18E7B25726E8D4430064BC9B /* App.xcframework in Frameworks */, 18E7B25326E8D43D0064BC9B /* FlutterPluginRegistrant.xcframework in Frameworks */, + 9BA8A47527C60D9F000365A3 /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1726,6 +1817,7 @@ 189DD52A26DE255300AB55B1 /* Products */, D09C770DC30B9BAAEAFC7945 /* Pods */, BFB922F5D81845AC32D1E1ED /* Frameworks */, + 9B33E3C727D85369003B0E62 /* Recovered References */, ); sourceTree = ""; }; @@ -1952,6 +2044,7 @@ 189DD5A726DFA09700AB55B1 /* Tool */ = { isa = PBXGroup; children = ( + 9B33E3C827D85379003B0E62 /* File */, E80CBDE727D0C528001E1EC2 /* Timer */, 9BA41F2227CBB7500043B11F /* UIColor */, 180116F6279E8C3100F2CBC0 /* Date */, @@ -2213,6 +2306,30 @@ E8C1CD6327D88EA300376F83 /* Protocol */, ); path = FaceView; + sourceTree = ""; + }; + 9B33E3C827D85379003B0E62 /* File */ = { + isa = PBXGroup; + children = ( + 9B33E3CF27D8542C003B0E62 /* CommonFileUtils.h */, + 9B33E3D027D8542D003B0E62 /* CommonFileUtils.m */, + 9B33E3C927D85379003B0E62 /* UploadFile.m */, + 9B33E3CA27D85379003B0E62 /* UploadFile.h */, + ); + path = File; + sourceTree = ""; + }; + 9B73CD06279A9A8B006AF255 /* UpdateModel */ = { + isa = PBXGroup; + children = ( + 9B73CD03279A9A6A006AF255 /* XPSkillCardSaveModel.h */, + 9B73CD04279A9A6A006AF255 /* XPSkillCardSaveModel.m */, + 9B73CD07279A9AA2006AF255 /* XPSkillCardUpdatePropModel.h */, + 9B73CD08279A9AA2006AF255 /* XPSkillCardUpdatePropModel.m */, + 9BA8A47B27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.h */, + 9BA8A47C27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.m */, + ); + path = UpdateModel; sourceTree = ""; }; 9B7B605827BB52FD0070BB72 /* AnchorView */ = { @@ -2300,6 +2417,17 @@ 9BEE3D1627858E5700C83219 /* XPNobleAuthorityDescView.m */, 9BBC02852786D75C0007C24B /* XPNobleUpgradeLevelView.h */, 9BBC02862786D75C0007C24B /* XPNobleUpgradeLevelView.m */, + ); + path = SubViews; + sourceTree = ""; + }; + 9B85B6D4279FDAA900A0A1AC /* SubViews */ = { + isa = PBXGroup; + children = ( + 9B85B6D5279FDABA00A0A1AC /* XPUserCardSkillCardView.h */, + 9B85B6D6279FDABA00A0A1AC /* XPUserCardSkillCardView.m */, + 9B85B6D8279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.h */, + 9B85B6D9279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.m */, ); path = SubViews; sourceTree = ""; @@ -2488,6 +2616,105 @@ path = Protocol; sourceTree = ""; }; + 9B92A34B2798068700AD168F /* SkillCard */ = { + isa = PBXGroup; + children = ( + 9B92A36027980D9E00AD168F /* Api */, + 9B92A34F279806C000AD168F /* Protocol */, + 9B92A34E279806BB00AD168F /* Presenter */, + 9B92A34D279806B700AD168F /* Model */, + 9B92A34C279806B200AD168F /* View */, + 9BA8A48127C726E8000365A3 /* ThemeColor+SkillCard.h */, + 9BA8A48227C726E8000365A3 /* ThemeColor+SkillCard.m */, + ); + path = SkillCard; + sourceTree = ""; + }; + 9B92A34C279806B200AD168F /* View */ = { + isa = PBXGroup; + children = ( + 9B92A3532798090C00AD168F /* SubViews */, + 9B33E3CC27D8540C003B0E62 /* XPVoiceCardViewController.h */, + 9B33E3CD27D8540C003B0E62 /* XPVoiceCardViewController.m */, + 9B92A350279807F300AD168F /* XPSkillCardViewController.h */, + 9B92A351279807F300AD168F /* XPSkillCardViewController.m */, + 9B92A36E27981F5B00AD168F /* XPSkillCardEditViewController.h */, + 9B92A36F27981F5B00AD168F /* XPSkillCardEditViewController.m */, + 9BA8A47027C5D590000365A3 /* XPVoiceCardCircleLayer.h */, + 9BA8A47127C5D590000365A3 /* XPVoiceCardCircleLayer.m */, + ); + path = View; + sourceTree = ""; + }; + 9B92A34D279806B700AD168F /* Model */ = { + isa = PBXGroup; + children = ( + 9B73CD06279A9A8B006AF255 /* UpdateModel */, + 9B92A3672798145000AD168F /* XPSkillCardTypeModel.h */, + 9B92A3682798145000AD168F /* XPSkillCardTypeModel.m */, + 9BCF58512798FDA1008401A4 /* XPSkillCardModel.h */, + 9BCF58522798FDA1008401A4 /* XPSkillCardModel.m */, + 9BCF58542798FE86008401A4 /* XPSkillCardPropModel.h */, + 9BCF58552798FE86008401A4 /* XPSkillCardPropModel.m */, + 9B9EEF4C27C8755C006B0EB3 /* XPSkillCardResourcePropModel.h */, + 9B9EEF4D27C8755C006B0EB3 /* XPSkillCardResourcePropModel.m */, + 9B9EEF5227C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.h */, + 9B9EEF5327C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.m */, + ); + path = Model; + sourceTree = ""; + }; + 9B92A34E279806BB00AD168F /* Presenter */ = { + isa = PBXGroup; + children = ( + 9B92A3542798096000AD168F /* XPSkillCardPresenter.h */, + 9B92A3552798096000AD168F /* XPSkillCardPresenter.m */, + ); + path = Presenter; + sourceTree = ""; + }; + 9B92A34F279806C000AD168F /* Protocol */ = { + isa = PBXGroup; + children = ( + 9B92A3572798097500AD168F /* XPSkillCardProtocol.h */, + ); + path = Protocol; + sourceTree = ""; + }; + 9B92A3532798090C00AD168F /* SubViews */ = { + isa = PBXGroup; + children = ( + 9B92A35A27980A2900AD168F /* XPSkillCardHeadView.h */, + 9B92A35B27980A2900AD168F /* XPSkillCardHeadView.m */, + 9B92A3642798132600AD168F /* XPSkillCardTypeView.h */, + 9B92A3652798132600AD168F /* XPSkillCardTypeView.m */, + 9B92A36B2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.h */, + 9B92A36C2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.m */, + 9BCF585A279909D7008401A4 /* XPSkillCardEditPropCell.h */, + 9BCF585B279909D7008401A4 /* XPSkillCardEditPropCell.m */, + 9BCF585D27995363008401A4 /* XPSkillCardSelectPropView.h */, + 9BCF585E27995363008401A4 /* XPSkillCardSelectPropView.m */, + 9BCF586027995426008401A4 /* XPSkillCardSelectPropCell.h */, + 9BCF586127995426008401A4 /* XPSkillCardSelectPropCell.m */, + 9B73CD0F279AE99B006AF255 /* XPSkillCardListCell.h */, + 9B73CD10279AE99B006AF255 /* XPSkillCardListCell.m */, + 9B7D8855279C099C00785A25 /* XPSkillCardListPropCell.h */, + 9B7D8856279C099C00785A25 /* XPSkillCardListPropCell.m */, + 9BA8A47E27C65098000365A3 /* XPSkillCardVoiceView.h */, + 9BA8A47F27C65098000365A3 /* XPSkillCardVoiceView.m */, + ); + path = SubViews; + sourceTree = ""; + }; + 9B92A36027980D9E00AD168F /* Api */ = { + isa = PBXGroup; + children = ( + 9B92A36127980DCC00AD168F /* Api+SkillCard.h */, + 9B92A36227980DCC00AD168F /* Api+SkillCard.m */, + ); + path = Api; + sourceTree = ""; + }; BFB922F5D81845AC32D1E1ED /* Frameworks */ = { isa = PBXGroup; children = ( @@ -2746,6 +2973,7 @@ E82325ED274E2D8E003A3332 /* View */ = { isa = PBXGroup; children = ( + 9B85B6D4279FDAA900A0A1AC /* SubViews */, E82325FD274E48D0003A3332 /* Cell */, E82325F0274E2DE6003A3332 /* XPUserCardViewController.h */, E82325F1274E2DE6003A3332 /* XPUserCardViewController.m */, @@ -4055,6 +4283,7 @@ children = ( E896EF912771AA6C00AD2CC1 /* Friend */, 9BC5C8EA277AFEDC007C8719 /* Noble */, + 9B92A34B2798068700AD168F /* SkillCard */, 9B92A33D2797ED4600AD168F /* MatchManage */, E83953232769FF2400CF2F24 /* DressUp */, E8E70D8026F2F3C500F03460 /* Cell */, @@ -4382,6 +4611,7 @@ E8ACEFEF27C8C45100F66D1A /* XPHomeHapppyRoomTableViewCell.m in Sources */, E84BF7DA277C72AC00EF8877 /* XPRoomRoleTableViewCell.m in Sources */, E839532D276A030F00CF2F24 /* XPMineDressUpListViewController.m in Sources */, + 9B9EEF5427C8AFEA006B0EB3 /* XPSkillCardRecordPropModel.m in Sources */, E8B846D826FDE17300A777FE /* XPMineRechargeProtocol.h in Sources */, E82D5C7D276B343300858D6D /* YYAnimatedImageView+ImageShow.m in Sources */, E8B846C726FDB45000A777FE /* XPMineUserInfoAlbumProtocol.h in Sources */, @@ -4407,6 +4637,7 @@ E824543826F5820A00BE8163 /* XPLoginVerifBindPhonePresenter.m in Sources */, E8B846BF26FD827900A777FE /* XPMineUserInfoAlbumViewController.m in Sources */, E824545C26F5EEBA00BE8163 /* XPMineVerifIdentityPresenter.m in Sources */, + 9B92A3562798096000AD168F /* XPSkillCardPresenter.m in Sources */, E8A1E44E2761F98600B294CA /* XPCandyTreeViewController.m in Sources */, E8899C852785CC69007944BE /* XPRoomDatingAnimationView.m in Sources */, E84BF7D4277C383700EF8877 /* XPRoomSettingInputView.m in Sources */, @@ -4419,6 +4650,7 @@ E8C6FFD72754BC61004DC9F0 /* XPHomeNavView.m in Sources */, E8AC723226F49710007D6E91 /* XPMineNotificationTableViewCell.m in Sources */, E8AC722926F488DA007D6E91 /* XPMineFeedbackProtocol.h in Sources */, + 9BCF58562798FE86008401A4 /* XPSkillCardPropModel.m in Sources */, E8AC721E26F472BF007D6E91 /* XPMineSettingProtocol.h in Sources */, 9BC5C91F277C902B007C8719 /* XPReleaseRadioView.m in Sources */, E83DB47A27462C4500D8CBD1 /* XPGiftBigPrizeModel.m in Sources */, @@ -4432,6 +4664,7 @@ E8EEB8F726FC2673007C6EBA /* UserPhoto.m in Sources */, E81C27A226EF23490031E639 /* XPEnum.h in Sources */, 9BB54966278303EB0090CD26 /* XPNobleCenterNavView.m in Sources */, + 9B92A36327980DCC00AD168F /* Api+SkillCard.m in Sources */, E88B5CB526FB20B800DA9178 /* XPMineTeenagerPwdView.m in Sources */, E81C279826EB3AC40031E639 /* LoginForgetPasswordProtocol.h in Sources */, E8C6FFD42754AA87004DC9F0 /* XPNoteView.m in Sources */, @@ -4468,6 +4701,7 @@ E8AC723D26F4B6AA007D6E91 /* XPLoginBindPhoneResultViewController.m in Sources */, 9B2A12D52783EEC700CED41B /* XPNobleCenterTableHeadView.m in Sources */, 9BEE3D11278584FE00C83219 /* XPNobleCenterEmptyView.m in Sources */, + 9BCF585F27995363008401A4 /* XPSkillCardSelectPropView.m in Sources */, E8A03DFC276350A60098D9EA /* XPCandyTreeGiftView.m in Sources */, 189DD73E26E21C3F00AB55B1 /* YYUtility.m in Sources */, E87A26FD27587E17002DDC7A /* HomeTagModel.m in Sources */, @@ -4514,6 +4748,7 @@ E81C27AB26EF2D920031E639 /* ThirdUserInfo.m in Sources */, E8788950273A699900BF1D57 /* ThemeColor+SendGift.m in Sources */, E81C279D26EEEC620031E639 /* XPConstant.m in Sources */, + 9B92A36D2798179B00AD168F /* XPSkillCardTypeCollectionViewCell.m in Sources */, 187EEEFE26E8A82C002833B2 /* NSObject+AutoCoding.m in Sources */, E884C36F2743AAC800E1EBED /* AttachmentModel.m in Sources */, E8AC721926F46E0B007D6E91 /* XPMineSettingItemModel.m in Sources */, @@ -4524,6 +4759,7 @@ 189DD6FF26E20E5900AB55B1 /* HttpRequestHelper.m in Sources */, E8788945273A55C200BF1D57 /* XPGiftInfoView.m in Sources */, 9BD63FAB277EE885006EB744 /* Api+RoomRadio.m in Sources */, + 9BA8A48327C726E8000365A3 /* ThemeColor+SkillCard.m in Sources */, E8AEAED6271412EC0017FCE0 /* XPRoomViewController.m in Sources */, E8E5E1A327C3730B00F457D8 /* XPHomeSectionView.m in Sources */, E8E70D9226F2F60C00F03460 /* XPMineItemModel.m in Sources */, @@ -4555,6 +4791,7 @@ 18F404C927609A4300A6C548 /* MessagePresenter.m in Sources */, 9B2A12DB2783F88800CED41B /* XPNoblePrivilegeCell.m in Sources */, E81366E326F0A1FC0076364C /* LoginBindPhoneViewController.m in Sources */, + 9B85B6DA279FDC5200A0A1AC /* XPUserCardSkillCollectionViewCell.m in Sources */, 189DD68426E1FDBB00AB55B1 /* XCHUDTool.m in Sources */, E8A6C29B27CF53BF00AC7442 /* XPHomeLikePresenter.m in Sources */, 189DD73F26E21C3F00AB55B1 /* YYUtility+Carrier.m in Sources */, @@ -4587,17 +4824,20 @@ E8412FB02779CB4D006E1101 /* XPRoomSettingPresenter.m in Sources */, E878893C273A54C300BF1D57 /* Api+Gift.m in Sources */, E81C279026EB314D0031E639 /* LoginForgetEditView.m in Sources */, + 9BA8A48027C65098000365A3 /* XPSkillCardVoiceView.m in Sources */, E8DEC9A82764A68B0078CB70 /* Api+MoreMenu.m in Sources */, E8A6C28F27CF43D600AC7442 /* XPHomeAttentionTableViewCell.m in Sources */, E8E5E19D27C36C3500F457D8 /* XPHomeMenuTableViewCell.m in Sources */, E8AC721026F43955007D6E91 /* UIImageConstant.m in Sources */, E81C27A026EEF83D0031E639 /* XPHtmlUrl.m in Sources */, E8A03DF0276303D40098D9EA /* XPCandyTreeRankTableViewCell.m in Sources */, + 9BCF58532798FDA1008401A4 /* XPSkillCardModel.m in Sources */, 18E7B1B726E8B2D10064BC9B /* Api+Main.m in Sources */, E8B846D326FDDBE600A777FE /* XPMineRechargeTableViewCell.m in Sources */, E824546126F5F4E400BE8163 /* XPMineResetPayPwdViewController.m in Sources */, E81D58822720082A003063FE /* MicroWaveView.m in Sources */, E8B825C226EA00DF009E8E9F /* LoginVerifCodePresent.m in Sources */, + 9B9EEF4E27C8755C006B0EB3 /* XPSkillCardResourcePropModel.m in Sources */, E88B5CB026FB1C6500DA9178 /* XPMineTeenagerPresenter.m in Sources */, E899C68927508F4E00E189E5 /* XPUserCardInfoModel.m in Sources */, 9B6B3AAB278C2EA7005551EC /* XPRoomNobleLevelUpView.m in Sources */, @@ -4611,11 +4851,13 @@ 189DD67E26E1FD8900AB55B1 /* UIImage+Utils.m in Sources */, E824545626F5E51900BE8163 /* XPMineVerifIdentityViewController.m in Sources */, E82D5C73276AE94800858D6D /* CarModel.m in Sources */, + 9B92A35C27980A2900AD168F /* XPSkillCardHeadView.m in Sources */, 186A534726FC6ED900D67B2C /* TTAlertConfig.m in Sources */, 18F403EE2758CF2F00A6C548 /* MessageContentImage.m in Sources */, 18E7B31E26F0984C0064BC9B /* UserLevelVo.m in Sources */, E82D5C7A276B25D100858D6D /* SpriteSheetImageManager.m in Sources */, E874B88B27215EAF003954B9 /* MicroQueueModel.m in Sources */, + 9B92A3662798132600AD168F /* XPSkillCardTypeView.m in Sources */, E8EE827D272B9A2300A17217 /* XPRoomSendTextView.m in Sources */, 9BD63FAE277EE97A006EB744 /* XPReleaseRadioPresenter.m in Sources */, E8EEB90626FC5772007C6EBA /* XPMineUserInfoEditViewController.m in Sources */, @@ -4639,6 +4881,8 @@ 18F404C3276098F100A6C548 /* Api+Message.m in Sources */, E8C6FFED27550CC2004DC9F0 /* HomeSearchResultModel.m in Sources */, 9BB549592782E6A30090CD26 /* XPNobleCenterPresenter.m in Sources */, + 9B85B6D7279FDABA00A0A1AC /* XPUserCardSkillCardView.m in Sources */, + 9B33E3CB27D85379003B0E62 /* UploadFile.m in Sources */, E8AEAEF327141C7C0017FCE0 /* XPRoomMessageContainerView.m in Sources */, E8C6FFE02754EEF9004DC9F0 /* XPHomeSearchViewController.m in Sources */, E8AE427327153A3500BEEBB2 /* XPRoomActivityContainerView.m in Sources */, @@ -4651,6 +4895,7 @@ E896EFA62771AEDD00AD2CC1 /* XPMineFansTableViewCell.m in Sources */, E8E7DAEB2745158500C631CC /* XPGiftUserInfoModel.m in Sources */, E83DB487274670DA00D8CBD1 /* XPRoomGiftBroadCastModel.m in Sources */, + 9BCF585C279909D7008401A4 /* XPSkillCardEditPropCell.m in Sources */, E8AC722C26F49580007D6E91 /* XPMineNotificaViewController.m in Sources */, 189DD52E26DE255300AB55B1 /* AppDelegate.m in Sources */, E83DB4842746661800D8CBD1 /* XPRoomGiftBroadcastView.m in Sources */, @@ -4658,17 +4903,19 @@ 9BC5B58727915CF6004960AE /* XPGlobalMessageManager.m in Sources */, E8A1E4572762092700B294CA /* XPCandyTreePresenter.m in Sources */, E86596542701A55500846EBD /* StatisticsServiceHelper.m in Sources */, - E8E70D8C26F2F5A500F03460 /* XPMineMatchCollectionViewCell.m in Sources */, + E8E70D8C26F2F5A500F03460 /* XPMineHeadItemCollectionViewCell.m in Sources */, 9B17F71827BD150600440843 /* SVGAParserManager.m in Sources */, E80DE40D2775ABA500BE5BCB /* XPFirstRechargeFlowLayout.m in Sources */, E896EFA22771AE9400AD2CC1 /* XPMineFriendViewController.m in Sources */, E8E70D8C26F2F5A500F03460 /* XPMineHeadItemCollectionViewCell.m in Sources */, + 9B92A352279807F300AD168F /* XPSkillCardViewController.m in Sources */, 186A534A26FC6ED900D67B2C /* TTActionSheetConfig.m in Sources */, 9BBC028B2786E05A0007C24B /* XPNobleCenterEntranceView.m in Sources */, E81C279326EB394D0031E639 /* LoginForgetPasswordViewController.m in Sources */, E81C278D26EAFAF60031E639 /* DESEncrypt.m in Sources */, E81366E726F0A49E0076364C /* NSString+Utils.m in Sources */, E87A26F627587C48002DDC7A /* XPHomePartyContainerViewController.m in Sources */, + 9BA8A47D27C63E20000365A3 /* XPSkillCardUpdatePropDetailModel.m in Sources */, E8EEB90126FC31B6007C6EBA /* XPMineUserInfoPresenter.m in Sources */, 18F404BB2760982000A6C548 /* ChatLimitModel.m in Sources */, 9B92A33C2797E38100AD168F /* XPMineHeadItemTableViewCell.m in Sources */, @@ -4679,6 +4926,7 @@ E84150C227747BF700A7F548 /* FirstRechargeModel.m in Sources */, E8A1E4512762082A00B294CA /* Api+CandyTree.m in Sources */, E839533C276A0CCD00CF2F24 /* XPMineCarTableViewCell.m in Sources */, + 9B33E3D127D8542D003B0E62 /* CommonFileUtils.m in Sources */, E8EEB8FE26FC2DF8007C6EBA /* XPMineUserInfoCustomNavView.m in Sources */, E839532A276A002800CF2F24 /* XPMineDressUpViewController.m in Sources */, E88B5CAD26FB16A800DA9178 /* XPMineTeenagerDesView.m in Sources */, @@ -4712,6 +4960,7 @@ 9B7B605B27BB53060070BB72 /* XPAnchorAudienceUpMicView.m in Sources */, E8B825BF26E9E57D009E8E9F /* LoginTicketInfo.m in Sources */, E8E5E18E27C3331E00F457D8 /* XPHomeRecommendViewController.m in Sources */, + 9B73CD05279A9A6A006AF255 /* XPSkillCardSaveModel.m in Sources */, E8E7DAE82744F5EF00C631CC /* XPGiftStorage.m in Sources */, E87AE7FC277AAC450037823A /* XPRoomTagPresenter.m in Sources */, E878894C273A607C00BF1D57 /* XPGiftUserCollectionViewCell.m in Sources */, @@ -4740,10 +4989,13 @@ E8DEC9AC2764A6CD0078CB70 /* XPRoomMoreMenuCollectionViewCell.m in Sources */, 9B7D804A2753783D003DAC0C /* SessionViewController.m in Sources */, E839533F276A0CDB00CF2F24 /* XPMineNameplateTableViewCell.m in Sources */, + 9B73CD11279AE99B006AF255 /* XPSkillCardListCell.m in Sources */, E8B846BC26FD7C1200A777FE /* UploadImage.m in Sources */, 9BCE6144277D657600CC0358 /* XPReleaseRadioTableViewCell.m in Sources */, 186A534D26FC6ED900D67B2C /* TTActionSheetView.m in Sources */, + 9B7D8857279C099C00785A25 /* XPSkillCardListPropCell.m in Sources */, E83DB481274649FB00D8CBD1 /* XPGiftBannerUserInfoModel.m in Sources */, + 9B33E3CE27D8540C003B0E62 /* XPVoiceCardViewController.m in Sources */, E878893F273A54F500BF1D57 /* XPGiftPresenter.m in Sources */, E8A03DF62763367F0098D9EA /* XPCandyTreeEmptyableViewCell.m in Sources */, E8AEAEED27141AE20017FCE0 /* XPRoomBackContainerView.m in Sources */, @@ -4759,6 +5011,7 @@ 189DD74526E21CCC00AB55B1 /* YYReachability.m in Sources */, E82109AD26F1C8A000FC3319 /* CountDownHelper.m in Sources */, E8A6C28C27CF436300AC7442 /* XPHomeLikeViewController.m in Sources */, + 9BCF586227995426008401A4 /* XPSkillCardSelectPropCell.m in Sources */, E8E70D8F26F2F5DB00F03460 /* XPMineMenuTableViewCell.m in Sources */, E8E5E1A927C3850400F457D8 /* XPHomeHotRoomCollectionViewCell.m in Sources */, 187EEEE126E89BFB002833B2 /* AccountModel.m in Sources */, @@ -4801,6 +5054,7 @@ 9BC5C8F6277B0263007C8719 /* XPNobleCenterListViewController.m in Sources */, 189DD75926E6003C00AB55B1 /* Api.m in Sources */, E87C0A9D27D9986700CB2241 /* XPRoomFaceCollectionFlowLayout.m in Sources */, + 9B92A37027981F5B00AD168F /* XPSkillCardEditViewController.m in Sources */, E8133916273E532D00708B66 /* XPGiftItemCollectionViewCell.m in Sources */, E833ED0D274FAD1C00A2463B /* XPKickUserModel.m in Sources */, E8788934273A53D700BF1D57 /* XPSendGiftView.m in Sources */, @@ -4811,6 +5065,7 @@ E838D9A0275E1BF60079E0B5 /* XPRoomAnimationView.m in Sources */, 9B0086C627BA392B0032BD2B /* AnchorStageView.m in Sources */, 9BCD02C72796C02800F396AA /* MicroNobleWaveView.m in Sources */, + 9B73CD09279A9AA2006AF255 /* XPSkillCardUpdatePropModel.m in Sources */, E874B88827215D39003954B9 /* MicroStateModel.m in Sources */, E877A7F427842EF800EFACED /* XPRoomDatingVipUpMicView.m in Sources */, E896EF9F2771AE7B00AD2CC1 /* XPMineAttentionViewController.m in Sources */, @@ -4823,8 +5078,10 @@ E81C1B2C27706E5C0020D1E4 /* ArrangeMicModel.m in Sources */, E87E91522796A15500A7B3F2 /* MicroExtModel.m in Sources */, E8788948273A55D000BF1D57 /* XPGiftBarView.m in Sources */, + 9BA8A47227C5D590000365A3 /* XPVoiceCardCircleLayer.m in Sources */, 9BAA5FF0277A23F4007453F3 /* XPPermissionsViewController.m in Sources */, E8412FA92779C2ED006E1101 /* XPRoomSettingItemModel.m in Sources */, + 9B92A3692798145000AD168F /* XPSkillCardTypeModel.m in Sources */, 189DD58F26DF97E700AB55B1 /* LoginPresenter.m in Sources */, E896EFB22771C93B00AD2CC1 /* XPMineFriendNumberView.m in Sources */, 9BB5495F2782E9DB0090CD26 /* NobleAuthInfo.m in Sources */, diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/Contents.json new file mode 100644 index 00000000..05bea885 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_add_large@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_add_large@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@2x.png new file mode 100644 index 00000000..65a4ae55 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@3x.png new file mode 100644 index 00000000..d5c48636 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_large.imageset/skillCard_add_large@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/Contents.json new file mode 100644 index 00000000..b4a19273 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_add_mini@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_add_mini@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@2x.png new file mode 100644 index 00000000..cb55e68b Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@3x.png new file mode 100644 index 00000000..4f03147e Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_add_mini.imageset/skillCard_add_mini@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/Contents.json new file mode 100644 index 00000000..603c47ba --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_arrow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_arrow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@2x.png new file mode 100644 index 00000000..c9fa0f86 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@3x.png new file mode 100644 index 00000000..1f1d555e Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_arrow.imageset/skillCard_arrow@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/Contents.json new file mode 100644 index 00000000..162d802a --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_edit@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_edit@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@2x.png new file mode 100644 index 00000000..0e321dac Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@3x.png new file mode 100644 index 00000000..19ea9fea Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_edit.imageset/skillCard_edit@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/Contents.json new file mode 100644 index 00000000..48244dee --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_voice_bg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_voice_bg@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@2x.png new file mode 100644 index 00000000..e5e6c9e7 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@3x.png new file mode 100644 index 00000000..e9a39542 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_bg.imageset/skillCard_voice_bg@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/Contents.json new file mode 100644 index 00000000..7234c2e7 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_voice_pause@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_voice_pause@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@2x.png new file mode 100644 index 00000000..33c3919d Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@3x.png new file mode 100644 index 00000000..bb382839 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_pause.imageset/skillCard_voice_pause@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/Contents.json new file mode 100644 index 00000000..9a8f2cdc --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_voice_play@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_voice_play@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@2x.png new file mode 100644 index 00000000..a9c14e23 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@3x.png new file mode 100644 index 00000000..1d3d79c8 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_play.imageset/skillCard_voice_play@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/Contents.json new file mode 100644 index 00000000..c0570e74 --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_voice_record_normal@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_voice_record_normal@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@2x.png new file mode 100644 index 00000000..e48ce00f Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@3x.png new file mode 100644 index 00000000..8f22cc1a Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_normal.imageset/skillCard_voice_record_normal@3x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/Contents.json b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/Contents.json new file mode 100644 index 00000000..8c6c741e --- /dev/null +++ b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "skillCard_voice_record_selected@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "skillCard_voice_record_selected@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@2x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@2x.png new file mode 100644 index 00000000..299c4320 Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@2x.png differ diff --git a/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@3x.png b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@3x.png new file mode 100644 index 00000000..a63aa43f Binary files /dev/null and b/xplan-ios/Assets.xcassets/Mine/SkillCard/skillCard_voice_record_selected.imageset/skillCard_voice_record_selected@3x.png differ diff --git a/xplan-ios/Base/MVP/Model/UserInfoModel.h b/xplan-ios/Base/MVP/Model/UserInfoModel.h index bd864fe8..4d497b3c 100644 --- a/xplan-ios/Base/MVP/Model/UserInfoModel.h +++ b/xplan-ios/Base/MVP/Model/UserInfoModel.h @@ -89,6 +89,9 @@ NS_ASSUME_NONNULL_BEGIN ///麦位昵称颜色 @property (nonatomic, copy) NSString *micNickColor; +///技能卡图标列表 +@property (nonatomic, strong) NSArray *absCardPics; + @end NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/Net/HttpRequestHelper.h b/xplan-ios/Base/Net/HttpRequestHelper.h index 8a8df6d1..3cfb33eb 100644 --- a/xplan-ios/Base/Net/HttpRequestHelper.h +++ b/xplan-ios/Base/Net/HttpRequestHelper.h @@ -50,6 +50,15 @@ success:(void (^)(BaseModel *data))success params:(NSDictionary *)params completion:(HttpRequestHelperCompletion)completion; + +/// 增加或编辑技能卡专用接口 Post 请求参数放入到 body 里 使用 application/json 类型传递 +/// @param path 请求地址 +/// @param params 参数 +/// @param completion 回调 ++ (void)postSkillCard:(NSString *)path + params:(NSString *)params + completion:(HttpRequestHelperCompletion)completion; + @end NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/Net/HttpRequestHelper.m b/xplan-ios/Base/Net/HttpRequestHelper.m index 6e694f18..7f858760 100644 --- a/xplan-ios/Base/Net/HttpRequestHelper.m +++ b/xplan-ios/Base/Net/HttpRequestHelper.m @@ -220,4 +220,87 @@ } } +/// 增加或编辑技能卡专用接口 Post 请求参数放入到 body 里 使用 application/json 类型传递 +/// @param path 请求地址 +/// @param params 参数 +/// @param completion 回调 ++ (void)postSkillCard:(NSString *)path + params:(NSString *)params + completion:(HttpRequestHelperCompletion)completion{ + + if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == 0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + completion(nil, -1, @"请检查网络连接。"); + }); + return; + } + + [self configHeaders]; + NSDictionary *baseParams = [self configBaseParmars:nil]; +#ifdef DEBUG +// NSLog(@"\nmethod:\n%@\nparameter:\n%@", method, params); +#endif + + AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; + NSString *url = API_HOST_URL; + NSString *urlPath = [NSString stringWithFormat:@"%@/%@", url ,path]; + + #ifdef DEBUG + NSLog(@"url:%@,parameter:%@",urlPath, baseParams); + #endif + + __block NSString *requestUrl = @""; + [baseParams.allKeys enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *value = baseParams[obj]; + requestUrl = [requestUrl stringByAppendingString:[NSString stringWithFormat:@"%@=%@&", obj, value]]; + }]; + + urlPath = [NSString stringWithFormat:@"%@?%@", urlPath, requestUrl]; + + NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:urlPath parameters:baseParams error:nil]; + request.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue]; + + [request setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; + + if ([[AccountInfoStorage instance] getUid].length > 0) { + [request setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"]; + [manager.requestSerializer setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"]; + } else { + [request setValue:nil forHTTPHeaderField:@"pub_uid"]; + } + if ([[AccountInfoStorage instance] getTicket].length > 0) { + [request setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"]; + [manager.requestSerializer setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"]; + }else { + [request setValue:nil forHTTPHeaderField:@"pub_ticket"]; + } + + NSError *error; + + [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; + + [[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { + if (responseObject) { + BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject]; + #ifdef DEBUG + NSLog(@"\n%@", [baseModel toJSONString]); + #endif + if (baseModel.code == 200) { + if (completion) { + completion(baseModel, 200, nil); + } + } else { + if (completion) { + completion(nil, baseModel.code, baseModel.message); + } + } + } + if (error) { + [self handleNetError:error failure:^(NSInteger resCode, NSString *message) { + completion(nil, resCode, message); + }]; + } + }] resume]; +} + @end diff --git a/xplan-ios/Base/Tool/File/CommonFileUtils.h b/xplan-ios/Base/Tool/File/CommonFileUtils.h new file mode 100644 index 00000000..1f305c8d --- /dev/null +++ b/xplan-ios/Base/Tool/File/CommonFileUtils.h @@ -0,0 +1,89 @@ +// +// CommonFileUtils.h +// Commons +// +// Created by 小城 on 14-6-5. +// Copyright (c) 2014年 YY Inc. All rights reserved. +// + +#import + +@interface CommonFileUtils : NSObject + +/**Some FilePaths + */ ++ (NSString *)documentsDirectory; ++ (NSString *)cachesDirectory; + +/** + * File Operation + */ + +/** + * 创建文件所在的目录 + * + * @param path 文件的绝对路径 + * + * @return 是否创建成功 + */ ++ (BOOL)createDirForPath:(NSString *)path; + +/** + * 创建目录 + * + * @param dirPath 目录绝对路径 + * + * @return 是否创建成功 + */ ++ (BOOL)createDirWithDirPath:(NSString *)dirPath; + +/** + * 删除文件 + * + * @param path 文件所在的绝对路径 + * + * @return 是否删除成功 + */ ++ (BOOL)deleteFileWithFullPath:(NSString *)path; + +/** + * 指定路径的文件是否存在 + * + * @param filePath 文件的绝对路径 + * + * @return 是否存在 + */ ++ (BOOL)isFileExists:(NSString *)filePath; + +/** + * 在文件的末尾追加文本内容 + * + * @param content 文本内容 + * @param filePath 文件绝对路径,比如保证该文件是存在的,返回会返回NO + * + * @return 是否追加成功 + */ ++ (BOOL)appendContent:(NSString *)content toFilePath:(NSString *)filePath; + + +/**FileUtils In UserDefault + */ ++ (BOOL)writeObject:(id)object toUserDefaultWithKey:(NSString*)key; ++ (id)readObjectFromUserDefaultWithKey:(NSString*)key; ++ (BOOL)deleteObjectFromUserDefaultWithKey:(NSString*)key; + +/**FileUtils In CachesPath + */ ++ (void)writeObject:(id)object toCachesPath:(NSString*)path; ++ (id)readObjectFromCachesPath:(NSString*)path; ++ (BOOL)deleteFileFromCachesPath:(NSString *)path; + +/**FileUtils In DocumentPath + */ ++ (void)writeObject:(id)object toDocumentPath:(NSString *)path; ++ (id)readObjectFromDocumentPath:(NSString *)path; ++ (BOOL)deleteFileFromDocumentPath:(NSString *)path; + ++ (BOOL)copyItem:(NSString *)destination toPath:(NSString *)toPath; + +@end diff --git a/xplan-ios/Base/Tool/File/CommonFileUtils.m b/xplan-ios/Base/Tool/File/CommonFileUtils.m new file mode 100644 index 00000000..7be9bb67 --- /dev/null +++ b/xplan-ios/Base/Tool/File/CommonFileUtils.m @@ -0,0 +1,273 @@ +// +// CommonFileUtils.m +// Commons +// +// Created by 小城 on 14-6-5. +// Copyright (c) 2014年 YY Inc. All rights reserved. +// + +#import "CommonFileUtils.h" +#import + +@implementation CommonFileUtils + ++ (NSString *)documentsDirectory +{ + static NSString *docsDir = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; + }); + return docsDir; +} + ++ (NSString *)cachesDirectory +{ + static NSString *cachesDir = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; + }); + return cachesDir; +} + ++ (BOOL)createDirForPath:(NSString *)path +{ + return [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; +} + ++ (BOOL)createDirWithDirPath:(NSString *)dirPath +{ + return [[NSFileManager defaultManager] createDirectoryAtPath:dirPath + withIntermediateDirectories:YES + attributes:nil + error:nil]; +} + ++ (BOOL)deleteFileWithFullPath:(NSString *)fullPath +{ + BOOL deleteSucc = NO; + if ([[NSFileManager defaultManager] isDeletableFileAtPath:fullPath]) { + deleteSucc = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:NULL]; + } + + return deleteSucc; +} + + +/**UserDefault + */ ++ (BOOL)writeObject:(id)object toUserDefaultWithKey:(NSString*)key +{ + if (object == nil || key == nil) return NO; + + NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:object]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:myEncodedObject forKey:key]; + return [defaults synchronize]; +} + ++ (id)readObjectFromUserDefaultWithKey:(NSString*)key +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSData *myEncodedObject = [defaults objectForKey:key]; + + if (myEncodedObject == nil) { + return nil; + } + + @try { + return [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject]; + } + @catch (NSException *e){ + return nil; + } +} + ++ (BOOL)deleteObjectFromUserDefaultWithKey:(NSString*)key +{ + if (!key) { + return NO; + } + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults removeObjectForKey:key]; + return [defaults synchronize]; +} + ++ (BOOL)isFileExists:(NSString *)filePath +{ + return [[NSFileManager defaultManager] fileExistsAtPath:filePath]; +} + ++ (BOOL)appendContent:(NSString *)content toFilePath:(NSString *)filePath +{ + if (![CommonFileUtils isFileExists:filePath]) { + return NO; + } + + BOOL appendSucc = YES; + + NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; + if (!fileHandle) { + appendSucc = NO; + } else { + [fileHandle seekToEndOfFile]; + [fileHandle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]]; + [fileHandle closeFile]; + } + + return appendSucc; +} + + +/**CachesPath + */ ++ (void)writeObject:(id)object toCachesPath:(NSString*)path +{ + if (object == nil || [path length] == 0) + return; + + NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path]; + [CommonFileUtils _writeObject:object toPath:fullPath]; +} + ++ (id)readObjectFromCachesPath:(NSString*)path +{ + if ([path length] == 0) + return nil; + + NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path]; + return [CommonFileUtils _readObjectFromPath:fullPath]; +} + ++ (BOOL)deleteFileFromCachesPath:(NSString *)path +{ + NSString *fullPath = [[CommonFileUtils cachesDirectory] stringByAppendingPathComponent:path]; + return [CommonFileUtils deleteFileWithFullPath:fullPath]; +} + +/**DocumentPath + */ ++ (void)writeObject:(id)object toDocumentPath:(NSString *)path +{ + if (object == nil || [path length] == 0) + return; + + NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path]; + [CommonFileUtils _writeObject:object toPath:fullPath]; + +} + ++ (id)readObjectFromDocumentPath:(NSString *)path +{ + if ([path length] == 0) + return nil; + + NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path]; + return [CommonFileUtils _readObjectFromPath:fullPath]; +} + ++ (BOOL)deleteFileFromDocumentPath:(NSString *)path +{ + NSString *fullPath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:path]; + return [CommonFileUtils deleteFileWithFullPath:fullPath]; +} + ++ (BOOL)copyItem:(NSString *)destination toPath:(NSString *)toPath +{ + NSError *error = nil; + [[NSFileManager defaultManager] copyItemAtPath:destination toPath:toPath error:&error]; + return error != nil; +} + +#pragma mark - private +static id getSemaphore(NSString *key) +{ + static NSMutableDictionary *dict = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + dict = [[NSMutableDictionary alloc] initWithCapacity:10]; + }); + + id obj = [dict objectForKey:key]; + if (!obj) + { + obj = [[NSObject alloc] init]; + [dict setObject:obj forKey:key]; + } + return obj; +} + +static dispatch_queue_t getFileQueue() +{ + static dispatch_queue_t queue = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = dispatch_queue_create("FileQueue", NULL); + }); + return queue; +} + + ++ (void)_writeObject:(id)obj toPath:(NSString *)fullPath +{ + if (obj == nil || [fullPath length] == 0) + return; + + id newObj = obj; + if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]]) + { + //集合类型为了避免出现写的同时另一个线程在操作同一个集合可能导致崩溃,这里在主线程生成一个新的集合 + if ([obj isKindOfClass:[NSMutableArray class]]) + newObj = [NSMutableArray arrayWithArray:obj]; + else if ([obj isKindOfClass:[NSArray class]]) + newObj = [NSArray arrayWithArray:obj]; + else if ([obj isKindOfClass:[NSMutableDictionary class]]) + newObj = [NSMutableDictionary dictionaryWithDictionary:obj]; + else + newObj = [NSDictionary dictionaryWithDictionary:obj]; + } + + id sema = getSemaphore(fullPath); + + //在queue中操作 + dispatch_async(getFileQueue(), ^{ + @synchronized(sema) + { + //必须先创建目录,否则archiveRootObject操作在没有目录的情况下会失败! + if ([CommonFileUtils createDirForPath:fullPath]) + { + [NSKeyedArchiver archiveRootObject:newObj toFile:fullPath]; + } +// else +// { + +// } + } + }); +} + ++ (id)_readObjectFromPath:(NSString *)fullPath +{ + id sema = getSemaphore(fullPath); + + if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) + { + @try + { + @synchronized(sema) + { + return [NSKeyedUnarchiver unarchiveObjectWithFile:fullPath]; + } + } + @catch (NSException *e) + { + return nil; + } + } + else + return nil; +} + +@end diff --git a/xplan-ios/Base/Tool/File/UploadFile.h b/xplan-ios/Base/Tool/File/UploadFile.h new file mode 100644 index 00000000..335b0536 --- /dev/null +++ b/xplan-ios/Base/Tool/File/UploadFile.h @@ -0,0 +1,28 @@ +// +// UploadFile.h +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UploadFile : NSObject + +/// 上传一个文件 +/// @param filePath 文件地址 +/// @param fileName 文件的名字 +/// @param token token +/// @param success 成功 +/// @param failure 失败 ++ (void)uploadFile:(NSString *)filePath + named:(NSString *)fileName + token:(NSString *)token + success:(void (^)(NSString *key, NSDictionary *resp))success + failure:(void (^)(NSNumber *resCode, NSString *message))failure; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Base/Tool/File/UploadFile.m b/xplan-ios/Base/Tool/File/UploadFile.m new file mode 100644 index 00000000..1adf34d3 --- /dev/null +++ b/xplan-ios/Base/Tool/File/UploadFile.m @@ -0,0 +1,37 @@ +// +// UploadFile.m +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import "UploadFile.h" +#import + +@implementation UploadFile + +/// 上传一个文件 +/// @param filePath 文件地址 +/// @param fileName 文件的名字 +/// @param token token +/// @param success 成功 +/// @param failure 失败 ++ (void)uploadFile:(NSString *)filePath + named:(NSString *)fileName + token:(NSString *)token + success:(void (^)(NSString *key, NSDictionary *resp))success + failure:(void (^)(NSNumber *resCode, NSString *message))failure { + QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { + builder.zone = [QNFixedZone zone2]; + }]; + QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; + [upManager putFile:filePath key:fileName token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { + if (resp) { + success(key,resp); + }else{ + failure(@(info.statusCode),info.error.localizedDescription); + } + } option:nil]; +} + +@end diff --git a/xplan-ios/Base/UI/ThemeColor.h b/xplan-ios/Base/UI/ThemeColor.h index c435a76b..a524d8b8 100644 --- a/xplan-ios/Base/UI/ThemeColor.h +++ b/xplan-ios/Base/UI/ThemeColor.h @@ -49,6 +49,8 @@ NS_ASSUME_NONNULL_BEGIN + (UIColor *)cancelButtonGradientEndColor; /// 取消的按钮文字颜色 0xFFA936 + (UIColor *)cancelButtonTextColor; +/// 取消按钮单一普通背景色 0xFFCE4E ++ (UIColor *)cancelButtonNormalBgColor; /// 按钮不可点击背景色 0xD2D5D7 + (UIColor *)disableButtonColor; /// 按钮不可点击文字颜色 0xF9F9F9 diff --git a/xplan-ios/Base/UI/ThemeColor.m b/xplan-ios/Base/UI/ThemeColor.m index 2462ff70..3b9db260 100644 --- a/xplan-ios/Base/UI/ThemeColor.m +++ b/xplan-ios/Base/UI/ThemeColor.m @@ -80,6 +80,10 @@ + (UIColor *)cancelButtonTextColor { return UIColorFromRGB(0xFFA936); } +/// 取消按钮单一普通背景色 0xFFCE4E ++ (UIColor *)cancelButtonNormalBgColor { + return UIColorRGBAlpha(0xFFCE4E, 0.3); +} /// 按钮不可点击背景色 0xD2D5D7 + (UIColor *)disableButtonColor { return UIColorFromRGB(0xD2D5D7); diff --git a/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.h b/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.h new file mode 100644 index 00000000..e316c57e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.h @@ -0,0 +1,47 @@ +// +// Api+SkillCard.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "Api.h" +#import "XPSkillCardSaveModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Api (SkillCard) + +/// 技能卡列表 +/// @param completion 完成 +/// @param uid 用户的uid ++ (void)requestSkillCardList:(HttpRequestHelperCompletion)completion + uid:(NSString *)uid; + +/// 未添加的所有卡片种类信息 +/// @param completion 完成 ++ (void)requestSkillCardTypeList:(HttpRequestHelperCompletion)completion; + +/// 获取默认技能卡信息 +/// @param completion 完成 +/// @param cardId 技能卡id ++ (void)requestdefaultSkillCardDetail:(HttpRequestHelperCompletion)completion cardId:(NSString *)cardId; + +/// 获取可编辑的技能卡信息 +/// @param completion 完成 +/// @param id 技能卡记录id ++ (void)requestSkillCardDetail:(HttpRequestHelperCompletion)completion id:(NSString *)cardId; + +/// 保存技能卡 +/// @param completion 完成 +/// @param skillCardRecordVo 技能卡信息 ++ (void)requestSaveSkillCard:(HttpRequestHelperCompletion)completion skillCardRecordVo:(XPSkillCardSaveModel *)skillCardRecordVo; + +/// 删除技能卡 +/// @param completion 完成 +/// @param id 技能卡id ++ (void)requestDeleteSkillCard:(HttpRequestHelperCompletion)completion id:(NSString *)cardId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.m b/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.m new file mode 100644 index 00000000..7cb00b2f --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Api/Api+SkillCard.m @@ -0,0 +1,54 @@ +// +// Api+SkillCard.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "Api+SkillCard.h" + +@implementation Api (SkillCard) + +/// 技能卡列表 +/// @param completion 完成 +/// @param uid 用户的uid ++ (void)requestSkillCardList:(HttpRequestHelperCompletion)completion + uid:(NSString *)uid { + [self makeRequest:@"skillCard/getUserAllSkillCardDetail" method:HttpRequestHelperMethodGET completion:completion, __FUNCTION__, uid, nil]; +} + +/// 未添加的所有卡片种类信息 +/// @param completion 完成 ++ (void)requestSkillCardTypeList:(HttpRequestHelperCompletion)completion { + [self makeRequest:@"skillCard/getTypeList" method:HttpRequestHelperMethodGET completion:completion, __FUNCTION__, nil]; +} + +/// 获取默认技能卡信息 +/// @param completion 完成 +/// @param cardId 技能卡id ++ (void)requestdefaultSkillCardDetail:(HttpRequestHelperCompletion)completion cardId:(NSString *)cardId { + [self makeRequest:@"skillCard/getCardInfoById" method:HttpRequestHelperMethodGET completion:completion, __FUNCTION__, cardId, nil]; +} + +/// 获取技能卡信息 +/// @param completion 完成 +/// @param id 技能卡id ++ (void)requestSkillCardDetail:(HttpRequestHelperCompletion)completion id:(NSString *)cardId { + [self makeRequest:@"skillCard/get" method:HttpRequestHelperMethodGET completion:completion, __FUNCTION__, cardId, nil]; +} + +/// 保存技能卡 +/// @param completion 完成 +/// @param skillCardRecordVo 技能卡信息 ++ (void)requestSaveSkillCard:(HttpRequestHelperCompletion)completion skillCardRecordVo:(XPSkillCardSaveModel *)skillCardRecordVo { + [HttpRequestHelper postSkillCard:@"skillCard/saveOrUpdate" params:[skillCardRecordVo toJSONString] completion:completion]; +} + +/// 删除技能卡 +/// @param completion 完成 +/// @param id 技能卡id ++ (void)requestDeleteSkillCard:(HttpRequestHelperCompletion)completion id:(NSString *)cardId { + [self makeRequest:@"skillCard/delete" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, cardId, nil]; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.h new file mode 100644 index 00000000..83210a84 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.h @@ -0,0 +1,24 @@ +// +// XPSkillCardSaveModel.h +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import +#import "XPSkillCardUpdatePropModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardSaveModel : NSObject + +///技能卡种类id +@property (nonatomic, assign) NSInteger cardId; +///技能卡记录id +@property (nonatomic, assign) NSInteger cardRecordId; + +@property (nonatomic, strong) NSMutableArray *propRecordVo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.m new file mode 100644 index 00000000..fa36427e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardSaveModel.m @@ -0,0 +1,22 @@ +// +// XPSkillCardSaveModel.m +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import "XPSkillCardSaveModel.h" + +@implementation XPSkillCardSaveModel + ++ (NSDictionary *)objectClassInArray { + return @{ + @"propRecordVo": XPSkillCardUpdatePropModel.class + }; +} + ++ (NSDictionary *)replacedKeyFromPropertyName { + return @{@"cardRecordId":@"id"}; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.h new file mode 100644 index 00000000..aaa8bdf8 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.h @@ -0,0 +1,21 @@ +// +// XPSkillCardUpdatePropDetailModel.h +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardUpdatePropDetailModel : NSObject + +///技能卡属性值 +@property (nonatomic, copy) NSString *propVal; +///技能卡id +@property (nonatomic, assign) NSInteger propId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.m new file mode 100644 index 00000000..a1534927 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropDetailModel.m @@ -0,0 +1,12 @@ +// +// XPSkillCardUpdatePropDetailModel.m +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import "XPSkillCardUpdatePropDetailModel.h" + +@implementation XPSkillCardUpdatePropDetailModel + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.h new file mode 100644 index 00000000..f89b7589 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.h @@ -0,0 +1,22 @@ +// +// XPSkillCardUpdatePropModel.h +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import +#import "XPSkillCardUpdatePropDetailModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardUpdatePropModel : NSObject + +///技能卡父类id +@property (nonatomic, assign) NSInteger parentId; + +@property (nonatomic, strong) NSMutableArray *refPropVos; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.m new file mode 100644 index 00000000..36264d9f --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/UpdateModel/XPSkillCardUpdatePropModel.m @@ -0,0 +1,18 @@ +// +// XPSkillCardUpdatePropModel.m +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import "XPSkillCardUpdatePropModel.h" + +@implementation XPSkillCardUpdatePropModel + ++ (NSDictionary *)objectClassInArray { + return @{ + @"refPropVos": XPSkillCardUpdatePropDetailModel.class + }; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.h new file mode 100644 index 00000000..391090ce --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.h @@ -0,0 +1,52 @@ +// +// XPSkillCardModel.h +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import +#import "XPSkillCardPropModel.h" +#import "XPSkillCardResourcePropModel.h" +#import "XPSkillCardRecordPropModel.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, SkillCardType) { + SkillCardTypeGame = 1, ///游戏 + SkillCardTypeTalent = 2, //才艺 + SkillCardTypeVoice = 3, //声音秀 +}; + +typedef NS_ENUM(NSUInteger, SkillCardStatusType) { + SkillCardStatusTypeDelete = 0, //删除 + SkillCardStatusTypeValid = 1,//有效 + SkillCardStatusTypeInreview = 2, //待审核 +}; + +@interface XPSkillCardModel : NSObject + +///技能卡记录id(添加技能卡后才有) +@property (nonatomic, assign) NSInteger cardRecordId; +///技能卡id +@property (nonatomic, assign) NSInteger cardId; +///技能卡所有资源属性列表 +@property (nonatomic, strong) NSArray *props; +///技能卡图片(背景图片) +@property (nonatomic, copy) NSString *pic; +///技能卡概要图片(资料卡的列表展示图片) +@property (nonatomic, copy) NSString *absCardPic; +///技能卡图标 +@property (nonatomic, copy) NSString *icon; +///技能卡名称 +@property (nonatomic, copy) NSString *name; +///技能卡类型 1游戏类 2才艺类 3声音秀 +@property (nonatomic, assign) SkillCardType type; +///技能卡添加的属性列表 +@property (nonatomic, strong) NSMutableArray *propRecordVo; +///技能卡的状态 0删除 1有效 2待审核 +@property (nonatomic, assign) SkillCardStatusType status; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.m new file mode 100644 index 00000000..1335ba80 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardModel.m @@ -0,0 +1,22 @@ +// +// XPSkillCardModel.m +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import "XPSkillCardModel.h" + +@implementation XPSkillCardModel + ++ (NSDictionary *)objectClassInArray { + return @{@"props": XPSkillCardResourcePropModel.class, + @"propRecordVo":XPSkillCardRecordPropModel.class + }; +} + ++ (NSDictionary *)replacedKeyFromPropertyName { + return @{@"cardRecordId":@"id"}; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.h new file mode 100644 index 00000000..6c80d43e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.h @@ -0,0 +1,45 @@ +// +// XPSkillCardPropModel.h +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import +#import "XPSkillCardResourcePropModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardPropModel : NSObject + +///技能卡种类id +@property (nonatomic, copy) NSString *cardId; + +//@property (nonatomic, assign) NSInteger id; +///技能卡属性id +@property (nonatomic, assign) NSInteger propId; +///是否必填 0非必填 1必填 +@property (nonatomic, assign) BOOL isMust; +///技能卡关联父标题属性id +@property (nonatomic, assign) NSInteger parentId; +///技能卡属性值 +@property (nonatomic, copy) NSString *propVal; + +@property (nonatomic, copy) NSString *parentVal; +///技能卡类别 0单选 1用户输入 2 多选 3 音频 +@property (nonatomic, assign) NSInteger state; +///技能卡属性排序值 +@property (nonatomic, assign) NSInteger seq; +///子属性id +@property (nonatomic, assign) NSInteger childPropId; +///子属性值 +@property (nonatomic, copy) NSString *childPropVal; +///技能卡多选数量限制 +@property (nonatomic, assign) NSInteger checkLimitNum; +///技能卡关联子属性集合 +@property (nonatomic, strong) NSMutableArray *refPropVos; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.m new file mode 100644 index 00000000..afbec4a2 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardPropModel.m @@ -0,0 +1,22 @@ +// +// XPSkillCardPropModel.m +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import "XPSkillCardPropModel.h" + +@implementation XPSkillCardPropModel + ++ (NSDictionary *)objectClassInArray { + return @{@"propDictVos": XPSkillCardPropModel.class, + @"refPropVos": XPSkillCardSourcePropDetailModel.class + }; +} + ++ (NSDictionary *)replacedKeyFromPropertyName { + return @{@"propId":@"id"}; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.h new file mode 100644 index 00000000..8ebf25e9 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.h @@ -0,0 +1,47 @@ +// +// XPSkillCardRecordPropModel.h +// xplan-ios +// +// Created by GreenLand on 2022/2/25. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardRecordPropDetailModel; +@interface XPSkillCardRecordPropModel : NSObject + +///技能卡属性id +@property (nonatomic, assign) NSInteger propId; +///是否必填 0非必填 1必填 +@property (nonatomic, assign) BOOL isMust; +///技能卡关联父标题属性id +@property (nonatomic, assign) NSInteger parentId; +///技能卡属性名称 +@property (nonatomic, copy) NSString *propVal; +///技能卡父属性名称 +@property (nonatomic, copy) NSString *parentVal; +///技能卡类别 0单选 1用户输入 2 多选 3 音频 +@property (nonatomic, assign) NSInteger state; +///技能卡属性排序值 +@property (nonatomic, assign) NSInteger seq; +///技能卡多选数量限制 +@property (nonatomic, assign) NSInteger checkLimitNum; +///技能卡关联子属性集合 +@property (nonatomic, strong) NSMutableArray *refPropVos; + +@end + +@interface XPSkillCardRecordPropDetailModel : NSObject + +///技能卡属性id +@property (nonatomic, assign) NSInteger propId; +///技能卡属性名称 +@property (nonatomic, copy) NSString *propVal; +///是否唯一选项 0多选 1唯一(多选时选了唯一后取消选中其他项) +@property (nonatomic, assign) NSInteger refIsOnlyCheck; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.m new file mode 100644 index 00000000..56ccf97c --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardRecordPropModel.m @@ -0,0 +1,22 @@ +// +// XPSkillCardRecordPropModel.m +// xplan-ios +// +// Created by GreenLand on 2022/2/25. +// + +#import "XPSkillCardRecordPropModel.h" +#import "NSObject+MJExtension.h" + +@implementation XPSkillCardRecordPropModel + ++ (NSDictionary *)objectClassInArray { + return @{@"refPropVos": XPSkillCardRecordPropDetailModel.class + }; +} + +@end + +@implementation XPSkillCardRecordPropDetailModel + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.h new file mode 100644 index 00000000..7cff1191 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.h @@ -0,0 +1,51 @@ +// +// XPSkillCardResourcePropModel.h +// xplan-ios +// +// Created by GreenLand on 2022/2/25. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardSourcePropDetailModel; +@interface XPSkillCardResourcePropModel : NSObject + +///技能卡种类id +@property (nonatomic, copy) NSString *cardId; +///技能卡属性id +@property (nonatomic, assign) NSInteger propId; +///是否必填 0非必填 1必填 +@property (nonatomic, assign) BOOL isMust; +///技能卡属性值 +@property (nonatomic, copy) NSString *propVal; +///技能卡类别 0单选 1用户输入 2 多选 3 音频 +@property (nonatomic, assign) NSInteger state; +///技能卡属性排序值 +@property (nonatomic, assign) NSInteger seq; +///技能卡多选数量限制 +@property (nonatomic, assign) NSInteger checkLimitNum; +///子属性资源集合 +@property (nonatomic, strong) NSArray *propDictVos; + +@end + + +@interface XPSkillCardSourcePropDetailModel : NSObject + +///技能卡属性id +@property (nonatomic, assign) NSInteger id; +///技能卡属性名称 +@property (nonatomic, copy) NSString *propVal; +///技能卡属性排序值 +@property (nonatomic, assign) NSInteger seq; +///技能卡关联父标题属性id +@property (nonatomic, assign) NSInteger parentId; +///是否唯一选项 0多选 1唯一(多选时选了唯一后取消选中其他项) +@property (nonatomic, assign) NSInteger refIsOnlyCheck; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.m new file mode 100644 index 00000000..eb4ee10b --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardResourcePropModel.m @@ -0,0 +1,26 @@ +// +// XPSkillCardResourcePropModel.m +// xplan-ios +// +// Created by GreenLand on 2022/2/25. +// + +#import "XPSkillCardResourcePropModel.h" +#import "NSObject+MJExtension.h" + +@implementation XPSkillCardResourcePropModel + ++ (NSDictionary *)objectClassInArray { + return @{@"propDictVos": XPSkillCardSourcePropDetailModel.class + }; +} + ++ (NSDictionary *)replacedKeyFromPropertyName { + return @{@"propId":@"id"}; +} + +@end + +@implementation XPSkillCardSourcePropDetailModel + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.h b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.h new file mode 100644 index 00000000..2761edee --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.h @@ -0,0 +1,23 @@ +// +// XPSkillCardTypeModel.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardTypeModel : NSObject + +///名称 +@property (nonatomic, copy) NSString *name; +//id +@property (nonatomic, assign) NSInteger cardId; +///图标 +@property (nonatomic, copy) NSString *icon; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.m b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.m new file mode 100644 index 00000000..02155701 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Model/XPSkillCardTypeModel.m @@ -0,0 +1,12 @@ +// +// XPSkillCardTypeModel.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardTypeModel.h" + +@implementation XPSkillCardTypeModel + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.h b/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.h new file mode 100644 index 00000000..6a15941d --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.h @@ -0,0 +1,42 @@ +// +// XPSkillCardPresenter.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "BaseMvpPresenter.h" + +NS_ASSUME_NONNULL_BEGIN +@class XPSkillCardSaveModel; +@interface XPSkillCardPresenter : BaseMvpPresenter + +/// 获取技能卡列表 +/// @param uid 用户uid +- (void)getSkillCardInfoWithUid:(NSString *)uid; + +///获取当前用户尚未添加的所有卡片种类信息 +- (void)getSkillCardTypeList; + +/// 获取编辑技能卡信息 +/// @param cardId 技能卡id +- (void)getSkillCardDetailWithCardId:(NSString *)cardId; + +/// 获取初始化的技能卡信息 +/// @param cardId 技能卡id +- (void)getDefaultSkillCardDetailWithCardId:(NSString *)cardId; + +///保存技能卡 +- (void)saveOrUpdateSkillCard:(XPSkillCardSaveModel *)skillCardModel; + +///删除技能卡 +///@param cardId 技能卡ID +- (void)deleteSkillCard:(NSString *)cardId; + +/// 上传声音文件 +/// @param filePath 文件路径 +- (void)uploadVoice:(NSString *)filePath; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.m b/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.m new file mode 100644 index 00000000..980e220e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Presenter/XPSkillCardPresenter.m @@ -0,0 +1,93 @@ +// +// XPSkillCardPresenter.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardPresenter.h" +// Protocol +#import "XPSkillCardProtocol.h" +// Tool +#import "Api+SkillCard.h" +#import "Api+Mine.h" +#import "UploadFile.h" +// Model +#import "XPSkillCardTypeModel.h" +#import "XPSkillCardModel.h" +#import "XPSkillCardSaveModel.h" + +@implementation XPSkillCardPresenter + +- (id)getView { + return ((id) [super getView]); +} + +/// 获取技能卡列表 +/// @param uid 用户uid +- (void)getSkillCardInfoWithUid:(NSString *)uid { + [Api requestSkillCardList:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + NSArray *array = [XPSkillCardModel modelsWithArray:data.data]; + [[self getView] onGetSkillCardListSuccess:array]; + } showLoading:YES] uid:uid]; +} + +///获取当前用户尚未添加的所有卡片种类信息 +- (void)getSkillCardTypeList { + [Api requestSkillCardTypeList:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + NSArray *array = [XPSkillCardTypeModel modelsWithArray:data.data]; + [[self getView] onGetSkillCardTypeListSuccess:array]; + } showLoading:YES]]; +} + +/// 获取初始化的技能卡信息 +/// @param cardId 技能卡id +- (void)getDefaultSkillCardDetailWithCardId:(NSString *)cardId { + [Api requestdefaultSkillCardDetail:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + XPSkillCardModel *model = [XPSkillCardModel modelWithDictionary:data.data]; + [[self getView] onGetDefaultSkillCardInfoSuccess:model]; + } showLoading:YES] cardId:cardId]; +} + +/// 获取编辑技能卡信息 +/// @param cardId 技能卡记录id +- (void)getSkillCardDetailWithCardId:(NSString *)cardId { + [Api requestSkillCardDetail:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + XPSkillCardModel *model = [XPSkillCardModel modelWithDictionary:data.data]; + [[self getView] onGetEditSkillCardInfoSuccess:model]; + } showLoading:YES] id:cardId]; +} + +///保存技能卡 +- (void)saveOrUpdateSkillCard:(XPSkillCardSaveModel *)skillCardModel { + [Api requestSaveSkillCard:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + [[self getView] onSaveSkillCardSuccess]; + } showLoading:YES] skillCardRecordVo:skillCardModel]; +} + +///删除技能卡 +///@param cardId 技能卡ID +- (void)deleteSkillCard:(NSString *)cardId { + [Api requestDeleteSkillCard:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + [[self getView] onDeleteSkillCardSuccess]; + } showLoading:YES] id:cardId]; +} + +/// 上传声音文件 +/// @param filePath 文件路径 +- (void)uploadVoice:(NSString *)filePath { + [Api qiniuUpLoadImage:[self createHttpCompletion:^(BaseModel * _Nonnull data) { + NSString *key = data.data[@"key"]; + NSString *token = data.data[@"token"]; + [UploadFile uploadFile:filePath named:key token:token success:^(NSString * _Nonnull key, NSDictionary * _Nonnull resp) { + NSString *url = resp[@"path"]; + [[self getView] uploadVoiceFileToThirdSuccess:url]; + } failure:^(NSNumber * _Nonnull resCode, NSString * _Nonnull message) { + [[self getView] showErrorToast:@"上传失败"]; + }]; + } showLoading:YES]]; + + +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/Protocol/XPSkillCardProtocol.h b/xplan-ios/Main/Mine/View/SkillCard/Protocol/XPSkillCardProtocol.h new file mode 100644 index 00000000..ed2ee3e0 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/Protocol/XPSkillCardProtocol.h @@ -0,0 +1,41 @@ +// +// XPSkillCardProtocol.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardTypeModel, XPSkillCardModel; +@protocol XPSkillCardProtocol + +@optional + +///当前用户技能卡列表 +- (void)onGetSkillCardListSuccess:(NSArray *)array; + +///未添加的技能卡类型列表 +- (void)onGetSkillCardTypeListSuccess:(NSArray *)array; + +///初始化技能卡数据 +- (void)onGetDefaultSkillCardInfoSuccess:(XPSkillCardModel *)model; + +///获取编辑的技能卡信息 +- (void)onGetEditSkillCardInfoSuccess:(XPSkillCardModel *)model; + +///保存技能卡成功 +- (void)onSaveSkillCardSuccess; + +///删除技能卡成功 +- (void)onDeleteSkillCardSuccess; + +///上传声音秀成功 +/// @param fileUrl 声音url +- (void)uploadVoiceFileToThirdSuccess:(NSString *)fileUrl; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.h b/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.h new file mode 100644 index 00000000..9aae07f1 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.h @@ -0,0 +1,22 @@ +// +// ThemeColor+SkillCard.h +// xplan-ios +// +// Created by GreenLand on 2022/2/24. +// + +#import "ThemeColor.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ThemeColor (SkillCard) + +/// 技能卡文字颜色 #8CA1FF ++ (UIColor *)skillCardTextColor; + +///技能卡红色强调色 #FB486A ++ (UIColor *)skillCardRedEmphasizeColor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.m b/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.m new file mode 100644 index 00000000..2a5517bb --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/ThemeColor+SkillCard.m @@ -0,0 +1,21 @@ +// +// ThemeColor+SkillCard.m +// xplan-ios +// +// Created by GreenLand on 2022/2/24. +// + +#import "ThemeColor+SkillCard.h" + +@implementation ThemeColor (SkillCard) + +/// 技能卡文字颜色 #8CA1FF ++ (UIColor *)skillCardTextColor { + return UIColorFromRGB(0x8CA1FF); +} + +///技能卡红色强调色 #FB486A ++ (UIColor *)skillCardRedEmphasizeColor { + return UIColorFromRGB(0xFB486A); +} +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.h new file mode 100644 index 00000000..a8c4aeb7 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.h @@ -0,0 +1,35 @@ +// +// XPSkillCardPropCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import +#import "XPSkillCardPropModel.h" +#import "XPSkillCardModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardEditPropCell; +@protocol XPSkillCardEditPropCellDelegate + +///用户输入的属性 +- (void)xPSkillCardPropCellPropValChange:(XPSkillCardEditPropCell *)cell selectArray:(NSArray *)selectArray; + +@end + +@interface XPSkillCardEditPropCell : UITableViewCell + +///技能卡默认全部数据 +@property (nonatomic, strong) XPSkillCardModel *defaultModel; + +@property (nonatomic, strong) XPSkillCardPropModel *model; +///是否最后一个cell +@property (nonatomic, assign) BOOL isLast; + +@property (nonatomic, weak) id delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.m new file mode 100644 index 00000000..43f978e4 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardEditPropCell.m @@ -0,0 +1,213 @@ +// +// XPSkillCardPropCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import "XPSkillCardEditPropCell.h" +///Third +#import +///Tool +#import "ThemeColor.h" +#import "NetImageView.h" + +@interface XPSkillCardEditPropCell () + +///是否必填 +@property (nonatomic,strong) UILabel *isMustLabel; +///名字 +@property (nonatomic,strong) UILabel *titleLabel; +///描述 +@property (nonatomic, strong) UILabel *subTitleLabel; +///箭头/编辑icon +@property (nonatomic, strong) UIButton *arrowButton; +///编辑框 +@property (nonatomic, strong) UITextField *editField; +///分割线 +@property (nonatomic, strong) UIView *devideView; + +@end + +@implementation XPSkillCardEditPropCell + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + [self initSubViews]; + [self initSubViewConstraints]; + } + return self; +} + +#pragma mark - Private Method +- (void)initSubViews { + [self.contentView addSubview:self.titleLabel]; + [self.contentView addSubview:self.isMustLabel]; + [self.contentView addSubview:self.subTitleLabel]; + [self.contentView addSubview:self.editField]; + [self.contentView addSubview:self.arrowButton]; + [self.contentView addSubview:self.devideView]; + self.backgroundColor = [UIColor clearColor]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editFieldChange:) name:UITextFieldTextDidChangeNotification object:self.editField]; +} + +- (void)initSubViewConstraints { + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(12); + make.top.mas_equalTo(24); + make.height.mas_equalTo(22); + make.width.mas_greaterThanOrEqualTo(22); + }]; + [self.isMustLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.titleLabel).mas_offset(2); + make.left.mas_equalTo(self.titleLabel.mas_right).mas_offset(2); + make.width.height.mas_equalTo(10); + }]; + [self.arrowButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-12); + make.width.height.mas_equalTo(22); + make.centerY.mas_equalTo(self.titleLabel); + }]; + [self.subTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(self.arrowButton.mas_left); + make.centerY.mas_equalTo(self.titleLabel); + }]; + [self.editField mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(self.arrowButton.mas_left); + make.centerY.mas_equalTo(self.titleLabel); + make.left.mas_equalTo(self.isMustLabel.mas_right).mas_offset(8); + make.bottom.mas_equalTo(self.devideView.mas_top); + make.width.mas_greaterThanOrEqualTo(100); + }]; + [self.devideView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.titleLabel.mas_bottom).mas_offset(10); + make.left.right.mas_equalTo(self.contentView).inset(12); + make.height.mas_equalTo(1); + make.bottom.mas_equalTo(self.contentView); + }]; +} + +- (void)editFieldChange:(NSNotification *)noti { + UITextField *sender = (UITextField *)[noti object]; + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardPropCellPropValChange: selectArray:)]) { + NSMutableArray *array = [NSMutableArray array]; + XPSkillCardSourcePropDetailModel *propItem = [[XPSkillCardSourcePropDetailModel alloc] init]; + propItem.parentId = self.model.propId; + propItem.id = self.model.propId; + propItem.propVal = sender.text; + [array addObject:propItem]; + [self.delegate xPSkillCardPropCellPropValChange:self selectArray:array]; + } +} +#pragma mark - UITextFieldDelegate +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + +#pragma mark - event +- (void)onArrowButtonClick:(UIButton *)button { + if (self.model.state == 1) { + [self.editField becomeFirstResponder]; + } +} + +#pragma mark - setter and getter +- (void)setModel:(XPSkillCardPropModel *)model { + _model = model; + self.titleLabel.text = model.propVal; + self.isMustLabel.hidden = !model.isMust; + if (model.refPropVos.count) { + NSMutableArray *array = [NSMutableArray array]; + for (int i = 0; i + +NS_ASSUME_NONNULL_BEGIN + +@protocol XPSkillCardHeadViewDelegate + +///点击添加技能卡按钮 +- (void)onSkillCardHeadViewAddButtonClick; + +@end + +@interface XPSkillCardHeadView : UIView + +@property (nonatomic, weak) id delegate; + +///是否添加了技能卡 +@property (nonatomic, assign) BOOL hadSkillCard; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardHeadView.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardHeadView.m new file mode 100644 index 00000000..ed9af12b --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardHeadView.m @@ -0,0 +1,62 @@ +// +// XPSkillCardHeadView.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardHeadView.h" +///Third +#import + +@interface XPSkillCardHeadView() + +@property (nonatomic, strong) UIButton *addButton; + +@end + +@implementation XPSkillCardHeadView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initView]; + [self initConstraints]; + } + return self; +} + +- (void)initView { + [self addSubview:self.addButton]; +} + +- (void)initConstraints { + [self.addButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.mas_equalTo(self).inset(15); + make.top.mas_equalTo(8); + make.bottom.mas_equalTo(-8); + }]; +} + +- (void)setHadSkillCard:(BOOL)hadSkillCard { + if (hadSkillCard) { + [_addButton setBackgroundImage:[UIImage imageNamed:@"skillCard_add_mini"] forState:UIControlStateNormal]; + } else { + [_addButton setBackgroundImage:[UIImage imageNamed:@"skillCard_add_large"] forState:UIControlStateNormal]; + } +} +#pragma mark - event +- (void)onAddButtonClick:(UIButton *)button { + if (self.delegate && [self.delegate respondsToSelector:@selector(onSkillCardHeadViewAddButtonClick)]) { + [self.delegate onSkillCardHeadViewAddButtonClick]; + } +} + +- (UIButton *)addButton { + if (!_addButton) { + _addButton = [[UIButton alloc] init]; + [_addButton setBackgroundImage:[UIImage imageNamed:@"skillCard_add_large"] forState:UIControlStateNormal]; + [_addButton addTarget:self action:@selector(onAddButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + } + return _addButton; +} +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.h new file mode 100644 index 00000000..73ca202a --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.h @@ -0,0 +1,36 @@ +// +// XPSkillCardListCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import +#import "XPSkillCardModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardListCell; +@protocol XPSkillCardListCellDelegate + +///编辑按钮点击 +- (void)xPSkillCardListCellEditButtonClick:(XPSkillCardListCell *)cell; +///删除声音秀 +- (void)xPSkillCardListCellDeleteVoiceButtonClick:(XPSkillCardListCell *)cell; +///重新录制 +- (void)xPSkillCardListCellRerecordButtonClick:(XPSkillCardListCell *)cell; +///播放、暂停 +- (void)xPSkillCardListCellPlayButtonClick:(XPSkillCardListCell *)cell button:(UIButton *)button; + +@end + +@interface XPSkillCardListCell : UITableViewCell + +///技能卡数据 +@property (nonatomic, strong) XPSkillCardModel *model; + +@property (nonatomic, weak) id delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.m new file mode 100644 index 00000000..12344dd1 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListCell.m @@ -0,0 +1,281 @@ +// +// XPSkillCardListCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/21. +// + +#import "XPSkillCardListCell.h" +///Third +#import +///Tool +#import "ThemeColor.h" +#import "NetImageView.h" +#import "XPMacro.h" +#import "TTPopup.h" +//View +#import "XPSkillCardListPropCell.h" +#import "XPSkillCardSelectPropView.h" +#import "XPSkillCardVoiceView.h" + +@interface XPSkillCardListCell () +///内容view +@property (nonatomic, strong) UIView *mainView; +///背景图片 +@property (nonatomic, strong) NetImageView *bgImageView; +///编辑按钮 +@property (nonatomic, strong) UIButton *editButton; +///logo图片 +@property (nonatomic,strong) NetImageView *logoImageView; +///名字 +@property (nonatomic,strong) UILabel *titleLabel; +///列表 +@property (nonatomic,strong) UITableView *tableView; +///属性列表 +@property (nonatomic, strong) NSMutableArray *dataArray; + +@property (nonatomic, strong) XPSkillCardVoiceView *voiceView; + +@end + +@implementation XPSkillCardListCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + [self initSubViews]; + [self initSubViewConstraints]; + [self setEvent]; + } + return self; +} + +#pragma mark - Private Method +- (void)initSubViews { + self.clipsToBounds = YES; + self.backgroundColor = [UIColor clearColor]; + [self.contentView addSubview:self.mainView]; + + [self.mainView addSubview:self.bgImageView]; + [self.mainView addSubview:self.logoImageView]; + [self.mainView addSubview:self.titleLabel]; + [self.mainView addSubview:self.editButton]; + [self.mainView addSubview:self.tableView]; + [self.mainView addSubview:self.voiceView]; + self.mainView.layer.cornerRadius = 8; + self.mainView.layer.masksToBounds = YES; +} + +- (void)initSubViewConstraints { + [self.mainView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.mas_equalTo(self.contentView).inset(15); + make.top.mas_equalTo(8); + make.bottom.mas_equalTo(self.contentView); + }]; + [self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(self.mainView); + }]; + + [self.logoImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(24); + make.left.mas_equalTo(16); + make.width.height.mas_equalTo(32); + }]; + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.logoImageView.mas_right).mas_offset(9); + make.centerY.mas_equalTo(self.logoImageView); + }]; + [self.editButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(self.logoImageView); + make.right.mas_equalTo(-15); + }]; + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.logoImageView.mas_bottom); + make.left.right.mas_equalTo(0); + make.bottom.mas_equalTo(self.mainView); + }]; + [self.voiceView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.logoImageView.mas_bottom); + make.left.right.mas_equalTo(0); + make.bottom.mas_equalTo(self.mainView); + }]; +} + +#pragma mark - tableViewDelegate +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.dataArray.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardListPropCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPSkillCardListPropCell class])]; + if (cell == nil) { + cell = [[XPSkillCardListPropCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPSkillCardListPropCell class])]; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.model = [self.dataArray objectAtIndex:indexPath.row]; + cell.isLast = self.dataArray.count == indexPath.row + 1; + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + return [[UIView alloc] initWithFrame:CGRectZero]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardRecordPropModel *item = [self.dataArray objectAtIndex:indexPath.row]; + return [self layoutCellHeightWithItem:item]; +} + +- (CGFloat)layoutCellHeightWithItem:(XPSkillCardRecordPropModel *)item { + CGFloat height = 56; + if (item.state == 0) { + return height; + } else { + CGRect rect = [item.parentVal boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 22) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16.f]} context:nil]; + CGFloat contentW = KScreenWidth - rect.size.width - 30 - 16 - 15 - 15; + CGRect contentRect = [item.propVal boundingRectWithSize:CGSizeMake(contentW, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16.f weight:UIFontWeightMedium]} context:nil]; + height = (contentRect.size.height + 34 > 56 ? contentRect.size.height + 40 : 56); + } + return height; +} + +#pragma mark - event +- (void)onEditButtonClick:(UIButton *)button { + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardListCellEditButtonClick:)]) { + [self.delegate xPSkillCardListCellEditButtonClick:self]; + } +} + +- (void)setEvent { + @kWeakify(self); + self.voiceView.buttonClick = ^(UIButton * _Nonnull button) { + @kStrongify(self); + switch (button.tag) { + case 101: {//播放、暂停 + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardListCellPlayButtonClick:button:)]) { + [self.delegate xPSkillCardListCellPlayButtonClick:self button:button]; + } + } + break; + case 102: {//删除录音 + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardListCellDeleteVoiceButtonClick:)]) { + [self.delegate xPSkillCardListCellDeleteVoiceButtonClick:self]; + } + } + break; + case 103: {//重新录制 + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardListCellRerecordButtonClick:)]) { + [self.delegate xPSkillCardListCellRerecordButtonClick:self]; + } + } + break; + default: + break; + } + }; +} + +#pragma mark - setter and getter +- (void)setModel:(XPSkillCardModel *)model { + _model = model; + self.bgImageView.imageUrl = self.model.pic; + self.logoImageView.imageUrl = self.model.icon; + self.titleLabel.text = self.model.name; + + if (model.type == SkillCardTypeVoice) { + self.tableView.hidden = YES; + self.voiceView.hidden = NO; + self.editButton.hidden = YES; + self.voiceView.model = model; + } else { + self.tableView.hidden = NO; + self.voiceView.hidden = YES; + self.editButton.hidden = NO; + } + [self.dataArray removeAllObjects]; + [self.dataArray addObjectsFromArray:model.propRecordVo]; + [self.tableView reloadData]; +} + +- (UIView *)mainView { + if (!_mainView) { + _mainView = [[UIView alloc] init]; + } + return _mainView; +} +- (NetImageView *)bgImageView { + if (!_bgImageView) { + _bgImageView = [[NetImageView alloc] init]; + _bgImageView.contentMode = UIViewContentModeScaleToFill; + } + return _bgImageView; +} + +- (NetImageView *)logoImageView { + if (!_logoImageView) { + _logoImageView = [[NetImageView alloc] init]; + } + return _logoImageView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:20]; + _titleLabel.textColor = [ThemeColor mainTextColor]; + } + return _titleLabel; +} + +- (UIButton *)editButton { + if (!_editButton) { + _editButton = [[UIButton alloc] init]; + [_editButton setTitle:@"编辑" forState:UIControlStateNormal]; + [_editButton addTarget:self action:@selector(onEditButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + _editButton.titleLabel.font = [UIFont systemFontOfSize:16]; + [_editButton setTitleColor:UIColorFromRGB(0x248CFE) forState:UIControlStateNormal]; + } + return _editButton; +} + +- (UITableView *)tableView { + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.tableFooterView = [UIView new]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _tableView.backgroundColor = [UIColor clearColor]; + if (@available(iOS 11.0, *)) { + _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } + [_tableView registerClass:[XPSkillCardListPropCell class] forCellReuseIdentifier:NSStringFromClass([XPSkillCardListPropCell class])]; + _tableView.estimatedRowHeight = 56; + _tableView.rowHeight = UITableViewAutomaticDimension; + if (@available(iOS 15.0, *)) { + _tableView.sectionHeaderTopPadding = 0; + } + _tableView.scrollEnabled = NO; + } + return _tableView; +} + +- (NSMutableArray *)dataArray { + if (!_dataArray) { + _dataArray = [NSMutableArray array]; + } + return _dataArray; +} + +- (XPSkillCardVoiceView *)voiceView { + if (!_voiceView) { + _voiceView = [[XPSkillCardVoiceView alloc] init]; + _voiceView.hidden = YES; + } + return _voiceView; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.h new file mode 100644 index 00000000..5f7abf1f --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.h @@ -0,0 +1,22 @@ +// +// XPSkillCardListPropCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/22. +// + +#import +#import "XPSkillCardRecordPropModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardListPropCell : UITableViewCell + +@property (nonatomic, strong) XPSkillCardRecordPropModel *model; + +///是否最后一个cell +@property (nonatomic, assign) BOOL isLast; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.m new file mode 100644 index 00000000..12121c3f --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardListPropCell.m @@ -0,0 +1,134 @@ +// +// XPSkillCardListPropCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/22. +// + +#import "XPSkillCardListPropCell.h" +///Third +#import +///Tool +#import "ThemeColor.h" +#import "NetImageView.h" +//View +#import "XPSkillCardEditPropCell.h" + +@interface XPSkillCardListPropCell () + +///是否必填 +@property (nonatomic,strong) UILabel *isMustLabel; +///名字 +@property (nonatomic,strong) UILabel *titleLabel; +///描述 +@property (nonatomic, strong) UILabel *subTitleLabel; +///分割线 +@property (nonatomic, strong) UIView *devideView; + +@end + + +@implementation XPSkillCardListPropCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + [self initSubViews]; + [self initSubViewConstraints]; + } + return self; +} + +#pragma mark - Private Method +- (void)initSubViews { + [self.contentView addSubview:self.titleLabel]; + [self.contentView addSubview:self.isMustLabel]; + [self.contentView addSubview:self.subTitleLabel]; + [self.contentView addSubview:self.devideView]; + self.backgroundColor = [UIColor clearColor]; +} + +- (void)initSubViewConstraints { + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(16); + make.top.mas_equalTo(24); + make.height.mas_equalTo(22); + }]; + [self.isMustLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.titleLabel).mas_offset(2); + make.left.mas_equalTo(self.titleLabel.mas_right).mas_offset(2); + make.width.height.mas_equalTo(10); + }]; + [self.subTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-15); + make.top.mas_equalTo(self.titleLabel); + make.left.mas_equalTo(self.titleLabel.mas_right).mas_offset(15); + make.height.mas_greaterThanOrEqualTo(22); + }]; + [self.devideView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.subTitleLabel.mas_bottom).mas_offset(10); + make.left.right.mas_equalTo(self.contentView).inset(12); + make.height.mas_equalTo(1); + make.bottom.mas_equalTo(self.contentView); + }]; +} + +#pragma mark - setter and getter +- (void)setModel:(XPSkillCardRecordPropModel *)model { + _model = model; + self.titleLabel.text = model.parentVal; + self.isMustLabel.hidden = !model.isMust; + [_titleLabel sizeToFit]; + if (model.refPropVos.count > 0) { + NSMutableArray *array = [NSMutableArray array]; + for (int i = 0; i< model.refPropVos.count; i++) { + XPSkillCardRecordPropDetailModel *item = model.refPropVos[i]; + [array addObject:item.propVal.length ? item.propVal : @""]; + } + self.subTitleLabel.text = [array componentsJoinedByString:@"、"]; + } else { + self.subTitleLabel.text = @""; + } +} + +- (void)setIsLast:(BOOL)isLast { + self.devideView.hidden = isLast; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:16]; + _titleLabel.textColor = [ThemeColor mainTextColor]; + } + return _titleLabel; +} + +- (UILabel *)isMustLabel { + if (!_isMustLabel) { + _isMustLabel = [[UILabel alloc] init]; + _isMustLabel.text = @"*"; + _isMustLabel.textColor = UIColorFromRGB(0xFB486A); + } + return _isMustLabel; +} + +- (UILabel *)subTitleLabel { + if (!_subTitleLabel) { + _subTitleLabel = [[UILabel alloc] init]; + _subTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; + _subTitleLabel.textColor = [ThemeColor mainTextColor]; + _subTitleLabel.numberOfLines = 0; + _subTitleLabel.textAlignment = NSTextAlignmentRight; + } + return _subTitleLabel; +} + +- (UIView *)devideView { + if (!_devideView) { + _devideView = [[UIView alloc] init]; + _devideView.backgroundColor = UIColorFromRGB(0xF1F1FA); + } + return _devideView; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.h new file mode 100644 index 00000000..46855b80 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.h @@ -0,0 +1,21 @@ +// +// XPSkillCardSelectPropCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import +#import "XPSkillCardResourcePropModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardSelectPropCell : UICollectionViewCell + +@property (nonatomic, strong) XPSkillCardSourcePropDetailModel *model; + +@property (nonatomic, assign) BOOL isSelected; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.m new file mode 100644 index 00000000..907adb39 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropCell.m @@ -0,0 +1,68 @@ +// +// XPSkillCardSelectPropCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import "XPSkillCardSelectPropCell.h" +///Third +#import +///Tool +#import "ThemeColor.h" + +@interface XPSkillCardSelectPropCell () +///显示名字 +@property (nonatomic,strong) UILabel *titleLabel; +@end + +@implementation XPSkillCardSelectPropCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self initSubViews]; + [self initSubViewConstraints]; + } + return self; +} + +#pragma mark - Private Method +- (void)initSubViews { + [self.contentView addSubview:self.titleLabel]; + self.contentView.backgroundColor = UIColorFromRGB(0xF1F1FA); + self.contentView.layer.cornerRadius = 8; + self.contentView.layer.masksToBounds = YES; +} + +- (void)initSubViewConstraints { + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(0); + }]; +} + +#pragma mark - Getters And Setters +- (void)setModel:(XPSkillCardSourcePropDetailModel *)model { + _model = model; + if (model) { + self.titleLabel.text = model.propVal; + } +} + +- (void)setIsSelected:(BOOL)isSelected { + self.contentView.backgroundColor = isSelected ? UIColorRGBAlpha(0xFFBC51, 0.1) : UIColorFromRGB(0xF1F1FA); + self.titleLabel.textColor = isSelected ? UIColorFromRGB(0xFFBC51) : [ThemeColor mainTextColor]; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:16]; + _titleLabel.textColor = [ThemeColor mainTextColor]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + } + return _titleLabel; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.h new file mode 100644 index 00000000..85f6184e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.h @@ -0,0 +1,37 @@ +// +// XPSkillCardSelectPropView.h +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardPropModel, XPSkillCardSourcePropDetailModel; +@protocol XPSkillCardSelectPropViewDelegate + +///完成选择 +- (void)xPSkillCardSelectPropViewCompleteSelect:(NSArray *)selectArray editIndex:(NSInteger)editIndex; + +@end + +@interface XPSkillCardSelectPropView : UIView + +///数据源 +@property (nonatomic, strong) NSArray *sourceArray; +///选择的选项 +@property (nonatomic, strong) NSMutableArray *selectArray; +///属性数据 +@property (nonatomic, strong) XPSkillCardPropModel *propModel; +///技能卡名称 +@property (nonatomic, copy) NSString *skillCardName; +///编辑的索引 +@property (nonatomic, assign) NSInteger editIndex; + +@property (nonatomic, weak) id delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.m new file mode 100644 index 00000000..6a62b696 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardSelectPropView.m @@ -0,0 +1,242 @@ +// +// XPSkillCardSelectPropView.m +// xplan-ios +// +// Created by GreenLand on 2022/1/20. +// + +#import "XPSkillCardSelectPropView.h" +///Third +#import +#import "XPMacro.h" +#import "ThemeColor.h" +#import "UIImage+Utils.h" +#import "XCHUDTool.h" +// View +#import "XPSkillCardSelectPropCell.h" +// Model +#import "XPSkillCardPropModel.h" +#import "XPSkillCardResourcePropModel.h" + +@interface XPSkillCardSelectPropView() + +@property (nonatomic, strong) UILabel *titleLabel; + +@property (nonatomic, strong) UICollectionView *collectionView; + +@property (nonatomic, strong) UIButton *confirmButton; +///选中的子属性名称集合 +@property (nonatomic, strong) NSMutableArray *selectPropNameArray; + +@end + +@implementation XPSkillCardSelectPropView + +- (void)drawRect:(CGRect)rect { + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(16, 16)]; + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.path = path.CGPath; + self.layer.mask = maskLayer; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initView]; + [self initConstraints]; + } + return self; +} + +- (void)initView { + self.backgroundColor = [ThemeColor alertBackgroundColor]; + [self addSubview:self.titleLabel]; + [self addSubview:self.collectionView]; + [self addSubview:self.confirmButton]; +} + +- (void)initConstraints { + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(24); + make.centerX.mas_equalTo(self); + make.height.mas_equalTo(22); + }]; + [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.mas_equalTo(self); + make.top.mas_equalTo(self.titleLabel.mas_bottom).mas_offset(32); + make.bottom.mas_equalTo(self.confirmButton.mas_top).mas_offset(-4); + }]; + [self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self); + make.bottom.mas_equalTo(kSafeAreaBottomHeight > 0 ? -kSafeAreaBottomHeight : -5); + make.width.mas_equalTo(240); + make.height.mas_equalTo(40); + }]; +} + +#pragma mark - UICollectionViewDatasource And UICollectionViewDelegate +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return self.sourceArray.count; +} + +- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardSelectPropCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPSkillCardSelectPropCell class]) forIndexPath:indexPath]; + XPSkillCardSourcePropDetailModel * item = [self.sourceArray objectAtIndex:indexPath.row]; + cell.model = item; + cell.isSelected = [self.selectPropNameArray containsObject:item.propVal]; + return cell; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { + [collectionView deselectItemAtIndexPath:indexPath animated:YES]; + XPSkillCardSourcePropDetailModel *item = [self.sourceArray objectAtIndex:indexPath.row]; + if ([self.selectPropNameArray containsObject:item.propVal]) {///取消选中 + [self.selectPropNameArray removeObject:item.propVal]; + NSInteger index = 0; + for (int i = 0; i 0) {//达到了多选限制 + [XCHUDTool showErrorWithMessage:@"最多可以选择3个哦~"]; + return; + } + ///擅长路线(全能王和其他的互斥) + if (item.refIsOnlyCheck) { + [self.selectPropNameArray removeAllObjects]; + [self.selectArray removeAllObjects]; + } else if (self.selectArray.count) {//选择了其他的 + NSInteger index = -1; + for (int i = 0; i -1) { + [self.selectArray removeObjectAtIndex:index]; + [self.selectPropNameArray removeObjectAtIndex:index]; + } + } + } + [self.selectPropNameArray addObject:propItem.propVal]; + [self.selectArray addObject:propItem]; + } + [self.collectionView reloadData]; + [self updateConfirmButton]; +} + +#pragma mark - UICollectionViewFlowlayout +- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { + return UIEdgeInsetsMake(0, 15, 0, 15); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { + return 16; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + CGFloat width = (KScreenWidth - 30 - 30) / 2; + return CGSizeMake(width, 40); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { + return 30; +} + +#pragma mark - event +- (void)onConfirmButtonClick:(UIButton *)sender { + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardSelectPropViewCompleteSelect: editIndex:)]) { + [self.delegate xPSkillCardSelectPropViewCompleteSelect:self.selectArray editIndex:self.editIndex]; + } +} + +- (void)updateConfirmButton { + if (self.selectArray.count | !self.propModel.isMust) { + [self.confirmButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor], [ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(50, 30)] forState:UIControlStateNormal]; + self.confirmButton.userInteractionEnabled = YES; + } else { + self.confirmButton.userInteractionEnabled = NO; + [self.confirmButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor disableButtonColor], [ThemeColor disableButtonColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(50, 30)] forState:UIControlStateNormal]; + } +} + +#pragma mark - setter and getter +- (void)setSourceArray:(NSArray *)sourceArray { + _sourceArray = sourceArray; + [self.collectionView reloadData]; +} + +- (void)setSelectArray:(NSMutableArray *)selectArray { + _selectArray = [NSMutableArray arrayWithArray:selectArray]; + for (XPSkillCardSourcePropDetailModel *item in selectArray) { + if (item.propVal.length) { + [self.selectPropNameArray addObject:item.propVal]; + } + } + [self updateConfirmButton]; +} + +- (void)setPropModel:(XPSkillCardPropModel *)propModel { + _propModel = propModel; + self.titleLabel.text = propModel.propVal; +} + +- (UICollectionView *)collectionView{ + if (!_collectionView) { + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; + _collectionView.dataSource = self; + _collectionView.delegate = self; + _collectionView.backgroundColor = [ThemeColor appCellBackgroundColor]; + [_collectionView registerClass:[XPSkillCardSelectPropCell class] forCellWithReuseIdentifier:NSStringFromClass([XPSkillCardSelectPropCell class])]; + _collectionView.layer.masksToBounds = YES; + _collectionView.layer.cornerRadius = 10; + } + return _collectionView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:16]; + _titleLabel.textColor = [ThemeColor mainTextColor]; + } + return _titleLabel; +} + +- (UIButton *)confirmButton { + if (!_confirmButton) { + _confirmButton = [[UIButton alloc] init]; + [_confirmButton setTitle:@"确定" forState:UIControlStateNormal]; + _confirmButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; + [_confirmButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor], [ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(50, 30)] forState:UIControlStateNormal]; + [_confirmButton addTarget:self action:@selector(onConfirmButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + _confirmButton.layer.cornerRadius = 20; + _confirmButton.layer.masksToBounds = YES; + } + return _confirmButton; +} + +- (NSMutableArray *)selectPropNameArray { + if (!_selectPropNameArray) { + _selectPropNameArray = [NSMutableArray array]; + } + return _selectPropNameArray; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.h new file mode 100644 index 00000000..fcd0b479 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.h @@ -0,0 +1,19 @@ +// +// XPSkillCardTypeCollectionViewCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import +#import "XPSkillCardTypeModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardTypeCollectionViewCell : UICollectionViewCell + +@property (nonatomic,strong) XPSkillCardTypeModel *itemModel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.m new file mode 100644 index 00000000..460b8239 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeCollectionViewCell.m @@ -0,0 +1,82 @@ +// +// XPSkillCardTypeCollectionViewCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardTypeCollectionViewCell.h" +///Third +#import +///Tool +#import "ThemeColor.h" +#import "NetImageView.h" + +@interface XPSkillCardTypeCollectionViewCell () +///显示图片 +@property (nonatomic,strong) NetImageView *logoImageView; +///显示名字 +@property (nonatomic,strong) UILabel *titleLabel; +@end + +@implementation XPSkillCardTypeCollectionViewCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self initSubViews]; + [self initSubViewConstraints]; + } + return self; +} + +#pragma mark - Private Method +- (void)initSubViews { + [self.contentView addSubview:self.logoImageView]; + [self.contentView addSubview:self.titleLabel]; + self.contentView.backgroundColor = UIColorFromRGB(0xF1F1FA); + self.contentView.layer.cornerRadius = 8; + self.contentView.layer.masksToBounds = YES; +} + +- (void)initSubViewConstraints { + [self.logoImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(32, 32)); + make.centerY.mas_equalTo(self.contentView); + make.left.mas_equalTo(10); + }]; + + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.logoImageView.mas_right).mas_offset(10); + make.right.mas_equalTo(self.contentView).mas_offset(-10); + make.centerY.mas_equalTo(self.contentView); + }]; +} + +#pragma mark - Getters And Setters +- (void)setItemModel:(XPSkillCardTypeModel *)itemModel { + _itemModel = itemModel; + if (_itemModel) { + self.logoImageView.imageUrl =_itemModel.icon; + self.titleLabel.text = _itemModel.name; + } +} + +- (NetImageView *)logoImageView { + if (!_logoImageView) { + _logoImageView = [[NetImageView alloc] init]; + } + return _logoImageView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:16]; + _titleLabel.textColor = [ThemeColor mainTextColor]; + } + return _titleLabel; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.h new file mode 100644 index 00000000..906378e9 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.h @@ -0,0 +1,28 @@ +// +// XPSkillCardTypeView.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import +#import "XPSkillCardTypeModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@class XPSkillCardTypeCollectionViewCell; +@protocol XPSkillCardTypeViewDelegate + +- (void)xPSkillCardTypeViewDidSelectItem:(XPSkillCardTypeModel *)item; + +@end + +@interface XPSkillCardTypeView : UIView + +@property (nonatomic, strong) NSArray *array; + +@property (nonatomic, weak) id delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.m new file mode 100644 index 00000000..aa740966 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardTypeView.m @@ -0,0 +1,109 @@ +// +// XPSkillCardTypeView.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardTypeView.h" +///Third +#import +#import "XPMacro.h" +#import "ThemeColor.h" +// View +#import "XPSkillCardTypeCollectionViewCell.h" + +@interface XPSkillCardTypeView() + +@property (nonatomic, strong) UICollectionView *collectionView; + +@end + +@implementation XPSkillCardTypeView + +- (void)drawRect:(CGRect)rect { + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(16, 16)]; + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.path = path.CGPath; + self.layer.mask = maskLayer; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initView]; + [self initConstraints]; + } + return self; +} + +- (void)initView { + self.backgroundColor = [ThemeColor alertBackgroundColor]; + [self addSubview:self.collectionView]; +} + +- (void)initConstraints { + [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.top.mas_equalTo(self); + make.bottom.mas_equalTo(0); + }]; +} + +#pragma mark - UICollectionViewDatasource And UICollectionViewDelegate +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return self.array.count; +} + +- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardTypeCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPSkillCardTypeCollectionViewCell class]) forIndexPath:indexPath]; + XPSkillCardTypeModel * item = [self.array objectAtIndex:indexPath.row]; + cell.itemModel = item; + return cell; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { + [collectionView deselectItemAtIndexPath:indexPath animated:YES]; + if (self.delegate && [self.delegate respondsToSelector:@selector(xPSkillCardTypeViewDidSelectItem:)]) { + XPSkillCardTypeModel * model = [self.array objectAtIndex:indexPath.row]; + [self.delegate xPSkillCardTypeViewDidSelectItem:model]; + } +} + +#pragma mark - UICollectionViewFlowlayout +- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { + return UIEdgeInsetsMake(13, 15, 13, 15); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { + return 20; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + CGFloat width = (KScreenWidth - 30 - 25) / 2; + return CGSizeMake(width, 48); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { + return 25; +} +#pragma mark - setter and getter +- (void)setArray:(NSArray *)array { + _array = array; + [self.collectionView reloadData]; +} + +- (UICollectionView *)collectionView{ + if (!_collectionView) { + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; + _collectionView.dataSource = self; + _collectionView.delegate = self; + _collectionView.backgroundColor = [ThemeColor appCellBackgroundColor]; + [_collectionView registerClass:[XPSkillCardTypeCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([XPSkillCardTypeCollectionViewCell class])]; + _collectionView.layer.masksToBounds = YES; + _collectionView.layer.cornerRadius = 10; + } + return _collectionView; +} + + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.h b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.h new file mode 100644 index 00000000..76f72d85 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.h @@ -0,0 +1,25 @@ +// +// XPSkillCardVoiceView.h +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import +#import "XPSkillCardModel.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef void(^OnButtonClick)(UIButton *button); + +@interface XPSkillCardVoiceView : UIView + +///技能卡数据 +@property (nonatomic, strong) XPSkillCardModel *model; + +///按钮点击 +@property (nonatomic, copy) OnButtonClick buttonClick; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.m b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.m new file mode 100644 index 00000000..d6a14d8e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/SubViews/XPSkillCardVoiceView.m @@ -0,0 +1,218 @@ +// +// XPSkillCardVoiceView.m +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import "XPSkillCardVoiceView.h" +///Third +#import +#import "XPMacro.h" +#import "ThemeColor+SkillCard.h" +#import "UIImage+Utils.h" + +@interface XPSkillCardVoiceView() + +///声音 +@property (nonatomic, strong) UIView *voiceView; +///播放按钮 +@property (nonatomic, strong) UIButton *playButton; +///时长 +@property (nonatomic, strong) UILabel *durationLabel; +///是否审核通过 +@property (nonatomic, strong) UILabel *reviewLabel; +///删除按钮 +@property (nonatomic, strong) UIButton *deleteButton; +///重新录制按钮 +@property (nonatomic, strong) UIButton *reRecordButton; + +@end + +@implementation XPSkillCardVoiceView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initView]; + [self initConstraints]; + } + return self; +} + +- (void)initView { + [self addSubview:self.voiceView]; + [self addSubview:self.playButton]; + [self addSubview:self.durationLabel]; + [self addSubview:self.reviewLabel]; + [self addSubview:self.deleteButton]; + [self addSubview:self.reRecordButton]; +} + +- (void)initConstraints { + [self.voiceView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(10); + make.height.mas_equalTo(30); + make.width.mas_equalTo(150); + make.centerX.mas_equalTo(self); + }]; + [self.playButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.voiceView).mas_offset(4); + make.centerY.mas_equalTo(self.voiceView); + make.width.height.mas_equalTo(24); + }]; + [self.durationLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.voiceView); + }]; + [self.reviewLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.voiceView.mas_right).mas_offset(5);; + make.centerY.mas_equalTo(self.voiceView); + }]; + [self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.voiceView.mas_bottom).mas_offset(20); + make.right.mas_equalTo(self.voiceView.mas_centerX).mas_offset(-10); + make.width.mas_equalTo(64); + make.height.mas_equalTo(20); + }]; + [self.reRecordButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.voiceView.mas_bottom).mas_offset(20); + make.left.mas_equalTo(self.voiceView.mas_centerX).mas_offset(10); + make.width.mas_equalTo(64); + make.height.mas_equalTo(20); + }]; +} + +#pragma mark - event +- (void)onPlayButtonClick:(UIButton *)sender { + if (self.buttonClick) { + self.buttonClick(sender); + } +} + +- (void)onDeleteButtonClick:(UIButton *)sender { + if (self.buttonClick) { + self.buttonClick(sender); + } +} + +- (void)onRerecordButtonClick:(UIButton *)sender { + if (self.buttonClick) { + self.buttonClick(sender); + } +} + +#pragma mark - setter getter +- (void)setModel:(XPSkillCardModel *)model { + for (XPSkillCardRecordPropModel *propItem in model.propRecordVo) { + if (propItem.state == 3) { + + } else if (propItem.state == 4) { + self.durationLabel.text = [NSString stringWithFormat:@"%@s", propItem.propVal]; + } + } + + switch (model.status) { + case SkillCardStatusTypeValid: { + self.reviewLabel.text = @"审核通过"; + self.reviewLabel.textColor = [ThemeColor appEmphasizeColor]; + } + break; + case SkillCardStatusTypeInreview: { + self.reviewLabel.text = @"审核中"; + self.reviewLabel.textColor = [ThemeColor textThirdColor]; + self.deleteButton.hidden = YES; + [self updateRerecordButtonContraints]; + } + break; + case SkillCardStatusTypeDelete: { + self.reviewLabel.text = @"审核不通过"; + self.reviewLabel.textColor = [ThemeColor skillCardRedEmphasizeColor]; + [self updateRerecordButtonContraints]; + } + break; + default: { + self.reviewLabel.text = @"审核中"; + self.reviewLabel.textColor = [ThemeColor textThirdColor]; + [self updateRerecordButtonContraints]; + } + break; + } +} + +- (void)updateRerecordButtonContraints { + [self.reRecordButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self); + make.top.mas_equalTo(self.voiceView.mas_bottom).mas_offset(20); + make.width.mas_equalTo(64); + make.height.mas_equalTo(20); + }]; +} + +- (UIView *)voiceView { + if (!_voiceView) { + _voiceView = [[UIView alloc] init]; + _voiceView.layer.cornerRadius = 15; + _voiceView.layer.masksToBounds = YES; + _voiceView.layer.borderWidth = 1; + _voiceView.layer.borderColor = [ThemeColor skillCardTextColor].CGColor; + } + return _voiceView; +} + +- (UIButton *)playButton { + if (!_playButton) { + _playButton = [[UIButton alloc] init]; + [_playButton setBackgroundImage:[UIImage imageNamed:@"skillCard_voice_play"] forState:UIControlStateNormal]; + [_playButton setBackgroundImage:[UIImage imageNamed:@"skillCard_voice_pause"] forState:UIControlStateSelected]; + [_playButton addTarget:self action:@selector(onPlayButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + _playButton.tag = 101; + } + return _playButton; +} + +- (UILabel *)durationLabel { + if (!_durationLabel) { + _durationLabel = [[UILabel alloc] init]; + _durationLabel.font = [UIFont systemFontOfSize:12]; + _durationLabel.textColor = [ThemeColor skillCardTextColor]; + } + return _durationLabel; +} + +- (UILabel *)reviewLabel { + if (!_reviewLabel) { + _reviewLabel = [[UILabel alloc] init]; + _reviewLabel.font = [UIFont systemFontOfSize:12]; + _reviewLabel.textColor = [ThemeColor textThirdColor]; + } + return _reviewLabel; +} + +- (UIButton *)deleteButton { + if (!_deleteButton) { + _deleteButton = [[UIButton alloc] init]; + [_deleteButton setTitle:@"删除录音" forState:UIControlStateNormal]; + [_deleteButton setTitleColor:[ThemeColor cancelButtonTextColor] forState:UIControlStateNormal]; + _deleteButton.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightMedium]; + [_deleteButton setBackgroundColor:[ThemeColor cancelButtonNormalBgColor]]; + [_deleteButton addTarget:self action:@selector(onDeleteButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + _deleteButton.layer.cornerRadius = 10; + _deleteButton.layer.masksToBounds = YES; + _deleteButton.tag = 102; + } + return _deleteButton; +} + +- (UIButton *)reRecordButton { + if (!_reRecordButton) { + _reRecordButton = [[UIButton alloc] init]; + [_reRecordButton setTitle:@"重新录制" forState:UIControlStateNormal]; + _reRecordButton.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightMedium]; + [_reRecordButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor], [ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(50, 20)] forState:UIControlStateNormal]; + [_reRecordButton addTarget:self action:@selector(onRerecordButtonClick:) forControlEvents:UIControlEventTouchUpInside]; + _reRecordButton.layer.cornerRadius = 10; + _reRecordButton.layer.masksToBounds = YES; + _reRecordButton.tag = 103; + } + return _reRecordButton; +} +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.h b/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.h new file mode 100644 index 00000000..d5bbe64a --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.h @@ -0,0 +1,21 @@ +// +// XPSkillCardEditViewController.h +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "MvpViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPSkillCardEditViewController : MvpViewController + +@property (nonatomic, assign) NSInteger cardId; + +///技能卡id(编辑技能卡时传入) +@property (nonatomic, assign) NSInteger cardRecordId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.m b/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.m new file mode 100644 index 00000000..2c83a596 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPSkillCardEditViewController.m @@ -0,0 +1,416 @@ +// +// XPSkillCardEditViewController.m +// xplan-ios +// +// Created by GreenLand on 2022/1/19. +// + +#import "XPSkillCardEditViewController.h" +// P +#import "XPSkillCardPresenter.h" +#import "XPSkillCardProtocol.h" +//Model +#import "XPSkillCardModel.h" +#import "XPSkillCardSaveModel.h" +#import "XPSkillCardResourcePropModel.h" +#import "XPSkillCardRecordPropModel.h" +// View +#import "XPSkillCardEditPropCell.h" +#import "XPSkillCardSelectPropView.h" +///Third +#import +///Tool +#import "XPMacro.h" +#import "TTPopup.h" +#import "ThemeColor.h" +#import "UIImage+Utils.h" +#import "NetImageView.h" + +@interface XPSkillCardEditViewController () +< +UITableViewDelegate, +UITableViewDataSource, +XPSkillCardProtocol, +XPSkillCardEditPropCellDelegate, +XPSkillCardSelectPropViewDelegate +> + +///内容view +@property (nonatomic, strong) UIView *mainView; +///背景图片 +@property (nonatomic, strong) NetImageView *bgImageView; +///列表 +@property (nonatomic,strong) UITableView *tableView; +///logo图片 +@property (nonatomic,strong) NetImageView *logoImageView; +///名字 +@property (nonatomic,strong) UILabel *titleLabel; +///属性列表 +@property (nonatomic, strong) NSMutableArray *dataArray; +///保存 +@property (nonatomic, strong) UIButton *saveButton; +//删除 +@property (nonatomic, strong) UIButton *deleteButton; +///初始化数据源 +@property (nonatomic, strong) XPSkillCardModel *model; +///属性数组 +@property (nonatomic, strong) NSMutableArray *propArray; + +@end + +@implementation XPSkillCardEditViewController + +- (XPSkillCardPresenter *)createPresenter { + return [[XPSkillCardPresenter alloc] init];; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self initSubViews]; + [self initSubViewConstraints]; + ///获取初始化技能卡所包含的信息 + [self.presenter getDefaultSkillCardDetailWithCardId:[NSString stringWithFormat:@"%zd", self.cardId]]; +} + +#pragma mark - initContraints +- (void)initSubViews { + self.title = @"技能卡"; + [self.view addSubview:self.mainView]; + [self.mainView addSubview:self.bgImageView]; + [self.mainView addSubview:self.logoImageView]; + [self.mainView addSubview:self.titleLabel]; + [self.mainView addSubview:self.tableView]; + self.mainView.layer.cornerRadius = 8; + self.mainView.layer.masksToBounds = YES; + + [self.view addSubview:self.saveButton]; + [self.view addSubview:self.deleteButton]; + self.deleteButton.hidden = !self.cardRecordId; +} + +- (void)initSubViewConstraints { + [self.mainView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.mas_equalTo(self.view).inset(15); + make.top.mas_equalTo(8); + make.height.mas_equalTo(24+55); + }]; + [self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(self.mainView); + }]; + + [self.logoImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(24); + make.left.mas_equalTo(12); + make.width.height.mas_equalTo(28); + }]; + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.logoImageView.mas_right).mas_offset(9); + make.centerY.mas_equalTo(self.logoImageView); + }]; + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.logoImageView.mas_bottom); + make.left.right.mas_equalTo(0); + make.bottom.mas_equalTo(self.mainView).mas_offset(-24); + }]; + + [self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self.view); + make.bottom.mas_equalTo(-kSafeAreaBottomHeight - 60); + make.width.mas_equalTo(240); + make.height.mas_equalTo(40); + }]; + [self.saveButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self.view); + make.bottom.mas_equalTo(self.deleteButton.mas_top).mas_offset(-20); + make.width.mas_equalTo(240); + make.height.mas_equalTo(40); + }]; +} + +#pragma mark - XPSkillCardProtocol +- (void)onGetDefaultSkillCardInfoSuccess:(XPSkillCardModel *)model { + _model = model; + self.bgImageView.imageUrl = model.pic; + self.logoImageView.imageUrl = model.icon; + self.titleLabel.text = model.name; + + if (self.cardRecordId) {///如果是编辑技能卡 + [self.presenter getSkillCardDetailWithCardId:[NSString stringWithFormat:@"%zd", self.cardRecordId]]; + } else {// 新增技能卡 + for (int i = 0; i 0 ? item.propId : -1; + editModel.propVal = item.propVal.length ? item.propVal : @""; + editModel.refIsOnlyCheck = item.refIsOnlyCheck; + [array addObject:editModel]; + } + } + model.refPropVos = [NSMutableArray arrayWithArray:array]; + [self.propArray addObject:model]; + } + [self.mainView mas_updateConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.propArray.count * 56 + 24 + 55); + }]; + [self.tableView reloadData]; +} + +///保存技能卡成功 +- (void)onSaveSkillCardSuccess { + [self showSuccessToast:@"保存成功"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.navigationController popViewControllerAnimated:YES]; + }); +} + +///删除技能卡成功 +- (void)onDeleteSkillCardSuccess { + [self showErrorToast:@"删除成功"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.navigationController popViewControllerAnimated:YES]; + }); +} + +#pragma mark - UITableViewDelegate And UITableViewDataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.propArray.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardEditPropCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPSkillCardEditPropCell class])]; + if (cell == nil) { + cell = [[XPSkillCardEditPropCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPSkillCardEditPropCell class])]; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.defaultModel = self.model; + cell.model = [self.propArray objectAtIndex:indexPath.row]; + cell.isLast = (self.propArray.count == indexPath.row + 1); + cell.delegate = self; + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + return [[UIView alloc] initWithFrame:CGRectZero]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 56; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [self.tableView endEditing:YES]; + XPSkillCardResourcePropModel *sourceProp = [self.model.props objectAtIndex:indexPath.row]; + XPSkillCardPropModel *editProp = [self.propArray objectAtIndex:indexPath.row]; + if (editProp.state == 0 || editProp.state == 2) { //单选\多选 + [self showSkillListWithSourceProps:sourceProp.propDictVos propModel:editProp selectArray:editProp.refPropVos editIndex:indexPath.row]; + } +} + +/// 显示属性弹窗 +/// @param props 属性数据源列表 +/// @param propModel 父属性 +/// @param selectArray 选择的子属性集合 +- (void)showSkillListWithSourceProps:(NSArray *)props propModel:(XPSkillCardPropModel *)propModel selectArray:(NSMutableArray *)selectArray editIndex:(NSInteger)editIndex { + XPSkillCardSelectPropView *view = [[XPSkillCardSelectPropView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, kSafeAreaBottomHeight + 370)]; + view.skillCardName = self.model.name; + view.editIndex = editIndex; + view.propModel = propModel; + view.selectArray = selectArray; + view.sourceArray = props; + view.delegate = self; + [TTPopup popupView:view style:TTPopupStyleActionSheet]; +} + +#pragma mark - XPSkillCardEditPropCellDelegate +- (void)xPSkillCardPropCellPropValChange:(XPSkillCardEditPropCell *)cell selectArray:(NSArray *)selectArray { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + XPSkillCardPropModel *model = [self.propArray objectAtIndex:indexPath.row]; + model.refPropVos = [NSMutableArray arrayWithArray:selectArray]; +} + +#pragma mark - XPSkillCardSelectPropViewDelegate +- (void)xPSkillCardSelectPropViewCompleteSelect:(NSArray *)selectArray editIndex:(NSInteger)editIndex { + [TTPopup dismiss]; + XPSkillCardPropModel *model = [self.propArray objectAtIndex:editIndex]; + model.refPropVos = [NSMutableArray arrayWithArray:selectArray]; + [self.tableView reloadData]; +} + +#pragma mark - events +- (void)onSaveButtonClick:(UIButton *)button { + for (XPSkillCardPropModel * proModel in self.propArray) { + if (proModel.isMust && proModel.refPropVos.count == 0) { + [self showErrorToast:@"请填写必填项~"]; + return; + } + } + NSMutableArray *propArray = [NSMutableArray array]; + for (int i = 0; i +///Tool +#import "XPMacro.h" +#import "AccountInfoStorage.h" +#import "TTPopup.h" +#import "ThemeColor.h" + +@interface XPSkillCardViewController () + +@property (nonatomic,strong) UITableView *tableView; +///头部加号 +@property (nonatomic, strong) XPSkillCardHeadView *headView; +///数据源 +@property (nonatomic, strong) NSMutableArray *dataSource; +/** player */ +//@property (nonatomic, strong) AVPlayer *player; +/** playerItem */ +//@property (nonatomic, strong) AVPlayerItem *playerItem; + +@end + +@implementation XPSkillCardViewController + +- (XPSkillCardPresenter *)createPresenter { + return [[XPSkillCardPresenter alloc] init];; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self initSubViews]; + [self initSubViewConstraints]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.presenter getSkillCardInfoWithUid:[NSString stringWithFormat:@"%zd", self.uid]]; +} + +#pragma mark - Private Method +- (void)initSubViews { + self.title = @"技能卡"; + [self.view addSubview:self.tableView]; +} + +- (void)initSubViewConstraints { + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.view); + make.left.right.bottom.mas_equalTo(self.view); + }]; +} + +#pragma mark - XPSkillCardProtocol +///成功获取当前添加的技能卡列表 +- (void)onGetSkillCardListSuccess:(NSArray *)array { + self.dataSource = [NSMutableArray arrayWithArray:array]; + self.headView.hadSkillCard = self.dataSource.count; + if (self.uid == [[AccountInfoStorage instance].getUid integerValue]) {//主态 + if (self.dataSource.count) {///有技能卡 + CGFloat height = (KScreenWidth - 30) * 64 / 345.0 + 16; + self.headView.frame = CGRectMake(0, 0, KScreenWidth, height); + } else { + CGFloat height = (KScreenWidth - 30) * 180 / 345.0 + 16; + self.headView.frame = CGRectMake(0, 0, KScreenWidth, height); + } + self.tableView.tableHeaderView = self.headView; + } else { + self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectZero]; + } + [self.tableView reloadData]; +} + +///未添加的技能卡类型列表 +- (void)onGetSkillCardTypeListSuccess:(NSArray *)array { + XPSkillCardTypeView *view = [[XPSkillCardTypeView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, kSafeAreaBottomHeight + 310)]; + view.array = array; + view.delegate = self; + [TTPopup popupView:view style:TTPopupStyleActionSheet]; +} + +///删除技能卡成功 +- (void)onDeleteSkillCardSuccess { + [self showErrorToast:@"删除成功"]; + [self.presenter getSkillCardInfoWithUid:[NSString stringWithFormat:@"%zd", self.uid]]; +} + +#pragma mark - XPSkillCardTypeViewDelegate +///选择了添加的技能卡类型 +- (void)xPSkillCardTypeViewDidSelectItem:(XPSkillCardTypeModel *)item { + [TTPopup dismiss]; + if ([item.name isEqualToString:@"声音秀"]) { + XPVoiceCardViewController *vc = [[XPVoiceCardViewController alloc] init]; + vc.cardId = item.cardId; + [self.navigationController pushViewController:vc animated:YES]; + } else { + XPSkillCardEditViewController *vc = [[XPSkillCardEditViewController alloc] init]; + vc.cardId = item.cardId; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +#pragma mark - UITableViewDelegate And UITableViewDataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.dataSource.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardListCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPSkillCardListCell class])]; + if (cell == nil) { + cell = [[XPSkillCardListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPSkillCardListCell class])]; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + cell.model = item; + cell.delegate = self; + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + return [[UIView alloc] initWithFrame:CGRectZero]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + return [self layoutCellHeightWithItem:item]; +} + +- (CGFloat)layoutCellHeightWithItem:(XPSkillCardModel *)item { + CGFloat height = 56 + 8 + 28; + if (item.type == SkillCardTypeVoice) { + height = 56 + 8 + 120; + return height; + } + for (int i = 0; i 56 ? contentRect.size.height + 40 : 56); + } + } + return height; +} + +#pragma mark - XPSkillCardHeadViewDelegate +///点击添加技能卡按钮 +- (void)onSkillCardHeadViewAddButtonClick { + [self.presenter getSkillCardTypeList]; +} + +#pragma mark - XPSkillCardListCellDelegate +///编辑技能卡 +- (void)xPSkillCardListCellEditButtonClick:(XPSkillCardListCell *)cell { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + XPSkillCardEditViewController *vc = [[XPSkillCardEditViewController alloc] init]; + vc.cardId = item.cardId; + vc.cardRecordId = item.cardRecordId; + [self.navigationController pushViewController:vc animated:YES]; +} + +///删除声音秀 +- (void)xPSkillCardListCellDeleteVoiceButtonClick:(XPSkillCardListCell *)cell { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + TTAlertConfig *config = [[TTAlertConfig alloc] init]; + TTAlertButtonConfig *cancelConfig = [[TTAlertButtonConfig alloc] init]; + cancelConfig.title = @"取消"; + TTAlertButtonConfig *confirmConfig = [[TTAlertButtonConfig alloc] init]; + confirmConfig.title = @"确定"; + config.cancelButtonConfig = cancelConfig; + config.confirmButtonConfig = confirmConfig; + [TTPopup alertWithMessage:@"确定要删除该技能卡?" confirmHandler:^{ + [self.presenter deleteSkillCard:[NSString stringWithFormat:@"%zd", item.cardRecordId]]; + } cancelHandler:^{ + }]; +} + +///重新录制 +- (void)xPSkillCardListCellRerecordButtonClick:(XPSkillCardListCell *)cell { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + XPVoiceCardViewController *vc = [[XPVoiceCardViewController alloc] init]; + vc.cardId = item.cardId; + vc.cardRecordId = item.cardRecordId; + [self.navigationController pushViewController:vc animated:YES]; +} + +///播放、暂停 +- (void)xPSkillCardListCellPlayButtonClick:(XPSkillCardListCell *)cell button:(UIButton *)button { + NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; + XPSkillCardModel * item = [self.dataSource objectAtIndex:indexPath.row]; + if (button.isSelected) { + + } else { + + } +} + +#pragma mark - Getters And Setters +- (void)setUid:(NSInteger)uid { + _uid = uid; +} + +- (UITableView *)tableView { + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.tableFooterView = [UIView new]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + _tableView.backgroundColor = [UIColor clearColor]; + if (@available(iOS 11.0, *)) { + _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } + [_tableView registerClass:[XPSkillCardListCell class] forCellReuseIdentifier:NSStringFromClass([XPSkillCardListCell class])]; + } + return _tableView; +} + +- (XPSkillCardHeadView *)headView { + if (!_headView) { + _headView = [[XPSkillCardHeadView alloc] init]; + _headView.delegate = self; + } + return _headView; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.h b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.h new file mode 100644 index 00000000..85330b52 --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.h @@ -0,0 +1,44 @@ +// +// XPVoiceCardCircleLayer.h +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface XPVoiceCardCircleLayer : CAShapeLayer + +/** + 建立一个展示圆形倒计时的Layer + @param strokeColor 倒计时线的颜色 + @param lineWidth 倒计时线的宽度 + @param radius 倒计时圆的半径 + */ ++ (XPVoiceCardCircleLayer *)layerWithStrokeColor:(UIColor *)strokeColor lineWidth:(CGFloat)lineWidth radius:(CGFloat)radius; + +@property (nonatomic, assign) BOOL clockWise; // 是否为顺时针 + +@property (nonatomic, assign) BOOL increase; // 是否递增动画 + +@property (nonatomic, assign) CGFloat totalCountDown; // 总计时 + +@property (nonatomic, assign) CGFloat radius; // 圆的半径 + +/** + 根据当前倒计时展示Layer(需要实现设置totalCountDown) + @param countDown 当前的倒计时 +*/ +- (void)showAnimationWithCountdown:(CGFloat)countDown; + +/** + 根据当前进度展示Layer + @param progress 当前的进度(0%-100%) +*/ +- (void)showAnimationWithProgress:(CGFloat)progress; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.m b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.m new file mode 100644 index 00000000..b51291fc --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardCircleLayer.m @@ -0,0 +1,47 @@ +// +// XPVoiceCardCircleLayer.m +// xplan-ios +// +// Created by GreenLand on 2022/2/23. +// + +#import "XPVoiceCardCircleLayer.h" + +@implementation XPVoiceCardCircleLayer + ++ (XPVoiceCardCircleLayer *)layerWithStrokeColor:(UIColor *)strokeColor lineWidth:(CGFloat)lineWidth radius:(CGFloat)radius { + XPVoiceCardCircleLayer *shapeLayer = [XPVoiceCardCircleLayer layer]; + shapeLayer.strokeColor = strokeColor.CGColor; + shapeLayer.lineWidth = lineWidth; + shapeLayer.fillColor = [UIColor clearColor].CGColor; // 填充色为无色 + shapeLayer.lineCap = kCALineCapRound; // 指定线的边缘是圆的 + shapeLayer.totalCountDown = 1; + shapeLayer.radius = radius; + return shapeLayer; +} + +- (void)showAnimationWithCountdown:(CGFloat)countDown { + if (_totalCountDown <= 0) { + NSAssert(NO, @"总计时不能为0"); + return; + } + [self showAnimationWithProgress:(_totalCountDown - countDown) * 1.0 / _totalCountDown]; +} + +- (void)showAnimationWithProgress:(CGFloat)progress { + CGFloat startA = - M_PI_2; // 设置进度条起点位置 + CGFloat endA; // 设置进度条终点位置 + CGFloat clockWiseFlag = _clockWise ? 1 : -1; + CGFloat progressFlag = _increase ? 1 : -1; + CGFloat percent = _increase ? progress : (1 - progress); + + // 顺增、逆减,顺时针构建环形 + BOOL shouldClockWiseBulid = (clockWiseFlag * progressFlag > 0); + + endA = startA + M_PI * 2 * percent * clockWiseFlag * progressFlag; + + UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_radius / 2, _radius / 2) radius:_radius / 2 - self.lineWidth / 2 startAngle:startA endAngle:endA clockwise:shouldClockWiseBulid]; // 构建环形 + self.path = [path CGPath]; +} + +@end diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.h b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.h new file mode 100644 index 00000000..f1e53c9e --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.h @@ -0,0 +1,21 @@ +// +// XPVoiceCardViewController.h +// xplan-ios +// +// Created by GreenLand on 2022/2/22. +// + +#import "MvpViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPVoiceCardViewController : MvpViewController + +@property (nonatomic, assign) NSInteger cardId; + +///技能卡id(编辑技能卡时传入) +@property (nonatomic, assign) NSInteger cardRecordId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.m b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.m new file mode 100644 index 00000000..fc0f56aa --- /dev/null +++ b/xplan-ios/Main/Mine/View/SkillCard/View/XPVoiceCardViewController.m @@ -0,0 +1,419 @@ +// +// XPVoiceCardViewController.m +// xplan-ios +// +// Created by GreenLand on 2022/2/22. +// + +#import "XPVoiceCardViewController.h" +// P +#import "XPSkillCardPresenter.h" +#import "XPSkillCardProtocol.h" +///Third +#import +#import +///Tool +#import "XPMacro.h" +#import "TTPopup.h" +#import "ThemeColor.h" +#import "UIImage+Utils.h" +#import "XCHUDTool.h" +#import "XPVoiceCardCircleLayer.h" +#import "AccountInfoStorage.h" +#import "YYUtility.h" +#import "CommonFileUtils.h" +///View +#import "XPMineUserInfoCustomNavView.h" +///Model +#import "XPSkillCardModel.h" +#import "XPSkillCardSaveModel.h" + +@interface XPVoiceCardViewController () + +@property (nonatomic, strong) XPMineUserInfoCustomNavView *navView; +///背景图 +@property (nonatomic, strong) UIImageView *backImageView; +///录制/停止按钮 +@property (nonatomic, strong) UIButton *recordButton; +///取消重新录制按钮 +@property (nonatomic, strong) UIButton *cancelButton; +///描述 +@property (nonatomic, strong) UILabel *descLabel; +@property (nonatomic, strong) XPSkillCardModel *model; +///属性数组 +@property (nonatomic, strong) NSMutableArray *propArray; +///录制动画图层 +@property (nonatomic, strong) XPVoiceCardCircleLayer *voiceLayer; +///定时器 +@property (nonatomic, strong) NSTimer *timer; +///倒计时 +@property (nonatomic, assign) NSInteger countdown; +///音频录制对象 +@property (nonatomic, strong) AVAudioRecorder *audioRecorder; +///音频文件名 +@property (nonatomic, copy) NSString *fileName; +///本地录制的音频地址 +@property (nonatomic, copy) NSString *totalFilePath; +///音频时长 +@property (nonatomic, assign) NSInteger duration; + +@end + +@implementation XPVoiceCardViewController + +- (XPSkillCardPresenter *)createPresenter { + return [[XPSkillCardPresenter alloc] init];; +} + +- (BOOL)isHiddenNavBar { + return YES; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self initSubViews]; + [self initSubViewConstraints]; + ///获取初始化技能卡所包含的信息 + [self.presenter getDefaultSkillCardDetailWithCardId:[NSString stringWithFormat:@"%zd", self.cardId]]; +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + self.voiceLayer.frame = CGRectMake(14, 14, 142, 142); +} + +#pragma mark - Private Method +- (void)initSubViews { + self.title = @"技能卡"; + self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; + [self.view addSubview:self.backImageView]; + [self.view addSubview:self.navView]; + [self.view addSubview:self.recordButton]; + [self.view addSubview:self.descLabel]; + [self.view addSubview:self.cancelButton]; +} + +- (void)initSubViewConstraints { + [self.backImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.right.mas_equalTo(self.view); + make.height.mas_equalTo(300); + }]; + [self.navView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.top.mas_equalTo(self.view); + make.height.mas_equalTo(kNavigationHeight); + }]; + [self.recordButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self.view); + make.top.mas_equalTo(kNavigationHeight + 85); + make.width.height.mas_equalTo(169); + }]; + [self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self.view); + make.top.mas_equalTo(self.recordButton.mas_bottom).mas_offset(30); + make.height.mas_equalTo(22); + }]; + [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self.view); + make.top.mas_equalTo(self.descLabel.mas_bottom).mas_offset(20); + make.width.mas_equalTo(144); + make.height.mas_equalTo(40); + }]; +} + +#pragma mark - events +- (void)onRecordButtonClick:(UIButton *)sender { + if (!sender.isSelected) { + [self startRecord]; + } else { + [self endRecord]; + } +} + +- (void)onCancelButtonClick:(UIButton *)sender { + [self cancelRecord]; +} + +- (void)startTimer { + [self stopTimer]; + self.cancelButton.hidden = NO; + self.voiceLayer.hidden = NO; + self.recordButton.selected = YES; + [self.recordButton.layer addSublayer:self.voiceLayer]; + self.countdown = 150; + __weak typeof(self) weakSelf = self; + self.timer = [NSTimer timerWithTimeInterval:0.1f repeats:YES block:^(NSTimer * _Nonnull timer) { + weakSelf.countdown--; + if (weakSelf.countdown > 0) { + [weakSelf.voiceLayer showAnimationWithCountdown:weakSelf.countdown]; + } else { + [weakSelf endRecord]; + } + }]; + [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; +} + +- (void)stopTimer { + if (self.timer) { + [self.timer invalidate]; + self.timer = nil; + } +} + +///开始录制声音 +- (void)startRecord { + [YYUtility checkMicPrivacy:^(BOOL succeed) { + if (succeed) { + AVAudioSession *audioSession = [AVAudioSession sharedInstance]; + [audioSession setCategory:AVAudioSessionCategoryRecord error:nil]; + //录音设置 + NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init]; + //录音格式 + [recordSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey]; + //采样率 + [recordSettings setValue :[NSNumber numberWithFloat:16000.0] forKey: AVSampleRateKey]; + //通道数 + [recordSettings setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey]; + //线性采样位数 + [recordSettings setValue :[NSNumber numberWithInt:16] forKey: AVLinearPCMBitDepthKey]; + //音频质量,采样质量 + [recordSettings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey]; + NSError *error = nil; + + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *date = [dateFormat stringFromDate:[NSDate date]]; + self.fileName = [NSString stringWithFormat:@"voiceShow_%@_%@.wav", [AccountInfoStorage instance].getUid, date]; + NSFileManager *fileMgr = [[NSFileManager alloc] init]; + //创建文件管理器 + NSString *filePath = [[CommonFileUtils documentsDirectory] stringByAppendingPathComponent:@"voiceShow"]; + self.totalFilePath = [filePath stringByAppendingPathComponent:self.fileName]; + + if(![fileMgr fileExistsAtPath:filePath]){//如果不存在,则说明是第一次运行这个程序,那么建立这个文件夹 + [fileMgr createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil]; + } + if ([fileMgr fileExistsAtPath:filePath]) { + NSURL *fileUrl = [NSURL fileURLWithPath:self.totalFilePath]; + self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:fileUrl settings:recordSettings error:&error]; + self.audioRecorder.meteringEnabled = YES; + [self.audioRecorder updateMeters]; + NSLog(@"%f",[self.audioRecorder peakPowerForChannel:0]); + if (self.audioRecorder) { + //启动或者恢复记录的录音文件 + if ([self.audioRecorder prepareToRecord] == YES) { + BOOL status = [self.audioRecorder record]; + if (status) { + [self startTimer]; + self.descLabel.text = @"录音开始,不少于3s哦"; + } + } else { + [XCHUDTool showErrorWithMessage:@"录制失败,请重试"]; + } + }else { + [XCHUDTool showErrorWithMessage:@"录制失败,请重试"]; + } + } + } else { + [XCHUDTool showErrorWithMessage:@"无麦克风权限,请到设置中打开麦克风权限"]; + } + }]; +} + +///结束录制 +- (void)endRecord { + [self stopTimer]; + [self.audioRecorder stop]; + self.audioRecorder = nil; + self.recordButton.selected = NO; + self.descLabel.text = @"点击录制语音(15s),展示你的才艺技能"; + self.cancelButton.hidden = YES; + self.voiceLayer.hidden = YES; + [self.voiceLayer removeFromSuperlayer]; + ///判断是否大于3s + AVAsset *audioAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:self.totalFilePath]]; + CMTime audioDuration = audioAsset.duration; + float audioDurationSeconds = CMTimeGetSeconds(audioDuration); + if (audioDurationSeconds >= 3) { + self.duration = (NSInteger)audioDurationSeconds; + [self uploadAudio]; + } else { + [self deleteAudioFile]; + [XCHUDTool showErrorWithMessage:@"录制的语音至少3s"]; + } +} + +///取消录制 +- (void)cancelRecord { + [self stopTimer]; + self.countdown = 0; + [self.audioRecorder stop]; + self.audioRecorder = nil; + self.recordButton.selected = NO; + self.descLabel.text = @"点击录制语音(15s),展示你的才艺技能"; + self.cancelButton.hidden = YES; + self.voiceLayer.hidden = YES; + [self.voiceLayer removeFromSuperlayer]; + [self deleteAudioFile]; +} + +///删除本地缓存文件 +- (void)deleteAudioFile { + [CommonFileUtils deleteFileWithFullPath:self.totalFilePath]; +} + +#pragma mark - 上传音频文件 +- (void)uploadAudio { + [self.presenter uploadVoice:self.totalFilePath]; +} + +#pragma mark - XPSkillCardProtocol +- (void)onGetDefaultSkillCardInfoSuccess:(XPSkillCardModel *)model { + _model = model; + if (self.cardRecordId) {///如果是编辑 + [self.presenter getSkillCardDetailWithCardId:[NSString stringWithFormat:@"%zd", self.cardRecordId]]; + } else { + [self.propArray addObjectsFromArray:self.model.props]; + } +} + +///获取编辑的技能卡信息成功 +- (void)onGetEditSkillCardInfoSuccess:(XPSkillCardModel *)model { + [self.propArray addObjectsFromArray:model.propRecordVo]; +} + +- (void)uploadVoiceFileToThirdSuccess:(NSString *)fileUrl { + NSMutableArray *propArray = [NSMutableArray array]; + if (self.cardRecordId) { + for (int i = 0; i ///顶部背景 @@ -208,6 +209,13 @@ { XPNobleCenterViewController *nobleCenterVC = [[XPNobleCenterViewController alloc] init]; [self.navigationController pushViewController:nobleCenterVC animated:YES]; + } + break; + case XPMineItemType_Skill_Card: + { + XPSkillCardViewController *skillCardVC = [[XPSkillCardViewController alloc] init]; + skillCardVC.uid = self.userInfo.uid; + [self.navigationController pushViewController:skillCardVC animated:YES]; } break; default: diff --git a/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.h b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.h new file mode 100644 index 00000000..e91e4d56 --- /dev/null +++ b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.h @@ -0,0 +1,18 @@ +// +// XPUserCardSkillCardView.h +// xplan-ios +// +// Created by GreenLand on 2022/1/25. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface XPUserCardSkillCardView : UIView + +@property (nonatomic, strong) NSArray *dataArray; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.m b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.m new file mode 100644 index 00000000..f6ea3a1b --- /dev/null +++ b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCardView.m @@ -0,0 +1,97 @@ +// +// XPUserCardSkillCardView.m +// xplan-ios +// +// Created by GreenLand on 2022/1/25. +// + +#import "XPUserCardSkillCardView.h" +#import "XPUserCardSkillCollectionViewCell.h" +///Third +#import +///Tool +#import "XPMacro.h" +#import "ThemeColor+UserCard.h" + +@interface XPUserCardSkillCardView() + +@property (nonatomic, strong) UICollectionView *collectionView; + +@end + +@implementation XPUserCardSkillCardView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self initSubView]; + [self initContraints]; + } + return self; +} + +- (void)initSubView { + [self addSubview:self.collectionView]; +} + +- (void)initContraints { + [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.bottom.mas_equalTo(0); + }]; +} + +#pragma mark - UICollectionViewDelegate +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return self.dataArray.count; +} + +- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + XPUserCardSkillCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPUserCardSkillCollectionViewCell class]) forIndexPath:indexPath]; + cell.imageView.imageUrl = [self.dataArray objectAtIndex:indexPath.item]; + return cell; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + CGFloat height = 30; + CGFloat width = 60; + XPUserCardSkillCollectionViewCell * cell = (XPUserCardSkillCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath]; + + UIImage* image = cell.imageView.image; + if (image) { + CGFloat scale = image.size.width / image.size.height; + return CGSizeMake(20 * scale, height); + } else { + NSURL *imgUrl = [NSURL URLWithString:[self.dataArray objectAtIndex:indexPath.item]]; + UIImage *myImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl]]; + CGFloat scale = myImage.size.width / myImage.size.height; + if (scale == 0) { + return CGSizeMake(60, height); + }else { + return CGSizeMake(20 * scale, height); + } + } + return CGSizeMake(width, height); +} + +- (void)setDataArray:(NSArray *)dataArray { + _dataArray = [NSArray arrayWithArray:dataArray]; + [self.collectionView reloadData]; +} + +- (UICollectionView *)collectionView{ + if (!_collectionView) { + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + layout.itemSize = CGSizeMake(60, 30); + layout.minimumLineSpacing = 0; + layout.minimumInteritemSpacing = 8; + layout.sectionInset = UIEdgeInsetsMake(0, 12, 0, 12); + layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; + _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; + _collectionView.showsHorizontalScrollIndicator = NO; + _collectionView.dataSource = self; + _collectionView.delegate = self; + _collectionView.backgroundColor = [UIColor clearColor]; + [_collectionView registerClass:[XPUserCardSkillCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([XPUserCardSkillCollectionViewCell class])]; + } + return _collectionView; +} +@end diff --git a/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.h b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.h new file mode 100644 index 00000000..f42a0997 --- /dev/null +++ b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.h @@ -0,0 +1,19 @@ +// +// XPUserCardSkillCollectionViewCell.h +// xplan-ios +// +// Created by GreenLand on 2022/1/25. +// + +#import +#import "NetImageView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XPUserCardSkillCollectionViewCell : UICollectionViewCell + +@property (nonatomic, strong) NetImageView *imageView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.m b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.m new file mode 100644 index 00000000..5e555434 --- /dev/null +++ b/xplan-ios/Main/Room/View/UserCard/View/SubViews/XPUserCardSkillCollectionViewCell.m @@ -0,0 +1,43 @@ +// +// XPUserCardSkillCollectionViewCell.m +// xplan-ios +// +// Created by GreenLand on 2022/1/25. +// + +#import "XPUserCardSkillCollectionViewCell.h" +///Third +#import + +@implementation XPUserCardSkillCollectionViewCell + +- (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.imageView]; +} + +- (void)initSubViewConstraints { + [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.mas_equalTo(0); + make.top.bottom.mas_equalTo(self.contentView).inset(5); + }]; +} + +#pragma mark - Getters And Setters +- (NetImageView *)imageView { + if (!_imageView) { + _imageView = [[NetImageView alloc] init]; + _imageView.contentMode = UIViewContentModeScaleAspectFit; + } + return _imageView; +} + +@end diff --git a/xplan-ios/Main/Room/View/UserCard/View/XPUserCardViewController.m b/xplan-ios/Main/Room/View/UserCard/View/XPUserCardViewController.m index c46f92a9..29035097 100644 --- a/xplan-ios/Main/Room/View/UserCard/View/XPUserCardViewController.m +++ b/xplan-ios/Main/Room/View/UserCard/View/XPUserCardViewController.m @@ -30,6 +30,7 @@ #import "XPSendGiftView.h" #import "NetImageView.h" #import "XPUserCardItemCollectionViewCell.h" +#import "XPUserCardSkillCardView.h" ///P #import "XPUserCardPresenter.h" #import "XPUserCardProtocol.h" @@ -91,6 +92,8 @@ @property (nonatomic,strong) UIButton *closeButton; ///列表 @property (nonatomic,strong) UICollectionView *collectionView; +///技能卡列表 +@property (nonatomic, strong) XPUserCardSkillCardView *skillCardView; ///分割线 @property (nonatomic,strong) UIView * sepLineView; ///操作的容器 @@ -145,6 +148,7 @@ [self.view addSubview:self.nobleImageView]; [self.stackView addArrangedSubview:self.userInfoView]; + [self.stackView addArrangedSubview:self.skillCardView]; [self.stackView addArrangedSubview:self.collectionView]; [self.stackView addArrangedSubview:self.sepLineView]; [self.stackView addArrangedSubview:self.operaStackView]; @@ -207,6 +211,10 @@ make.top.mas_equalTo(self.backView).mas_offset(-70); make.right.mas_equalTo(self.backView).offset(nobleMargin*0.5); make.left.mas_equalTo(self.backView).mas_offset(-nobleMargin*0.5); + }]; + [self.skillCardView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(self.userInfoView); + make.height.mas_equalTo(0); }]; [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(self.userInfoView); @@ -516,6 +524,12 @@ } else { self.reportButton.hidden = NO; } + if (userInfo.absCardPics.count) { + [self.skillCardView mas_updateConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(30); + }]; + } + self.skillCardView.dataArray = userInfo.absCardPics; } - (void)onGetFunctionArraySccess:(NSArray *)array { @@ -1035,6 +1049,13 @@ return _idLabel; } +- (XPUserCardSkillCardView *)skillCardView { + if (!_skillCardView) { + _skillCardView = [[XPUserCardSkillCardView alloc] init]; + } + return _skillCardView; +} + - (UICollectionView *)collectionView{ if (!_collectionView) { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];