Мәтінді енгізу негізінде UITableViewCell динамикалық өлшемін өзгертеді

Мен олардың ішіндегі UITextView биіктігінің негізінде UITableViewCell кейбір динамикалық өлшемдерін өзгертуге тырысамын. UITextView деген көрсеткішті сақтап, оны heightForRowAtIndexPath ішіндегі мазмұн өлшемін алу арқылы шешуге болатын көптеген шешімдер бар, бірақ барлық кесте жолдардың белгісіз санымен және олардың ішінде белгісіз саны бар жолдар UITextView , бұл мүмкін емес. heightForRowAtIndexPath кезінде аталған ұяшыққа қоңырау шалсам оңай болар еді, бірақ бұл әдіс қандай да бір ұяшық жасалмас бұрын шақырылған шексіз циклды және бұзылуды тудырады. Кез келген басқа шешімдер?

Мен ұяшық үшін UITableViewCell қосалқы сыныбын пайдаланамын:

- (void)initalizeInputView {
   //Initialization code
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    self.textView = [[UITextView alloc] initWithFrame:CGRectZero];
    self.textView.autocorrectionType = UITextAutocorrectionTypeDefault;
    self.textView.autocapitalizationType = UITextAutocapitalizationTypeNone;
    self.textView.textAlignment = NSTextAlignmentRight;
    self.textView.textColor = [UIColor lightBlueColor];
    self.textView.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:17];
    self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.textView.keyboardType = UIKeyboardTypeDefault;
    [self addSubview:self.textView];

    self.textView.delegate = self;
}

- (BOOL)resignFirstResponder {
    if (_delegate && [_delegate respondsToSelector:@selector(tableViewCell:didEndEditingWithLongString:)]) {
        [_delegate tableViewCell:self didEndEditingWithLongString:self.stringValue];
    }
    return [super resignFirstResponder];
}

- (void)setKeyboardType:(UIKeyboardType)keyboardType
{
    self.textView.keyboardType = keyboardType;
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self initalizeInputView];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initalizeInputView];
    }
    return self;
}

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    if (selected) {
        [self.textView becomeFirstResponder];
    }
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    if (selected) {
        [self.textView becomeFirstResponder];
    }
}

- (void)setStringValue:(NSString *)value {
    self.textView.text = value;
}

- (NSString *)stringValue {
    return self.textView.text;
}

- (void)textViewDidBeginEditing:(UITextView *)textView
{
   //For keyboard scroll
    UITableView *tableView = (UITableView *)self.superview;
    AppSetupViewController *parent = (AppSetupViewController *)_delegate;
    parent.activeCellIndexPath = [tableView indexPathForCell:self];
}

- (void)textViewDidChange:(UITextView *)textView
{
    if (textView.contentSize.height > contentRowHeight) {

        contentRowHeight = textView.contentSize.height;

        UITableView *tableView = (UITableView *)self.superview;
        [tableView beginUpdates];
        [tableView endUpdates];

        [textView setFrame:CGRectMake(0, 0, 300.0, textView.contentSize.height)];
    }
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    if (_delegate && [_delegate respondsToSelector:@selector(tableViewCell:didEndEditingWithLongString:)]) {
        [_delegate tableViewCell:self didEndEditingWithLongString:self.stringValue];
    }
    UITableView *tableView = (UITableView *)self.superview;
    [tableView deselectRowAtIndexPath:[tableView indexPathForCell:self] animated:YES];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    CGRect editFrame = CGRectInset(self.contentView.frame, 10, 10);

    if (self.textLabel.text && [self.textLabel.text length] != 0) {
        CGSize textSize = [self.textLabel sizeThatFits:CGSizeZero];
        editFrame.origin.x += textSize.width + 10;
        editFrame.size.width -= textSize.width + 10;
        self.textView.textAlignment = NSTextAlignmentRight;
    } else {
        self.textView.textAlignment = NSTextAlignmentLeft;
    }

    self.textView.frame = editFrame;
}

cellForRowAtIndexPath ішінде жасалған мына сияқты:

