subclass UITableViewCell
一般是通过改变单元格的contentView来改变整个单元格的外观与行为,比如自定义UILabel,UIButton然后添加到contentView中
举例,当整个单元格进入编辑模式,是要移动contentView,来给删除图标[delete control]腾位置。此时是移动了contentView
1.创建类
#import<UIKit/UIKit.h>
@interface BNRItemCell : UITableViewCell
@end
2.建立BNRItemCell.xib,通过xib来建立自己的cell。 在空的xib中拖入一个UITableViewCell,选择Table View Cell在identity inspector中
更改链接类为 BNRItemCell.接下来你就可以在xib中拖入元件,自定义了。
最后,建立outle链接,outlet要求 :
Connection : Outlet
Object: Item Cell
Storage: weak
此时File's Owner还未建立任何连接 '
3.加载注册使用
-(void)viewDidLoad
{
[super viewDidLoad];
// 加载
UINib *nib = [UINib nibWithNibName:@"BNRItemCell" bundle:nil];
// 注册
[self.tableView registerNib:nil forCellReuseIdentifier:@"BNRItemCell"];
}
在BNRItemsViewControllers中,修改tableView:cellFroRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
BNRItemCell *cell = [tableView dequeueResuableCellWithIdentifier:@"BNRItemCell" forIndexPath:indexPath];
// sub view
// self.nameLabel.text = ...
// self.serialNumberLabel.text = ...
return cell;
}
4.为单元格添加约束
当window的尺寸改变,table view改变尺寸,然后cell也要改变尺寸。注意,此时cell一般不改变高度,
如果想要,可以手动rowHeight或者delegate the method: tableView:heightForRowAtIndexPath:
压缩图片:
-(void)setThumbnailFromImage:(UIImage *)image
{
CGSize origImageSize = image.size;
// 压缩图片的尺寸
CGRect newRect = CGRectMake(0, 0, 40, 40);
// 计算一个等比缩放的比例
float ratio = MAX(newRect.size.width / origImageSize.width,
newRect.size.height / origImageSize.height);
// 创建一个转换的bitmap context
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);
//创建带圆角矩形的矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0];
[path addClip];
CGRect projectRect;
projectRect.size.width = ratio * origImageSize.width;
projectRect.size.height = ratio * origImageSize.height;
projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0;
projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0;
[image drawInRect:projectRect];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
self.thumbnail = smallImage;
// clean up the image context resources;
UIGraphicsEndImageContext();
}
当你选择照片或者拍照后,调用它压缩设置压缩图片
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = info[UIImagePickerControllerOriginalImage];
[self.item setThumbnailFromImage:image];
}
5.添加动作。Cell作为中间人转达动作 relaying
比如你单击一个略缩图可以看到原图。在略缩图上添加一个透明的可单击控件
此时该透明控件UIButton与thumnail要有一个约束,同时选中两项:
Leading Edges: 0
Trailing Edges: 0
Top Edges: 0
Bottom Edges: 0
-(IBAction)showImage:(id)sender
{
}
如果直接在上面实现则会有一个问题,这个showImage实在ItemCell中,也就是UITableViewCell,它不是controller它无法获取到image的数据,你也不可以在压缩之前保存image
!!!!方法:由controller提供一个block,然后单击的时候调用这个block!!!! 就是回调
************************************************************************
mvc,如果view中需要执行某项操作,但是不应该放在这处理,可以使用block回调使用,也不要保存临时变量什么的
************************************************************************
@property (nonatomic, copy) void (^actionBlock)(void);
注意必须声明为copy,block与其他对象不同,它创建直接存才于堆中
void(^)(NSString *parm1,int anotherParm);
-(IBAction)showImage:(id)sender
{
if(self.actionBlock){
self.actionBlock();
}
}
在获取cell的controller中,修改:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellFroRowAtIndexPath:(NSIndexPath *)indexPath
{
BNRItemCell *cell = [tableView dequeueResuableCellWithIdentifier:@"BNRItemCell" forIndexPath:indexPath];
// sub view
// self.nameLabel.text = ...
// self.serialNumberLabel.text = ...
cell.actionBlock = ^{
NSLog(@"Going to show image for %@",item);
}
return cell;
}
6.在block中使用popover controller来显示图片
新建一个BNRImageViewController ,UIViewController子类
-(void)loadView
{
UIImageView *imageView = [[UIImageView alloc] init];
imageView.contentMode = UIImageViewModeScaleAspectFit;
self.view = imageView;
}
-------
在BNRImageViewController中声明一个属性,就是显示的图片
@property (nonatomic,strong) UIImage *image;
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImageView *imageView = (UIImageView *)self.imageView;
imageView.image = self.image;
}
======================
在BNRItemViewController中添加属性:
@property (nonatomic,strong) UIPopoverController *imagePopver;
cell.actionBlock = ^{
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
NSString *itemKey = item.itemKey;
UIImage *img = [[BNRImageStore sharedStore] imageForKey:itemKey];
if(!img){
return;
}
CGRect rect = [self.view convertRect:cell.thumbnailView.bounds
fromView:cell.thumbnailView];
BNRImageViewController *ivc = [[BNRImageViewController alloc] init];
ivc.image = img;
self.imagePopver = [[UIPopoverController alloc] initWithContentViewController:ivc];
self.imagePopver.popoverContent = CGSizeMake(600,600);
[self.imagePopver presentPopoverFromRect:rect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
}
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
self.imagePopover = nil;
}
!!!!在一个controller中popover一个UIPopoverController!!!!
//popover需要指定一个viewController
使用block的时候避免相互指向而造成内存泄漏。
__weak BNRItemCell *weakCell = cell;
cell.actionBlock = ^{
BNRItemCell *strongCell = weakCell; // 最好是这样,直接使用cell不安全
}
__block XXXX定义的才能在block中修改,默认是只读的。
7.UICollectionView
与UITableView和相似:
1.都是UIScrollView的子类
2.都显示单元格,不同的是UICollectionView:UICollectionViewCell
3.有个data source 提供数据给cells
4.有个delegate实现当点击,就是selected的时候
5.UICollectView提供dataSource、delegate