XYMakingFriendsMainViewController.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //
  2. // XYMakingFriendsMainViewController.m
  3. // Starbuds
  4. //
  5. // Created by 翟玉磊 on 2020/12/4.
  6. // Copyright © 2020 翟玉磊. All rights reserved.
  7. //
  8. #import "XYMakingFriendsMainViewController.h"
  9. #import "XYVoiceMatchViewController.h"
  10. #import "XYMakingFriendsSkillViewController.h"
  11. #import "XYMakingFriendsMainSkillMaskView.h"
  12. #import "XYMarkingFriendsMainSkillTopView.h"
  13. #import "XYPeiPlayUserInfoEditAlertView.h"
  14. /*
  15. 滑动生效距离
  16. */
  17. #define SlideDistance 50.0f
  18. typedef enum : NSUInteger {
  19. XYMakingFriendsSlideStateNormal, // 默认状态(显示语音速配)
  20. XYMakingFriendsSlideStateUpSlideing, // 向上滑动中(松手进入切换状态中)
  21. XYMakingFriendsSlideStateShowSkill, // 显示技能列表(动画已结束)
  22. XYMakingFriendsSlideStateDownSlideing, // 向下滑动中(松手今日切换到速配界面动画中)
  23. } XYMakingFriendsSlideState;
  24. @interface XYMakingFriendsMainViewController ()
  25. @property (nonatomic, strong) UIView *voiceMatchingView;
  26. @property (nonatomic, strong) UIImageView *voiceMatchingBgImageView;
  27. @property (nonatomic, strong) XYVoiceMatchViewController *voiceMatchViewController;
  28. @property (nonatomic, strong) UIView *middleView;
  29. @property (nonatomic, strong) UIImageView *middleBgView;
  30. @property (nonatomic, strong) UIImageView *middleImageView;
  31. @property (nonatomic, strong) XYMarkingFriendsMainSkillTopView *skillTopView;
  32. @property (nonatomic, strong) UIView *listView;
  33. @property (nonatomic, strong) UIImageView *listMenuBgImageView;
  34. @property (nonatomic, strong) XYMakingFriendsSkillViewController *skillViewController;
  35. /// 列表蒙版
  36. @property (nonatomic, strong) XYMakingFriendsMainSkillMaskView *listMaskView;
  37. @property (nonatomic, assign) XYMakingFriendsSlideState slideState;
  38. /// 下拉开始的触摸点
  39. @property (nonatomic, assign) CGPoint downBeginPoint;
  40. @property (nonatomic, assign) CGFloat currentSkillListScrollOffsetY;
  41. @end
  42. @implementation XYMakingFriendsMainViewController
  43. - (void)dealloc {
  44. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"SKILL_LIST_SCROLL_OFFSET_Y" object:nil];
  45. }
  46. - (instancetype)init
  47. {
  48. self = [super init];
  49. if (self) {
  50. self.prefersNavigationBarHidden = YES;
  51. }
  52. return self;
  53. }
  54. - (void)viewDidLoad {
  55. [super viewDidLoad];
  56. // Do any additional setup after loading the view.
  57. // 设置默认状态
  58. self.slideState = XYMakingFriendsSlideStateNormal;
  59. [self setupUI];
  60. // 添加拖动手势
  61. // self.view.userInteractionEnabled = YES;
  62. // UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
  63. // [self.view addGestureRecognizer:pan];
  64. // v1.10
  65. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveSkillListScrollOffsetYNotification:) name:@"SKILL_LIST_SCROLL_OFFSET_Y" object:nil];
  66. //资料完善度提醒(内部做分数判断)
  67. [[XYPeiPlayUserInfoEditAlertView shareInstance] show:JoinTypeVoiceChat];
  68. }
  69. - (void)setupUI {
  70. [self.view addSubview:self.middleView];
  71. [self.middleView addSubview:self.middleBgView];
  72. [self.middleView addSubview:self.middleImageView];
  73. [self.middleView addSubview:self.skillTopView];
  74. [self.view addSubview:self.voiceMatchingView];
  75. [self.view addSubview:self.listView];
  76. }
  77. - (void)saveSkillListScrollOffsetYNotification:(NSNotification *)notification {
  78. CGFloat offsetY = [notification.object[@"offsetY"] floatValue];
  79. self.currentSkillListScrollOffsetY = offsetY;
  80. }
  81. #pragma mark — Action
  82. - (void)panAction:(UIPanGestureRecognizer *)panGestureRecognizer {
  83. CGPoint movePoint = [panGestureRecognizer translationInView:self.view];
  84. NSLog(@"movePoint:%@", NSStringFromCGPoint(movePoint));
  85. if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) {
  86. // 只处理下拉触发点 进行保存 用来判断触摸的是哪个位置
  87. if (self.slideState == XYMakingFriendsSlideStateShowSkill) {
  88. // 获取触摸点
  89. CGPoint locationPoint = [panGestureRecognizer locationInView:self.view];
  90. self.downBeginPoint = locationPoint;
  91. }
  92. }else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
  93. switch (self.slideState) {
  94. case XYMakingFriendsSlideStateNormal:
  95. case XYMakingFriendsSlideStateUpSlideing:
  96. // 根据滑动距离切换状态
  97. if (movePoint.y > 0) {
  98. return;
  99. }
  100. self.voiceMatchingView.frame = CGRectMake(self.voiceMatchingView.f_x, movePoint.y, self.voiceMatchingView.f_width, self.voiceMatchingView.f_heigh);
  101. self.listView.frame = CGRectMake(self.listView.f_x, self.voiceMatchingView.f_top-68.0f, self.listView.f_width, self.listView.f_heigh);
  102. if (movePoint.y > -SlideDistance) {
  103. // 回复原位
  104. self.slideState = XYMakingFriendsSlideStateNormal;
  105. }else {
  106. // 松手则进入刷新状态
  107. self.slideState = XYMakingFriendsSlideStateUpSlideing;
  108. }
  109. break;
  110. case XYMakingFriendsSlideStateShowSkill:
  111. {
  112. // 根据滑动距离切换状态
  113. if (movePoint.y < 0) {
  114. return;
  115. }
  116. if (self.downBeginPoint.y < (STATUS_HEIGHT+48.0f+20.0f)) {
  117. // 触发点在顶部中间层
  118. self.middleView.frame = CGRectMake(self.middleView.f_x, -self.middleView.f_heigh+self.middleImageView.f_heigh+movePoint.y, self.middleView.f_width, self.middleView.f_heigh);
  119. self.listView.frame = CGRectMake(self.listView.f_x, STATUS_HEIGHT+48.0f+movePoint.y, self.listView.f_width, self.listView.f_heigh);
  120. }else {
  121. if (self.currentSkillListScrollOffsetY > 0 ) {
  122. return;
  123. }
  124. // 触发点在skillView上
  125. self.skillViewController.view.frame = CGRectMake(self.skillViewController.view.f_x, 20.0f+movePoint.y, self.skillViewController.view.f_width, self.skillViewController.view.f_heigh);
  126. }
  127. if (movePoint.y < SlideDistance) {
  128. // 回复原位
  129. self.slideState = XYMakingFriendsSlideStateShowSkill;
  130. }else {
  131. // 松手则进入刷新状态
  132. self.slideState = XYMakingFriendsSlideStateDownSlideing;
  133. }
  134. // 交友Tab,点底部区域[上滑]的次数
  135. // [StatisticsManager event:@"match_slideup_click"];
  136. }
  137. break;
  138. case XYMakingFriendsSlideStateDownSlideing:
  139. // 根据滑动距离切换状态
  140. if (movePoint.y < 0) {
  141. return;
  142. }
  143. if (self.downBeginPoint.y < (STATUS_HEIGHT+48.0f+20.0f)) {
  144. // 触发点在顶部中间层
  145. self.middleView.frame = CGRectMake(self.middleView.f_x, -self.middleView.f_heigh+self.middleImageView.f_heigh+movePoint.y, self.middleView.f_width, self.middleView.f_heigh);
  146. self.listView.frame = CGRectMake(self.listView.f_x, STATUS_HEIGHT+48.0f+movePoint.y, self.listView.f_width, self.listView.f_heigh);
  147. }else {
  148. // 触发点在skillView上
  149. self.skillViewController.view.frame = CGRectMake(self.skillViewController.view.f_x, 20.0f+movePoint.y, self.skillViewController.view.f_width, self.skillViewController.view.f_heigh);
  150. }
  151. if (movePoint.y < SlideDistance) {
  152. // 回复原位
  153. self.slideState = XYMakingFriendsSlideStateShowSkill;
  154. }else {
  155. // 松手则进入刷新状态
  156. self.slideState = XYMakingFriendsSlideStateDownSlideing;
  157. }
  158. break;
  159. default:
  160. // 其他状态不需要处理
  161. break;
  162. }
  163. }else if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
  164. // 销毁保存的触摸点
  165. self.downBeginPoint = CGPointZero;
  166. [self changeState:self.slideState];
  167. }
  168. }
  169. /// 快速匹配
  170. - (void)quickMatchAction {
  171. self.slideState = XYMakingFriendsSlideStateDownSlideing;
  172. [self changeState:self.slideState];
  173. // 开启匹配/取消匹配
  174. [self.voiceMatchViewController startVoiceMatch];
  175. }
  176. - (void)changeState:(XYMakingFriendsSlideState)state {
  177. switch (state) {
  178. case XYMakingFriendsSlideStateNormal:
  179. {
  180. // 回复到原状态
  181. [UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  182. self.voiceMatchingView.frame = CGRectMake(self.voiceMatchingView.f_x, 0, self.voiceMatchingView.f_width, self.voiceMatchingView.f_heigh);
  183. self.listView.frame = CGRectMake(self.listView.f_x, self.voiceMatchingView.f_top-68.0f, self.listView.f_width, self.listView.f_heigh);
  184. } completion:^(BOOL finished) {
  185. }];
  186. }
  187. break;
  188. case XYMakingFriendsSlideStateUpSlideing:
  189. {
  190. // 切换到技能界面
  191. [UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  192. self.voiceMatchingView.frame = CGRectMake(self.voiceMatchingView.f_x, -self.voiceMatchingView.f_heigh+68.0f, self.voiceMatchingView.f_width, self.voiceMatchingView.f_heigh);
  193. self.listView.frame = CGRectMake(self.listView.f_x, self.voiceMatchingView.f_top-68.0f, self.listView.f_width, self.listView.f_heigh);
  194. } completion:^(BOOL finished) {
  195. self.skillTopView.hidden = NO;
  196. [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  197. self.voiceMatchingView.frame = CGRectMake(self.voiceMatchingView.f_x, -self.voiceMatchingView.f_heigh, self.voiceMatchingView.f_width, self.voiceMatchingView.f_heigh);
  198. self.middleView.frame = CGRectMake(self.middleView.f_x, -self.middleView.f_heigh+self.middleImageView.f_heigh, self.middleView.f_width, self.middleView.f_heigh);
  199. self.listView.frame = CGRectMake(self.listView.f_x, STATUS_HEIGHT+48.0f, self.listView.f_width, self.listView.f_heigh);
  200. } completion:^(BOOL finished) {
  201. // 切换状态
  202. self.slideState = XYMakingFriendsSlideStateShowSkill;
  203. self.listMaskView.hidden = YES;
  204. if (self.voiceMatchViewController.matchStatus == XYVoiceMatchingStatusOpenMatching) {
  205. // 匹配中 则需要取消匹配
  206. [self.voiceMatchViewController startVoiceMatch];
  207. }
  208. }];
  209. }];
  210. }
  211. break;
  212. case XYMakingFriendsSlideStateShowSkill:
  213. {
  214. // 回复到技能界面
  215. [UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  216. self.middleView.frame = CGRectMake(self.middleView.f_x, -self.middleView.f_heigh+self.middleImageView.f_heigh, self.middleView.f_width, self.middleView.f_heigh);
  217. self.listView.frame = CGRectMake(self.listView.f_x, STATUS_HEIGHT+48.0f, self.listView.f_width, self.listView.f_heigh);
  218. self.skillViewController.view.frame = CGRectMake(self.skillViewController.view.f_x, 20.0f, self.skillViewController.view.f_width, self.skillViewController.view.f_heigh);
  219. } completion:^(BOOL finished) {
  220. }];
  221. }
  222. break;
  223. case XYMakingFriendsSlideStateDownSlideing:
  224. {
  225. // 切换到原始状态
  226. // 开始显示速配动画
  227. [UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  228. self.middleView.frame = CGRectMake(self.middleView.f_x, -self.middleView.f_heigh, self.middleView.f_width, self.middleView.f_heigh);
  229. self.voiceMatchingView.frame = CGRectMake(self.voiceMatchingView.f_x, 0, self.voiceMatchingView.f_width, self.voiceMatchingView.f_heigh);
  230. self.listView.frame = CGRectMake(self.listView.f_x, self.voiceMatchingView.f_top-68.0f, self.listView.f_width, self.listView.f_heigh);
  231. self.skillViewController.view.frame = CGRectMake(self.skillViewController.view.f_x, 20.0f, self.skillViewController.view.f_width, self.skillViewController.view.f_heigh);
  232. } completion:^(BOOL finished) {
  233. // 切换状态
  234. self.slideState = XYMakingFriendsSlideStateNormal;
  235. self.listMaskView.hidden = NO;
  236. self.skillTopView.hidden = YES;
  237. }];
  238. }
  239. break;
  240. }
  241. }
  242. #pragma mark — Getter
  243. - (UIView *)voiceMatchingView {
  244. if (!_voiceMatchingView) {
  245. _voiceMatchingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
  246. _voiceMatchingBgImageView = [[UIImageView alloc] initWithFrame:self.voiceMatchingView.bounds];
  247. _voiceMatchingBgImageView.image = ImageNamed(@"xy_friend_qm_bg");
  248. [_voiceMatchingView addSubview:_voiceMatchingBgImageView];
  249. _voiceMatchViewController = XYVoiceMatchViewController.new;
  250. [self addChildViewController:_voiceMatchViewController];
  251. [_voiceMatchingView addSubview:_voiceMatchViewController.view];
  252. _voiceMatchViewController.view.frame = _voiceMatchingView.bounds;
  253. kWEAKSELF
  254. _voiceMatchViewController.XYVoiceMatchViewControllerUserArrsBlock = ^(NSMutableArray * _Nonnull userArrs) {
  255. [weakSelf.skillTopView setupMatchUserArray:userArrs];
  256. };
  257. }
  258. return _voiceMatchingView;
  259. }
  260. - (UIImageView *)voiceMatchingBgImageView {
  261. if (!_voiceMatchingBgImageView) {
  262. _voiceMatchingBgImageView = [[UIImageView alloc] initWithFrame:self.voiceMatchingView.bounds];
  263. _voiceMatchingBgImageView.image = ImageNamed(@"xy_friend_qm_bg");
  264. }
  265. return _voiceMatchingBgImageView;
  266. }
  267. - (UIView *)middleView {
  268. if (!_middleView) {
  269. _middleView = [[UIView alloc] initWithFrame:CGRectMake(0, -SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT-TABBAR_HEIGHT)];
  270. _middleView.backgroundColor = Color_Clear;
  271. }
  272. return _middleView;
  273. }
  274. - (UIImageView *)middleBgView {
  275. if (!_middleBgView) {
  276. _middleBgView = [[UIImageView alloc] initWithFrame:self.middleView.bounds];
  277. _middleBgView.image = ImageNamed(@"xy_friend_qm_bg");
  278. }
  279. return _middleBgView;
  280. }
  281. - (UIImageView *)middleImageView {
  282. if (!_middleImageView) {
  283. _middleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, self.middleView.f_heigh-136.0f, self.middleView.f_width, 136.0f)];
  284. _middleImageView.image = ImageNamed(@"xy_friend_middle_bg");
  285. }
  286. return _middleImageView;
  287. }
  288. - (XYMarkingFriendsMainSkillTopView *)skillTopView {
  289. if (!_skillTopView) {
  290. _skillTopView = [[XYMarkingFriendsMainSkillTopView alloc] initWithFrame:CGRectMake(0, self.middleImageView.f_y+STATUS_HEIGHT, self.middleView.f_width, 48.0f)];
  291. _skillTopView.hidden = YES;
  292. WeakSelf
  293. [_skillTopView setQuickMatchBlock:^{
  294. // 快速匹配
  295. [weakSelf quickMatchAction];
  296. }];
  297. }
  298. return _skillTopView;
  299. }
  300. - (UIView *)listView {
  301. if (!_listView) {
  302. // _listView = [[UIView alloc] initWithFrame:CGRectMake(0, self.voiceMatchingView.f_top-68.0f, SCREEN_WIDTH, SCREEN_HEIGHT - STATUS_HEIGHT - 48.0f)];
  303. // _listView.backgroundColor = Color_Clear;
  304. //
  305. // _listMenuBgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 68.0f)];
  306. // _listMenuBgImageView.image = ImageNamed(@"xy_friend_menu_bg");
  307. // [_listView addSubview:_listMenuBgImageView];
  308. //
  309. // _skillViewController = XYMakingFriendsSkillViewController.new;
  310. // [self addChildViewController:_skillViewController];
  311. // [_listView addSubview:_skillViewController.view];
  312. // _skillViewController.view.frame = CGRectMake(0, 20.0f, _listView.f_width, _listView.f_heigh - 20.0f);
  313. //
  314. // _listMaskView = [[XYMakingFriendsMainSkillMaskView alloc] initWithFrame:_skillViewController.view.frame];
  315. // _listMaskView.backgroundColor = ColorFromHexStringWithAlpha(@"#FFFFFF", 0.4);
  316. // [_listView addSubview:_listMaskView];
  317. }
  318. return _listView;
  319. }
  320. @end