else if ([paramType isEqualToString:@"longString"]) {
            MyIdentifier = @"AppActionLongString";

            LongStringInputTableViewCell *cell = (LongStringInputTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
            cell.textLabel.text = [[[_selectedAction objectForKey:@"parameters"] objectAtIndex:indexPath.row] objectForKey:@"name"];
            cell.params = [[_selectedAction objectForKey:@"parameters"] objectAtIndex:indexPath.row];

            cell.textView.text = [results objectAtIndex:indexPath.row];

            return cell;
        }

ViewController ішіндегі айнымалыға тек биіктікті қайтару жақсы емес, себебі мен айтқанымдай, осы ұяшықтардың бірнешееуі үстелде болуы мүмкін.

Рахмет

2
Пайдаланушы енгізу үшін. Қазіргі сәтте, оны аяқтағаннан кейін делегат әдісін пайдаланып ViewController-ге жіберемін және олардың әрқайсысын Массивте сақтаймын. Мен өлшемді өзгерту жұмысын бастаған кезде, өлшемдерді тексеру үшін әрбір негізгі енгізуден кейін делегат әдісін шақырамын.
қосылды автор Darren, көзі
TextView мәтінін қайдан алуға болады?
қосылды автор Rox, көзі

9 жауаптар

жай ғана түсініктеме

if (cell == nil)

Үміт, бұл сізге көмектеседі.

2
қосылды

жай ғана түсініктеме

if (cell == nil)

Үміт, бұл сізге көмектеседі.

2
қосылды

Бұл әдісті tableviewCell динамикалық түрде өзгерту үшін пайдаланыңыз. Алдымен пайдаланушы кірісін NSMutable массивінде және қайта жүктеу кестесінен кейін сақтаңыз. Сізге көмектесетініне сенемін.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    NSString *msg =[self.messages objectAtIndex:indexPath.row];
    CGSize  textSize = { 120, 10000.0 };
    CGSize size = [msg sizeWithFont:[UIFont systemFontOfSize:15]
                  constrainedToSize:textSize
                      lineBreakMode:UILineBreakModeWordWrap];


return size.height+20;

}

1
қосылды
Рахмет. Мен бұған дейін осындай нәрсе жасадым. Мәселе мұнда ені 120 деп орнатылған. Менің енімім динамикалық, өйткені TextView алдымен CGRectZero параметріне UIViewAutoresizingFlexibleWidth параметрімен орнатылады, сол себепті ол қалдырылған бос орынды толтырады Атауы. Мен ені басып алу үшін ұяшыққа сілтеме алмаймын.
қосылды автор Darren, көзі
Ұяшықта сол жақта тақырып белгісі және оң жақта textView бар. TextView ені тақырып белгісінің еніне байланысты.
қосылды автор Darren, көзі
Aha, иә, мен мұны істей аламын. Мен мұны тез арада көремін. Рахмет
қосылды автор Darren, көзі
Биіктігіңіз икемді болуы керек, бірақ ені өлшемін түзете аласыз. ол 320 болуы мүмкін
қосылды автор Rox, көзі
Ол динамикалық болса, тақырып белгісінің енін алуы мүмкін. содан кейін әдепкі енден енін шығарып, мәтіндік кеңістіктің енін орнатыңыз.
қосылды автор Rox, көзі
жақсы, маған көмектесе білу.
қосылды автор Rox, көзі

Биіктікте ForRowAtIndexPath кезінде аталған ұяшыққа қоңырау шалсам оңай болар еді, бірақ бұл әдіс қандай да бір жасушаның тіпті жасалмас бұрын шақырылған шексіз циклды және бұзылуды тудырады. Кез-келген басқа шешімдер?

Сен істей аласың. Мен шексіз циклды тудыратын cellForRowAtIndexPath деп атауға тырысып жатырсыз деп ойлаймын. Бірақ, сіз тікелей dequeueReusableCellWithIdentifier деп қоңырау шалып, ұяшықты тікелей декларациялауыңыз керек.

