// // PDDetailViewController.m // FirstLink // // Created by 王孝道 on 15/6/3. // Copyright (c) 2015年 FirstLink. All rights reserved. // 拼单详情页面 #import "PindanDetailController.h" #import "PindanSelectDetailView.h" #import "PdDetailKeyboardInputView.h" #import "SubmitOrderController.h" #import "PindanDeleteCommentView.h" #import "ChatViewController.h" #import "FLImageHelper.h" #import "FLShareHelper.h" #import "WebViewController.h" #import "FLControllerHelper.h" #import "FLProgressHUDHelper.h" #import "PindanDetailHeaderView.h" #import "DetailNavigationBar.h" #import "UIImageView+FLAddition.h" #import "PdProductShowCell.h" #import "PdCommentCell.h" #import "DetailMainImgCell.h" #import "DetailPriceExplainCell.h" #import "DetailTalkCell.h" #import "DetailTransitHeaderCell.h" #import "DetailTransitCommonCell.h" #import "DetailAuthorityCell.h" #import "DetailProductHeaderCell.h" #import "DetailFeatureCell.h" #import "DetailSourceCell.h" #import "DetailCommentHeadCell.h" #import "DetailNoCommentCell.h" #import "DetailMoreCommentCell.h" #import "FKCollectAnimationTool.h" #import "FKBuyRemindView.h" #import "FKDetailReform.h" #import "FKDetailRequest.h" #import "XHImageViewer.h" #import "FKWeixinShareView.h" #define contentOffsetKeyPath @"contentOffset" #define SHOW_IDCARD_ALERT_TAG 666 @interface PindanDetailController () @property (nonatomic, strong) PindanDetailViewModel *viewModel; @property (nonatomic, strong) NSString *userID; @property (nonatomic, strong) NSString *postID; @property (nonatomic, strong) UITableView *tableView; @property (nonatomic, strong) DetailNavigationBar *navBar; @property (nonatomic, strong) PdDetailBottomView *bottomView; @property (nonatomic, strong) PindanDetailHeaderView *itemShowHeaderView; @property (nonatomic, strong) PdDetailKeyboardInputView *boardInputView; // 键盘弹出辅助输入视图 @property (nonatomic, strong) PindanDeleteCommentView *deleteCommentView; // 删除自己的评论 @property (nonatomic, strong) PindanSelectDetailView *selectDetailView; // 选择规格和数量 @property (nonatomic, strong) UIView *coverView; @property (nonatomic, strong) NSTimer *countTimer; @property (nonatomic, strong) UIButton *arrowBtn; @property (nonatomic, strong) XHImageViewer *imageBrowser; // 图片查看器 @property (nonatomic, strong) FKCollectAnimationTool *collectAnimTool; // 收藏动画管理 @end @implementation PindanDetailController - (instancetype)initWithUserID:(NSString *)userID postID:(NSString *)postID { self = [super init]; if (self) { self.viewModel.userID = @"0"; self.viewModel.postID = postID; } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.edgesForExtendedLayout = UIRectEdgeAll; self.automaticallyAdjustsScrollViewInsets = NO; if (self.openURLPara) { self.viewModel.userID = @"0"; self.viewModel.postID = self.openURLPara[@"post_id"]; } [self addRefresh]; [self configTableView]; [self configKeyboardNotifications]; [self addAllSubViews]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [self.tableView removeObserver:self.navBar forKeyPath:contentOffsetKeyPath]; [self.tableView removeObserver:self forKeyPath:contentOffsetKeyPath]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [UIApplication sharedApplication].statusBarHidden = NO; [self.navigationController setNavigationBarHidden:YES animated:YES]; [self requestForInitialData]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.tabBarController.tabBar setHidden:YES]; // [self.tabBarController.tabBar setTranslucent:YES]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.countTimer invalidate]; self.countTimer = nil; } #pragma mark - Request - (void)addRefresh{ [self initRefreshControlWithTableView:self.tableView]; [self.refreshControl setBottomEnabled:NO]; } - (void)forceRefresh { [self requestForInitialData]; } - (void)requestForInitialData { // 请求初始化数据 [self.hudView show:YES]; NSDictionary *infoDict = [self.viewModel infoForRequestType:kRequestTypeDetail withInfo:nil]; [FKDetailRequest requestWithType:kRequestTypeDetail info:infoDict delegate:self]; } - (void)requestWarnWithBottomState:(kPindanState)state { BOOL remindState = state == kPindanStateRemind ? YES : NO; kRequestType type = remindState ? kRequestTypeAddLike : kRequestTypeRemoveLike; NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil]; [FKDetailRequest requestWithType:type info:infoDict delegate:self]; } - (void)refreshCommentWithScroll:(BOOL)scrollToComment { // 重新刷新评论数据 [self.hudView show:NO]; kRequestType type = scrollToComment ? kRequestTypeRefreshCommentScroll : kRequestTypeRefreshComment; NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil]; [FKDetailRequest requestWithType:type info:infoDict delegate:self]; } - (void)trackBehaviorWithType:(kBehaviorType)type{ // 行为统计 NSString *jsonStr = [FLRequestHelper JSONStringWithKeys:@[@"post_id"] values:@[self.viewModel.postID]]; [BehaviorTrackManger requestBehaviorType:type jsonString:jsonStr]; } #pragma mark - refresh delegate - (void)refreshControl:(FKRefreshControl *)refreshControl didEngageRefreshDirection:(RefreshDirection)direction{ if (direction == RefreshDirectionTop) { [self requestForInitialData]; } } #pragma mark - response - (void)networkDidSuccessResponse:(NSDictionary*)response identify:(int)identify header:(MSGHeader*)header { [self.refreshControl finishRefreshingDirection:RefreshDirectionTop]; WeakSelf(weakSelf); dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.hudView hide:YES]; [weakSelf.hudView removeFromSuperview]; weakSelf.hudView = nil; }); if (header.code.intValue == RESPONSE_MSG_NORMAL) { switch (identify) { case kRequestTypeDetail: { [self.viewModel saveIntoDataSource:[FKDetailReform parserDetailItemWithDict:response]]; if (self.selectDetailView.specsArray.count > 0) { self.viewModel.pindanDetailItem.specsArray = self.selectDetailView.specsArray; } [self refreshContent]; break; } case kRequestTypeAddCollect:{ [self.viewModel setIsFavorite:YES]; [self configCollectButton:YES]; [self.tableView reloadData]; break; } case kRequestTypeRemoveCollect:{ [self.viewModel setIsFavorite:NO]; [self configCollectButton:NO]; [self.tableView reloadData]; break; } case kRequestTypeShareUrlCircle:{ [self.viewModel setShareURL:[FKDetailReform parserShareURLwithDict:response]]; [self shareToFriendCircle:YES withUrlString:[self.viewModel shareURL]]; break; } case kRequestTypeShareUrlFriend:{ [self.viewModel setShareURL:[FKDetailReform parserShareURLwithDict:response]]; [self shareToFriendCircle:NO withUrlString:[self.viewModel shareURL]]; break; } case kRequestTypeAddLike:{ self.bottomView.state = kPindanStateCancelRemind; [FLProgressHUDHelper showText:@"开售提醒成功, 拼单再次开启时\n我们会以短信方式提醒您!" inView:self.view]; break; } case kRequestTypeRemoveLike:{ self.bottomView.state = kPindanStateRemind; [FLProgressHUDHelper showText:@"取消开售提醒成功" inView:self.view]; break; } case kRequestTypeRefreshComment:{ [self.viewModel setCommentArray:[FKDetailReform parserCommentArrayWithDict:response]]; [self.viewModel setCommentCount:[FKDetailReform parserCommentCountWithDict:response]]; [self.tableView reloadData]; break; } case kRequestTypeRefreshCommentScroll:{ [self.viewModel setCommentArray:[FKDetailReform parserCommentArrayWithDict:response]]; [self.viewModel setCommentCount:[FKDetailReform parserCommentCountWithDict:response]]; [self.tableView reloadData]; [self scrollToCommentArea]; break; } case kRequestTypeAddSelfComment: case kRequestTypeAddOtherComment:{ [self refreshCommentWithScroll:YES]; break; } case kRequestTypeRemoveComment:{ [self refreshCommentWithScroll:NO]; break; } default: break; } } else{ [FLProgressHUDHelper showText:header.msg inView:self.view]; } } - (void)networkDidReceiveError:(NSError*)error identify:(int)identify header:(MSGHeader*)header{ WeakSelf(weakSelf); dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.hudView hide:YES]; [weakSelf.hudView removeFromSuperview]; weakSelf.hudView = nil; }); [self.refreshControl finishRefreshingDirection:RefreshDirectionTop]; [FLProgressHUDHelper showText:header.msg inView:self.view]; } #pragma mark - TableView DataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [self.viewModel numberOfSectionsInTableView]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.viewModel numberOfRowsInSection:section]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [self.viewModel cellHeightForIndexPath:indexPath]; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return CGFLOAT_MIN; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section == 1) return CGFLOAT_MIN; return 10; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { kDetailCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath]; UITableViewCell *targetCell = [tableView dequeueReusableCellWithIdentifier:[self.viewModel cellIdentifyForIndexPath:indexPath]]; switch (cellType) { case kDetailCellTypePriceExplain:{ DetailPriceExplainCell *priceCell = (DetailPriceExplainCell *)targetCell; [priceCell configWithDetailViewModel:self.viewModel indexPath:indexPath]; priceCell.delegate = self; [priceCell.collectBtn addTarget:self action:@selector(collectBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } break; case kDetailCellTypeProductShow: { ProductShowItem *showItem = [self.viewModel productShowArray][indexPath.row - 1]; PdProductShowCell *showCell = (PdProductShowCell *)targetCell; [showCell configWithShowItem:showItem]; showCell.delegate = self; } break; case kDetailCellTypeComment:{ PdCommentCell *commentCell = (PdCommentCell *)targetCell; [self configCommentCell:commentCell forIndexPath:indexPath]; } break; case kDetailCellTypeMoreComment:{ DetailMoreCommentCell *moreCell = (DetailMoreCommentCell *)targetCell; [moreCell.moreActionBtn addTarget:self action:@selector(pushAllCommentBtn) forControlEvents:UIControlEventTouchUpInside]; } break; case kDetailCellTypeProductHeader: case kDetailCellTypeFeature: case kDetailCellTypeNoComment:{ return targetCell; } break; default: [targetCell configWithDetailViewModel:self.viewModel indexPath:indexPath]; break; } return targetCell; } #pragma mark - TableView Delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { kDetailCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; switch (cellType) { case kDetailCellTypeMainImg:{ [self clickImgCell:cell atIndex:indexPath]; } break; case kDetailCellTypeSpecGuige:{ if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) { [self showLoginActionMenu]; return; } [self.selectDetailView showToView:self.navigationController.view animated:YES]; } break; case kDetailCellTypeComment:{ if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) { [self showLoginActionMenu]; return; } // 点击评论 self.boardInputView.tag = indexPath.row - 1; if ([self.viewModel isCommentBySelfForRow:indexPath.row - 1]) { // 删除自己的评论 [self.deleteCommentView showInView:self.view animated:YES]; return; } [self.boardInputView.textView becomeFirstResponder]; } break; case kDetailCellTypeTransitLink:{ if (![FLStringHelper isUrlString:[self.viewModel buyChannel]]) return; [self pushWebViewControllerWithUrl:[self.viewModel buyChannel]]; [self trackBehaviorWithType:kBehaviorDetailLink]; } break; case kDetailCellTypeNoComment:{ self.boardInputView.tag = - 1; [self.boardInputView.textView becomeFirstResponder]; } break; default: break; } } #pragma mark - Cells Delegate - (void)clickProductImg:(PdProductShowCell *)cell{ NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; if (indexPath){ [self clickImgCell:cell atIndex:indexPath]; } } - (void)clickImgCell:(UITableViewCell *)imgCell atIndex:(NSIndexPath *)indexPath{ if (imgCell && indexPath) { [self showImgBrowerWithSelectIndex:indexPath.row sourceCell:imgCell]; } } - (void)showImgBrowerWithSelectIndex:(NSUInteger)index sourceCell:(UITableViewCell *)sourceCell{ NSArray *imgUrlArray = [self.viewModel allProductIMGURLArray]; NSMutableArray *imgArrayM = [NSMutableArray arrayWithCapacity:imgUrlArray.count]; for (int i = 0; i < imgUrlArray.count; i++) { UIImageView *newImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, UISCREENWIDTH, UISCREENWIDTH)]; if (i > 0){ ProductShowItem *showItem = [self.viewModel showItemAtIndex:i - 1]; if (showItem) newImgView.frame = CGRectMake(0, 0, UISCREENWIDTH, [showItem realImgHeightForRealWidth:UISCREENWIDTH]); } [newImgView sd_setImageWithURL:[NSURL URLWithString:imgUrlArray[i]]]; if (i == index) [sourceCell.contentView addSubview:newImgView]; [imgArrayM addObject:newImgView]; } [self.imageBrowser showWithImageViews:imgArrayM selectedView:(UIImageView *)imgArrayM[index]]; } - (void)priceDetailCell:(DetailPriceExplainCell *)cell showPriceExplain:(BOOL)show { self.viewModel.showPriceExplain = show; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; if (indexPath) { [self.tableView reloadData]; } } - (void)shareToFriendCircle:(BOOL)isFriendCircle withUrlString:(NSString *)url { if (!url || url.length == 0) return; NSString *title = [self.viewModel title]; NSString *desc = [self.viewModel introduceText]; UIImage *image = [self firstPhotoForShare]; // 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]; if (image) { [FLShareHelper shareToWeixin:title description:desc thumbImage:image webURL:url scene:isFriendCircle ? WeixinSceneCicle : WeixinSceneFriend]; } } #pragma mark - Alert View Delegate - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (SHOW_IDCARD_ALERT_TAG == alertView.tag) { if ([self.viewModel hasSpecs]) { [self.selectDetailView showToView:self.navigationController.view animated:YES]; } else { [self pushSubmitOrderController:nil]; } } } #pragma mark - RemindView Delegate - (void)remindViewClickToBuy:(FKBuyRemindView *)remindView{ if (remindView.isVip == YES) { // 去管家购买 [[FLControllerHelper currentTabBarController].tabBar setHidden:NO]; [FLControllerHelper selectTabbarControllerAtIndex:2]; [self.navigationController popToRootViewControllerAnimated:NO]; } else{ // 去开通Vip // FKVipBuyController *vipBuy = [[FKVipBuyController alloc]init]; // vipBuy.type = FKVipBuyTypeNormal; // vipBuy.delegate = self; // [self.navigationController pushViewController:vipBuy animated:YES]; } } - (void)remindViewClickToRemind:(FKBuyRemindView *)remindView{ [self requestWarnWithBottomState:kPindanStateRemind]; } #pragma mark - FKCollectAnimationToolDelegate - (void)allCollectAnimationFinish:(FKCollectAnimationTool *)tool{ kRequestType type = tool.collectSelected ? kRequestTypeAddCollect : kRequestTypeRemoveCollect; NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:nil]; [FKDetailRequest requestWithType:type info:infoDict delegate:self]; // 用户行为打点 kBehaviorType behaviorType = tool.collectSelected ? kBehaviorDetailCollect : kBehaviorDetailNoCollect; [self trackBehaviorWithType:behaviorType]; } #pragma mark - PDDetailMenuDelegate - (void)detailMenuBtnClickWithIndex:(NSInteger)tag { if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) { [self showLoginActionMenu]; return; } // 底部按钮事件 switch (tag) { case kBottomCommentBtnTag:{ // 评论 self.boardInputView.tag = - 1; [self.boardInputView.textView becomeFirstResponder]; } break; case kBottomServiceBtnTag:{ // 客服 [self pushChatViewController]; [self trackBehaviorWithType:kBehaviorDetailServe]; } break; case kBottomShareBtnTag:{ [self showShareView]; } break; case kBottomConfirmBtnTag:{ [self checkBuyWithPindanStatus]; } break; default: break; } } - (void)checkBuyWithPindanStatus { kPindanState state = self.bottomView.state; if (state == kPindanStateOnlyVIP || state == kPindanStateOnlyNew || state == kPindanStateWaitBegin) return; switch (state) { case kPindanStateNormal:{ // 判断是否符合购买权限 if ([self.viewModel isOnlyNew] == YES && [self.viewModel userOrderCount] > 0) { [FLProgressHUDHelper showText:@"该商品仅限新用户购买" inView:self.view]; } else if ([self.viewModel isOnlyVIP] == YES && [self.viewModel userLevel] != kUserLevelVIP){ [FLProgressHUDHelper showText:@"该商品仅限会员购买" inView:self.view]; } if ([self.viewModel isNeedIDCard] && ![self.viewModel isHasShowIDCardAlert]) { [self showRequireIDCardAlert]; [self.viewModel setHasShowIDCardAlert]; } else { if ([self.viewModel hasSpecs]) { [self.selectDetailView showToView:self.navigationController.view animated:YES]; } else { [self pushSubmitOrderController:nil]; } } break; } case kPindanStateRemind:{ FKBuyRemindView *remindView = [[FKBuyRemindView alloc]init]; remindView.delegate = self; remindView.isVip = [self.viewModel userLevel] == kUserLevelVIP ? YES : NO; [remindView showInView:self.view]; } break; case kPindanStateCancelRemind:{ [self requestWarnWithBottomState:kPindanStateCancelRemind]; } break; default: break; } } #pragma mark - key board observe - (void)keyboardWillChange:(NSNotification *)notification { if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) { // 键盘弹出 [self showBoardViewWithNotification:notification]; [self setCommentPlaceHolder]; } else if ([notification.name isEqualToString:UIKeyboardWillHideNotification]){ // 键盘退出 [self dismissBoardViewWithNotification:notification]; } else if ([notification.name isEqualToString:UIKeyboardDidShowNotification]){ } else if ([notification.name isEqualToString:UIKeyboardDidHideNotification]){ self.boardInputView.textView.text = @""; } } #pragma mark - tableView observe - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"contentOffset"]) { CGFloat maxContentY = self.tableView.contentSize.height; if (maxContentY <= 0) return; CGFloat midY = (maxContentY - (UISCREENHEIGH - 50)) / 2.0f; CGFloat showY = (maxContentY - (UISCREENHEIGH - 50)) / 3.0f * 2; CGFloat newY = [change[@"new"] CGPointValue].y; if (newY >= showY) { self.arrowBtn.hidden = NO; }else if (newY <= midY){ self.arrowBtn.hidden = YES; } } } #pragma mark - event response - (void)leftNaviBtnClick { [self.navigationController popViewControllerAnimated:YES]; } - (void)collectBtnClick:(UIButton *)sender { if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) { [self showLoginActionMenu]; return; } sender.selected = !sender.selected; [self.collectAnimTool showAnimationWithCollect:sender.selected inView:self.view]; } - (void)scrollTopArrowBtnClick:(UIButton *)sender { NSIndexPath *targetIndex = [NSIndexPath indexPathForRow:0 inSection:0]; [self.tableView scrollToRowAtIndexPath:targetIndex atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)commentConfirmBtnClick { // 发送评论 NSString *commentContent = self.boardInputView.textView.text; NSInteger commentIndex = self.boardInputView.tag; if (!commentContent || commentContent.length == 0){ [FLProgressHUDHelper showText:@"评论内容不能为空" inView:self.view]; return; } kRequestType type = commentIndex >= 0 ? kRequestTypeAddOtherComment : kRequestTypeAddSelfComment; NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithDictionary:@{COMMENT_CONTENT_KEY : commentContent}]; CommentItem *item = [self.viewModel commentItemForIndex:commentIndex]; if (item) { [dictM setObject:item.buyerID forKey:REPLY_TO_USER_ID_KEY]; } [self.hudView show:YES]; NSDictionary *infoDict = [self.viewModel infoForRequestType:type withInfo:dictM]; [FKDetailRequest requestWithType:type info:infoDict delegate:self]; [self.boardInputView.textView resignFirstResponder]; [self.boardInputView resignFirstResponder]; [self.view endEditing:YES]; } - (void)deleteCommentButtonClick { // 删除自己的评论 [self.hudView show:YES]; CommentItem *item = [self.viewModel commentItemForIndex:self.boardInputView.tag]; if (!item) return; NSDictionary *dict = @{COMMENT_ID_KEY : item.commentID, COMMENT_ITEM_ID_KEY : item.itemID, COMMENT_SELLER_ID_KEY : item.sellerID}; NSDictionary *infoDict = [self.viewModel infoForRequestType:kRequestTypeRemoveComment withInfo:dict]; [FKDetailRequest requestWithType:kRequestTypeRemoveComment info:infoDict delegate:self]; [self.deleteCommentView dismissAnimation]; } - (void)commentCoverViewClick { [self.boardInputView.textView resignFirstResponder]; [self.boardInputView resignFirstResponder]; self.boardInputView.textView.text = nil; } - (void)scrollToCommentArea { // 滚动到评论区 NSIndexPath *targetIndexPath = [NSIndexPath indexPathForRow:1 inSection:([self.viewModel numberOfSectionsInTableView] - 1)]; [self.tableView scrollToRowAtIndexPath:targetIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; } - (void)setCommentPlaceHolder{ NSString *placeHolderString = [self.viewModel getCommentPlaceHolderWithIndex:self.boardInputView.tag]; if ([self.boardInputView.placeHolder isEqualToString:placeHolderString]) return; // 防止切换输入法再次发送keyboardwillshow通知,会让holder显示出来 self.boardInputView.placeHolder = placeHolderString; } #pragma mark - Keyboard Notification - (void)showBoardViewWithNotification:(NSNotification *)notification { CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; CGRect endRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; UIViewAnimationOptions curve = (UIViewAnimationOptions)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; self.coverView.alpha = 0; WeakSelf(weakSelf); [UIView animateWithDuration:duration delay:0 options:curve animations:^{ weakSelf.boardInputView.frame = CGRectMake(endRect.origin.x, endRect.origin.y - 50, CGRectGetWidth(self.boardInputView.bounds), CGRectGetHeight(self.boardInputView.bounds)); weakSelf.coverView.alpha = 1.0f; } completion:^(BOOL finished) { }]; } - (void)dismissBoardViewWithNotification:(NSNotification *)notification { CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; CGRect endRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; UIViewAnimationOptions curve = (UIViewAnimationOptions)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; self.coverView.alpha = 1; WeakSelf(weakSelf); [UIView animateWithDuration:duration delay:0 options:curve animations:^{ weakSelf.coverView.alpha = 0; weakSelf.boardInputView.frame = CGRectMake(0, endRect.origin.y, CGRectGetWidth(self.boardInputView.bounds), CGRectGetHeight(self.boardInputView.bounds)); } completion:^(BOOL finished) { }]; } #pragma mark - private method - (void)refreshContent { [self.tableView reloadData]; [self configCountTimer]; [self configCollectButton:[self.viewModel isFavorite]]; [self.bottomView setState:[self.viewModel pindanState]]; self.bottomView.commitBtn.hidden = NO; if ([self.viewModel hasSpecs]) { // 从提交页面回来,更新购物车 [self.selectDetailView refreshSelectSpecContent]; } } - (void)timeCountDown { [self.viewModel setTimeInterval:([self.viewModel timeInterval] - 1)]; NSTimeInterval time = self.viewModel.timeInterval; DetailPriceExplainCell *priceCell = nil; for (UITableViewCell *cell in self.tableView.visibleCells) { if ([cell isKindOfClass:[DetailPriceExplainCell class]]){ priceCell = (DetailPriceExplainCell *)cell; break; } } if (time <= 0) { if (self.viewModel.pindanState == kPindanStateWaitBegin) { self.viewModel.pindanDetailItem.isPindanBegin = YES; [self requestForInitialData]; }else{ self.bottomView.state = [self.viewModel isRemind] ? kPindanStateCancelRemind : kPindanStateRemind; if (priceCell){ priceCell.priceLabel.textColor = UIColorFromRGB(0xcccccc); priceCell.countTimeLabel.text = @"拼单已结束"; } } }else{ if (priceCell) [priceCell resetTimeStrWithInterval:time isBegin:self.viewModel.pindanDetailItem.isPindanBegin]; } } - (void)showShareView { FKWeixinShareView *shareView = [[FKWeixinShareView alloc]init]; WeakSelf(weakSelf); [shareView showInView:self.view actionBlock:^(kShareViewActionType type) { [weakSelf clickShareForType:type]; }]; } - (void)clickShareForType:(kShareViewActionType)type{ kRequestType reqType = (type == kShareViewActionTypeCircle) ? kRequestTypeShareUrlCircle : kRequestTypeShareUrlFriend; NSDictionary *infoDict = [self.viewModel infoForRequestType:reqType withInfo:nil]; [FKDetailRequest requestWithType:reqType info:infoDict delegate:self]; // 行为统计 kBehaviorType beHaviorType = (type == kShareViewActionTypeFriend) ? kBehaviorDetailShareF : kBehaviorDetailShareC; [self trackBehaviorWithType:beHaviorType]; } - (void)showRequireIDCardAlert { NSString *text = @"您正在购买“直邮”商品,此类商品到货时间更短哦。"; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:text delegate:self cancelButtonTitle:nil otherButtonTitles:@"我知道了", nil]; alertView.tag = SHOW_IDCARD_ALERT_TAG; alertView.delegate = self; [alertView show]; } - (NSDictionary *)chatViewControllerExtData { return @{EXT_MSG_TYPE_V2: @{EXT_MSG_TYPE_TRACK_V2: @{EXT_MSG_TITLE_V2 : @"用户正在看商品:", EXT_MSG_PRICE_V2 : [self.viewModel totalPrice], EXT_MSG_DESC_V2 : [self.viewModel title], EXT_MSG_PIC_URL_V2 : [self.viewModel firstPic], EXT_MSG_ITEM_URL_V2 : [self.viewModel webURL], EXT_MSG_USER_ID_V2 : [self.viewModel userID], EXT_MSG_POST_ID_V2 : [self.viewModel postID] }}, EXT_MSG_ORDER_TITLE: [FLStringHelper replaceNilWithEmpty:[self.viewModel title]], EXT_QUEUE_NAME : QueueNameShouqian}; } - (UIImage *)firstPhotoForShare { UIImage *image = nil; for (UITableViewCell *cell in self.tableView.visibleCells) { if ([cell isKindOfClass:[DetailMainImgCell class]]) { DetailMainImgCell *mainCell = (DetailMainImgCell *)cell; image = mainCell.mainImgView.image; break; } } if (!image) { DetailMainImgCell *mainCell = [self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass([DetailMainImgCell class])]; image = mainCell.mainImgView.image; } if (image) { image = [FLImageHelper generateThumbnailFromCenter:image frame:CGSizeMake(SHARE_IMAGE_LENGTH, SHARE_IMAGE_LENGTH)]; } else { image = [FLImageHelper generateThumbnailFromCenter:[FLImageHelper getAppIcon] frame:CGSizeMake(SHARE_IMAGE_LENGTH, SHARE_IMAGE_LENGTH)]; } return image; } #pragma mark - Push Controller - (void)pushWebViewControllerWithUrl:(NSString *)url { WebViewController *newViewController = [[FLControllerHelper currentStoryBoard] instantiateViewControllerWithIdentifier:@"WebViewController"]; newViewController.url = url; newViewController.hidesBottomBarWhenPushed = YES; [self.navigationController setNavigationBarHidden:NO animated:NO]; [self.navigationController pushViewController:newViewController animated:YES]; } - (void)pushSubmitOrderController:(NSArray *)specArray { FKPurchaseCache *cache = [FKPurchaseCache new]; [self.viewModel saveDataIntoCache:cache orderType:kOrderTypeNoraml]; SubmitOrderController *submitCtrl = [[SubmitOrderController alloc] initWithPurchaseCache:cache]; [self.navigationController pushViewController:submitCtrl animated:YES]; } - (void)pushChatViewController { ChatViewController *chatController = [[ChatViewController alloc] initWithChatter:[self.viewModel serviceUserID] isGroup:NO]; chatController.naviTitle = [self.viewModel serviceNickname]; chatController.receiverHeadURL = [self.viewModel serviceHeadURL]; chatController.msgExtData = [self chatViewControllerExtData]; [self.navigationController pushViewController:chatController animated:YES]; } - (void)pushAllCommentBtn{ } #pragma mark - Config Method - (void)configCountTimer { if ([self.viewModel isProductStateEnd] || [self.viewModel isProductStateSaleDone]){ [self.countTimer invalidate]; } else { [self.countTimer fire]; } } - (void)configCollectButton:(BOOL)status { self.navBar.collectBtn.selected = status; if (self.delegate && [self.delegate respondsToSelector:@selector(collectStatusChange:status:)]) { [self.delegate collectStatusChange:[self.viewModel postID] status:status]; } } - (void)configCommentCell:(PdCommentCell *)commentCell forIndexPath:(NSIndexPath *)indexPath{ CommentItem *item = [self.viewModel commentArray][indexPath.row - 1]; if (item) { [commentCell.iconImgView sd_setImageWithURL:[NSURL URLWithString:item.buyerHeaderPic]]; commentCell.bottomLine.hidden = NO; commentCell.timeLabel.text = [FLStringHelper convertToPredigestStringFromString:item.createTime]; commentCell.commentLabel.text = item.content; commentCell.nameLabel.attributedText = [item getRealCommentTitle]; NSInteger rowCount = [self.tableView numberOfRowsInSection:indexPath.section]; if (indexPath.row == rowCount - 1) commentCell.bottomLine.hidden = YES; } } - (void)configKeyboardNotifications{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardDidHideNotification object:nil]; } - (void)configTableView { [self.tableView registerClass:[DetailMainImgCell class] forCellReuseIdentifier:NSStringFromClass([DetailMainImgCell class])]; [self.tableView registerClass:[DetailPriceExplainCell class] forCellReuseIdentifier:NSStringFromClass([DetailPriceExplainCell class])]; [self.tableView registerClass:[DetailTalkCell class] forCellReuseIdentifier:NSStringFromClass([DetailTalkCell class])]; [self.tableView registerClass:[DetailTransitHeaderCell class] forCellReuseIdentifier:NSStringFromClass([DetailTransitHeaderCell class])]; [self.tableView registerClass:[DetailTransitCommonCell class] forCellReuseIdentifier:NSStringFromClass([DetailTransitCommonCell class])]; [self.tableView registerClass:[PdProductShowCell class] forCellReuseIdentifier:NSStringFromClass([PdProductShowCell class])]; [self.tableView registerClass:[PdCommentCell class] forCellReuseIdentifier:NSStringFromClass([PdCommentCell class])]; [self.tableView registerClass:[DetailAuthorityCell class] forCellReuseIdentifier:NSStringFromClass([DetailAuthorityCell class])]; [self.tableView registerClass:[DetailProductHeaderCell class] forCellReuseIdentifier:NSStringFromClass([DetailProductHeaderCell class])]; [self.tableView registerClass:[DetailFeatureCell class] forCellReuseIdentifier:NSStringFromClass([DetailFeatureCell class])]; [self.tableView registerClass:[DetailSourceCell class] forCellReuseIdentifier:NSStringFromClass([DetailSourceCell class])]; [self.tableView registerClass:[DetailCommentHeadCell class] forCellReuseIdentifier:NSStringFromClass([DetailCommentHeadCell class])]; [self.tableView registerClass:[DetailNoCommentCell class] forCellReuseIdentifier:NSStringFromClass([DetailNoCommentCell class])]; [self.tableView registerClass:[DetailMoreCommentCell class] forCellReuseIdentifier:NSStringFromClass([DetailMoreCommentCell class])]; [self.tableView addObserver:self.navBar forKeyPath:contentOffsetKeyPath options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; [self.tableView addObserver:self forKeyPath:contentOffsetKeyPath options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; } #pragma mark - Layout - (void)addAllSubViews { [self.view addSubview:self.tableView]; [self.view addSubview:self.bottomView]; // [self.view addSubview:self.commentField]; // 不做显示只用来控制键盘的弹出 [self.view addSubview:self.coverView]; [self.view addSubview:self.navBar]; [self.view addSubview:self.arrowBtn]; [self.view addSubview:self.boardInputView]; self.boardInputView.frame = CGRectMake(0, UISCREENHEIGH, UISCREENWIDTH, 50); [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.insets(UIEdgeInsetsZero); }]; WeakSelf(weakSelf); [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.equalTo(weakSelf.view); make.bottom.equalTo(weakSelf.bottomView.mas_top); }]; [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.bottom.equalTo(weakSelf.view); make.height.equalTo(@50); }]; [self.navBar mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.equalTo(self.view); make.height.equalTo(@64); }]; [self.arrowBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.view).offset(- 20); make.bottom.equalTo(self.bottomView.mas_top).offset(- 20); }]; } #pragma mark - getter && setter - (UITableView *)tableView { if (_tableView == nil) { _tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped]; _tableView.dataSource = self; _tableView.delegate = self; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.sectionHeaderHeight = 0; _tableView.backgroundColor = UIColorFromRGB(0xeeeeee); } return _tableView; } - (PdDetailBottomView *)bottomView { if (_bottomView == nil) { _bottomView = [[PdDetailBottomView alloc]init]; _bottomView.delegate = self; _bottomView.commitBtn.hidden = YES; // 初始化状态时先隐藏 } return _bottomView; } - (PindanDetailViewModel *)viewModel { if (_viewModel == nil) { _viewModel = [[PindanDetailViewModel alloc]init]; } return _viewModel; } - (PdDetailKeyboardInputView *)boardInputView { if (_boardInputView == nil) { _boardInputView = [[PdDetailKeyboardInputView alloc]init]; _boardInputView.bounds = CGRectMake(0, 0, UISCREENWIDTH, 50); [_boardInputView.confirmButton addTarget:self action:@selector(commentConfirmBtnClick) forControlEvents:UIControlEventTouchUpInside]; } return _boardInputView; } - (UIView *)coverView { if (_coverView == nil) { _coverView = [[UIView alloc]init]; _coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4f]; _coverView.alpha = 0; UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(commentCoverViewClick)]; [_coverView addGestureRecognizer:singleTap]; } return _coverView; } - (PindanDeleteCommentView *)deleteCommentView { if (_deleteCommentView == nil) { _deleteCommentView = [[PindanDeleteCommentView alloc]init]; [_deleteCommentView.deleteButton addTarget:self action:@selector(deleteCommentButtonClick) forControlEvents:UIControlEventTouchUpInside]; } return _deleteCommentView; } - (PindanSelectDetailView *)selectDetailView { if (_selectDetailView == nil) { _selectDetailView = [[PindanSelectDetailView alloc] initWithViewModel:self.viewModel]; [_selectDetailView initialLayoutWithState:[self.viewModel productState]]; WeakSelf(weakSelf); _selectDetailView.selectDoneAction = ^(PindanSelectDetailView *selectView){ [weakSelf pushSubmitOrderController:selectView.specsArray]; }; } return _selectDetailView; } - (PindanDetailHeaderView *)itemShowHeaderView { if (_itemShowHeaderView == nil) { _itemShowHeaderView = [[PindanDetailHeaderView alloc]init]; } return _itemShowHeaderView; } - (DetailNavigationBar *)navBar { if (_navBar == nil) { _navBar = [[DetailNavigationBar alloc]init]; [_navBar.leftButton addTarget:self action:@selector(leftNaviBtnClick) forControlEvents:UIControlEventTouchUpInside]; [_navBar.collectBtn addTarget:self action:@selector(collectBtnClick:) forControlEvents:UIControlEventTouchUpInside]; } return _navBar; } - (NSTimer *)countTimer { if (_countTimer == nil) { _countTimer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(timeCountDown) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:_countTimer forMode:NSRunLoopCommonModes]; } return _countTimer; } - (UIButton *)arrowBtn { if (_arrowBtn == nil) { _arrowBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_arrowBtn setImage:[UIImage imageNamed:@"fanhuidingbu"] forState:UIControlStateNormal]; [_arrowBtn addTarget:self action:@selector(scrollTopArrowBtnClick:) forControlEvents:UIControlEventTouchUpInside]; _arrowBtn.hidden = YES; // 数据未加载到之前先隐藏 } return _arrowBtn; } - (XHImageViewer *)imageBrowser{ if (_imageBrowser == nil) { _imageBrowser = [[XHImageViewer alloc] init]; _imageBrowser.dismissInCenter = YES; } return _imageBrowser; } - (FKCollectAnimationTool *)collectAnimTool{ if (_collectAnimTool == nil) { _collectAnimTool = [[FKCollectAnimationTool alloc]init]; _collectAnimTool.delegate = self; } return _collectAnimTool; } @end