Kan du animere en høyde endring på en UITableViewCell når valgt?

stemmer
368

Jeg bruker en UITableViewpå min iPhone app, og jeg har en liste over personer som tilhører en gruppe. Jeg ønsker det, slik at når brukeren klikker på en bestemt person (således markere cellen), vokser cellen i høyden for å vise flere UI kontroller for å endre egenskapene for den personen.

Er dette mulig?

Publisert på 20/01/2009 klokken 03:17
kilden bruker
På andre språk...                            


21 svar

stemmer
842

Jeg fant en veldig enkel løsning på dette som en bivirkning til en UITableViewjeg jobbet på .....

Oppbevar mobil høyde i en variabel som rapporterer opprinnelige høyde normalt via tableView: heightForRowAtIndexPath:, så når du ønsker å animere en høyde endring, bare endre verdien av variabelen, og kaller dette ...

[tableView beginUpdates];
[tableView endUpdates];

Du finner det ikke gjøre en full reload men er nok for UITableViewå vite det har å tegne cellene, gripe tak i ny høyde verdi for cellen .... og gjett hva? Det animerer endringen for deg. Søt.

Jeg har en mer detaljert forklaring og full kodeeksempler på bloggen min ... Animate UITableView Cellehøyde Change

Svarte 14/01/2010 kl. 11:42
kilden bruker

stemmer
56

Jeg liker svaret av Simon Lee. Jeg gjorde faktisk ikke prøve denne metoden, men det ser ut som det ville endre størrelsen på alle cellene i listen. Jeg hadde håpet på en endring av akkurat den cellen som er avlyttet. Jeg kinda gjorde det som Simon, men med bare en liten forskjell. Dette vil endre utseendet til en celle når det er valgt. Og det gjør animere. Bare en annen måte å gjøre det.

Opprett en int å holde en verdi for den gjeldende valgte cellen Indeks:

int currentSelection;

Deretter:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}

Deretter:

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

    if ([indexPath row] == currentSelection) {
        return  80;
    }
    else return 40;


}

Jeg er sikker på at du kan gjøre tilsvarende endringer i Tableview: cellForRowAtIndexPath: å endre type celle eller laste en xib fil for cellen.

Liker du dette, vil currentSelection starter på 0. Du må foreta justeringer hvis du ikke vil at den første cellen i listen (ved indeks 0) å se valgt som standard.

Svarte 25/04/2011 kl. 23:25
kilden bruker

stemmer
19

Legge en eiendom for å holde styr på den valgte cellen

@property (nonatomic) int currentSelection;

Sett den til en sentinel verdi (for eksempel) viewDidLoad, for å sørge for at de UITableViewstarter i 'normal' stilling

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //sentinel
    self.currentSelection = -1;
}

I heightForRowAtIndexPathdu kan stille høyden du ønsker for den valgte cellen

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}

I didSelectRowAtIndexPathdu lagre gjeldende valg og lagre en dynamisk høyde, om nødvendig

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // set selection
        self.currentSelection = indexPath.row;
        // save height for full text label
        self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

I didDeselectRowAtIndexPathangi valget indeksen tilbake til fast punkt verdi og animere cellen tilbake til normalform

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {       
        // do things with your cell here

        // sentinel
        self.currentSelection = -1;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}
Svarte 05/08/2013 kl. 16:02
kilden bruker

stemmer
13

reloadData er ikke bra fordi det er ingen animasjon ...

Dette er hva jeg er for tiden prøver:

NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

Det fungerer nesten rett. Nesten. Jeg øke høyden på cellen, og noen ganger er det en liten "hikke" i tabellen visningen som cellen skiftes ut, som om noen rulling posisjon i tabellen visningen blir bevart, den nye cellen (som er den første cellen i tabellen) ender opp med sin forskyvning er for høy, og den spretter scrollview for å flytte den.

Svarte 06/05/2009 kl. 23:24
kilden bruker

stemmer
10

Jeg løst med reloadRowsAtIndexPaths.

Jeg sparer i didSelectRowAtIndexPathden indexPath av cellen valgt og kalle reloadRowsAtIndexPathspå slutten (du kan sende NSMutableArray for liste over elementets du ønsker reload).

I heightForRowAtIndexPathdu kan sjekke om indexPath er på listen eller ikke fra expandIndexPath cellens og sende høyde.

Du kan sjekke dette grunnleggende eksempel: https://github.com/ferminhg/iOS-Examples/tree/master/iOS-UITableView-Cell-Height-Change/celdascambiadetam Det er en enkel løsning.

jeg legge en slags kode hvis hjelpe deg

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 20;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath
{
    if ([indexPath isEqual:_expandIndexPath])
        return 80;

    return 40;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Celda";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    [cell.textLabel setText:@"wopwop"];

    return cell;
}