кесте көрінісін делегат іске асыру of TLIndexPathTools . heightForRowAtIndexPath әдісі келесідей:

( EDIT Алдымен ұяшықты шын мәнінде бұзатын prototypeForCellIdentifier әдісін қосуды ұмытып қалдыңыз.)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id item = [self.dataModel itemAtIndexPath:indexPath];
    NSString *cellId = [self cellIdentifierAtIndexPath:indexPath];
    if (cellId) {
        UITableViewCell *cell = [self prototypeForCellIdentifier:cellId];
        if ([cell conformsToProtocol:@protocol(TLDynamicSizeView)]) {
            id v = (id)cell;
            id data;
            if ([item isKindOfClass:[TLIndexPathItem class]]) {
                TLIndexPathItem *i = (TLIndexPathItem *)item;
                data = i.data;
            } else {
                data = item;
            }
            CGSize computedSize = [v sizeWithData:data];
            return computedSize.height;
        } else {
            return cell.bounds.size.height;
        }
    }

    return 44.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView prototypeForCellIdentifier:(NSString *)cellIdentifier
{
    UITableViewCell *cell;
    if (cellIdentifier) {
        cell = [self.prototypeCells objectForKey:cellIdentifier];
        if (!cell) {
            if (!self.prototypeCells) {
                self.prototypeCells = [[NSMutableDictionary alloc] init];
            }
            cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
            //TODO this will fail if multiple tables are being used and they have
            //overlapping identifiers. The key needs to be unique to the table
            [self.prototypeCells setObject:cell forKey:cellIdentifier];
        }
    }
    return cell;
}

Бұл кез-келген ұяшықтың биіктігін автоматты түрде есептеу үшін қолдануға болатын TLDynamicSizeView хаттамасын қолданады. Мұнда мысал жобасы жұмыс істейді. Хаттаманың жасуша хаттамасының орындалуы келесідей:

@implementation DynamicHeightCell

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.originalSize = self.bounds.size;
    self.originalLabelSize = self.label.bounds.size;
}

- (void)configureWithText:(NSString *)text
{
    self.label.text = text;
    [self.label sizeToFit];
}

#pragma mark - TLDynamicSizeView

- (CGSize)sizeWithData:(id)data
{
    [self configureWithText:data];
    //the dynamic size is calculated by taking the original size and incrementing
    //by the change in the label's size after configuring
    CGSize labelSize = self.label.bounds.size;
    CGSize size = self.originalSize;
    size.width += labelSize.width - self.originalLabelSize.width;
    size.height += labelSize.height - self.originalLabelSize.height;
    return size;
}

@end
0
қосылды

Биіктікте ForRowAtIndexPath кезінде аталған ұяшыққа қоңырау шалсам оңай болар еді, бірақ бұл әдіс қандай да бір жасушаның тіпті жасалмас бұрын шақырылған шексіз циклды және бұзылуды тудырады. Кез-келген басқа шешімдер?

Сен істей аласың. Мен шексіз циклды тудыратын cellForRowAtIndexPath деп атауға тырысып жатырсыз деп ойлаймын. Бірақ, сіз тікелей dequeueReusableCellWithIdentifier деп қоңырау шалып, ұяшықты тікелей декларациялауыңыз керек.

кесте көрінісін делегат іске асыру of TLIndexPathTools . heightForRowAtIndexPath әдісі келесідей:

