iOS订单折扣视图应用于购物车界面(支持添加/删除/选择折扣)

简介: iOS订单折扣视图应用于购物车界面(支持添加/删除/选择折扣)

前言

应用场景

  1. 购物车界面选择整单折扣

image.png

  1. 无品收银台界面选择订单折扣

image.png

支持的视图类型

typedef enum : NSUInteger {
/**
 下拉选择折扣,支持删除和添加 (最大列数4个)
*/
    QCTDiscountViewType4col,
    /**
     从侧边划出选择折扣视图 (最大列数3个)
    */
    QCTDiscountViewType3col,
} QCTDiscountViewType;

iOS开发交流,欢迎关注公众号:iOS逆向

I 、用法

折扣视图由表格的cell组成

1.1   cell的初始化

case QCTDropDownMenuViewSection4delete:
        {
            QCTDiscountTableViewCell *cell = [QCTDiscountTableViewCell tableViewCellWithTableView:tableView block:^(QCTDiscountModel * sender) {
                if (sender == nil) {
                    return ;
                }
                if (sender.isADDorDelete) {
                    if ([sender.name isEqualToString:@"+"]) {
                        UIView *view = weakSelf.modal.contentView;
                        if ([view isMemberOfClass:[DiscountPickerView class]]) {
                            [weakSelf.modal show:YES];
                        }else{
                            [weakSelf.modal showContentView:self.discountPickerV animated:YES];
                            weakSelf.modal.positionMode = STModelPositionCenterBottom;
                        }
                    }else if([sender.name isEqualToString:@"-"]){
                        [weakSelf showpromptDeleteView];
                    }
                }else{
#pragma mark - ******** 处理折扣的点击事件
                    [weakSelf setupClickDiscount:sender];
                }
                //
            } models:nil];
            [cell setType:QCTDiscountViewType4col];
            [cell setModels:[self getdiscountModelsWithArray:self.viewModel.discountContainAddDeleteModels index:indexPath.row clos:4 ]];
            return cell;
            //
            //
        }
            break;

获取每一行的数据模型

#pragma mark - ******** 获取每一行的数据模型
- (NSMutableArray*)getdiscountModelsWithArray:(NSMutableArray*)discountModels index:(NSInteger)row  clos:(NSInteger)clos{
    // 获取总行
    NSInteger all = (discountModels.count -1) /clos +1;//4
    if (row> all) {
        return nil;
    }
    NSInteger startIndex = (row)*(clos);//0 4
    NSInteger endIndex = startIndex+(clos-1);//3,7
    NSMutableArray* tmp = [NSMutableArray array];
    NSInteger realendIndex = endIndex > (discountModels.count-1) ?  discountModels.count-1 :  endIndex;
    for (NSInteger i =startIndex ; i<= realendIndex ; i++) {
        [tmp addObject:discountModels[i]];
    }
    return tmp;
}

1.2 视图的初始化

- (void)setModels:( id)models{
    _models =models;
        self.cellView.model = models;
}
- (QCTDiscountView *)cellView{
    if (nil == _cellView) {
        QCTDiscountView *tmpView = [[QCTDiscountView alloc]init];
        _cellView = tmpView;
        [tmpView setBackgroundColor:kcellColor];
        [self.contentView addSubview:_cellView];
        __weak __typeof__(self) weakSelf = self;
        [_cellView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(weakSelf.contentView).offset( kAdjustRatio(kSideMargin+4));
            make.right.equalTo(weakSelf.contentView).offset(- kAdjustRatio(kSideMargin+4));
            make.top.equalTo(weakSelf.contentView).offset(kAdjustRatio(0));
            make.bottom.equalTo(weakSelf.contentView).offset(kAdjustRatio(0));
        }];
        [_cellView setBlock:^(id  _Nonnull sender) {
            if (weakSelf.block) {
                weakSelf.block(sender);
            }
        }];
    }
    return _cellView;
}

II、 DiscountView核心代码

2.1  QCTDiscountView.h

#import "QCTDiscountBtn.h"
NS_ASSUME_NONNULL_BEGIN
typedef enum : NSUInteger {
    QCTDiscountViewType4col,
    QCTDiscountViewType3col,
} QCTDiscountViewType;
@interface QCTDiscountView : UIView
@property (nonatomic, copy) void (^block)(id sender);
@property (nonatomic, strong) id model;
@property (nonatomic, assign) QCTDiscountViewType type;
@end

2.2   QCTDiscountView.m

#import "QCTDiscountView.h"
/**
 iOS 自定义折扣处理视图:支持添加/删除/选择折扣 【 应用场景:购物车界面选择整单折扣,无品收银台界面选择订单折扣】
 */
