No Description

PindanDetailController.m 43KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. //
  2. // PDDetailViewController.m
  3. // FirstLink
  4. //
  5. // Created by 王孝道 on 15/6/3.
  6. // Copyright (c) 2015年 FirstLink. All rights reserved.
  7. // 拼单详情页面
  8. #import "PindanDetailController.h"
  9. #import "PindanSelectDetailView.h"
  10. #import "PdDetailKeyboardInputView.h"
  11. #import "SubmitOrderController.h"
  12. #import "PindanDeleteCommentView.h"
  13. #import "ChatViewController.h"
  14. #import "FLImageHelper.h"
  15. #import "FLShareHelper.h"
  16. #import "WebViewController.h"
  17. #import "FLControllerHelper.h"
  18. #import "FLProgressHUDHelper.h"
  19. #import "PindanDetailHeaderView.h"
  20. #import "DetailNavigationBar.h"
  21. #import "UIImageView+FLAddition.h"
  22. #import "PdProductShowCell.h"
  23. #import "PdCommentCell.h"
  24. #import "DetailMainImgCell.h"
  25. #import "DetailPriceExplainCell.h"
  26. #import "DetailTalkCell.h"
  27. #import "DetailTransitHeaderCell.h"
  28. #import "DetailTransitCommonCell.h"
  29. #import "DetailAuthorityCell.h"
  30. #import "DetailProductHeaderCell.h"
  31. #import "DetailFeatureCell.h"
  32. #import "DetailSourceCell.h"
  33. #import "DetailCommentHeadCell.h"
  34. #import "DetailNoCommentCell.h"
  35. #import "DetailMoreCommentCell.h"
  36. #import "FKCollectAnimationTool.h"
  37. #import "FKBuyRemindView.h"
  38. #import "FKDetailReform.h"
  39. #import "FKDetailRequest.h"
  40. #import "XHImageViewer.h"
  41. #import "FKWeixinShareView.h"
  42. #define contentOffsetKeyPath @"contentOffset"
  43. #define SHOW_IDCARD_ALERT_TAG 666
  44. @interface PindanDetailController () <UITableViewDataSource, UITableViewDelegate, DetailPriceExplainCellDelegate, PDDetailMenuDelegate, FKBuyRemindViewDelegate, FLNetworkDelegate, PdProductShowCellDelegate, FKCollectAnimationToolDelegate, UIAlertViewDelegate>
  45. @property (nonatomic, strong) PindanDetailViewModel *viewModel;
  46. @property (nonatomic, strong) NSString *userID;
  47. @property (nonatomic, strong) NSString *postID;
  48. @property (nonatomic, strong) UITableView *tableView;
  49. @property (nonatomic, strong) DetailNavigationBar *navBar;
  50. @property (nonatomic, strong) PdDetailBottomView *bottomView;
  51. @property (nonatomic, strong) PindanDetailHeaderView *itemShowHeaderView;
  52. @property (nonatomic, strong) PdDetailKeyboardInputView *boardInputView; // 键盘弹出辅助输入视图
  53. @property (nonatomic, strong) PindanDeleteCommentView *deleteCommentView; // 删除自己的评论
  54. @property (nonatomic, strong) PindanSelectDetailView *selectDetailView; // 选择规格和数量
  55. @property (nonatomic, strong) UIView *coverView;
  56. @property (nonatomic, strong) NSTimer *countTimer;
  57. @property (nonatomic, strong) UIButton *arrowBtn;
  58. @property (nonatomic, strong) XHImageViewer *imageBrowser; // 图片查看器
  59. @property (nonatomic, strong) FKCollectAnimationTool *collectAnimTool; // 收藏动画管理
  60. @end
  61. @implementation PindanDetailController
  62. - (instancetype)initWithUserID:(NSString *)userID postID:(NSString *)postID {
  63. self = [super init];
  64. if (self) {
  65. self.viewModel.userID = @"0";
  66. self.viewModel.postID = postID;
  67. }
  68. return self;
  69. }
  70. - (void)viewDidLoad {
  71. [super viewDidLoad];
  72. self.edgesForExtendedLayout = UIRectEdgeAll;
  73. self.automaticallyAdjustsScrollViewInsets = NO;
  74. if (self.openURLPara) {
  75. self.viewModel.userID = @"0";
  76. self.viewModel.postID = self.openURLPara[@"post_id"];
  77. }
  78. [self addRefresh];
  79. [self configTableView];
  80. [self configKeyboardNotifications];
  81. [self addAllSubViews];
  82. }
  83. - (void)dealloc {
  84. [[NSNotificationCenter defaultCenter] removeObserver:self];
  85. [self.tableView removeObserver:self.navBar forKeyPath:contentOffsetKeyPath];
  86. [self.tableView removeObserver:self forKeyPath:contentOffsetKeyPath];
  87. }
  88. - (void)viewWillAppear:(BOOL)animated {
  89. [super viewWillAppear:animated];
  90. [UIApplication sharedApplication].statusBarHidden = NO;
  91. [self.navigationController setNavigationBarHidden:YES animated:YES];
  92. [self requestForInitialData];
  93. }
  94. - (void)viewDidAppear:(BOOL)animated {
  95. [super viewDidAppear:animated];
  96. [self.tabBarController.tabBar setHidden:YES];
  97. // [self.tabBarController.tabBar setTranslucent:YES];
  98. }
  99. - (void)viewWillDisappear:(BOOL)animated {
  100. [super viewWillDisappear:animated];
  101. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
  102. }
  103. - (void)viewDidDisappear:(BOOL)animated {
  104. [super viewDidDisappear:animated];
  105. [self.countTimer invalidate]; self.countTimer = nil;
  106. }
  107. #pragma mark - Request
  108. - (void)addRefresh{
  109. [self initRefreshControlWithTableView:self.tableView];
  110. [self.refreshControl setBottomEnabled:NO];
  111. }
  112. - (void)forceRefresh {
  113. [self requestForInitialData];
  114. }
  115. - (void)requestForInitialData {
  116. // 请求初始化数据
  117. [self.hudView show:YES];
  118. NSDictionary *infoDict = [self.viewModel infoForRequestType:kRequestTypeDetail withInfo:nil];
  119. [FKDetailRequest requestWithType:kRequestTypeDetail info:infoDict delegate:self];
  120. }
  121. - (void)requestWarnWithBottomState:(kPindanState)state {
  122. BOOL remindState = state == kPindanStateRemind ? YES : NO;
  123. kRequestType type = remindState ? kRequestTypeAddLike : kRequestTypeRemoveLike;
  124. NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil];
  125. [FKDetailRequest requestWithType:type info:infoDict delegate:self];
  126. }
  127. - (void)refreshCommentWithScroll:(BOOL)scrollToComment {
  128. // 重新刷新评论数据
  129. [self.hudView show:NO];
  130. kRequestType type = scrollToComment ? kRequestTypeRefreshCommentScroll : kRequestTypeRefreshComment;
  131. NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil];
  132. [FKDetailRequest requestWithType:type info:infoDict delegate:self];
  133. }
  134. - (void)trackBehaviorWithType:(kBehaviorType)type{
  135. // 行为统计
  136. NSString *jsonStr = [FLRequestHelper JSONStringWithKeys:@[@"post_id"] values:@[self.viewModel.postID]];
  137. [BehaviorTrackManger requestBehaviorType:type jsonString:jsonStr];
  138. }
  139. #pragma mark - refresh delegate
  140. - (void)refreshControl:(FKRefreshControl *)refreshControl didEngageRefreshDirection:(RefreshDirection)direction{
  141. if (direction == RefreshDirectionTop) {
  142. [self requestForInitialData];
  143. }
  144. }
  145. #pragma mark - response
  146. - (void)networkDidSuccessResponse:(NSDictionary*)response identify:(int)identify header:(MSGHeader*)header {
  147. [self.refreshControl finishRefreshingDirection:RefreshDirectionTop];
  148. WeakSelf(weakSelf);
  149. dispatch_async(dispatch_get_main_queue(), ^{
  150. [weakSelf.hudView hide:YES];
  151. [weakSelf.hudView removeFromSuperview];
  152. weakSelf.hudView = nil;
  153. });
  154. if (header.code.intValue == RESPONSE_MSG_NORMAL) {
  155. switch (identify) {
  156. case kRequestTypeDetail: {
  157. [self.viewModel saveIntoDataSource:[FKDetailReform parserDetailItemWithDict:response]];
  158. if (self.selectDetailView.specsArray.count > 0) {
  159. self.viewModel.pindanDetailItem.specsArray = self.selectDetailView.specsArray;
  160. }
  161. [self refreshContent];
  162. break;
  163. }
  164. case kRequestTypeAddCollect:{
  165. [self.viewModel setIsFavorite:YES];
  166. [self configCollectButton:YES];
  167. [self.tableView reloadData];
  168. break;
  169. }
  170. case kRequestTypeRemoveCollect:{
  171. [self.viewModel setIsFavorite:NO];
  172. [self configCollectButton:NO];
  173. [self.tableView reloadData];
  174. break;
  175. }
  176. case kRequestTypeShareUrlCircle:{
  177. [self.viewModel setShareURL:[FKDetailReform parserShareURLwithDict:response]];
  178. [self shareToFriendCircle:YES withUrlString:[self.viewModel shareURL]];
  179. break;
  180. }
  181. case kRequestTypeShareUrlFriend:{
  182. [self.viewModel setShareURL:[FKDetailReform parserShareURLwithDict:response]];
  183. [self shareToFriendCircle:NO withUrlString:[self.viewModel shareURL]];
  184. break;
  185. }
  186. case kRequestTypeAddLike:{
  187. self.bottomView.state = kPindanStateCancelRemind;
  188. [FLProgressHUDHelper showText:@"开售提醒成功, 拼单再次开启时\n我们会以短信方式提醒您!" inView:self.view];
  189. break;
  190. }
  191. case kRequestTypeRemoveLike:{
  192. self.bottomView.state = kPindanStateRemind;
  193. [FLProgressHUDHelper showText:@"取消开售提醒成功" inView:self.view];
  194. break;
  195. }
  196. case kRequestTypeRefreshComment:{
  197. [self.viewModel setCommentArray:[FKDetailReform parserCommentArrayWithDict:response]];
  198. [self.viewModel setCommentCount:[FKDetailReform parserCommentCountWithDict:response]];
  199. [self.tableView reloadData];
  200. break;
  201. }
  202. case kRequestTypeRefreshCommentScroll:{
  203. [self.viewModel setCommentArray:[FKDetailReform parserCommentArrayWithDict:response]];
  204. [self.viewModel setCommentCount:[FKDetailReform parserCommentCountWithDict:response]];
  205. [self.tableView reloadData];
  206. [self scrollToCommentArea];
  207. break;
  208. }
  209. case kRequestTypeAddSelfComment:
  210. case kRequestTypeAddOtherComment:{
  211. [self refreshCommentWithScroll:YES];
  212. break;
  213. }
  214. case kRequestTypeRemoveComment:{
  215. [self refreshCommentWithScroll:NO];
  216. break;
  217. }
  218. default:
  219. break;
  220. }
  221. } else{
  222. [FLProgressHUDHelper showText:header.msg inView:self.view];
  223. }
  224. }
  225. - (void)networkDidReceiveError:(NSError*)error identify:(int)identify header:(MSGHeader*)header{
  226. WeakSelf(weakSelf);
  227. dispatch_async(dispatch_get_main_queue(), ^{
  228. [weakSelf.hudView hide:YES];
  229. [weakSelf.hudView removeFromSuperview];
  230. weakSelf.hudView = nil;
  231. });
  232. [self.refreshControl finishRefreshingDirection:RefreshDirectionTop];
  233. [FLProgressHUDHelper showText:header.msg inView:self.view];
  234. }
  235. #pragma mark - TableView DataSource
  236. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  237. return [self.viewModel numberOfSectionsInTableView];
  238. }
  239. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  240. return [self.viewModel numberOfRowsInSection:section];
  241. }
  242. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  243. return [self.viewModel cellHeightForIndexPath:indexPath];
  244. }
  245. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  246. return CGFLOAT_MIN;
  247. }
  248. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  249. if (section == 1) return CGFLOAT_MIN;
  250. return 10;
  251. }
  252. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  253. kDetailCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath];
  254. UITableViewCell *targetCell = [tableView dequeueReusableCellWithIdentifier:[self.viewModel cellIdentifyForIndexPath:indexPath]];
  255. switch (cellType) {
  256. case kDetailCellTypePriceExplain:{
  257. DetailPriceExplainCell *priceCell = (DetailPriceExplainCell *)targetCell;
  258. [priceCell configWithDetailViewModel:self.viewModel indexPath:indexPath];
  259. priceCell.delegate = self;
  260. [priceCell.collectBtn addTarget:self action:@selector(collectBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  261. }
  262. break;
  263. case kDetailCellTypeProductShow: {
  264. ProductShowItem *showItem = [self.viewModel productShowArray][indexPath.row - 1];
  265. PdProductShowCell *showCell = (PdProductShowCell *)targetCell;
  266. [showCell configWithShowItem:showItem];
  267. showCell.delegate = self;
  268. }
  269. break;
  270. case kDetailCellTypeComment:{
  271. PdCommentCell *commentCell = (PdCommentCell *)targetCell;
  272. [self configCommentCell:commentCell forIndexPath:indexPath];
  273. }
  274. break;
  275. case kDetailCellTypeMoreComment:{
  276. DetailMoreCommentCell *moreCell = (DetailMoreCommentCell *)targetCell;
  277. [moreCell.moreActionBtn addTarget:self action:@selector(pushAllCommentBtn) forControlEvents:UIControlEventTouchUpInside];
  278. }
  279. break;
  280. case kDetailCellTypeProductHeader:
  281. case kDetailCellTypeFeature:
  282. case kDetailCellTypeNoComment:{
  283. return targetCell;
  284. }
  285. break;
  286. default:
  287. [targetCell configWithDetailViewModel:self.viewModel indexPath:indexPath];
  288. break;
  289. }
  290. return targetCell;
  291. }
  292. #pragma mark - TableView Delegate
  293. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  294. kDetailCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath];
  295. UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
  296. switch (cellType) {
  297. case kDetailCellTypeMainImg:{
  298. [self clickImgCell:cell atIndex:indexPath];
  299. }
  300. break;
  301. case kDetailCellTypeSpecGuige:{
  302. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  303. [self showLoginActionMenu];
  304. return;
  305. }
  306. [self.selectDetailView showToView:self.navigationController.view animated:YES];
  307. }
  308. break;
  309. case kDetailCellTypeComment:{
  310. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  311. [self showLoginActionMenu];
  312. return;
  313. }
  314. // 点击评论
  315. self.boardInputView.tag = indexPath.row - 1;
  316. if ([self.viewModel isCommentBySelfForRow:indexPath.row - 1]) { // 删除自己的评论
  317. [self.deleteCommentView showInView:self.view animated:YES];
  318. return;
  319. }
  320. [self.boardInputView.textView becomeFirstResponder];
  321. }
  322. break;
  323. case kDetailCellTypeTransitLink:{
  324. if (![FLStringHelper isUrlString:[self.viewModel buyChannel]]) return;
  325. [self pushWebViewControllerWithUrl:[self.viewModel buyChannel]];
  326. [self trackBehaviorWithType:kBehaviorDetailLink];
  327. }
  328. break;
  329. case kDetailCellTypeNoComment:{
  330. self.boardInputView.tag = - 1;
  331. [self.boardInputView.textView becomeFirstResponder];
  332. }
  333. break;
  334. default:
  335. break;
  336. }
  337. }
  338. #pragma mark - Cells Delegate
  339. - (void)clickProductImg:(PdProductShowCell *)cell{
  340. NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
  341. if (indexPath){
  342. [self clickImgCell:cell atIndex:indexPath];
  343. }
  344. }
  345. - (void)clickImgCell:(UITableViewCell *)imgCell atIndex:(NSIndexPath *)indexPath{
  346. if (imgCell && indexPath) {
  347. [self showImgBrowerWithSelectIndex:indexPath.row sourceCell:imgCell];
  348. }
  349. }
  350. - (void)showImgBrowerWithSelectIndex:(NSUInteger)index sourceCell:(UITableViewCell *)sourceCell{
  351. NSArray *imgUrlArray = [self.viewModel allProductIMGURLArray];
  352. NSMutableArray *imgArrayM = [NSMutableArray arrayWithCapacity:imgUrlArray.count];
  353. for (int i = 0; i < imgUrlArray.count; i++) {
  354. UIImageView *newImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, UISCREENWIDTH, UISCREENWIDTH)];
  355. if (i > 0){
  356. ProductShowItem *showItem = [self.viewModel showItemAtIndex:i - 1];
  357. if (showItem) newImgView.frame = CGRectMake(0, 0, UISCREENWIDTH, [showItem realImgHeightForRealWidth:UISCREENWIDTH]);
  358. }
  359. [newImgView sd_setImageWithURL:[NSURL URLWithString:imgUrlArray[i]]];
  360. if (i == index) [sourceCell.contentView addSubview:newImgView];
  361. [imgArrayM addObject:newImgView];
  362. }
  363. [self.imageBrowser showWithImageViews:imgArrayM selectedView:(UIImageView *)imgArrayM[index]];
  364. }
  365. - (void)priceDetailCell:(DetailPriceExplainCell *)cell showPriceExplain:(BOOL)show {
  366. self.viewModel.showPriceExplain = show;
  367. NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
  368. if (indexPath) {
  369. [self.tableView reloadData];
  370. }
  371. }
  372. - (void)shareToFriendCircle:(BOOL)isFriendCircle withUrlString:(NSString *)url {
  373. if (!url || url.length == 0) return;
  374. NSString *title = [self.viewModel title];
  375. NSString *desc = [self.viewModel introduceText];
  376. UIImage *image = [self firstPhotoForShare];
  377. // NSString *urlString = [NSString stringWithFormat:@"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx29b4f4d1f6839e5a&redirect_uri=%s&response_type=code&scope=snsapi_base&state=1#wechat_redirect", url.UTF8String];
  378. if (image) {
  379. [FLShareHelper shareToWeixin:title description:desc thumbImage:image webURL:url scene:isFriendCircle ? WeixinSceneCicle : WeixinSceneFriend];
  380. }
  381. }
  382. #pragma mark - Alert View Delegate
  383. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  384. if (SHOW_IDCARD_ALERT_TAG == alertView.tag) {
  385. if ([self.viewModel hasSpecs]) {
  386. [self.selectDetailView showToView:self.navigationController.view animated:YES];
  387. } else {
  388. [self pushSubmitOrderController:nil];
  389. }
  390. }
  391. }
  392. #pragma mark - RemindView Delegate
  393. - (void)remindViewClickToBuy:(FKBuyRemindView *)remindView{
  394. if (remindView.isVip == YES) {
  395. // 去管家购买
  396. [[FLControllerHelper currentTabBarController].tabBar setHidden:NO];
  397. [FLControllerHelper selectTabbarControllerAtIndex:2];
  398. [self.navigationController popToRootViewControllerAnimated:NO];
  399. } else{
  400. // 去开通Vip
  401. // FKVipBuyController *vipBuy = [[FKVipBuyController alloc]init];
  402. // vipBuy.type = FKVipBuyTypeNormal;
  403. // vipBuy.delegate = self;
  404. // [self.navigationController pushViewController:vipBuy animated:YES];
  405. }
  406. }
  407. - (void)remindViewClickToRemind:(FKBuyRemindView *)remindView{
  408. [self requestWarnWithBottomState:kPindanStateRemind];
  409. }
  410. #pragma mark - FKCollectAnimationToolDelegate
  411. - (void)allCollectAnimationFinish:(FKCollectAnimationTool *)tool{
  412. kRequestType type = tool.collectSelected ? kRequestTypeAddCollect : kRequestTypeRemoveCollect;
  413. NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil];
  414. [FKDetailRequest requestWithType:type info:infoDict delegate:self];
  415. // 用户行为打点
  416. kBehaviorType behaviorType = tool.collectSelected ? kBehaviorDetailCollect : kBehaviorDetailNoCollect;
  417. [self trackBehaviorWithType:behaviorType];
  418. }
  419. #pragma mark - PDDetailMenuDelegate
  420. - (void)detailMenuBtnClickWithIndex:(NSInteger)tag {
  421. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  422. [self showLoginActionMenu];
  423. return;
  424. }
  425. // 底部按钮事件
  426. switch (tag) {
  427. case kBottomCommentBtnTag:{
  428. // 评论
  429. self.boardInputView.tag = - 1;
  430. [self.boardInputView.textView becomeFirstResponder];
  431. }
  432. break;
  433. case kBottomServiceBtnTag:{
  434. // 客服
  435. [self pushChatViewController];
  436. [self trackBehaviorWithType:kBehaviorDetailServe];
  437. }
  438. break;
  439. case kBottomShareBtnTag:{
  440. [self showShareView];
  441. }
  442. break;
  443. case kBottomConfirmBtnTag:{
  444. [self checkBuyWithPindanStatus];
  445. }
  446. break;
  447. default:
  448. break;
  449. }
  450. }
  451. - (void)checkBuyWithPindanStatus {
  452. kPindanState state = self.bottomView.state;
  453. if (state == kPindanStateOnlyVIP || state == kPindanStateOnlyNew || state == kPindanStateWaitBegin) return;
  454. switch (state) {
  455. case kPindanStateNormal:{
  456. // 判断是否符合购买权限
  457. if ([self.viewModel isOnlyNew] == YES && [self.viewModel userOrderCount] > 0) {
  458. [FLProgressHUDHelper showText:@"该商品仅限新用户购买" inView:self.view];
  459. } else if ([self.viewModel isOnlyVIP] == YES && [self.viewModel userLevel] != kUserLevelVIP){
  460. [FLProgressHUDHelper showText:@"该商品仅限会员购买" inView:self.view];
  461. }
  462. if ([self.viewModel isNeedIDCard] && ![self.viewModel isHasShowIDCardAlert]) {
  463. [self showRequireIDCardAlert];
  464. [self.viewModel setHasShowIDCardAlert];
  465. } else {
  466. if ([self.viewModel hasSpecs]) {
  467. [self.selectDetailView showToView:self.navigationController.view animated:YES];
  468. } else {
  469. [self pushSubmitOrderController:nil];
  470. }
  471. }
  472. break;
  473. }
  474. case kPindanStateRemind:{
  475. FKBuyRemindView *remindView = [[FKBuyRemindView alloc]init];
  476. remindView.delegate = self;
  477. remindView.isVip = [self.viewModel userLevel] == kUserLevelVIP ? YES : NO;
  478. [remindView showInView:self.view];
  479. }
  480. break;
  481. case kPindanStateCancelRemind:{
  482. [self requestWarnWithBottomState:kPindanStateCancelRemind];
  483. }
  484. break;
  485. default:
  486. break;
  487. }
  488. }
  489. #pragma mark - key board observe
  490. - (void)keyboardWillChange:(NSNotification *)notification {
  491. if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) {
  492. // 键盘弹出
  493. [self showBoardViewWithNotification:notification];
  494. [self setCommentPlaceHolder];
  495. } else if ([notification.name isEqualToString:UIKeyboardWillHideNotification]){
  496. // 键盘退出
  497. [self dismissBoardViewWithNotification:notification];
  498. } else if ([notification.name isEqualToString:UIKeyboardDidShowNotification]){
  499. } else if ([notification.name isEqualToString:UIKeyboardDidHideNotification]){
  500. self.boardInputView.textView.text = @"";
  501. }
  502. }
  503. #pragma mark - tableView observe
  504. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  505. if ([keyPath isEqualToString:@"contentOffset"]) {
  506. CGFloat maxContentY = self.tableView.contentSize.height;
  507. if (maxContentY <= 0) return;
  508. CGFloat midY = (maxContentY - (UISCREENHEIGH - 50)) / 2.0f;
  509. CGFloat showY = (maxContentY - (UISCREENHEIGH - 50)) / 3.0f * 2;
  510. CGFloat newY = [change[@"new"] CGPointValue].y;
  511. if (newY >= showY) {
  512. self.arrowBtn.hidden = NO;
  513. }else if (newY <= midY){
  514. self.arrowBtn.hidden = YES;
  515. }
  516. }
  517. }
  518. #pragma mark - event response
  519. - (void)leftNaviBtnClick {
  520. [self.navigationController popViewControllerAnimated:YES];
  521. }
  522. - (void)collectBtnClick:(UIButton *)sender {
  523. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  524. [self showLoginActionMenu];
  525. return;
  526. }
  527. sender.selected = !sender.selected;
  528. [self.collectAnimTool showAnimationWithCollect:sender.selected inView:self.view];
  529. }
  530. - (void)scrollTopArrowBtnClick:(UIButton *)sender {
  531. NSIndexPath *targetIndex = [NSIndexPath indexPathForRow:0 inSection:0];
  532. [self.tableView scrollToRowAtIndexPath:targetIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
  533. }
  534. - (void)commentConfirmBtnClick {
  535. // 发送评论
  536. NSString *commentContent = self.boardInputView.textView.text;
  537. NSInteger commentIndex = self.boardInputView.tag;
  538. if (!commentContent || commentContent.length == 0){
  539. [FLProgressHUDHelper showText:@"评论内容不能为空" inView:self.view];
  540. return;
  541. }
  542. kRequestType type = commentIndex >= 0 ? kRequestTypeAddOtherComment : kRequestTypeAddSelfComment;
  543. NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithDictionary:@{COMMENT_CONTENT_KEY : commentContent}];
  544. CommentItem *item = [self.viewModel commentItemForIndex:commentIndex];
  545. if (item) {
  546. [dictM setObject:item.buyerID forKey:REPLY_TO_USER_ID_KEY];
  547. }
  548. [self.hudView show:YES];
  549. NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:dictM];
  550. [FKDetailRequest requestWithType:type info:infoDict delegate:self];
  551. [self.boardInputView.textView resignFirstResponder];
  552. [self.boardInputView resignFirstResponder];
  553. [self.view endEditing:YES];
  554. }
  555. - (void)deleteCommentButtonClick {
  556. // 删除自己的评论
  557. [self.hudView show:YES];
  558. CommentItem *item = [self.viewModel commentItemForIndex:self.boardInputView.tag];
  559. if (!item) return;
  560. NSDictionary *dict = @{COMMENT_ID_KEY : item.commentID, COMMENT_ITEM_ID_KEY : item.itemID, COMMENT_SELLER_ID_KEY : item.sellerID};
  561. NSDictionary *infoDict = [self.viewModel infoForRequestType:kRequestTypeRemoveComment withInfo:dict];
  562. [FKDetailRequest requestWithType:kRequestTypeRemoveComment info:infoDict delegate:self];
  563. [self.deleteCommentView dismissAnimation];
  564. }
  565. - (void)commentCoverViewClick {
  566. [self.boardInputView.textView resignFirstResponder];
  567. [self.boardInputView resignFirstResponder];
  568. self.boardInputView.textView.text = nil;
  569. }
  570. - (void)scrollToCommentArea {
  571. // 滚动到评论区
  572. NSIndexPath *targetIndexPath = [NSIndexPath indexPathForRow:1 inSection:([self.viewModel numberOfSectionsInTableView] - 1)];
  573. [self.tableView scrollToRowAtIndexPath:targetIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
  574. }
  575. - (void)setCommentPlaceHolder{
  576. NSString *placeHolderString = [self.viewModel getCommentPlaceHolderWithIndex:self.boardInputView.tag];
  577. if ([self.boardInputView.placeHolder isEqualToString:placeHolderString]) return; // 防止切换输入法再次发送keyboardwillshow通知,会让holder显示出来
  578. self.boardInputView.placeHolder = placeHolderString;
  579. }
  580. #pragma mark - Keyboard Notification
  581. - (void)showBoardViewWithNotification:(NSNotification *)notification {
  582. CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  583. CGRect endRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  584. UIViewAnimationOptions curve = (UIViewAnimationOptions)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  585. self.coverView.alpha = 0;
  586. WeakSelf(weakSelf);
  587. [UIView animateWithDuration:duration delay:0 options:curve animations:^{
  588. weakSelf.boardInputView.frame = CGRectMake(endRect.origin.x, endRect.origin.y - 50, CGRectGetWidth(self.boardInputView.bounds), CGRectGetHeight(self.boardInputView.bounds));
  589. weakSelf.coverView.alpha = 1.0f;
  590. } completion:^(BOOL finished) {
  591. }];
  592. }
  593. - (void)dismissBoardViewWithNotification:(NSNotification *)notification {
  594. CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
  595. CGRect endRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  596. UIViewAnimationOptions curve = (UIViewAnimationOptions)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  597. self.coverView.alpha = 1;
  598. WeakSelf(weakSelf);
  599. [UIView animateWithDuration:duration delay:0 options:curve animations:^{
  600. weakSelf.coverView.alpha = 0;
  601. weakSelf.boardInputView.frame = CGRectMake(0, endRect.origin.y, CGRectGetWidth(self.boardInputView.bounds), CGRectGetHeight(self.boardInputView.bounds));
  602. } completion:^(BOOL finished) {
  603. }];
  604. }
  605. #pragma mark - private method
  606. - (void)refreshContent {
  607. [self.tableView reloadData];
  608. [self configCountTimer];
  609. [self configCollectButton:[self.viewModel isFavorite]];
  610. [self.bottomView setState:[self.viewModel pindanState]];
  611. self.bottomView.commitBtn.hidden = NO;
  612. if ([self.viewModel hasSpecs]) {
  613. // 从提交页面回来,更新购物车
  614. [self.selectDetailView refreshSelectSpecContent];
  615. }
  616. }
  617. - (void)timeCountDown {
  618. [self.viewModel setTimeInterval:([self.viewModel timeInterval] - 1)];
  619. NSTimeInterval time = self.viewModel.timeInterval;
  620. DetailPriceExplainCell *priceCell = nil;
  621. for (UITableViewCell *cell in self.tableView.visibleCells) {
  622. if ([cell isKindOfClass:[DetailPriceExplainCell class]]){
  623. priceCell = (DetailPriceExplainCell *)cell;
  624. break;
  625. }
  626. }
  627. if (time <= 0) {
  628. if (self.viewModel.pindanState == kPindanStateWaitBegin) {
  629. self.viewModel.pindanDetailItem.isPindanBegin = YES;
  630. [self requestForInitialData];
  631. }else{
  632. self.bottomView.state = [self.viewModel isRemind] ? kPindanStateCancelRemind : kPindanStateRemind;
  633. if (priceCell){
  634. priceCell.priceLabel.textColor = UIColorFromRGB(0xcccccc);
  635. priceCell.countTimeLabel.text = @"拼单已结束";
  636. }
  637. }
  638. }else{
  639. if (priceCell) [priceCell resetTimeStrWithInterval:time isBegin:self.viewModel.pindanDetailItem.isPindanBegin];
  640. }
  641. }
  642. - (void)showShareView {
  643. FKWeixinShareView *shareView = [[FKWeixinShareView alloc]init];
  644. WeakSelf(weakSelf);
  645. [shareView showInView:self.view actionBlock:^(kShareViewActionType type) {
  646. [weakSelf clickShareForType:type];
  647. }];
  648. }
  649. - (void)clickShareForType:(kShareViewActionType)type{
  650. kRequestType reqType = (type == kShareViewActionTypeCircle) ? kRequestTypeShareUrlCircle : kRequestTypeShareUrlFriend;
  651. NSDictionary *infoDict = [self.viewModel infoForRequestType:reqType withInfo:nil];
  652. [FKDetailRequest requestWithType:reqType info:infoDict delegate:self];
  653. // 行为统计
  654. kBehaviorType beHaviorType = (type == kShareViewActionTypeFriend) ? kBehaviorDetailShareF : kBehaviorDetailShareC;
  655. [self trackBehaviorWithType:beHaviorType];
  656. }
  657. - (void)showRequireIDCardAlert {
  658. NSString *text = @"您正在购买“直邮”商品,此类商品到货时间更短哦。";
  659. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"温馨提示"
  660. message:text
  661. delegate:self
  662. cancelButtonTitle:nil
  663. otherButtonTitles:@"我知道了",
  664. nil];
  665. alertView.tag = SHOW_IDCARD_ALERT_TAG;
  666. alertView.delegate = self;
  667. [alertView show];
  668. }
  669. - (NSDictionary *)chatViewControllerExtData {
  670. return @{EXT_MSG_TYPE_V2: @{EXT_MSG_TYPE_TRACK_V2: @{EXT_MSG_TITLE_V2 : @"用户正在看商品:",
  671. EXT_MSG_PRICE_V2 : [self.viewModel totalPrice],
  672. EXT_MSG_DESC_V2 : [self.viewModel title],
  673. EXT_MSG_PIC_URL_V2 : [self.viewModel firstPic],
  674. EXT_MSG_ITEM_URL_V2 : [self.viewModel webURL],
  675. EXT_MSG_USER_ID_V2 : [self.viewModel userID],
  676. EXT_MSG_POST_ID_V2 : [self.viewModel postID]
  677. }},
  678. EXT_MSG_ORDER_TITLE: [FLStringHelper replaceNilWithEmpty:[self.viewModel title]],
  679. EXT_QUEUE_NAME : QueueNameShouqian};
  680. }
  681. - (UIImage *)firstPhotoForShare {
  682. UIImage *image = nil;
  683. for (UITableViewCell *cell in self.tableView.visibleCells) {
  684. if ([cell isKindOfClass:[DetailMainImgCell class]]) {
  685. DetailMainImgCell *mainCell = (DetailMainImgCell *)cell;
  686. image = mainCell.mainImgView.image;
  687. break;
  688. }
  689. }
  690. if (!image) {
  691. DetailMainImgCell *mainCell = [self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass([DetailMainImgCell class])];
  692. image = mainCell.mainImgView.image;
  693. }
  694. if (image) {
  695. image = [FLImageHelper generateThumbnailFromCenter:image frame:CGSizeMake(SHARE_IMAGE_LENGTH, SHARE_IMAGE_LENGTH)];
  696. } else {
  697. image = [FLImageHelper generateThumbnailFromCenter:[FLImageHelper getAppIcon] frame:CGSizeMake(SHARE_IMAGE_LENGTH, SHARE_IMAGE_LENGTH)];
  698. }
  699. return image;
  700. }
  701. #pragma mark - Push Controller
  702. - (void)pushWebViewControllerWithUrl:(NSString *)url {
  703. WebViewController *newViewController = [[FLControllerHelper currentStoryBoard] instantiateViewControllerWithIdentifier:@"WebViewController"];
  704. newViewController.url = url;
  705. newViewController.hidesBottomBarWhenPushed = YES;
  706. [self.navigationController setNavigationBarHidden:NO animated:NO];
  707. [self.navigationController pushViewController:newViewController animated:YES];
  708. }
  709. - (void)pushSubmitOrderController:(NSArray *)specArray {
  710. FKPurchaseCache *cache = [FKPurchaseCache new];
  711. [self.viewModel saveDataIntoCache:cache orderType:kOrderTypeNoraml];
  712. SubmitOrderController *submitCtrl = [[SubmitOrderController alloc] initWithPurchaseCache:cache];
  713. [self.navigationController pushViewController:submitCtrl animated:YES];
  714. }
  715. - (void)pushChatViewController {
  716. ChatViewController *chatController = [[ChatViewController alloc] initWithChatter:[self.viewModel serviceUserID]
  717. isGroup:NO];
  718. chatController.naviTitle = [self.viewModel serviceNickname];
  719. chatController.receiverHeadURL = [self.viewModel serviceHeadURL];
  720. chatController.msgExtData = [self chatViewControllerExtData];
  721. [self.navigationController pushViewController:chatController animated:YES];
  722. }
  723. - (void)pushAllCommentBtn{
  724. }
  725. #pragma mark - Config Method
  726. - (void)configCountTimer {
  727. if ([self.viewModel isProductStateEnd] || [self.viewModel isProductStateSaleDone]){
  728. [self.countTimer invalidate];
  729. } else {
  730. [self.countTimer fire];
  731. }
  732. }
  733. - (void)configCollectButton:(BOOL)status {
  734. self.navBar.collectBtn.selected = status;
  735. if (self.delegate && [self.delegate respondsToSelector:@selector(collectStatusChange:status:)]) {
  736. [self.delegate collectStatusChange:[self.viewModel postID] status:status];
  737. }
  738. }
  739. - (void)configCommentCell:(PdCommentCell *)commentCell forIndexPath:(NSIndexPath *)indexPath{
  740. CommentItem *item = [self.viewModel commentArray][indexPath.row - 1];
  741. if (item) {
  742. [commentCell.iconImgView sd_setImageWithURL:[NSURL URLWithString:item.buyerHeaderPic]];
  743. commentCell.bottomLine.hidden = NO;
  744. commentCell.timeLabel.text = [FLStringHelper convertToPredigestStringFromString:item.createTime];
  745. commentCell.commentLabel.text = item.content;
  746. commentCell.nameLabel.attributedText = [item getRealCommentTitle];
  747. NSInteger rowCount = [self.tableView numberOfRowsInSection:indexPath.section];
  748. if (indexPath.row == rowCount - 1) commentCell.bottomLine.hidden = YES;
  749. }
  750. }
  751. - (void)configKeyboardNotifications{
  752. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil];
  753. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardDidShowNotification object:nil];
  754. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillHideNotification object:nil];
  755. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardDidHideNotification object:nil];
  756. }
  757. - (void)configTableView {
  758. [self.tableView registerClass:[DetailMainImgCell class] forCellReuseIdentifier:NSStringFromClass([DetailMainImgCell class])];
  759. [self.tableView registerClass:[DetailPriceExplainCell class] forCellReuseIdentifier:NSStringFromClass([DetailPriceExplainCell class])];
  760. [self.tableView registerClass:[DetailTalkCell class] forCellReuseIdentifier:NSStringFromClass([DetailTalkCell class])];
  761. [self.tableView registerClass:[DetailTransitHeaderCell class] forCellReuseIdentifier:NSStringFromClass([DetailTransitHeaderCell class])];
  762. [self.tableView registerClass:[DetailTransitCommonCell class] forCellReuseIdentifier:NSStringFromClass([DetailTransitCommonCell class])];
  763. [self.tableView registerClass:[PdProductShowCell class] forCellReuseIdentifier:NSStringFromClass([PdProductShowCell class])];
  764. [self.tableView registerClass:[PdCommentCell class] forCellReuseIdentifier:NSStringFromClass([PdCommentCell class])];
  765. [self.tableView registerClass:[DetailAuthorityCell class] forCellReuseIdentifier:NSStringFromClass([DetailAuthorityCell class])];
  766. [self.tableView registerClass:[DetailProductHeaderCell class] forCellReuseIdentifier:NSStringFromClass([DetailProductHeaderCell class])];
  767. [self.tableView registerClass:[DetailFeatureCell class] forCellReuseIdentifier:NSStringFromClass([DetailFeatureCell class])];
  768. [self.tableView registerClass:[DetailSourceCell class] forCellReuseIdentifier:NSStringFromClass([DetailSourceCell class])];
  769. [self.tableView registerClass:[DetailCommentHeadCell class] forCellReuseIdentifier:NSStringFromClass([DetailCommentHeadCell class])];
  770. [self.tableView registerClass:[DetailNoCommentCell class] forCellReuseIdentifier:NSStringFromClass([DetailNoCommentCell class])];
  771. [self.tableView registerClass:[DetailMoreCommentCell class] forCellReuseIdentifier:NSStringFromClass([DetailMoreCommentCell class])];
  772. [self.tableView addObserver:self.navBar forKeyPath:contentOffsetKeyPath options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
  773. [self.tableView addObserver:self forKeyPath:contentOffsetKeyPath options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
  774. }
  775. #pragma mark - Layout
  776. - (void)addAllSubViews {
  777. [self.view addSubview:self.tableView];
  778. [self.view addSubview:self.bottomView];
  779. // [self.view addSubview:self.commentField]; // 不做显示只用来控制键盘的弹出
  780. [self.view addSubview:self.coverView];
  781. [self.view addSubview:self.navBar];
  782. [self.view addSubview:self.arrowBtn];
  783. [self.view addSubview:self.boardInputView];
  784. self.boardInputView.frame = CGRectMake(0, UISCREENHEIGH, UISCREENWIDTH, 50);
  785. [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
  786. make.edges.insets(UIEdgeInsetsZero);
  787. }];
  788. WeakSelf(weakSelf);
  789. [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
  790. make.top.left.right.equalTo(weakSelf.view);
  791. make.bottom.equalTo(weakSelf.bottomView.mas_top);
  792. }];
  793. [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  794. make.left.right.bottom.equalTo(weakSelf.view);
  795. make.height.equalTo(@50);
  796. }];
  797. [self.navBar mas_makeConstraints:^(MASConstraintMaker *make) {
  798. make.left.right.top.equalTo(self.view);
  799. make.height.equalTo(@64);
  800. }];
  801. [self.arrowBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  802. make.right.equalTo(self.view).offset(- 20);
  803. make.bottom.equalTo(self.bottomView.mas_top).offset(- 20);
  804. }];
  805. }
  806. #pragma mark - getter && setter
  807. - (UITableView *)tableView {
  808. if (_tableView == nil) {
  809. _tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
  810. _tableView.dataSource = self;
  811. _tableView.delegate = self;
  812. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  813. _tableView.sectionHeaderHeight = 0;
  814. _tableView.backgroundColor = UIColorFromRGB(0xeeeeee);
  815. }
  816. return _tableView;
  817. }
  818. - (PdDetailBottomView *)bottomView {
  819. if (_bottomView == nil) {
  820. _bottomView = [[PdDetailBottomView alloc]init];
  821. _bottomView.delegate = self;
  822. _bottomView.commitBtn.hidden = YES; // 初始化状态时先隐藏
  823. }
  824. return _bottomView;
  825. }
  826. - (PindanDetailViewModel *)viewModel {
  827. if (_viewModel == nil) {
  828. _viewModel = [[PindanDetailViewModel alloc]init];
  829. }
  830. return _viewModel;
  831. }
  832. - (PdDetailKeyboardInputView *)boardInputView {
  833. if (_boardInputView == nil) {
  834. _boardInputView = [[PdDetailKeyboardInputView alloc]init];
  835. _boardInputView.bounds = CGRectMake(0, 0, UISCREENWIDTH, 50);
  836. [_boardInputView.confirmButton addTarget:self action:@selector(commentConfirmBtnClick) forControlEvents:UIControlEventTouchUpInside];
  837. }
  838. return _boardInputView;
  839. }
  840. - (UIView *)coverView {
  841. if (_coverView == nil) {
  842. _coverView = [[UIView alloc]init];
  843. _coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4f];
  844. _coverView.alpha = 0;
  845. UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(commentCoverViewClick)];
  846. [_coverView addGestureRecognizer:singleTap];
  847. }
  848. return _coverView;
  849. }
  850. - (PindanDeleteCommentView *)deleteCommentView {
  851. if (_deleteCommentView == nil) {
  852. _deleteCommentView = [[PindanDeleteCommentView alloc]init];
  853. [_deleteCommentView.deleteButton addTarget:self action:@selector(deleteCommentButtonClick) forControlEvents:UIControlEventTouchUpInside];
  854. }
  855. return _deleteCommentView;
  856. }
  857. - (PindanSelectDetailView *)selectDetailView {
  858. if (_selectDetailView == nil) {
  859. _selectDetailView = [[PindanSelectDetailView alloc] initWithViewModel:self.viewModel];
  860. [_selectDetailView initialLayoutWithState:[self.viewModel productState]];
  861. WeakSelf(weakSelf);
  862. _selectDetailView.selectDoneAction = ^(PindanSelectDetailView *selectView){
  863. [weakSelf pushSubmitOrderController:selectView.specsArray];
  864. };
  865. }
  866. return _selectDetailView;
  867. }
  868. - (PindanDetailHeaderView *)itemShowHeaderView {
  869. if (_itemShowHeaderView == nil) {
  870. _itemShowHeaderView = [[PindanDetailHeaderView alloc]init];
  871. }
  872. return _itemShowHeaderView;
  873. }
  874. - (DetailNavigationBar *)navBar {
  875. if (_navBar == nil) {
  876. _navBar = [[DetailNavigationBar alloc]init];
  877. [_navBar.leftButton addTarget:self action:@selector(leftNaviBtnClick) forControlEvents:UIControlEventTouchUpInside];
  878. [_navBar.collectBtn addTarget:self action:@selector(collectBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  879. }
  880. return _navBar;
  881. }
  882. - (NSTimer *)countTimer {
  883. if (_countTimer == nil) {
  884. _countTimer = [NSTimer timerWithTimeInterval:1.0f
  885. target:self
  886. selector:@selector(timeCountDown)
  887. userInfo:nil
  888. repeats:YES];
  889. [[NSRunLoop currentRunLoop] addTimer:_countTimer forMode:NSRunLoopCommonModes];
  890. }
  891. return _countTimer;
  892. }
  893. - (UIButton *)arrowBtn {
  894. if (_arrowBtn == nil) {
  895. _arrowBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  896. [_arrowBtn setImage:[UIImage imageNamed:@"fanhuidingbu"] forState:UIControlStateNormal];
  897. [_arrowBtn addTarget:self action:@selector(scrollTopArrowBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  898. _arrowBtn.hidden = YES; // 数据未加载到之前先隐藏
  899. }
  900. return _arrowBtn;
  901. }
  902. - (XHImageViewer *)imageBrowser{
  903. if (_imageBrowser == nil) {
  904. _imageBrowser = [[XHImageViewer alloc] init];
  905. _imageBrowser.dismissInCenter = YES;
  906. }
  907. return _imageBrowser;
  908. }
  909. - (FKCollectAnimationTool *)collectAnimTool{
  910. if (_collectAnimTool == nil) {
  911. _collectAnimTool = [[FKCollectAnimationTool alloc]init];
  912. _collectAnimTool.delegate = self;
  913. }
  914. return _collectAnimTool;
  915. }
  916. @end