( EDIT Алдымен ұяшықты шын мәнінде бұзатын prototypeForCellIdentifier әдісін қосуды ұмытып қалдыңыз.)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id item = [self.dataModel itemAtIndexPath:indexPath];
    NSString *cellId = [self cellIdentifierAtIndexPath:indexPath];
    if (cellId) {
        UITableViewCell *cell = [self prototypeForCellIdentifier:cellId];
        if ([cell conformsToProtocol:@protocol(TLDynamicSizeView)]) {
            id v = (id)cell;
            id data;
            if ([item isKindOfClass:[TLIndexPathItem class]]) {
                TLIndexPathItem *i = (TLIndexPathItem *)item;
                data = i.data;
            } else {
                data = item;
            }
            CGSize computedSize = [v sizeWithData:data];
            return computedSize.height;
        } else {
            return cell.bounds.size.height;
        }
    }

    return 44.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView prototypeForCellIdentifier:(NSString *)cellIdentifier
{
    UITableViewCell *cell;
    if (cellIdentifier) {
        cell = [self.prototypeCells objectForKey:cellIdentifier];
        if (!cell) {
            if (!self.prototypeCells) {
                self.prototypeCells = [[NSMutableDictionary alloc] init];
            }
            cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
            //TODO this will fail if multiple tables are being used and they have
            //overlapping identifiers. The key needs to be unique to the table
            [self.prototypeCells setObject:cell forKey:cellIdentifier];
        }
    }
    return cell;
}

Бұл кез-келген ұяшықтың биіктігін автоматты түрде есептеу үшін қолдануға болатын TLDynamicSizeView хаттамасын қолданады. Мұнда мысал жобасы жұмыс істейді. Хаттаманың жасуша хаттамасының орындалуы келесідей:

@implementation DynamicHeightCell

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.originalSize = self.bounds.size;
    self.originalLabelSize = self.label.bounds.size;
}

- (void)configureWithText:(NSString *)text
{
    self.label.text = text;
    [self.label sizeToFit];
}

#pragma mark - TLDynamicSizeView

- (CGSize)sizeWithData:(id)data
{
    [self configureWithText:data];
    //the dynamic size is calculated by taking the original size and incrementing
    //by the change in the label's size after configuring
    CGSize labelSize = self.label.bounds.size;
    CGSize size = self.originalSize;
    size.width += labelSize.width - self.originalLabelSize.width;
    size.height += labelSize.height - self.originalLabelSize.height;
    return size;
}

@end
0
қосылды

Биіктікте ForRowAtIndexPath кезінде аталған ұяшыққа қоңырау шалсам оңай болар еді, бірақ бұл әдіс қандай да бір жасушаның тіпті жасалмас бұрын шақырылған шексіз циклды және бұзылуды тудырады. Кез-келген басқа шешімдер?

Сен істей аласың. Мен шексіз циклды тудыратын cellForRowAtIndexPath деп атауға тырысып жатырсыз деп ойлаймын. Бірақ, сіз тікелей dequeueReusableCellWithIdentifier деп қоңырау шалып, ұяшықты тікелей декларациялауыңыз керек.

кесте көрінісін делегат іске асыру of TLIndexPathTools . heightForRowAtIndexPath әдісі келесідей:

( EDIT Алдымен ұяшықты шын мәнінде бұзатын prototypeForCellIdentifier әдісін қосуды ұмытып қалдыңыз.)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id item = [self.dataModel itemAtIndexPath:indexPath];
    NSString *cellId = [self cellIdentifierAtIndexPath:indexPath];
    if (cellId) {
        UITableViewCell *cell = [self prototypeForCellIdentifier:cellId];
        if ([cell conformsToProtocol:@protocol(TLDynamicSizeView)]) {
            id v = (id)cell;
            id data;
            if ([item isKindOfClass:[TLIndexPathItem class]]) {
                TLIndexPathItem *i = (TLIndexPathItem *)item;
                data = i.data;
            } else {
                data = item;
            }
            CGSize computedSize = [v sizeWithData:data];
            return computedSize.height;
        } else {
            return cell.bounds.size.height;
        }
    }

    return 44.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView prototypeForCellIdentifier:(NSString *)cellIdentifier
{
    UITableViewCell *cell;
    if (cellIdentifier) {
        cell = [self.prototypeCells objectForKey:cellIdentifier];
        if (!cell) {
            if (!self.prototypeCells) {
                self.prototypeCells = [[NSMutableDictionary alloc] init];
            }
            cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
            //TODO this will fail if multiple tables are being used and they have
            //overlapping identifiers. The key needs to be unique to the table
            [self.prototypeCells setObject:cell forKey:cellIdentifier];
        }
    }
    return cell;
}

