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