美文网首页
UITableView

UITableView

作者: MarkTang | 来源:发表于2016-01-14 08:58 被阅读102次

UITableView

创建UITableView

  • 代码

  • 使用Masonry布局

  • storyboard

    • 动态单元格记得使用唯一标识符a
    • xib和storyboard差不多

    注意点:循环利用 有if就有else

刷新数据

  • 全局刷新
[self.table reloadData];
  • 局部刷新
    • 添加(带动画)
 [self.wineArr insertObject:wine atIndex:0];
    NSArray *indepath = @[[NSIndexPath indexPathForRow:0 inSection:0]];
    [self.table insertRowsAtIndexPaths:indepath withRowAnimation:UITableViewRowAnimationRight];
  • 删除(带动画)
    NSArray *delate =@[[NSIndexPath indexPathForRow:0 inSection:0]];
    [self.table deleteRowsAtIndexPaths:delate withRowAnimation:UITableViewRowAnimationMiddle];
  • 刷新(带动画)
NSArray *update =@[[NSIndexPath indexPathForRow:0 inSection:0]];
    [self.table reloadRowsAtIndexPaths:update withRowAnimation:UITableViewRowAnimationMiddle];

左划删除

#pragma make - UITbaleViewDalegate
/** 只要有这个方法就会出现向左划就会出现删除按钮,点击按钮会调用这个方法(iOS9以前一定要调用这个方法才会出现,但是在iOS9后只要调用下面的方法一样可以出现按钮)*/
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.wineArr removeObjectAtIndex:indexPath.row];
    NSArray *delate =@[
                       [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]
                       ];
    [self.table deleteRowsAtIndexPaths:delate withRowAnimation:UITableViewRowAnimationMiddle];
}
/** 这个方法返回的字符串是你要现实在左划按钮上面显示的字,如何和下面方法同时存在下面方法优先级更高*/
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"删除";
}



//自定义左划的按钮
-(NSArray<UITableViewRowAction *>*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath

{
    //这是代表一个按钮 block里面的代码是点击这个按钮之后会执行的操作
    UITableViewRowAction *action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除a" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        //和上面删除的方法相同代码
        [self.wineArr removeObjectAtIndex:indexPath.row];
        NSArray *delate =@[
                           [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]
                           ];
        [self.table deleteRowsAtIndexPaths:delate withRowAnimation:UITableViewRowAnimationMiddle];
        
    }];
    
    UITableViewRowAction * action2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"关注" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        //这个方法只是展示用,现在不推荐使用
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"谢谢关注" message:@"😘" delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:nil, nil];
        alert.show;
        //推出编辑模式
        self.table.editing = NO;
    }];
    
    //先加的按钮在右边
    return @[action1,action2];
}

编辑模式

    //让tabel进入编辑模式
    //取反 是编辑模式久让它变成不是 否则相反
    self.table.editing = !self.table.editing;
    //带动画的方法
    [self.table setEditing:!self.table.isEditing animated:YES];

多行编辑模式下的删除

- (void)viewDidLoad {
    [super viewDidLoad];
   
    //让批量删除可以多选,默认有一个样式
    self.table.allowsMultipleSelectionDuringEditing = YES;
    //删除按钮状态
    self.ddd.enabled = NO;

}
//批量删除按钮
- (IBAction)remove {
    
    //让tabel进入编辑模式
    //取反 是编辑模式久让它变成不是 否则相反
    //self.table.editing = !self.table.editing;
    //带动画的方法
    [self.table setEditing:!self.table.isEditing animated:YES];
    self.ddd.enabled = !self.ddd.enabled;
    
}
//删除按钮
- (IBAction)deleate {
    //零时数组保存数据
    NSMutableArray *tempArr = [NSMutableArray array];
    //注意:千万不要一边遍历数组,一边操作这个数组,因为数组中的索引会一直发生变化
    for (NSIndexPath *indexpath in self.table.indexPathsForVisibleRows) {
        [tempArr addObject:self.wineArr[indexpath.row]];
    }
    //在数据源中把用户选择的数据删除
    [self.wineArr removeObjectsInArray:tempArr];
    //tableVieW删除这些列表
    [self.table deleteRowsAtIndexPaths:self.table.indexPathsForVisibleRows withRowAnimation:UITableViewRowAnimationAutomatic];
    
}

