it-swarm.dev

Değiştirirken UITableView canlandırması için bir yeniden yükleme verisine sahip olma

İki modlu bir UITableView var. Modlar arasında geçiş yaptığımızda, bölüm başına farklı sayıda bölümler ve hücreler var. İdeal olarak, masa büyüyünce veya küçülürken harika bir animasyon olur.

İşte denediğim kod, fakat hiçbir şey yapmıyor:

CGContextRef context = UIGraphicsGetCurrentContext(); 
[UIView beginAnimations:nil context:context]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.5]; 

[self.tableView reloadData];
[UIView commitAnimations];

Bunu nasıl yapabildiğime dair bir fikrin var mı?

164
Chris Butler

Aslında çok basit:

[_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

/ belgeler :

Bu yöntemin çağrılması tablo görünümünün kendi veri kaynağını istemesini sağlar. belirtilen bölümler için yeni hücreler. Tablo görünümü, .__ canlandırır. Eski hücrelerin harekete geçmesiyle içine yeni hücrelerin yerleştirilmesi.

384
dmarnel

Kullanmak isteyebilirsiniz:

Amaç-C

[UIView transitionWithView: self.tableView
                  duration: 0.35f
                   options: UIViewAnimationOptionTransitionCrossDissolve
                animations: ^(void)
 {
      [self.tableView reloadData];
 }
                completion: nil];

Swift

UIView.transitionWithView(tableView,
                          duration: 0.35,
                          options: .TransitionCrossDissolve,
                          animations:
{ () -> Void in
    self.tableView.reloadData()
},
                          completion: nil);

Swift

UIView.transition(with: tableView,
                  duration: 0.35,
                  options: .transitionCrossDissolve,
                  animations: { self.tableView.reloadData() }) // left out the unnecessary syntax in the completion block and the optional completion parameter

Güçlük yok. : D

Ayrıca, daha serin etkiler için istediğiniz UIViewAnimationOptionTransitionsöğesinden herhangi birini kullanabilirsiniz:

  • TransitionNonename__
  • TransitionFlipFromLeftname__
  • TransitionFlipFromRightname__
  • TransitionCurlUpname__
  • TransitionCurlDownname__
  • TransitionCrossDissolvename__
  • TransitionFlipFromTopname__
  • TransitionFlipFromBottomname__
239
Kenn Cal

CATransition sınıfını kullanarak daha fazla özgürlüğe sahip olun.

Solma ile sınırlı değil, aynı zamanda hareketleri yapabilir ..


Örneğin:

(QuartzCore) almayı unutma

CATransition *transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.fillMode = kCAFillModeForwards;
transition.duration = 0.5;
transition.subtype = kCATransitionFromBottom;

[[self.tableView layer] addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];

type vs. gibi ihtiyaçlarınızı karşılamak için kCATransitionFade öğesini değiştirin.

Swift'de uygulama:

let transition = CATransition()
transition.type = kCATransitionPush
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.fillMode = kCAFillModeForwards
transition.duration = 0.5
transition.subtype = kCATransitionFromTop
self.tableView.layer.addAnimation(transition, forKey: "UITableViewReloadDataAnimationKey")
// Update your data source here
self.tableView.reloadData()

CATransition için referans

69
code ninja

O zaman veri yapınızı güncelleyebileceğinize inanıyorum:

[tableView beginUpdates];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[tableView endUpdates];

Ayrıca, "withRowAnimation" tam olarak bir boole değil, bir animasyon tarzıdır:

UITableViewRowAnimationFade,
UITableViewRowAnimationRight,
UITableViewRowAnimationLeft,
UITableViewRowAnimationTop,
UITableViewRowAnimationBottom,
UITableViewRowAnimationNone,
UITableViewRowAnimationMiddle
59
Tiago Fael Matos

Bu yanıtların tümü, yalnızca 1 bölümden oluşan bir UITableView kullandığınızı varsayar.

1 bölümden fazla kullanımın olduğu durumları doğru bir şekilde ele almak için:

NSRange range = NSMakeRange(0, myTableView.numberOfSections);
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
[myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

(Not: 0'dan fazla bölümünüz olduğundan emin olmalısınız!)

Unutulmaması gereken diğer bir şey, veri kaynağınızı bu kodla eşzamanlı olarak güncellemeye çalışırsanız, NSInternalInconsistencyException ile karşılaşabilirsiniz. Bu durumda, buna benzer bir mantık kullanabilirsiniz:

int sectionNumber = 0; //Note that your section may be different

int nextIndex = [currentItems count]; //starting index of newly added items

[myTableView beginUpdates];

for (NSObject *item in itemsToAdd) {
    //Add the item to the data source
    [currentItems addObject:item];

    //Add the item to the table view
    NSIndexPath *path = [NSIndexPath indexPathForRow:nextIndex++ inSection:sectionNumber];
    [myTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationAutomatic];
}

[myTableView endUpdates];
23
diadyne

Buna yaklaşmanın yolu, tableView'a satırları ve bölümleri kaldırmak ve eklemek için söylemektir.

insertRowsAtIndexPaths:withRowAnimation:, deleteRowsAtIndexPaths:withRowAnimation:, insertSections:withRowAnimation: ve deleteSections:withRowAnimation:

uITableView yöntemleri. Bu yöntemleri çağırdığınızda, tablo istediğiniz öğeleri içeri/dışarı hareketlendirir, ardından canlandırıp kendisinin yeniden çağırmasını sağlar, böylece bu animasyondan sonra durumu güncelleyebilirsiniz. Bu kısım önemlidir - eğer her şeyi elinizden alıyorsanız ancak tablonun dataSource tarafından döndürülen verileri değiştirmiyorsanız, satırlar animasyon tamamlandıktan sonra tekrar belirecektir. 

Dolayısıyla, uygulama akışınız şöyle olacaktır:

[self setTableIsInSecondState:YES];

[myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];

Tablonuzun dataSource yöntemleri, [self tableIsInSecondState] (veya her neyse) öğesini işaretleyerek doğru yeni bölümler ve satırların setini döndürdüğü sürece, bu aradığınız efekti elde edecektir.

17
iKenndac

En iyi cevap hakkında yorum yapamam, ancak Swift uygulaması şöyle olacaktır: 

self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)

reoadSections için ilk argümana güncellemek istediğiniz kadar bölüm ekleyebilirsiniz.

Dokümanlardaki diğer animasyonlar: https://developer.Apple.com/reference/uikit/uitableviewrowanimation

fade Girilen veya silinen satır veya satırlar tablo görünümüne girer veya çıkar.

right Girilen satır veya satırlar sağdan içeri kayar; Silinen satır veya satırlar sağa doğru kayar.

left Girilen satır veya satırlar soldan kayar; Silinen satır veya satırlar sola doğru kayar.

top Girilen satır ya da satırlar yukarıdan içeri kayar; Silinen satır veya satırlar yukarı doğru kayar.

bottom Girilen satır veya satırlar alttan içeri doğru kayar; Silinen satır veya satırlar aşağıya doğru kayar.

case none Girilen veya silinen satırlar varsayılan animasyonları kullanır.

middle Tablo görünümü, eski ya da yeni hücreleri, yaptıkları ya da işgal edecekleri alanda ortada tutmaya çalışır. İPhone 3.2'de bulunur.

automatic Tablo görünümü sizin için uygun bir animasyon stili seçer. (İOS 5.0'da tanıtılmıştır.)

16
Christopher Larsen

Swift Uygulaması:

let range = NSMakeRange(0, self.tableView!.numberOfSections())
let indexSet = NSIndexSet(indexesInRange: range)
self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
9
Michael Peterson

Swift 4 @dmarnel answer için sürüm:

tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
9
chengsam

Swift 4 için

tableView.reloadSections([0], with: UITableView.RowAnimation.fade)
2
Claus
CATransition *animation = [CATransition animation];
animation.duration = .3;
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setDuration:.3];

[[_elementTableView layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];

[tableView reloadData];
1
Mayur Sardana

Swift içinde yeniden yükleme verisi olmadan animasyon (/ şu şekilde yapılabilir) (2.2 sürümünden itibaren):

tableview.beginUpdates()
var indexPathsToDeleteForAnimation: [NSIndexPath] = []
var numOfCellsToRemove = ArrayOfItemsToRemove ?? 0

// Do your work here
while numOfCellsToRemove > 0 {
    // ...or here, if you need to add/remove the same amount of objects to/from somewhere
    indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
    numOfCellsToRemove -= 1
}
tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
tableview.endUpdates()

animasyon sona erdikten sonra reloadData () öğesini çağırmanız gerekirse, CATransaction'daki değişiklikleri aşağıdaki gibi kabul edebilirsiniz:

CATransaction.begin()
CATransaction.setCompletionBlock({() in self.tableview.reloadData() })
tableview.beginUpdates()
var indexPathsToDeleteForAnimation: [NSIndexPath] = []
var numOfCellsToRemove = ArrayOfItemsToRemove.count ?? 0

// Do your work here
while numOfCellsToRemove > 0 {
     // ...or here, if you need to add/remove the same amount of objects to/from somewhere
     indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
     numOfCellsToRemove -= 1
}
tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
tableview.endUpdates()
CATransaction.commit()

Satırları sildiğinizde durum için mantık gösterilir, ancak aynı fikir satır eklemek için de geçerlidir. Ayrıca, animasyonu düzgün yapmak için UITableViewRowAnimation.Left olarak da değiştirebilir veya mevcut diğer animasyonlar arasından seçim yapabilirsiniz.

1
Vitalii

UITableView hücrelerine kendi özel animasyonlarınızı eklemek istiyorsanız,

[theTableView reloadData];
[theTableView layoutSubviews];
NSArray* visibleViews = [theTableView visibleCells];

görünür hücrelerin bir dizi almak için. Sonra her hücreye herhangi bir özel animasyon ekleyin.

Pürüzsüz bir özel hücre animasyonu için yayınlanan bu Gist göz atın. https://Gist.github.com/floprr/1b7a58e4a18449d962bd

1
flopr

Benim durumumda, tablo görünümüne 10 satır daha eklemek istedim ("daha fazla sonuç göster" işlevi için) ve aşağıdakileri yaptım:

  NSInteger tempNumber = self.numberOfRows;
  self.numberOfRows += 10;
  NSMutableArray *arrayOfIndexPaths = [[NSMutableArray alloc] init];
  for (NSInteger i = tempNumber; i < self.numberOfRows; i++) {
    [arrayOfIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
  }
  [self.tableView beginUpdates];
  [self.tableView insertRowsAtIndexPaths:arrayOfIndexPaths withRowAnimation:UITableViewRowAnimationTop];
  [self.tableView endUpdates];

Çoğu durumda, "self.numberOfRows" yerine, genellikle tableview için nesne dizisinin sayısını kullanırsınız. Bu çözümün sizin için iyi çalıştığından emin olmak için, "arrayOfIndexPaths", eklenen satırların dizin yollarının doğru bir dizisi olmalıdır. Satır, bu dizin yollarından herhangi biri için mevcutsa, kod çökebilir, bu nedenle çökmesini önlemek için bu dizin yollarında "reloadRowsAtIndexPaths: withRowAnimation:" yöntemini kullanmalısınız

1
Lucas Chwe

Tüm bölümleri yeniden yükle öğesine, yalnızca özel süre seçeneğine sahip değil.

Özel süreyi ayarlamak için kullanıcı durationUIView.animate parametresi.

UIView.animate(withDuration: 0.4, animations: { [weak self] in
    guard let `self` = self else { return }
    let indexSet = IndexSet(integersIn: 0..<self.tableView.numberOfSections)
    self.tableView.reloadSections(indexSet, with: UITableView.RowAnimation.fade)
})
0
JPetric