• IOS开发基础知识--碎片15


    1:将自定义对象转化成NsData存入数据库

    要转为nsdata自定义对象要遵循<NSCoding>的协议,然后实现encodeWithCoder,initwithcode对属性转化,实例如下:
    
    HMShop.h
    #import <Foundation/Foundation.h>
    
    @interface HMShop : NSObject <NSCoding>
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) double  price;
    @end
    
    HMShop.m
    #import "HMShop.h"
    
    @implementation HMShop
    - (void)encodeWithCoder:(NSCoder *)encoder
    {
        [encoder encodeObject:self.name forKey:@"name"];
        [encoder encodeDouble:self.price forKey:@"price"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder
    {
        if (self = [super init]) {
            self.name = [decoder decodeObjectForKey:@"name"];
            self.price = [decoder decodeDoubleForKey:@"price"];
        }
        return self;
    }
    
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"%@ <-> %f", self.name, self.price];
    }
    @end
    
    操作:
    
    - (void)addShops
    {
        NSMutableArray *shops = [NSMutableArray array];
        for (int i = 0; i<100; i++) {
            HMShop *shop = [[HMShop alloc] init];
            shop.name = [NSString stringWithFormat:@"商品--%d", i];
            shop.price = arc4random() % 10000;
            
            NSData *data = [NSKeyedArchiver archivedDataWithRootObject:shop];
            [self.db executeUpdateWithFormat:@"INSERT INTO t_shop(shop) VALUES (%@);", data];
        }
    }
    
    - (void)readShops
    {
        FMResultSet *set = [self.db executeQuery:@"SELECT * FROM t_shop LIMIT 10,10;"];
        while (set.next) {
            NSData *data = [set objectForColumnName:@"shop"];
            HMShop *shop = [NSKeyedUnarchiver unarchiveObjectWithData:data];
            NSLog(@"%@", shop);
        }
    }
    
    *把对象转成nsdata的理由,因为在存入数据库时会变成字符串,不利转化,所以先把其序列化转化成nsdata,然后存进数据库,取出时同样先为nsdata再转化;

    2:增加子控制器,用来提取一些公共的内容布局,瘦身当前viewcontroller

    DetailsViewController *details = [[DetailsViewController alloc] init];
        details.photo = self.photo;
        details.delegate = self;
        [self addChildViewController:details]; 
        CGRect frame = self.view.bounds;
        frame.origin.y = 110;
        details.view.frame = frame;
        [self.view addSubview:details.view];
        [details didMoveToParentViewController:self];

    3:用协议来分离出调用

    在子控制器创建一个协议,然后在其内部对它进行处理传参
    
    子控制器.h
    @protocol DetailsViewControllerDelegate
    
    - (void)didSelectPhotoAttributeWithKey:(NSString *)key;
    
    @end
    
    
    @interface DetailsViewController : UITableViewController
    
    @property (nonatomic, strong) Photo *photo;
    @property (nonatomic, weak) id <DetailsViewControllerDelegate> delegate;
    
    @end
    
    子控制器.m
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *key = self.keys[(NSUInteger) indexPath.row];
        //对它进行传参,让其在父控制器去实现
        [self.delegate didSelectPhotoAttributeWithKey:key]; 
    }
    
    
    父控制器.m
    @interface PhotoViewController () <DetailsViewControllerDelegate>
    @end
    
    然后(得到参数,进行原本子控制器要进行的操作):
    - (void)didSelectPhotoAttributeWithKey:(NSString *)key
    {
        DetailViewController *detailViewController = [[DetailViewController alloc] init];
        detailViewController.key = key;
        [self.navigationController pushViewController:detailViewController animated:YES];
    }

    4:关于kvo的运用

    //进度值改变 增加kvo 传值 key为fractionCompleted
    - (void)setProgress:(NSProgress *)progress{
        if (_progress) {
            [_progress removeObserver:self forKeyPath:@"fractionCompleted"];
        }
        _progress = progress;
        if (_progress) {
            [_progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];
        }
    }
    //消息kvo消息
    - (void)dealloc{
        if (_progress) {
            [_progress removeObserver:self forKeyPath:@"fractionCompleted"];
        }
        _progress = nil;
    }
    
    #pragma mark KVO
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        if ([keyPath isEqualToString:@"fractionCompleted"]) {
            NSProgress *progress = (NSProgress *)object;
            NSProgress *cellProgress = _offsourecebean.cDownloadTask.progress;
            BOOL belongSelf = NO;
            if (cellProgress && cellProgress == progress) {
                belongSelf = YES;
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                if (self) {
                    [self showProgress:progress belongSelf:belongSelf];
                }
            });
        } else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    
    *注意增加监听后在不用时要进行消除,移除观察,其中addObserver可以是其它对象,然后在其内部实现observeValueForKeyPath这个协议;增加监听时可以设置options类型,也可以多类型一起;比如NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld;当被监听的对象发生变化时,会马上通知监听对象,使它可以做出一些响应,比如视图的更新;

     5:自定义UITableViewCell的accessoryView 判断哪个Button按下

    UITableview的开发中经常要自定义Cell右侧的AccessoryView,把他换成带图片的按钮,并在用户Tap时判断出是哪个自定义按钮被按下了。
    
    创建自定义按钮,并设为AccessoryView
    if (cell == nil) { 
        cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault                                  reuseIdentifier:identifier]; 
       
        UIImage *image= [ UIImage imageNamed:@"delete.png" ];
        UIButton *button = [ UIButton buttonWithType:UIButtonTypeCustom ];
        CGRect frame = CGRectMake( 0.0 , 0.0 , image.size.width , image.size.height );
        button. frame = frame;
        [button setBackgroundImage:image forState:UIControlStateNormal ];
        button. backgroundColor = [UIColor clearColor ];
        [button addTarget:self action:@selector(buttonPressedAction  forControlEvents:UIControlEventTouchUpInside]; 
        cell. accessoryView = button;
     } 
    
    如果将Button加入到cell.contentView中,也是可以的。
    cell.contentView addSubview:button];
    
    在Tap时进行判断,得到用户Tap的Cell的IndexPath
    - (void)buttonPressedAction  id)sender 
    { 
       UIButton *button = (UIButton *)sender; 
       (UITableViewCell*)cell = [button superview]; 
       int row = [myTable indexPathForCell:cell].row; 
    } 
    
    对于加到contentview里的Button
    (UITableViewCell*)cell = [[button superview] superview];

    6:直接运用系统自带的UITableViewCell,其中cell.accessoryView可以自定义控件

    #import "MyselfViewController.h"
    
    @interface MyselfViewController ()
    
    @property (nonatomic, retain) NSMutableArray *datasource;
    
    @end
    
    @implementation MyselfViewController
    -(void)dealloc {
        [_datasource release];
        [super dealloc];
    }
    
    -(NSMutableArray *)datasource {
        if (!_datasource) {
            self.datasource = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MyselfList" ofType:@"plist"]];
        }
        return _datasource;
    }
    
    -(instancetype)init {
        self = [super initWithStyle:UITableViewStyleGrouped];
        if (self) {
    
        }
        return self;
    }
    
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
        self.tableView.rowHeight = 70;
        self.navigationItem.title = @"我的";
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return self.datasource.count;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
        // Return the number of rows in the section.
        return [self.datasource[section] count];
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
        NSDictionary *dict = [self.datasource[indexPath.section] objectAtIndex:indexPath.row];
        cell.textLabel.text = dict[@"title"];
        cell.imageView.image = [UIImage imageNamed:dict[@"imageName"]];
    
        if (indexPath.section == 2 && indexPath.row == 0) {
            cell.accessoryView = [[[UISwitch alloc] init] autorelease];
        } else {
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
        
        return cell;
    }
    
    @end
  • 相关阅读:
    自定义注解!绝对是程序员装逼的利器!!
    我女儿说要看雪,但是我家在南方,于是我默默的拿起了键盘,下雪咯。
    零基础转行前端,如何拿下了字节跳动、美团等大厂offer
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    web面试必问的题
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    520了,用32做个简单的小程序
    虚拟机找不到本机vmnet0,vmnet8,无法连接xshell,解决方案
    Linux用户登出之后保持后台进程(nohup)
    Debian取消从光盘安装软件的方式(please insert the disc labeled)
  • 原文地址:https://www.cnblogs.com/wujy/p/4569838.html
Copyright © 2020-2023  润新知