1.png

自定义编辑模式多选的按钮

首先模型中增加一个属性

@property(assign,nonatomic,getter=ischeck)BOOL check;

让后自定义cell中重写方法

//重写initWithStyle方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
     
        UIImageView *checkImage = [[UIImageView alloc]init];
        checkImage.image = [UIImage imageNamed:@"check"];
        checkImage.hidden = YES;
        [self.contentView addSubview:checkImage];
        self.check = checkImage;
    }
    return self;
}
//布局子控件
- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat WH = 24;
    CGFloat X = self.contentView.frame.size.width - WH- 10;
    CGFloat Y = (self.contentView.frame.size.height - WH)*0.5;
    self.check.frame = CGRectMake(X, Y, WH, WH);
}
//设置数据
- (void)setWine:(Wine *)wine
{
    _wine = wine;
    self.imageView.image = [UIImage imageNamed:wine.image];
    self.textLabel.text = wine.name;
    self.detailTextLabel.text = wine.money;
    //根据传进来的模型判断是否显示打勾的图片
    if (wine.ischeck) {
        self.check.hidden = NO;
    }else
    {
        self.check.hidden = YES;
    }
}
重点就是声明一个数组,用来保存用户选取的哪个
/** 用户选取要删除的数组*/
@property(strong,nonatomic)NSMutableArray *SelectArr;


//懒加载
- (NSMutableArray *)SelectArr
{
    if (!_SelectArr) {
        _SelectArr = [NSMutableArray array];
    }
    return _SelectArr;
}



#pragma mark - UITableViewDalegate
//监听用户选点击了哪一行
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Wine *wine = self.WineArr[indexPath.row];
    if (wine.ischeck) {
        wine.check = NO;
        [self.SelectArr removeObject:indexPath];
       
     }else{
        wine.check = YES;
        [self.SelectArr addObject:indexPath];
        
    }
    NSLog(@"%@",indexPath);
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

//删除方法
- (IBAction)deleate {
    NSMutableArray *tempArr = [NSMutableArray array];
    
    for (NSIndexPath *indexpatha in self.SelectArr) {
        [tempArr addObject:self.WineArr[indexpatha.row]];
    }
    //删除数据源中的数据
    [self.WineArr removeObjectsInArray:tempArr];
    
    [self.Tabel deleteRowsAtIndexPaths:self.SelectArr withRowAnimation:UITableViewRowAnimationAutomatic];
    //重置数组为
    [self.SelectArr removeAllObjects];
    
}

通知

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //监听通知
    NSNotificationCenter *Notice = [NSNotificationCenter defaultCenter];
    [Notice addObserver:self selector:@selector(countAdd:) name:@"AddCount" object:nil];
    [Notice addObserver:self selector:@selector(countRemove:) name:@"RemoveCount" object:nil];
    
}
//在销毁前移除通知
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self];
}
-(void)countAdd:(NSNotification *)note
{   //发布者
    WineTableViewCell *cell = note.object;
    int price = self.Price.text.intValue + cell.wine.money.intValue;
    self.Price.text = [NSString stringWithFormat:@"%d",price];
    
}
-(void)countRemove:(NSNotification *)note

{
    //发布者
    WineTableViewCell *cell = note.object;
    int price = self.Price.text.intValue - cell.wine.money.intValue;
    self.Price.text = [NSString stringWithFormat:@"%d",price];
    
}

- (IBAction)add {
    self.wine.count ++;
    self.count.text = [NSString stringWithFormat:@"%ld",(long)self.wine.count];
    self.remove.enabled = YES;
    //发布通知
    [[NSNotificationCenter defaultCenter]postNotificationName:@"AddCount" object:self];
    
}
- (IBAction)deleate {
    self.wine.count --;
    self.count.text = [NSString stringWithFormat:@"%ld",(long)self.wine.count];
    if (self.wine.count==0) {
        self.remove.enabled = NO;
    }
    //发布通知
    [[NSNotificationCenter defaultCenter]postNotificationName:@"RemoveCount" object:self];
    
}