#pragma mark -
#pragma mark Tableview Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSMutableArray *modifiedRows = [NSMutableArray array];
    // Deselect cell
    [tableView deselectRowAtIndexPath:indexPath animated:TRUE];
    _expandIndexPath = indexPath;
    [modifiedRows addObject:indexPath];

    // This will animate updating the row sizes
    [tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];
}
Svarte 14/11/2014 kl. 13:20
kilden bruker

stemmer
10

Jeg vet ikke hva alt dette om å ringe beginUpdates / endUpdates etter hverandre er, kan du bare bruke -[UITableView reloadRowsAtIndexPaths:withAnimation:]. Her er et eksempel prosjekt .

Svarte 02/08/2014 kl. 22:52
kilden bruker

stemmer
3
BOOL flag;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    flag = !flag;
    [tableView beginUpdates];
    [tableView reloadRowsAtIndexPaths:@[indexPath] 
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES == flag ? 20 : 40;
}
Svarte 15/08/2016 kl. 16:32
kilden bruker

stemmer
2

bare et notat for en som meg som søker etter legge "Flere detaljer" på tilpasset celle.

[tableView beginUpdates];
[tableView endUpdates];

Gjorde en utmerket jobb, men ikke glem å "crop" celle visning. Fra Interface Builder velge Cell -> Innhold View -> fra Eiendom Inspector velg " Clip subview "

Svarte 25/03/2015 kl. 20:08
kilden bruker

stemmer
2

Prøv dette er for å utvide indexwise rad:

@property (nonatomic) NSIndexPath *expandIndexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
if ([indexPath isEqual:self.expandedIndexPath])
    return 100;

return 44;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *modifiedRows = [NSMutableArray array];
if ([indexPath isEqual:self.expandIndexPath]) {
    [modifiedRows addObject:self.expandIndexPath];
    self.expandIndexPath = nil;
} else {
    if (self.expandedIndexPath)
        [modifiedRows addObject:self.expandIndexPath];

    self.expandIndexPath = indexPath;
    [modifiedRows addObject:indexPath];
}

// This will animate updating the row sizes
[tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];

// Preserve the deselection animation (if desired)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ViewControllerCellReuseIdentifier];
    cell.textLabel.text = [NSString stringWithFormat:@"I'm cell %ld:%ld", (long)indexPath.section, (long)indexPath.row];

return cell;
}
Svarte 24/09/2014 kl. 05:41
kilden bruker

stemmer
1

I stedet for beginUpdates()/ endUpdates()er anbefalt samtalen nå:

tableView.performBatchUpdates(nil, completion: nil)

Apple sier, om beginUpdates / endUpdates: "Bruk performBatchUpdates (_. Ferdigstillelse :) metode i stedet for dette når det er mulig"

Se: https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates

Svarte 19/11/2018 kl. 16:47
kilden bruker

stemmer
1

Heres en kortere versjon av Simons svar for Swift 3. Det gir også mulighet for veksling av cellens utvalg

var cellIsSelected: IndexPath?


  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    cellIsSelected = cellIsSelected == indexPath ? nil : indexPath
    tableView.beginUpdates()
    tableView.endUpdates()
  }


  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellIsSelected == indexPath {
      return 250
    }
    return 65
  }
Svarte 30/05/2017 kl. 23:36
kilden bruker

stemmer
1

Swift versjon av Simon Lee svar.

// MARK: - Variables 
  var isCcBccSelected = false // To toggle Bcc.



    // MARK: UITableViewDelegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    // Hide the Bcc Text Field , until CC gets focused in didSelectRowAtIndexPath()
    if self.cellTypes[indexPath.row] == CellType.Bcc {
        if (isCcBccSelected) {
            return 44
        } else {
            return 0
        }
    }

    return 44.0
}

Deretter i didSelectRowAtIndexPath ()

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

    // To Get the Focus of CC, so that we can expand Bcc
    if self.cellTypes[indexPath.row] == CellType.Cc {

        if let cell = tableView.cellForRowAtIndexPath(indexPath) as? RecipientTableViewCell {

            if cell.tag == 1 {
                cell.recipientTypeLabel.text = "Cc:"
                cell.recipientTextField.userInteractionEnabled = true
                cell.recipientTextField.becomeFirstResponder()

                isCcBccSelected = true

                tableView.beginUpdates()
                tableView.endUpdates()
            }
        }
    }
}
Svarte 07/06/2016 kl. 15:30
kilden bruker

stemmer
0

Swift 4 og Above

legge under kode inn i deg Tableview er didselect rad delegat metode

tableView.beginUpdates()
tableView.setNeedsLayout()
tableView.endUpdates()
Svarte 23/11/2018 kl. 11:53
kilden bruker

stemmer
0

innganger -

tableView.beginUpdates () tableView.endUpdates () disse funksjonene vil ikke kalle

funk Tableview (_ Tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}

Men, hvis du gjør det, tableView.reloadRows (ved: [selectedIndexPath som IndexPath!] Med: .none)

