Проблема с UILabel в текстовом разделе viewForFooterInSection

#iphone #objective-c #uilabel

#iPhone #objective-c #uilabel

Вопрос:

Я хочу отобразить два фрагмента текста в двух разных нижних колонтитулах в моей таблице.

В тексте для раздела 3 используется titleForFooterInSection :

 - (NSString *)tableView:(UITableView *)tv titleForFooterInSection:(NSInteger)section
{
    if (section == 3)
        return @"SOME TEXT FOR SECTION 3";
    else
        return @"";
}
  

и отлично работает и имеет правильный стиль.
Я также хочу добавить текст более сложного формата (на самом деле просто выровненный по левому краю), поэтому я создаю ярлык и добавляю его в viewForFooterInSection , который работает, но не дополнен (не начинается с x = 20 и y = 20, начинается вплотную к основному краю Windows) и не оформлен как другой текст.

 - (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
{
    if (section == 1) 
    {
        UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 100, 50)] autorelease];
        label.text = @"SOME COMPLICATED TEXT FOR SECTION 1rn"
        "rn"
        "MORE TEXT HERErn"
        "AND HERE.rn"

        label.backgroundColor = [UIColor clearColor];
        label.font = [UIFont systemFontOfSize:14];
        label.shadowColor = [UIColor colorWithWhite:0.8 alpha:0.8];
        label.textColor = [UIColor blueColor];

        label.lineBreakMode = UILineBreakModeWordWrap;
        label.textAlignment = UITextAlignmentLeft;
        label.numberOfLines = 0;

       [label sizeToFit];

    return label;       
    }

    else
        return nil;

}

-(CGFloat)tableView:(UITableView *)tv heightForFooterInSection:(NSInteger)section
{
    if (section == 1) 
        return 180.0f;
    else if (section == 3)
        return 50.0f;
    else 
        return 0.0f;
}
  

Ответ №1:

Чтобы получить заполнение, добавьте метку в другое представление, прежде чем возвращать ее в виде нижнего колонтитула;

 - (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
{
  ...
  CGRect footerFrame = [tv rectForFooterInSection:1];
  CGRect labelFrame = CGRectMake(20, 20, footerFrame.size.width - 40, footerFrame.size.height - 40);

  UIView *footer = [[UIView alloc] initWithFrame:footerFrame];
  UILabel *footerLabel = [[UILabel alloc] initWithFrame:labelFrame];

  [footer addSubview:footerLabel];
  [footerLabel release];
  ...
  return footer;
}
  

ПРИМЕЧАНИЕ: Возможно, вам захочется *footer расширить область, чтобы избежать утечки памяти или использовать autorelease .

Я не уверен, какие системные значения по умолчанию установлены для метки, которую он создает для хранения текста, который вы предоставляете в качестве заголовка для нижнего колонтитула. Я думаю, вам нужно будет поэкспериментировать при создании метки нижнего колонтитула, поскольку Google не выдал ничего полезного.

РЕДАКТИРОВАТЬ: Вместо того, чтобы помещать весь код в viewForFooterInSection метод, я использую пользовательский UIView;

 @interface CustomHeaderView : UIView {
    NSString *headerTitle;
}
@property (nonatomic, retain) NSString *headerTitle;
@end

@implementation CustomHeaderView

@synthesize headerTitle;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {

        // create frame with padding    
        CGRect labelFrame = CGRectMake(8, 8, frame.size.width - 16, frame.size.height - 16);

        UILabel *headerText = [[UILabel alloc] initWithFrame:labelFrame];
        [headerText setNumberOfLines:0];
        [headerText setFont:[UIFont boldSystemFontOfSize:14.0]];            
        [self addSubview:headerText];

        [headerText release];           
    }
    return self;
}

- (void)setHeaderTitle:(NSString *)title {

    [title retain];
    [headerTitle release];

    UILabel *label = [[self subviews] objectAtIndex:0];
    [label setText:title];
    [label sizeToFit];

    CGRect viewFrame = [self frame];
    CGRect labelFrame = [label frame];

    viewFrame.size.height = labelFrame.size.height   16;
    [self setFrame:viewFrame];

    [self setNeedsLayout];

    headerTitle = title;
}

- (void)dealloc {
    [headerTitle release];
    [super dealloc];
}

@end
  

Это позволяет мне задать текст заголовка и изменить размер заголовка для содержимого. Я лениво загружаю это в свой контроллер просмотра;

 @interface MyViewController
{
    UIView *headerView;
}
- (UIView *) headerView;
@end

@implementation MyViewController

- (UIView *) headerView {

    if(headerView)
        return headerView;

    float w = [[self view] bounds].size.width;

    // height irrelevant as long as non zero custom view will resize
    CGRect headerFrame = CGRectMake(0, 0, w, 32);

    headerView = [[CustomHeaderView alloc] initWithFrame:headerFrame];

    return headerView;
}

- (UIView *) tableView:(UITableView *)tv viewForHeaderInSection:(NSInteger)sec {
    return [self headerView];
}


- (void) viewWillAppear:(BOOL)animated {
    [(CustomHeaderView *)[self headerView] setHeaderTitle:@"My Custom Header"]];
}

@end
  

Комментарии:

1. В CGRect footerFrame = [tv rectForFooterInSection: 1] появляется плохой EXE-файл; — Я изменил его на GRect footerFrame = CGRectMake(0, 0, 320, 180); и это то же самое, что и в моем оригинальном примере

2. @daidai извините, что не пытался запустить этот код и пытался предложить избегать жесткого кодирования ширины для поддержки разных ориентаций экрана. У меня есть пользовательский класс view для создания дополненного заголовка, смотрите Мою правку.

3. вау, это долго, разве это не просто добавить метку… спасибо за ваш ответ. Я внедрил ваш код, но он никогда не вызывает setFooterTitle и, следовательно, не отображает текст…

4. получил его отображение, поместив текст внутри инициализации.

5. @daidai, конечно, кажется чрезмерным только для заполнения! Я думаю, вам нужно вызвать [[self tableView] setNeedsDisplay] после того, как вы введете текст viewWillAppear . Если вам никогда не понадобится перезагружать контроллер представления с новым заголовком, инициализация будет работать нормально.

Ответ №2:

Убедитесь, что вы возвращаете правильную высоту в - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; методе делегирования.

Комментарии:

1. Очень сложно правильно рассчитать высоту нижнего колонтитула для всех языков пользовательского интерфейса. Я хочу, чтобы UITableView автоматически вычислял правильную высоту нижнего колонтитула.

2. В любом случае высота должна быть возвращена из упомянутого мной делегата.