block写法不要移除 执行block中的代码块
    // 监听通知
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    
    [center addObserverForName:@"plusClickNotification"  object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        // 发布者
        XMGWineCell *cell = note.object;
        
        // 计算总价
        int totalPrice = self.totalPriceLabel.text.intValue + cell.wine.money.intValue;
        
        // 设置总价
        self.totalPriceLabel.text = [NSString stringWithFormat:@"%d",totalPrice];

        
    }];


kvo

@implementation ViewController
- (NSMutableArray *)WineData
{
    if (!_WineData) {
        _WineData = [Wine mj_objectArrayWithFilename:@"wine.plist"];
        //监听属性变化
        for (Wine *wine in _WineData) {
            [wine addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
        }
    }
    
    return _WineData;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    
}
//移除KVO
- (void)dealloc
{
    for (Wine *wine in _WineData) {
        [wine removeObserver:self forKeyPath:@"count"];
    }
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(Wine*)wine change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    int new = [change[NSKeyValueChangeNewKey] intValue];
    int old = [change[NSKeyValueChangeOldKey]intValue];
    if (new>old) {
        int price = self.Price.text.intValue + wine.money.intValue;
        self.Price.text = [NSString stringWithFormat:@"%d",price];
        self.buyBtn.enabled = YES;
    }else
    {
        int price = self.Price.text.intValue - wine.money.intValue;
        self.Price.text = [NSString stringWithFormat:@"%d",price];
        self.buyBtn.enabled = (price>0);
        
    }
}


block写法


  • 缺点:在类中一使用到就会调用了
  • 如果一个类使用来kvo监听,苹果木默认会给这个类生成一个子类,在子类中监听这些事情

代理

#import <UIKit/UIKit.h>
@class Wine,WineTableViewCell;
/** 代理*/
@protocol WineTableViewCellDalegate <NSObject>

@optional
-(void)wineCellClickAddBtn:(WineTableViewCell *)wine;
-(void)wineCellClickDeleateBtn:(WineTableViewCell *)wine;
@end

@interface WineTableViewCell : UITableViewCell

/** 模型*/
@property(strong,nonatomic)Wine *wine;

/** 代理属性*/
@property(weak,nonatomic)id <WineTableViewCellDalegate> delegate;
@end



@implementation WineTableViewCell
 /** 代理*/
    if ([self.delegate respondsToSelector:@selector(wineCellClickAddBtn:)]) {
        [self.delegate wineCellClickAddBtn:self];
    }

    /** 代理*/
    if ([self.delegate respondsToSelector:@selector(wineCellClickDeleateBtn:)]) {
        [self.delegate wineCellClickDeleateBtn:self];
    }
    
    //设置代理
    cell.delegate = self;
    //遵守协议
    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate,WineTableViewCellDalegate>
    //实现方法
    #pragma mark - WineTableViewCellDalegate
-(void)wineCellClickAddBtn:(WineTableViewCell *)wine
{
    int price = self.Price.text.intValue + wine.wine.money.intValue;
    self.Price.text = [NSString stringWithFormat:@"%d",price];
    self.buyBtn.enabled = YES;
    //添加到购物车
    if (![self.shopping containsObject:wine.wine])
    {
        [self.shopping addObject:wine.wine];
    }
}
-(void)wineCellClickDeleateBtn:(WineTableViewCell *)wine
{
    int price = self.Price.text.intValue - wine.wine.money.intValue;
    self.Price.text = [NSString stringWithFormat:@"%d",price];
    self.buyBtn.enabled = (price>0);
    //移除购物车
    if (wine.wine.count==0) {
        [self.shopping removeObject:wine.wine];
    }
    
}

相关文章

网友评论

      本文标题:UITableView

      本文链接:https://www.haomeiwen.com/subject/dsockttx.html