iOS 练习项目 Landmarks (二):自定义 UITableViewCell
iOS 练习项目 Landmarks (二):自定义 UITableViewCell
自定义 UITableViewCell:PlaceCell
相较于AccessoryType为UITableViewCellAccessoryDisclosureIndicator的UITableViewCell,只需要在textLabel和箭头中间插入一个UIButton,作为收藏按钮。
同时修改了frame的样式,现在PlaceCell会在上方空出10px的空位,imageView不会占满整个Cell。
PlaceCell.h:
#import <UIKit/UIKit.h>
#import "Place.h"
NS_ASSUME_NONNULL_BEGIN
@interface PlaceCell : UITableViewCell
@property (nonatomic) UIButton *starButton;
//@property (nonatomic, strong) UIImage *photo;
//@property (nonatomic, strong) NSString *labelStr;
@end
NS_ASSUME_NONNULL_END
PlaceCell.m:
#import "PlaceCell.h"
@interface PlaceCell()
{
UIButton *_starButton;
}
@end
@implementation PlaceCell
//@synthesize photo;
//@synthesize labelStr;
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
[self initSubView];
}
return self;
}
- (void)setFrame:(CGRect)frame
{
frame.origin.y += 10;
frame.size.height -= 10;
[super setFrame:frame];
}
#pragma mark - 初始化视图
- (void)initSubView
{
CGRect buttonFrame = CGRectMake(320, 12, 25, 25);
// 创建并设置 UIButton 对象
self.starButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.starButton.frame = buttonFrame;
// 设置样式
[self.starButton setTitle:@"" forState:UIControlStateNormal];
[self.starButton setImage:[UIImage imageNamed:@"Image_star"] forState:UIControlStateNormal];
[self.starButton setImage:[UIImage imageNamed:@"Image_starred"] forState:UIControlStateSelected];
[self setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; // 辅助指示视图为箭头
// 添加目标-动作对
[self.starButton addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:self.starButton];
}
- (void)btnClicked:(UIButton *)sender
{
sender.selected = !sender.selected;
NSLog(@"tag: %ld", sender.tag);
}
starButton 的点击事件
PlaceCell新增的一个starButton,分别设置了常规状态和点击状态的图片,为starButton添加了一个目标-动作对,在单击收藏按钮时会改变按钮的状态,进而切换显示的图片。
读plist进行数据源初始化
一个一个addObject太慢了,而且代码太长,把数据保存在plist,读它来进行places数组的初始化:
#pragma mark - 初始化 places 数组
- (void)initPlaces
{
// 创建数组
self.places = [NSMutableArray array];
// 读文件
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistUrl = [bundle URLForResource:@"PlaceInfo" withExtension:@"plist"];
NSDictionary *placesInfoDic = [NSDictionary dictionaryWithContentsOfURL:plistUrl];
// 遍历
for (int i = 0; i< [placesInfoDic count]; i++)
{
NSString *key = [[NSString alloc] initWithFormat:@"%i", i];
NSDictionary *placeInfo = [placesInfoDic objectForKey:key];
// 初始化对象
Place *place = [Place alloc];
[place setSight:[placeInfo objectForKey:@"sight"]];
[place setScenicArea:[placeInfo objectForKey:@"scenicArea"]];
[place setState:[placeInfo objectForKey:@"state"]];
[place setPicture:[UIImage imageNamed:[placeInfo objectForKey:@"pictureUrl"]]];
// [place setFavorite:[placeInfo valueForKey:@"favorite"]]; // wrong
[place setFavorite:[(NSNumber *)[placeInfo objectForKey:@"favorite"] boolValue]];
NSLog(@"placeInfo favorite: %@", [placeInfo objectForKey:@"favorite"]);
[place setLocation:[[CLLocation alloc] initWithLatitude:[[placeInfo objectForKey:@"latitude"] doubleValue] longitude:[[placeInfo objectForKey:@"longitude"] doubleValue]]];
NSLog(@"%@", place);
// Place *place = [[Place alloc] initWithSight:[placeInfo objectForKey:@"sight"] scenicArea:[placeInfo objectForKey:@"scenicArea"] state:[placeInfo objectForKey:@"state"] picture:[UIImage imageNamed:[placeInfo objectForKey:@"pictureUrl"]] favorite:[placeInfo objectForKey:@"favorite"] location:[[CLLocation alloc] initWithLatitude:[[placeInfo objectForKey:@"latitude"] doubleValue] longitude:[[placeInfo objectForKey:@"longitude"] doubleValue]]];
// 插入数组
[self.places addObject:place];
}
}
数据保存在一个名叫placeInfo的plist里:
注意Boolean转BOOL的细节:将Boolean用一个NSNumber类封装,再用boolValue方法取出BOOL值。
杂项:Place 的 description
重写了模型 Place 的 description 方法,主要用于在 initPlaces 方法中检验 Place 实例是否初始化成功。
-(NSString *)description
{
return [[NSString alloc] initWithFormat:@"sight = %@, scenicArea = %@, state = %@, picture = %@, favorite = %d, location = %@",[self sight], [self scenicArea], [self state], [self picture], [self favorite] , [self location]];
运行效果
点击收藏按钮会切换按钮的状态,也就会改变按钮的图片。