// // SelectDetailView.m // FirstLink // // Created by 王孝道 on 15/5/28. // Copyright (c) 2015年 FirstLink. All rights reserved. // #import "PindanSelectDetailView.h" #import "FirstLinkAppDelegate.h" #import "PindanSpecItem.h" #define kDurationTime 0.3f #define kSpecBtnTagBase 100 #define kSpecBtnfontsize 13 #define KSpecBtnTitleMargin 15 // 文字距离边框边距 #define kNumChangeBtnTagBase 50 @interface PindanSelectDetailView (){ UIButton *_selectedSpecBtn; // 选中的规格按钮 } @property (nonatomic, strong) PindanDetailViewModel *viewModel; @property (nonatomic, strong) UIView *contentView; @property (nonatomic, strong) UIScrollView *specScrollView; //规格和数量滑动scrollView @property (nonatomic, strong) UITextField *numField; @property (nonatomic, strong) UILabel *detailLabel; @property (nonatomic, strong) UILabel *numLabel; @property (nonatomic, strong) UIButton *basketBtn; @property (nonatomic, strong) CAAnimationGroup *groupAnim; @property (nonatomic, strong) NSMutableArray *animImgViewArray; @property (nonatomic, strong) UIView *middleLine; @property (nonatomic, assign) BOOL isEnd; // 是否已经结束 @property (nonatomic, strong) UIImageView *vipImageIcon; @end @implementation PindanSelectDetailView @synthesize imageView = _imageView; @synthesize priceLabel = _priceLabel; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGestureClick:)]; [self addGestureRecognizer:tap]; _isEnd = NO; } return self; } - (instancetype)initWithViewModel:(PindanDetailViewModel *)viewModel { self = [super init]; if (self) { _viewModel = viewModel; _specsArray = [_viewModel specsArray]; _limitedAmount = [_viewModel limiteNum]; _nationalPostage = [_viewModel internationalPostage].floatValue; } return self; } + (NSString *)cdnImgUrlStringWithString:(NSString *)imgUrl { return [NSString stringWithFormat:@"%@%@", imgUrl, [FLStringHelper cdnParamaterString:80 height:80]]; } - (void)initialLayoutWithState:(ProductState)state{ self.isEnd = state == ProductStateNormal ? NO : YES; UIButton *cancelBtn = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setImage:[UIImage imageNamed:@"withasingle_body_delete_n"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(cancelBtnClick) forControlEvents:UIControlEventTouchUpInside]; button; }); UIButton *confirmBtn = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitle:@"加入购物篮" forState:UIControlStateNormal]; [button setBackgroundColor:self.isEnd ? UIColorFromRGB(0xe5e5e5) : UIColorFromRGB(0xff6362)]; [button addTarget:self action:@selector(confirmBtnClick) forControlEvents:UIControlEventTouchUpInside]; button.layer.cornerRadius = 5; if (self.isEnd) button.enabled = NO; button; }); [self addSubview:self.contentView]; [self.contentView addSubview:cancelBtn]; [self.contentView addSubview:self.middleLine]; [self.contentView addSubview:self.imageView]; [self.contentView addSubview:self.priceLabel]; [self.contentView addSubview:self.detailLabel]; [self.contentView addSubview:self.specScrollView]; [self.contentView addSubview:confirmBtn]; [self.contentView addSubview:self.basketBtn]; [self.contentView addSubview:self.numLabel]; UIView *superView = self.contentView; [cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superView).offset(10); make.right.equalTo(superView).offset(- 15); }]; [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(superView).offset(15); make.top.equalTo(superView).offset(- 15); make.width.height.equalTo(@80); }]; [self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.imageView.mas_right).offset(15); make.top.equalTo(superView).offset(15); }]; [self.contentView addSubview:self.vipImageIcon]; [self.vipImageIcon mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.priceLabel.mas_right).offset(10); make.centerY.equalTo(self.priceLabel).offset(0); }]; [self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.priceLabel); make.bottom.equalTo(self.imageView).offset(- 5); }]; [self.middleLine mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.imageView); make.right.equalTo(cancelBtn); make.height.equalTo(@0.5); make.top.equalTo(self.imageView.mas_bottom).offset(5); }]; [self.specScrollView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(superView); make.top.equalTo(self.middleLine.mas_bottom); make.height.equalTo(@130); }]; [self.basketBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.middleLine); make.bottom.equalTo(superView).offset(- 10); make.width.height.mas_equalTo(35); }]; [confirmBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.basketBtn.mas_right).offset(20); make.right.equalTo(self.middleLine); make.bottom.equalTo(superView).offset(- 10); make.height.equalTo(@35); }]; [self.numLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.basketBtn).offset(15); make.centerY.equalTo(self.basketBtn).offset(- 12); make.size.mas_equalTo(CGSizeMake(15, 15)); }]; [self setInitialUIdata]; [self layoutSpecScrollView]; } - (void)setInitialUIdata { // 初始化默认数据 self.numField.text = @"1"; PindanSpecItem *specItem = [self specItemAtIndex:[self getFirstSelectedIndex]]; if (specItem) { CGFloat unitPrice = 0; if ([self.viewModel isVIP] && specItem.vipPrice.length >0) { if ([specItem.vipPrice isKindOfClass:[NSString class]]) unitPrice = specItem.vipPrice.floatValue / 100.0f + self.nationalPostage / 100.0f; self.vipImageIcon.hidden = NO; } else { if ([specItem.price isKindOfClass:[NSString class]]) unitPrice = specItem.price.floatValue / 100.0f + self.nationalPostage / 100.0f; self.vipImageIcon.hidden = YES; } self.priceLabel.text = [NSString stringWithFormat:@"¥%.2f", unitPrice]; self.detailLabel.text = specItem.name; [self.imageView sd_setImageWithURL:[NSURL URLWithString:[PindanSelectDetailView cdnImgUrlStringWithString:specItem.imgUrl]]]; } } - (void)layoutSpecScrollView { UIView *superView = self.specScrollView; UILabel *speLabel = ({ UILabel *label = [[UILabel alloc]init]; label.text = @"规格"; label.backgroundColor = [UIColor clearColor]; label.textColor = UIColorFromRGB(0x333333); label.font = [UIFont systemFontOfSize:15]; label.textAlignment = NSTextAlignmentCenter; label; }); UILabel *numLabel = ({ UILabel *label = [[UILabel alloc]init]; label.backgroundColor = [UIColor clearColor]; label.font = [UIFont systemFontOfSize:15]; label.textColor = UIColorFromRGB(0x333333); label.text = @"数量"; label; }); UIButton *addButton = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.tag = kNumChangeBtnTagBase + 0; [button setImage:[UIImage imageNamed:@"specification_body_add_n"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(changNumBtnClick:) forControlEvents:UIControlEventTouchUpInside]; button; }); UIButton *reduceButton = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.tag = kNumChangeBtnTagBase + 1; [button setImage:[UIImage imageNamed:@"specification_body_lower_n"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(changNumBtnClick:) forControlEvents:UIControlEventTouchUpInside]; button; }); UIView *containerView = [[UIView alloc]init]; // 放颜色规格按钮 containerView.backgroundColor = [UIColor clearColor]; CGFloat containerH = [self heigtForAllSpecsBtn]; [self.specScrollView addSubview:speLabel]; [self.specScrollView addSubview:containerView]; [self.specScrollView addSubview:addButton]; [self.specScrollView addSubview:reduceButton]; [self.specScrollView addSubview:self.numField]; [self.specScrollView addSubview:numLabel]; [speLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superView); make.left.equalTo(superView).offset(10); make.height.equalTo(@20); }]; [containerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(superView).offset(10); make.right.equalTo(superView).offset(- 10); make.width.equalTo(@(UISCREENWIDTH - 20)); make.top.equalTo(speLabel.mas_bottom); make.height.equalTo(@(containerH)); }]; [addButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(containerView.mas_bottom).offset(10); make.right.equalTo(superView).offset(- 10); make.left.equalTo(superView).offset(UISCREENWIDTH - 10 - 30); make.bottom.equalTo(superView).offset(- 10); make.width.height.equalTo(@30); }]; [self.numField mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(addButton.mas_left).offset(- 2); make.top.height.equalTo(addButton); make.width.equalTo(@60); }]; [reduceButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.width.height.equalTo(addButton); make.right.equalTo(self.numField.mas_left).offset(- 2); }]; [numLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(superView).offset(10); make.bottom.equalTo(reduceButton); }]; [self initializeButtonsWithContainer:containerView]; } - (void)initializeButtonsWithContainer:(UIView *)containerView { UIButton *preBtn = nil; CGFloat rowNum = 0; // 第几行 for (int i = 0; i < self.specsArray.count; i++) { PindanSpecItem *specItem = [self specItemAtIndex:i]; BOOL selected = [self getFirstSelectedIndex] == i ? YES : NO; BOOL enabled = [self isSpecBtnEnabledAtIndex:i]; if (self.isEnd) enabled = NO; // 已结束状态 全部禁用 UIButton *button = [self createCommonSpecsBtnWithTitle:specItem.name tag:i + kSpecBtnTagBase selected:selected enabled:enabled]; if (selected) _selectedSpecBtn = button; [containerView addSubview:button]; CGFloat btnWidth = [self sizeForText:specItem.name withFontSize:kSpecBtnfontsize].width + 2 * KSpecBtnTitleMargin; // 判断当前button是否另起一行 BOOL rowChange = NO; NSUInteger curentRowNum = [self rowNumberForSepcsBtnIndex:i]; if (curentRowNum > rowNum && i > 0) { rowChange = YES; rowNum = curentRowNum; } if (i == 0) { [button mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(containerView); make.top.equalTo(containerView).offset(10); make.width.equalTo(@(btnWidth)); make.height.equalTo(@30); }]; }else if (rowChange){ [button mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(containerView); make.top.equalTo(preBtn.mas_bottom).offset(10); make.width.equalTo(@(btnWidth)); make.height.equalTo(@30); }]; }else{ [button mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(preBtn.mas_right).offset(10); make.top.height.equalTo(preBtn); make.width.equalTo(@(btnWidth)); }]; } preBtn = button; } } - (UIButton *)createCommonSpecsBtnWithTitle:(NSString *)title tag:(int)tag selected:(BOOL)selected enabled:(BOOL)enabled { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.titleLabel.font = [UIFont systemFontOfSize:kSpecBtnfontsize]; [button addTarget:self action:@selector(specsBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:title forState:UIControlStateNormal]; button.layer.borderWidth = 0.5f; button.layer.borderColor = selected ? [UIColorFromRGB(0xff6362) CGColor] : [UIColorFromRGB(0xc4cccc) CGColor]; UIColor *titleColor = selected ? UIColorFromRGB(0xff6362) : UIColorFromRGB(0x666666); [button setTitleColor:titleColor forState:UIControlStateNormal]; button.tag = tag; button.enabled = enabled; if (!enabled){ [button setBackgroundColor:UIColorFromRGB(0xeeeeee)]; [button setTitleColor:UIColorFromRGB(0xcccccc) forState:UIControlStateNormal]; button.layer.borderColor = [UIColor clearColor].CGColor; } return button; } - (BOOL)isSpecBtnEnabledAtIndex:(NSInteger)index { PindanSpecItem *specItem = [self specItemAtIndex:index]; if ([specItem.stock isKindOfClass:[NSString class]] && specItem.stock.integerValue == 0) { // 库存为0 return NO; } return YES; } - (PindanSpecItem *)specItemAtIndex:(NSUInteger)index{ if (self.specsArray.count > 0 && self.specsArray.count > index) { return self.specsArray[index]; } return nil; } - (NSInteger)getFirstSelectedIndex { __block NSInteger index = 0; [self.specsArray enumerateObjectsUsingBlock:^(PindanSpecItem *obj, NSUInteger idx, BOOL *stop) { if (![obj.stock isKindOfClass:[NSString class]] || obj.stock.integerValue > 0) { index = idx; *stop = YES; } }]; return index; } // 根据规格按钮算出所在行数 - (NSUInteger)rowNumberForSepcsBtnIndex:(NSUInteger)index { if (self.specsArray.count == 0 || index >= self.specsArray.count) { return 0; } CGFloat screenMargin = 10; // 规格按钮距离屏幕边距 CGFloat betMargin = 5; // 规格按钮之间边距 CGFloat rowLength = 2 * screenMargin; // 累计行长度 CGFloat rowCount = 0; // 共几行 for (int i = 0; i < index + 1; i++) { PindanSpecItem *specItem = [self specItemAtIndex:i]; if (specItem.name.length == 0) continue; CGFloat titleWidth = [self sizeForText:specItem.name withFontSize:kSpecBtnfontsize].width; CGFloat buttonWidth = titleWidth + 2 * KSpecBtnTitleMargin; rowLength += (buttonWidth + (i ? betMargin : 0)); if (rowLength >= UISCREENWIDTH) { rowCount++; rowLength = buttonWidth + 2 * screenMargin; // 假设不可能一个规格按钮超出一行 } } return rowCount; } // 规格按钮视图容器的总高度 - (CGFloat)heigtForAllSpecsBtn { NSUInteger rowCount = [self rowNumberForSepcsBtnIndex:self.specsArray.count - 1] + 1; return (rowCount + 1) * 15 + rowCount * 30; } - (CGSize)sizeForText:(NSString *)text withFontSize:(CGFloat)fontSize { if (text.length == 0 || fontSize <= 0) { return CGSizeZero; } NSDictionary *dict = @{NSFontAttributeName : [UIFont systemFontOfSize:fontSize]}; return [text sizeWithAttributes:dict]; } // 限购数量 - (NSInteger)limitedAmountForIndex:(NSInteger)index { return self.limitedAmount == 0 ? NSIntegerMax : self.limitedAmount; } // 库存限制 - (NSInteger)limitedStockForIndex:(NSInteger)index { PindanSpecItem *specItem = self.specsArray[index]; return [specItem.stock isKindOfClass:[NSString class]] ? specItem.stock.integerValue : NSIntegerMax; } - (void)showToView:(UIView *)view animated:(BOOL)animated { if (!view) { return; } CGFloat height = view.frame.size.height; CGFloat width = view.frame.size.width; CGFloat contentH = 250; // 内容高度 [view addSubview:self]; [self setFrame:view.frame]; [self.contentView setFrame:CGRectMake(0, height, width, contentH)]; self.backgroundColor = [UIColor clearColor]; CGFloat duration = animated ? kDurationTime : 0; [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f]; [self.contentView setFrame:CGRectMake(0, height - contentH, width, contentH)]; } completion:nil]; } #pragma mark - event response - (void)changNumBtnClick:(UIButton *)sender { if (self.isEnd) return; NSInteger numLimit = [self limitedAmountForIndex:self.selectedSpecsIndex]; NSInteger stockLimit = [self limitedStockForIndex:self.selectedSpecsIndex]; PindanSpecItem *specItem = self.specsArray[self.selectedSpecsIndex]; NSInteger number = [self.numField.text integerValue]; // 选中数量 NSInteger basketNum = self.basketBtn.tag; // 购物车中数量 NSInteger specNum = specItem.selectedAmount; // 当前选中规格购物篮中数量 if (sender.tag - kNumChangeBtnTagBase == 0) { number++; if (number + basketNum > numLimit){ NSString *warnString = [NSString stringWithFormat:@"每个账号只能购买%ld件哦", (long)numLimit]; [FLProgressHUDHelper showText:warnString inView:self.superview]; return; } if (number + specNum > stockLimit){ NSString *warnString = [NSString stringWithFormat:@"该商品库存仅剩%ld件", (long)stockLimit]; [FLProgressHUDHelper showText:warnString inView:self.superview]; return; } }else if (sender.tag - kNumChangeBtnTagBase == 1){ number--; } if (number <= 0) number = 1; self.numField.text = [NSString stringWithFormat:@"%ld", (long)number]; } - (void)specsBtnClick:(UIButton *)sender { if (sender == _selectedSpecBtn) return; if (_selectedSpecBtn) { _selectedSpecBtn.layer.borderColor = [UIColorFromRGB(0xc4cccc) CGColor]; [_selectedSpecBtn setTitleColor:UIColorFromRGB(0x666666) forState:UIControlStateNormal]; } sender.layer.borderColor = [UIColorFromRGB(0xff6362) CGColor]; [sender setTitleColor:UIColorFromRGB(0xff6362) forState:UIControlStateNormal]; _selectedSpecBtn = sender; // 刷新UI PindanSpecItem *specItem = self.specsArray[self.selectedSpecsIndex]; if (specItem){ CGFloat unitPrice = 0; if ([self.viewModel isVIP] && specItem.vipPrice.length >0) { self.vipImageIcon.hidden = NO; if ([specItem.vipPrice isKindOfClass:[NSString class]]) unitPrice = specItem.vipPrice.floatValue; } else { self.vipImageIcon.hidden = YES; if ([specItem.price isKindOfClass:[NSString class]]) unitPrice = specItem.price.floatValue; } self.detailLabel.text = specItem.name; self.priceLabel.text = [NSString stringWithFormat:@"¥%.2f", (unitPrice + self.nationalPostage) / 100.0f]; self.numField.text = @"1"; [self.imageView sd_setImageWithURL:[NSURL URLWithString:[PindanSelectDetailView cdnImgUrlStringWithString:specItem.imgUrl]]]; [self.contentView bringSubviewToFront:self.imageView]; } } - (void)cancelBtnClick { [UIView animateWithDuration:kDurationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.backgroundColor = [UIColor clearColor]; [self.contentView setFrame:CGRectOffset(self.contentView.frame, 0, CGRectGetHeight(self.contentView.frame))]; } completion:^(BOOL finished) { [self removeFromSuperview]; }]; } - (void)confirmBtnClick { if (self.isEnd) return; NSInteger numLimit = [self limitedAmountForIndex:self.selectedSpecsIndex]; NSInteger stockLimit = [self limitedStockForIndex:self.selectedSpecsIndex]; PindanSpecItem *specItem = self.specsArray[self.selectedSpecsIndex]; NSInteger number = [self.numField.text integerValue]; // 选中数量 NSInteger basketNum = self.basketBtn.tag; // 购物车中数量 NSInteger specNum = specItem.selectedAmount; // 当前选中规格购物篮中数量 if (number + basketNum > numLimit){ NSString *warnString = [NSString stringWithFormat:@"每个账号只能购买%ld件哦", (long)numLimit]; [FLProgressHUDHelper showText:warnString inView:self.superview]; return; } if (number + specNum > stockLimit){ NSString *warnString = [NSString stringWithFormat:@"该商品库存仅剩%ld件", (long)stockLimit]; [FLProgressHUDHelper showText:warnString inView:self.superview]; return; } specItem.selectedAmount += number; self.basketBtn.tag += number; NSString *animKey = @"animationGroup"; if (_animImgViewArray == nil) { _animImgViewArray = [NSMutableArray array]; } UIImageView *targetImgView = nil; for (UIImageView *imageView in self.animImgViewArray) { CAAnimation *anim = [imageView.layer animationForKey:animKey]; if (!anim) targetImgView = imageView; } if (!targetImgView){ targetImgView = [[UIImageView alloc]initWithImage:self.imageView.image]; targetImgView.layer.masksToBounds = YES; targetImgView.layer.cornerRadius = 5; [self.contentView addSubview:targetImgView]; [targetImgView setFrame:self.imageView.frame]; [self.animImgViewArray addObject:targetImgView]; } [targetImgView sd_setImageWithURL:[NSURL URLWithString:[PindanSelectDetailView cdnImgUrlStringWithString:specItem.imgUrl]]]; [self.contentView bringSubviewToFront:targetImgView]; targetImgView.tag = number; [targetImgView.layer addAnimation:self.groupAnim forKey:animKey]; } - (void)tapGestureClick:(UITapGestureRecognizer *)tapGesture { CGPoint location = [tapGesture locationInView:self]; BOOL isOnContent = CGRectContainsPoint(self.contentView.frame, location); if (isOnContent) { return; }else{ [self cancelBtnClick]; } } - (void)ClickbasketBtn:(UIButton *)sender{ if (self.basketBtn.tag <= 0) return; [UIView animateWithDuration:kDurationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.backgroundColor = [UIColor clearColor]; [self.contentView setFrame:CGRectOffset(self.contentView.frame, 0, CGRectGetHeight(self.contentView.frame))]; } completion:^(BOOL finished) { if (self.selectDoneAction) self.selectDoneAction(self); [self removeFromSuperview]; }]; } - (void)refreshSelectSpecContent{ NSInteger allCount = 0; for (PindanSpecItem *item in self.specsArray) { allCount += item.selectedAmount; } self.basketBtn.tag = allCount; self.numLabel.text = [NSString stringWithFormat:@"%ld", (long)self.basketBtn.tag]; } #pragma mark - animation delegate - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ self.basketBtn.selected = YES; self.numLabel.text = [NSString stringWithFormat:@"%ld", (long)self.basketBtn.tag]; self.numLabel.hidden = NO; } #pragma mark - getter && setter - (UIView *)contentView { if (_contentView == nil) { _contentView = [[UIView alloc]init]; _contentView.backgroundColor = [UIColor whiteColor]; } return _contentView; } - (UIImageView *)imageView { if (_imageView == nil) { _imageView = [[UIImageView alloc]init]; _imageView.layer.masksToBounds = YES; _imageView.layer.cornerRadius = 5; } return _imageView; } - (UIImageView *)vipImageIcon { if (_vipImageIcon == nil) { _vipImageIcon = [[UIImageView alloc]init]; _vipImageIcon.image = [UIImage imageNamed:@"VipPriceIcon"]; _vipImageIcon.hidden = YES; } return _vipImageIcon; } - (UILabel *)priceLabel { if (_priceLabel == nil) { _priceLabel = [[UILabel alloc]init]; _priceLabel.backgroundColor = [UIColor clearColor]; _priceLabel.font = [UIFont systemFontOfSize:13]; _priceLabel.textAlignment = NSTextAlignmentRight; _priceLabel.textColor = UIColorFromRGB(0xff6362); } return _priceLabel; } - (UILabel *)detailLabel { if (_detailLabel == nil) { _detailLabel = [[UILabel alloc]init]; _detailLabel.backgroundColor = [UIColor clearColor]; _detailLabel.font = [UIFont systemFontOfSize:13]; _detailLabel.textColor = UIColorFromRGB(0x999999); } return _detailLabel; } - (UIScrollView *)specScrollView { if (_specScrollView == nil) { _specScrollView = [[UIScrollView alloc]init]; _specScrollView.backgroundColor = [UIColor clearColor]; _specScrollView.showsHorizontalScrollIndicator = NO; _specScrollView.showsVerticalScrollIndicator = NO; } return _specScrollView; } - (UITextField *)numField { if (_numField == nil) { _numField = [[UITextField alloc]init]; _numField.textAlignment = NSTextAlignmentCenter; _numField.layer.borderWidth = 0.5f; _numField.layer.borderColor = [UIColorFromRGB(0xcccccc) CGColor]; _numField.enabled = NO; } return _numField; } - (UILabel *)numLabel{ if (_numLabel == nil) { _numLabel = [[UILabel alloc]init]; _numLabel.backgroundColor = UIColorFromRGB(0xff6362); _numLabel.layer.cornerRadius = 7.5; _numLabel.layer.masksToBounds = YES; _numLabel.textColor = [UIColor whiteColor]; _numLabel.font = [UIFont systemFontOfSize:10]; _numLabel.textAlignment = NSTextAlignmentCenter; _numLabel.hidden = YES; } return _numLabel; } - (UIButton *)basketBtn{ if (_basketBtn == nil) { _basketBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_basketBtn setImage:[UIImage imageNamed:@"product_basketH"] forState:UIControlStateSelected]; [_basketBtn setImage:[UIImage imageNamed:@"product_basket_n"] forState:UIControlStateNormal]; [_basketBtn addTarget:self action:@selector(ClickbasketBtn:) forControlEvents:UIControlEventTouchUpInside]; _basketBtn.tag = 0; } return _basketBtn; } - (UIView *)middleLine{ if (_middleLine == nil) { _middleLine = [[UIView alloc]init]; _middleLine.backgroundColor = UIColorFromRGB(0xe0e0e0); } return _middleLine; } - (CAAnimationGroup *)groupAnim{ if (_groupAnim == nil) { CGFloat animDuration = 0.6f; CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"]; anim.duration = animDuration; anim.repeatCount = 1; anim.removedOnCompletion = YES; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(self.imageView.layer.position.x, self.imageView.layer.position.y)]; [path addQuadCurveToPoint:self.basketBtn.layer.position controlPoint:CGPointMake(self.imageView.layer.position.x + 100, self.imageView.layer.position.y)]; anim.path = path.CGPath; CABasicAnimation *alpAnim = [CABasicAnimation animationWithKeyPath:@"opacity"]; alpAnim.fromValue = @1.0; alpAnim.toValue = @0.2f; alpAnim.duration = animDuration; CAKeyframeAnimation *scaleAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CATransform3D transform1 = CATransform3DMakeScale(0.8, 0.8, 1.0f); CATransform3D transform2 = CATransform3DMakeScale(0.4, 0.4, 1.0f); CATransform3D transform3 = CATransform3DMakeScale(0.4, 0.4, 1.0f); scaleAnim.values = @[[NSValue valueWithCATransform3D:transform1], [NSValue valueWithCATransform3D:transform2], [NSValue valueWithCATransform3D:transform3],]; scaleAnim.keyTimes = @[@0, @0.6, @1.0]; CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotateAnim.fromValue = @0; rotateAnim.toValue = @(2 * M_PI * 3); rotateAnim.duration = animDuration; _groupAnim = [CAAnimationGroup animation]; _groupAnim.duration = animDuration; _groupAnim.removedOnCompletion = YES; _groupAnim.animations = @[anim, alpAnim, scaleAnim, rotateAnim]; _groupAnim.delegate = self; } return _groupAnim; } - (NSInteger)selectedSpecsIndex { if (!_selectedSpecBtn) { return 0; } return _selectedSpecBtn.tag - kSpecBtnTagBase; } - (NSInteger)selectedAmount { return [self.numField.text integerValue]; } @end