MKMapView にいくつかの MKAnnotations を含むアプリを作成しています。私の問題が発生する、これらの注釈によって表される場所に関する詳細情報を含むリスト (UITableView) もあります。私は独自の UITableViewCell サブクラスを使用します。これには 3 つの UILabels があります。場所の名前のデフォルトの textLabel、addressLabel、phoneNumberLabel です。これらのラベルのテキストが大きすぎて 1 行に表示できない状況を考慮し、それに応じて UILabels のサイズを変更する必要があります。また、電話番号や住所がなく、それに応じて UILabels が「消える」(フレームサイズが 0) という状況も考慮する必要があります。
問題は、テーブルを下にスクロールすると、画面の上部からセルが消えることです (さらにスクロールすると、より多くのセルが非表示になり、ほとんどの UITableView ではセルがまったく表示されず、セクション ヘッダーだけが表示されます。テーブル全体のサイズは変わりませんが)。
(スクリーンショットはここにあるはずでしたが、stackoverflow で投稿できませんでした :( ) ![ここに画像の説明を入力][1]
これが私のカスタム UITableViewCell サブクラスです:
@implementation POICell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.addressLabel = [[UILabel alloc] init];
self.phoneNumberLabel = [[UILabel alloc] init];
[self addSubview:self.addressLabel];
[self addSubview:self.phoneNumberLabel];
self.addressLabel.font = [UIFont fontWithName:@"Helvetica" size:14];
self.phoneNumberLabel.font = [UIFont fontWithName:@"Helvetica" size:14];
self.textLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:20];
self.addressLabel.lineBreakMode = UILineBreakModeWordWrap;
self.phoneNumberLabel.lineBreakMode = UILineBreakModeWordWrap;
self.textLabel.lineBreakMode = UILineBreakModeWordWrap;
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect titleFrame = self.frame;
titleFrame.origin.x += 30;
titleFrame.size.width -= 60;
titleFrame.size.height = [self.textLabel.text sizeWithFont:self.textLabel.font forWidth:self.textLabel.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height;
self.textLabel.frame = titleFrame;
if (self.addressLabel.text != nil) {
self.addressLabel.frame = CGRectMake(titleFrame.origin.x, [DDUtility yRelativeTo:self.textLabel withMargin:0], titleFrame.size.width, [self.addressLabel.text sizeWithFont:self.addressLabel.font forWidth:self.addressLabel.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height);
}
else {
self.addressLabel.frame = CGRectMake(titleFrame.origin.x, [DDUtility yRelativeTo:self.textLabel withMargin:0], 0, 0);
}
NSString *labelText = self.addressLabel.text;
if (self.phoneNumberLabel.text != nil) {
self.phoneNumberLabel.frame = CGRectMake(titleFrame.origin.x, [DDUtility yRelativeTo:self.addressLabel withMargin:0], titleFrame.size.width, [self.phoneNumberLabel.text sizeWithFont:self.phoneNumberLabel.font forWidth:self.phoneNumberLabel.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height);
}
else {
self.phoneNumberLabel.frame = CGRectMake(titleFrame.origin.x, [DDUtility yRelativeTo:self.addressLabel withMargin:0], 0, 0);
}
labelText = self.phoneNumberLabel.text;
}
ここでは、2 つのテーブルのデリゲートとデータソースの両方である UIViewController の一部です。categoryTable は問題なく動作します。
poiArraysDictionary は、キーが Point of Interest カテゴリの名前であり、値がこのカテゴリのポイントの配列であるディクショナリです。ポイント自体は、サーバーから JSON として取得する辞書であり、名前、住所 (null の場合もある)、電話番号 (null の場合もある) などのキーを使用します。
- (void) viewDidLoad {
(...)
UITableView *poiTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 120, listView.frame.size.width, listView.frame.size.height - 120) style:UITableViewStylePlain];
poiTable.separatorStyle = UITableViewCellSeparatorStyleNone;
//poiTable.rowHeight = 80;
poiTable.dataSource = self;
poiTable.delegate = self;
poiTable.backgroundColor = [UIColor clearColor];
self.poiTable = poiTable;
[poiTable reloadData];
[self.listView addSubview:poiTable];
(...)
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.categoryTable) {
return 1;
}
else {
return [self.categoryArray count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.categoryTable) {
return [self.categoryArray count];
}
else {
return [[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:section]] count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.categoryTable) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"categoryCell"];
if (cell == nil) {
cell = [[[CategoryCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"categoryCell"] autorelease];
}
cell.textLabel.text = [self.categoryArray objectAtIndex:indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
return cell;
}
else {
POICell *cell = [tableView dequeueReusableCellWithIdentifier:@"poiCell"];
if (cell == nil) {
cell = [[[POICell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"poiCell"] autorelease];
}
/*int maxIndex = [self.pointsOfInterestArray count];
int index;
int indexInSection = 0;
for (index = 0; index < maxIndex; ++index) {
if ([((NSString*)([((NSDictionary*)([self.pointsOfInterestArray objectAtIndex:index])) objectForKey:@"category"])) isEqualToString:[self.categoryArray objectAtIndex:indexPath.section]]) {
if (indexInSection != indexPath.row) {
++indexInSection;
}
else {
break;
}
}
}
cell.textLabel.text = [[self.pointsOfInterestArray objectAtIndex:index] objectForKey:@"name"];
if ([[[self.pointsOfInterestArray objectAtIndex:index] objectForKey:@"address"] class] != [NSNull class]) {
cell.addressLabel.text = [[self.pointsOfInterestArray objectAtIndex:index] objectForKey:@"address"];
}
if ([[[self.pointsOfInterestArray objectAtIndex:index] objectForKey:@"phone"] class] != [NSNull class]) {
cell.phoneNumberLabel.text = [[self.pointsOfInterestArray objectAtIndex:index] objectForKey:@"phone"];
}*/
if ([[[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"name"] class] == [NSNull class]) {
return nil;
}
cell.textLabel.text = [[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"name"];
if ([[[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"address"] class] == [NSNull class]) {
cell.addressLabel.text = nil;
}
else {
cell.addressLabel.text = [[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"address"];
}
if ([[[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"phone"] class] == [NSNull class]) {
cell.phoneNumberLabel.text = nil;
}
else {
cell.phoneNumberLabel.text = [@"telefon: " stringByAppendingString:[[[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] objectForKey:@"phone"]];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
CGRect cellFrame = cell.frame;
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (tableView == self.categoryTable) {
return 0;
}
else {
return 40;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.categoryTable) {
return 50;
}
else {
NSDictionary *point = [[self.poiArraysDictionary objectForKey:[self.categoryArray objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
CGFloat rowHeight = 0;
if ([[point objectForKey:@"name"] class] != [NSNull class]) {
rowHeight += [[point objectForKey:@"name"] sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:20] forWidth:self.poiTable.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height;
}
if ([[point objectForKey:@"address"] class] != [NSNull class]) {
rowHeight += [[point objectForKey:@"address"] sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] forWidth:self.poiTable.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height;
}
if ([[point objectForKey:@"phone"] class] != [NSNull class]) {
rowHeight += [[point objectForKey:@"phone"] sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] forWidth:self.poiTable.frame.size.width lineBreakMode:NSLineBreakByWordWrapping].height;
}
return rowHeight;
}
}