@interface QCTDiscountView ()
@end
@implementation QCTDiscountView
- (instancetype)init
{
    self = [super init];
    if (self) {
        UITapGestureRecognizer *cutTap = [[UITapGestureRecognizer alloc] init];
        cutTap.cancelsTouchesInView = NO;// 设置tableView的点击事件优先级,低于cell的选中事件
        [[cutTap rac_gestureSignal] subscribeNext:^(id x) {
            NSLog(@"QCTDiscountView");
        }];
        [self  addGestureRecognizer:cutTap];
    }
    return self;
}
- (void)setType:(QCTDiscountViewType)type{
    switch (type) {
        case QCTDiscountViewType4col:
        {
            [self setupSubView:4];
        }
            break;
        case QCTDiscountViewType3col:
        {
            [self setupSubView:3];
        }
            break;
        default:
            break;
    }
}
- (void)setupSubView:(NSInteger)col{
    QCTDiscountBtn * lasttmp;
    for (int i = 0; i<col; i++) {
        QCTDiscountBtn * tmp = [QCTDiscountBtn new];
        tmp.tag = i+1000;
        [self addSubview:tmp];
        __weak __typeof__(self) weakSelf = self;
        [tmp mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(weakSelf);
            make.width.equalTo(weakSelf).offset(-kAdjustRatio(15*(col-1)*0.25)).dividedBy(col);
            if (i%col == 0) {
                make.left.equalTo(weakSelf);
            }else{
                make.left.equalTo(lasttmp.mas_right).offset(kAdjustRatio(15));
            }
            make.bottom.equalTo(weakSelf).offset(kAdjustRatio(-20));
            make.top.equalTo(weakSelf).offset(kAdjustRatio(0));
        }];
        lasttmp = tmp;
        tmp.hidden = YES;
        UITapGestureRecognizer *cutTap = [[UITapGestureRecognizer alloc] init];
        [[cutTap rac_gestureSignal] subscribeNext:^(id x) {
            NSLog(@"model: %@",tmp.models.name);
            if (weakSelf.block) {
                weakSelf.block(tmp.models);
            }
        }];
        [tmp addGestureRecognizer:cutTap];
    }
}
/**
 Masonry比例用法
 */
- (void)setModel:(NSMutableArray *)model{
    _model = model;
    // 构建子试图
    for (int i = 0; i<model.count; i++) {
        id obj = model[i];
        QCTDiscountBtn * tmp = (QCTDiscountBtn *)[self viewWithTag:i + 1000];;
        tmp.models = obj;        
    }
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    CGPoint redBtnPoint = [self convertPoint:point toView:self];
    for (UIView *obj in self.subviews) {
        if ( CGRectContainsPoint(obj.frame, redBtnPoint) ) {
            return obj;
        }
    }
        if (redBtnPoint.y <= CGRectGetMaxY(self.frame)) {
            return self;
        }
  return  [super hitTest:point withEvent:event];
}
@end

III、数据模型DiscountModel

@interface QCTDiscountModel : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) BOOL isSlelected;
@property (nonatomic,assign) BOOL isdeleted;
@property (nonatomic,copy) NSString *imageName;
@property (nonatomic,assign) BOOL isADDorDelete;
+ (instancetype)getQCTDiscountModelWithname:(NSString*)name;
+ (NSMutableArray*)getQCTDiscountModels:(NSMutableArray*)arr;
@property (nonatomic,assign) BOOL isfirstModel;

see also

git 代码分支管理教程

目录
相关文章
|
1月前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
1月前
|
搜索推荐 IDE API
打造个性化天气应用:iOS开发之旅
【9月更文挑战第35天】在这篇文章中,我们将一起踏上iOS开发的旅程,通过创建一个个性化的天气应用来探索Swift编程语言的魅力和iOS平台的强大功能。无论你是编程新手还是希望扩展你的技能集,这个项目都将为你提供实战经验,帮助你理解从构思到实现一个应用的全过程。让我们开始吧,构建你自己的天气应用,探索更多可能!
62 1
|
8天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
23 1
|
17天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
40 5
|
2月前
|
存储 IDE 开发工具
移动应用开发之旅:打造你的首个iOS应用
【9月更文挑战第23天】在数字化浪潮中,移动应用已成为连接用户与数字世界的关键桥梁。本文将带领读者踏上开发属于自己的第一个iOS移动应用的旅程,从理解移动操作系统的核心概念出发,逐步深入到实际的应用构建过程中。通过简洁明了的语言和具体的代码示例,我们将一起探索如何在苹果的iOS平台上实现一个简单的“待办事项列表”应用,让读者不仅能够学习到编程知识,还能体会到将想法转化为现实产品的成就感。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供一个实用的指南,帮助你迈出成为移动应用开发者的第一步。
|
2月前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
58 5
|
2月前
|
开发工具 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的关键考量
在数字时代的浪潮中,安卓和iOS这两大操作系统如同双子星座般耀眼夺目,引领着移动应用的潮流。它们各自拥有独特的魅力和深厚的用户基础,为开发者提供了广阔的舞台。然而,正如每枚硬币都有两面,安卓与iOS在开发过程中也展现出了截然不同的特性。本文将深入剖析这两者在开发环境、编程语言、用户体验设计等方面的显著差异,并探讨如何根据目标受众和项目需求做出明智的选择。无论你是初涉移动应用开发的新手,还是寻求拓展技能边界的资深开发者,这篇文章都将为你提供宝贵的见解和实用的建议,帮助你在安卓与iOS的开发之路上更加从容自信地前行。