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 代码分支管理教程

目录
相关文章
|
3月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
334 4
|
4月前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
4月前
|
搜索推荐 IDE API
打造个性化天气应用:iOS开发之旅
【9月更文挑战第35天】在这篇文章中,我们将一起踏上iOS开发的旅程,通过创建一个个性化的天气应用来探索Swift编程语言的魅力和iOS平台的强大功能。无论你是编程新手还是希望扩展你的技能集,这个项目都将为你提供实战经验,帮助你理解从构思到实现一个应用的全过程。让我们开始吧,构建你自己的天气应用,探索更多可能!
95 1
|
3月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
70 2
|
3月前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
3月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
94 1
|
4月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
78 5
|
数据可视化 iOS开发
iOS界面布局之一——使用autoresizing进行动态布局
iOS界面布局之一——使用autoresizing进行动态布局
275 0
iOS界面布局之一——使用autoresizing进行动态布局
|
1月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
141 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    141
  • 4
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    223
  • 5
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    87
  • 6
    深入探索iOS开发中的SwiftUI框架
    143
  • 7
    ios样式开关按钮jQuery插件
    58
  • 8
    Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
    74
  • 9
    深入探索iOS与Android操作系统的安全性差异
    102
  • 10
    安卓与iOS开发中的跨平台策略:一次编码,多平台部署
    174