Бұл кез-келген ұяшықтың биіктігін автоматты түрде есептеу үшін қолдануға болатын TLDynamicSizeView хаттамасын қолданады. Мұнда мысал жобасы жұмыс істейді. Хаттаманың жасуша хаттамасының орындалуы келесідей:

@implementation DynamicHeightCell

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.originalSize = self.bounds.size;
    self.originalLabelSize = self.label.bounds.size;
}

- (void)configureWithText:(NSString *)text
{
    self.label.text = text;
    [self.label sizeToFit];
}

#pragma mark - TLDynamicSizeView

- (CGSize)sizeWithData:(id)data
{
    [self configureWithText:data];
    //the dynamic size is calculated by taking the original size and incrementing
    //by the change in the label's size after configuring
    CGSize labelSize = self.label.bounds.size;
    CGSize size = self.originalSize;
    size.width += labelSize.width - self.originalLabelSize.width;
    size.height += labelSize.height - self.originalLabelSize.height;
    return size;
}

@end
0
қосылды

Ұяшықта көрсетілетін мәтін көлеміне негізделген динамикалық кесте көрінісі ұяшық биіктігіне мұқтаж болдым. Мен оны мына жолмен шешдім:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (!isLoading)
        {

            if ([self.conditionsDataArray count]>0)
            {
                Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row];

                int height;

                UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)];   //you can set your frame according to your need

                textview.text  = condition.comment;

                textview.autoresizingMask = UIViewAutoresizingFlexibleHeight;

                [tableView addSubview:textview];

                textview.hidden = YES;

                height = textview.contentSize.height;

                NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height);

                [textview removeFromSuperview];

                [textview release];

                return height;
       }

       return 55;  //Default height, if data is in loading state
}

Мәтін көрінісі қосымша көрініс ретінде қосылып, содан кейін жасырын болғанына назар аударыңыз, сондықтан оны SubView ретінде қосыңыз, әйтпесе оның биіктігі қарастырылмайды.

0
қосылды

Ұяшықта көрсетілетін мәтін көлеміне негізделген динамикалық кесте көрінісі ұяшық биіктігіне мұқтаж болдым. Мен оны мына жолмен шешдім:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (!isLoading)
        {

            if ([self.conditionsDataArray count]>0)
            {
                Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row];

                int height;

                UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)];   //you can set your frame according to your need

                textview.text  = condition.comment;

                textview.autoresizingMask = UIViewAutoresizingFlexibleHeight;

                [tableView addSubview:textview];

                textview.hidden = YES;

                height = textview.contentSize.height;

                NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height);

                [textview removeFromSuperview];

                [textview release];

                return height;
       }

       return 55;  //Default height, if data is in loading state
}

Мәтін көрінісі қосымша көрініс ретінде қосылып, содан кейін жасырын болғанына назар аударыңыз, сондықтан оны SubView ретінде қосыңыз, әйтпесе оның биіктігі қарастырылмайды.

0
қосылды

Ұяшықта көрсетілетін мәтін көлеміне негізделген динамикалық кесте көрінісі ұяшық биіктігіне мұқтаж болдым. Мен оны мына жолмен шешдім:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (!isLoading)
        {

            if ([self.conditionsDataArray count]>0)
            {
                Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row];

                int height;

                UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)];   //you can set your frame according to your need

                textview.text  = condition.comment;

                textview.autoresizingMask = UIViewAutoresizingFlexibleHeight;

                [tableView addSubview:textview];

                textview.hidden = YES;

                height = textview.contentSize.height;

                NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height);

                [textview removeFromSuperview];

                [textview release];

                return height;
       }

       return 55;  //Default height, if data is in loading state
}

Мәтін көрінісі қосымша көрініс ретінде қосылып, содан кейін жасырын болғанына назар аударыңыз, сондықтан оны SubView ретінде қосыңыз, әйтпесе оның биіктігі қарастырылмайды.

0
қосылды