Det vil kalle funk tabellvisning (_ Tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {} denne funksjonen.

Svarte 28/03/2018 kl. 11:08
kilden bruker

stemmer
0

Swift versjon av Simon Lee svar :

tableView.beginUpdates()
tableView.endUpdates()

Husk at du bør endre høyde egenskaper FØR endUpdates() .

Svarte 08/02/2018 kl. 14:11
kilden bruker

stemmer
0

Ja det er mulig.

UITableView har en representant metode didSelectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [UIView animateWithDuration:.6
                          delay:0
         usingSpringWithDamping:UIViewAnimationOptionBeginFromCurrentState
          initialSpringVelocity:0
                        options:UIViewAnimationOptionBeginFromCurrentState animations:^{

                            cellindex = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
                            NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
                            [violatedTableView beginUpdates];
                            [violatedTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
                            [violatedTableView endUpdates];
                        }
                     completion:^(BOOL finished) {
    }];
}

Men i ditt tilfelle hvis brukeren ruller og velger en annen celle så u må ha den sist valgte cellen til å krympe og utvide den gjeldende valgte cellen reloadRowsAtIndexPaths:samtaler heightForRowAtIndexPath:så håndtere tilsvarende.

Svarte 01/08/2016 kl. 11:29
kilden bruker

stemmer
0

Sjekk denne metoden etter iOS 7 og senere.

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewAutomaticDimension;
}

Forbedringer har blitt avgitt til dette i iOS 8. Vi kan sette det som tilhører tabellvisningen selv.

Svarte 04/03/2016 kl. 12:10
kilden bruker

stemmer
0

Jeg brukte @ Joy er kjempebra svar, og det fungerte utmerket med iOS 8.4 og XCode 7.1.1.

I tilfelle du ønsker å gjøre mobil toggle-stand, endret jeg -tableViewDidSelect til følgende:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//This is the bit I changed, so that if tapped once on the cell, 
//cell is expanded. If tapped again on the same cell, 
//cell is collapsed. 
    if (self.currentSelection==indexPath.row) {
        self.currentSelection = -1;
    }else{
        self.currentSelection = indexPath.row;
    }
        // animate
        [tableView beginUpdates];
        [tableView endUpdates];

}

Jeg håper noe av dette hjalp deg.

Svarte 19/11/2015 kl. 21:00
kilden bruker

stemmer
0

Her er min kode av tilpassede UITableViewunderklasse, som utvider UITextViewpå tabellcelle, uten omlasting (og mistet fokus på tastaturet):

- (void)textViewDidChange:(UITextView *)textView {
    CGFloat textHeight = [textView sizeThatFits:CGSizeMake(self.width, MAXFLOAT)].height;
    // Check, if text height changed
    if (self.previousTextHeight != textHeight && self.previousTextHeight > 0) {
        [self beginUpdates];

        // Calculate difference in height
        CGFloat difference = textHeight - self.previousTextHeight;

        // Update currently editing cell's height
        CGRect editingCellFrame = self.editingCell.frame;
        editingCellFrame.size.height += difference;
        self.editingCell.frame = editingCellFrame;

        // Update UITableView contentSize
        self.contentSize = CGSizeMake(self.contentSize.width, self.contentSize.height + difference);

        // Scroll to bottom if cell is at the end of the table
        if (self.editingNoteInEndOfTable) {
            self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + difference);
        } else {
            // Update all next to editing cells
            NSInteger editingCellIndex = [self.visibleCells indexOfObject:self.editingCell];
            for (NSInteger i = editingCellIndex; i < self.visibleCells.count; i++) {
                UITableViewCell *cell = self.visibleCells[i];
                CGRect cellFrame = cell.frame;
                cellFrame.origin.y += difference;
                cell.frame = cellFrame;
            }
        }
        [self endUpdates];
    }
    self.previousTextHeight = textHeight;
}
Svarte 10/11/2015 kl. 02:14
kilden bruker

stemmer
-1

Jeg bare løst dette problemet med en liten hack:

static int s_CellHeight = 30;
static int s_CellHeightEditing = 60;

- (void)onTimer {
    cellHeight++;
    [tableView reloadData];
    if (cellHeight < s_CellHeightEditing)
        heightAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(onTimer) userInfo:nil repeats:NO] retain];
}

- (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
        if (isInEdit) {
            return cellHeight;
        }
        cellHeight = s_CellHeight;
        return s_CellHeight;
}

Når jeg trenger å utvide cellen høyden jeg satt isInEdit = YESog kaller metoden [self onTimer], og det animerer cellevekst før det kommer til s_CellHeightEditing verdi :-)

Svarte 20/08/2009 kl. 20:18
kilden bruker

stemmer
-2

Få indexpath av den valgte raden. Last bordet. I heightForRowAtIndexPath metode for UITableViewDelegate, angir høyden på det valgte til en annen høyde og for de andre rad gå tilbake til normalhøyde rad

Svarte 21/01/2009 kl. 15:13
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more