回答:
あなたはこの解決策を探しています:
StaticDataTableViewController 2.0
https://github.com/xelvenone/StaticDataTableViewController
アニメーションの有無にかかわらず、静的セルを表示/非表示/再読み込みできます!
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];
常に(reloadDataAnimated:YES / NO)のみを使用することに注意してください([self.tableView reloadData]を直接呼び出さないでください)
これは、高さを0に設定したハッキーソリューションを使用せず、変更をアニメーション化してセクション全体を非表示にすることができます
IBOutletCollection
ことだけですが、それがどのように違いを生むのかわかりません。昨日だけコードをダウンロードしたので、古いバージョンではないと思います。
UITableで静的セルを非表示にするには:
UITableViewコントローラーデリゲートクラス:
Objective-C:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if(cell == self.cellYouWantToHide)
return 0; //set the hidden cell's height to 0
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
迅速:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
このメソッドは、UITableのセルごとに呼び出されます。非表示にするセルに対して呼び出しを行ったら、高さを0に設定します。アウトレットを作成してターゲットセルを識別します。
ClipToBounds
問題を回避するには、セルを非表示に設定することもできます。これは私にはきれいに思えます。;-)
最善の方法は、次のブログhttp://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/で説明されているとおりです。
静的なテーブルビューをインターフェイスビルダーで通常どおりに設計します–潜在的に非表示になっているすべてのセルを完備します。ただし、非表示にする可能性のあるすべてのセルに対して行う必要のあることが1つあります。セルの「Clip subviews」プロパティを確認してください。そうしないと、セルのコンテンツが非表示になっても(高さを縮小して)消えません。 - もっと後で)。
SO –セルにスイッチがあり、スイッチはいくつかの静的セルを非表示にして表示することになっています。それをIBActionに接続し、そこで実行します。
[self.tableView beginUpdates]; [self.tableView endUpdates];
これにより、セルの表示と非表示の素晴らしいアニメーションが得られます。次のテーブルビューデリゲートメソッドを実装します。
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need // Show or hide cell if (self.mySwitch.on) { return 44; // Show the cell - adjust the height as you need } else { return 0; // Hide the cell } } return 44; }
以上です。スイッチを押すと、セルが非表示になり、スムーズなアニメーションで再表示されます。
私の解決策はGarethと同様の方向に進みますが、私はいくつかのことを異なる方法で行います。
ここに行く:
1.セルを非表示にする
セルを直接非表示にする方法はありません。UITableViewController
は静的セルを提供するデータソースであり、現在、「セルxを提供しない」ことを通知する方法はありません。そのUITableViewController
ため、静的セルを取得するためににデリゲートする独自のデータソースを提供する必要があります。
最も簡単なのは、サブクラス化しUITableViewController
、セルを非表示にするときに異なる動作が必要なすべてのメソッドをオーバーライドすることです。
最も単純なケース(単一のセクションテーブル、すべてのセルの高さが同じ)では、次のようになります。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Recalculate indexPath based on hidden cells
indexPath = [self offsetIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
int offsetRow = indexPath.row + numberOfCellsHiddenAbove;
return [NSIndexPath indexPathForRow:offsetRow inSection:offsetSection];
}
テーブルに複数のセクションがある場合、またはセルの高さが異なる場合は、より多くのメソッドをオーバーライドする必要があります。ここでも同じ原則が適用されます。スーパーに委任する前に、indexPath、section、rowをオフセットする必要があります。
またdidSelectRowAtIndexPath:
、同様のメソッドのindexPathパラメータは、状態(つまり、非表示のセルの数)に応じて、同じセルに対して異なります。そのため、indexPathパラメータを常にオフセットし、これらの値を操作することをお勧めします。
2.変更をアニメーション化する
Garethがすでに述べたように、reloadSections:withRowAnimation:
メソッドを使用して変更をアニメーション化すると、大きな不具合が発生します。
reloadData:
その後すぐに電話をかけると、アニメーションが大幅に改善されることがわかりました(わずかな不具合が残っただけです)。テーブルはアニメーション後に正しく表示されます。
だから私がやっていることは:
- (void)changeState
{
// Change state so cells are hidden/unhidden
...
// Reload all sections
NSIndexSet* reloadSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];
[tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadData];
}
numberOfRowsInSection:
は、テーブルが初めてロードされたときにのみ呼び出されるということです。[self.tableView reloadData]を呼び出したとき- numberOfRowsInSection:
再び呼び出されることはありません。cellForRowAtIndexPath:
呼ばれるだけです。何が欠けていますか?
cellOneOutlet.hidden = true
以下のメソッドをオーバーライドして、非表示になっているセルのステータスを確認し、それらのセルの高さ0を返します。これは、static tableViewのセルをすばやく非表示にする方法の1つです。
override func tableView(tableView: UITableView, heightForRowAtIndexPathindexPath: NSIndexPath) -> CGFloat
{
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
if tableViewCell.hidden == true
{
return 0
}
else{
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
。に置き換えられたと思いlet tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
ます。
UITableViewController
、UITableView
デリゲートメソッドはありません。それを呼び出すためにheightForRow
、他のメソッドも必要ですか?
実際にセクションを非表示にし、セクションを削除しない代替案を思いつきました。@ henning77のアプローチを試しましたが、静的UITableViewのセクション数を変更すると、問題が発生し続けました。この方法は私にとっては本当にうまくいきましたが、私は主に行ではなくセクションを非表示にしようとしています。一部の行をその場で正常に削除していますが、かなり面倒なので、表示または非表示にする必要があるセクションにグループ化しようとしました。以下は、セクションを非表示にする方法の例です。
まず、NSMutableArrayプロパティを宣言します
@property (nonatomic, strong) NSMutableArray *hiddenSections;
viewDidLoadで(またはデータを照会した後)、非表示にするセクションを配列に追加できます。
- (void)viewDidLoad
{
hiddenSections = [NSMutableArray new];
if(some piece of data is empty){
// Add index of section that should be hidden
[self.hiddenSections addObject:[NSNumber numberWithInt:1]];
}
... add as many sections to the array as needed
[self.tableView reloadData];
}
次に、以下のTableViewデリゲートメソッドを実装します。
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return nil;
}
return [super tableView:tableView titleForHeaderInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
[cell setHidden:YES];
}
}
次に、高さを0に設定できないため、非表示セクションのヘッダーとフッターの高さを1に設定します。これにより、2ピクセルのスペースが追加されますが、次の表示されるヘッダーの高さを調整することで埋め合わせることができます。
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat height = [super tableView:tableView heightForHeaderInSection:section];
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
height = 1; // Can't be zero
}
else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
// Adjust height for previous hidden sections
CGFloat adjust = 0;
for(int i = (section - 1); i >= 0; i--){
if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
adjust = adjust + 2;
}
else {
break;
}
}
if(adjust > 0)
{
if(height == -1){
height = self.tableView.sectionHeaderHeight;
}
height = height - adjust;
if(height < 1){
height = 1;
}
}
}
return height;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return 1;
}
return [super tableView:tableView heightForFooterInSection:section];
}
次に、非表示にする特定の行がある場合は、numberOfRowsInSectionとcellForRowAtIndexPathで返される行を調整できます。この例では、3つの行があるセクションがあり、3つは空で、削除する必要があります。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];
if(self.organization != nil){
if(section == 5){ // Contact
if([self.organization objectForKey:@"Phone"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"Email"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"City"] == [NSNull null]){
rows--;
}
}
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
このoffsetIndexPathを使用して、行を条件付きで削除する行のindexPathを計算します。セクションのみを非表示にする場合は不要
- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
int row = indexPath.row;
if(self.organization != nil){
if(indexPath.section == 5){
// Adjust row to return based on which rows before are hidden
if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){
row = row + 2;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){
row++;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
}
}
NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];
return offsetPath;
}
オーバーライドするメソッドはたくさんありますが、このアプローチについて私が気に入っているのは、再利用できることです。hiddenSections配列を設定して追加すると、正しいセクションが非表示になります。行を非表示にするのは少しトリッキーですが、可能です。グループ化されたUITableViewを使用している場合、境界線が正しく描画されないため、非表示にする行の高さを0に設定することはできません。
NSMutableSet
しhiddenSections
ます。主にメンバーシップをテストしているので、はるかに高速です。
NSMutableSet
forの使用についても優れhiddenSections
ていますが、回答のポイントは、どのタイプのデータ構造を使用するかについて、nit-pickyより概念的であると理解しています。
結局のところ、静的なUITableViewのセルを非表示にして、アニメーションで表示できます。そして、それを達成することはそれほど難しくありません。
要旨:
Use tableView:heightForRowAtIndexPath:
ある状態に基づいてセルの高さを動的に指定します。tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
内部に電話しないでくださいtableView:heightForRowAtIndexPath:
。キャッシュされたindexPathを使用して、セルを区別します。はい、確かにそれは可能ですが、現在同じ問題に取り組んでいます。セルを非表示にして、すべてが正常に機能するようになりましたが、現在、アニメーションをきれいに表示することはできません。これが私が見つけたものです:
最初のセクションの最初の行のON / OFFスイッチの状態に基づいて行を非表示にしています。スイッチがオンの場合、同じセクションのその下に1行あり、それ以外の場合は2つの異なる行があります。
スイッチが切り替えられたときに呼び出されるセレクターがあり、どの状態にあるかを示す変数を設定します。次に、次を呼び出します。
[[self tableView] reloadData];
tableView:willDisplayCell:forRowAtIndexPath:関数をオーバーライドし、セルを非表示にすることになっている場合は、次のようにします。
[cell setHidden:YES];
セルとその内容は非表示になりますが、セルが占めるスペースは削除されません。
スペースを削除するには、tableView:heightForRowAtIndexPath:関数をオーバーライドし、非表示にする必要がある行に0を返します。
また、tableView:numberOfRowsInSection:をオーバーライドして、そのセクションの行数を返す必要もあります。テーブルがグループ化されたスタイルの場合、丸い角が正しいセルで発生するように、ここで奇妙なことを行う必要があります。私の静的テーブルには、セクションのセルの完全なセットがあるため、オプションを含む最初のセルがあり、次にON状態オプション用の1つのセルとOFF状態オプション用の2つのセル、合計4つのセルがあります。オプションがオンの場合、4を返す必要があります。これには非表示のオプションが含まれるため、表示される最後のオプションには丸いボックスがあります。オプションがオフの場合、最後の2つのオプションは表示されないので、2を返します。これはすべて不格好な感じです。これがあまり明確でない場合は申し訳ありませんが、説明するのが難しいです。セットアップを説明するために、これはIBのテーブルセクションの構成です。
したがって、オプションがONの場合、テーブルは次の2つの行を報告します。
オプションがオフの場合、テーブルは次の4つの行を報告します。
このアプローチは、いくつかの理由で正しくないと思います。これまでのところ、これまでの実験で得た限りです。そのため、より良い方法を見つけた場合は、お知らせください。これまでに確認した問題は次のとおりです。
行数が基になるデータに含まれていると思われる数と異なることをテーブルに伝えるのは間違っています。
変化をアニメーション化できないようです。reloadDataの代わりにtableView:reloadSections:withRowAnimation:を使用してみましたが、結果が意味をなさないようですが、まだこれを機能させようとしています。現在発生しているように見えるのは、tableViewが正しい行を更新しないため、表示されるべき非表示のままになり、最初の行の下に空白が残ることです。これは、基礎となるデータに関する最初の点に関連していると思います。
うまくいけば、誰かが別の方法を提案したり、おそらくアニメーションを拡張する方法を提案したりできるでしょう。関数へのハイパーリンクがないことをお詫びし、ハイパーリンクを挿入しましたが、私はかなり新しいユーザーなので、スパムフィルターによって拒否されました。
[[self tableView] reloadData];
セルを非表示にした後でもう一度電話をかける必要があると確信しています
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
、UITableViewController
サブクラスを呼び出すだけです。インデックスパスには静的なインデックスが付けられます-動的ではありません...
Justasの答えによると、しかしSwift 4の場合:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
tableView.reloadRows(at:, with:)
行がすでに表示されているときに高さを変更した場合、セルを更新する必要がある場合があります。
さて、いくつか試した後、私は一般的ではない答えを持っています。「isHidden」または「hidden」変数を使用して、このセルを非表示にする必要があるかどうかを確認しています。
ビューコントローラーにIBOutletを作成します。
@IBOutlet weak var myCell: UITableViewCell!
myCell
カスタム関数のを更新します。たとえば、viewDidLoadに追加できます。
override func viewDidLoad() {
super.viewDidLoad()
self.myCell.isHidden = true
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
guard !cell.isHidden else {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
これにより、デリゲートメソッドのロジックが削減され、ビジネス要件に集中するだけで済みます。
セルの非表示/表示、rowHeightの変更、または自動レイアウト制約による混乱は、自動レイアウトの問題が原因で機能しませんでした。コードが耐えられなくなった。
単純な静的テーブルの場合、私にとって最も効果的だったのは次のとおりです。
これが私のテーブルビューコントローラの例です。
@IBOutlet weak var titleCell: UITableViewCell!
@IBOutlet weak var nagCell: UITableViewCell!
@IBOutlet weak var categoryCell: UITableViewCell!
var cellsToShow: [UITableViewCell] = []
override func viewDidLoad() {
super.viewDidLoad()
determinCellsToShow()
}
func determinCellsToShow() {
if detail!.duration.type != nil {
cellsToShow = [titleCell, nagCell, categoryCell]
}
else {
cellsToShow = [titleCell, categoryCell]
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return cellsToShow[indexPath.row]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellsToShow.count
}
iOS 11の場合、モハメド・サレの回答の修正版が最もよく機能し、Appleのドキュメントに基づいていくつかの改良点があることがわかりました。うまくアニメーション化し、醜いハッキングやハードコードされた値を回避し、すでにInterface Builderで設定されている行の高さを使用します。
基本的な概念は、非表示の行の行の高さを0に設定することです。次に、を使用tableView.performBatchUpdates
して、一貫して機能するアニメーションをトリガーします。
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == indexPathOfHiddenCell {
if cellIsHidden {
return 0
}
}
// Calling super will use the height set in your storyboard, avoiding hardcoded values
return super.tableView(tableView, heightForRowAt: indexPath)
}
確認する必要がcellIsHidden
ありindexPathOfHiddenCell
、ユースケースに適切に設定されます。私のコードでは、それらはテーブルビューコントローラーのプロパティです。
可視性を制御するメソッド(ボタンアクションまたはのようなdidSelectRow
)では、performBatchUpdates
ブロック内のcellIsHidden状態を切り替えます。
tableView.performBatchUpdates({
// Use self to capture for block
self.cellIsHidden = !self.cellIsHidden
}, completion: nil)
AppleはperformBatchUpdates
、beginUpdates
endUpdates
可能な場合はいつでも/を推奨しています。
静的テーブルでセルをアニメーション化するための解決策を見つけました。
// Class for wrapping Objective-C block
typedef BOOL (^HidableCellVisibilityFunctor)();
@interface BlockExecutor : NSObject
@property (strong,nonatomic) HidableCellVisibilityFunctor block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block;
@end
@implementation BlockExecutor
@synthesize block = _block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block
{
BlockExecutor * executor = [[BlockExecutor alloc] init];
executor.block = block;
return executor;
}
@end
追加の辞書は1つだけ必要です。
@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end
そしてMyTableViewControllerの実装を見てください。indexPathを表示インデックスと非表示インデックスの間で変換するには、2つのメソッドが必要です...
- (NSIndexPath*)recoverIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row <= indexPath.row + rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row+rowDelta inSection:indexPath.section];
}
- (NSIndexPath*)mapToNewIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row < indexPath.row - rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row-rowDelta inSection:indexPath.section];
}
UISwitch値の1つのIBActionが変化します:
- (IBAction)birthdaySwitchChanged:(id)sender
{
NSIndexPath * indexPath = [self mapToNewIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
if (self.birthdaySwitch.on)
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
else
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
いくつかのUITableViewDataSourceおよびUITableViewDelegateメソッド:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numberOfRows = [super tableView:tableView numberOfRowsInSection:section];
for (NSIndexPath * indexPath in [self.hidableCellsDict allKeys])
if (indexPath.section == section)
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:indexPath];
numberOfRows -= (executor.block()?0:1);
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// initializing dictionary
self.hidableCellsDict = [NSMutableDictionary dictionary];
[self.hidableCellsDict setObject:[BlockExecutor executorWithBlock:^(){return self.birthdaySwitch.on;}] forKey:[NSIndexPath indexPathForRow:1 inSection:1]];
}
- (void)viewDidUnload
{
[self setBirthdaySwitch:nil];
[super viewDidUnload];
}
@end
迅速な回答:
TableViewControllerに次のメソッドを追加します。
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
非表示にしたいセルをtableViewが描画しようとした場合、上記のメソッドにより高さが0ptに設定されるため、それは表示されません。それ以外は変更されません。
その点に注意してください indexPathOfCellYouWantToHide
いつでも変更できることに :)
> Swift 2.2では、いくつかの答えをここにまとめました。
ストーリーボードからアウトレットを作成して、staticCellにリンクします。
@IBOutlet weak var updateStaticCell: UITableViewCell!
override func viewDidLoad() {
...
updateStaticCell.hidden = true
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 0
} else {
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
最初のセルを非表示にしたいので、上記のように高さを0に設定します。
テーブルビューの一番下にあるセルを非表示にする最も簡単なシナリオでは、セルを非表示にした後でtableViewのcontentInsetを調整できます。
- (void)adjustBottomInsetForHiddenSections:(NSInteger)numberOfHiddenSections
{
CGFloat bottomInset = numberOfHiddenSections * 44.0; // or any other 'magic number
self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, -bottomInset, self.tableView.contentInset.right);
}
これは、https://github.com/k06a/ABStaticTableViewControllerを使用してこれを行う新しい方法です
NSIndexPath *ip = [NSIndexPath indexPathForRow:1 section:1];
[self deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade]
k06a(https://github.com/k06a/ABStaticTableViewController)からのソリューションは、セルのヘッダーとフッターを含むセクション全体を非表示にするため、より優れています。このソリューション(https://github.com/peterpaulis/StaticDataTableViewController)は、フッター以外のすべてを非表示にします。
編集
でフッターを非表示にする場合は、解決策を見つけましたStaticDataTableViewController
。これはStaticTableViewController.mファイルにコピーする必要があるものです:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {
return [super tableView:tableView titleForFooterInSection:section];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
CGFloat height = [super tableView:tableView heightForFooterInSection:section];
if (self.originalTable == nil) {
return height;
}
if (!self.hideSectionsWithHiddenRows) {
return height;
}
OriginalSection * os = self.originalTable.sections[section];
if ([os numberOfVissibleRows] == 0) {
//return 0;
return CGFLOAT_MIN;
} else {
return height;
}
//return 0;
return CGFLOAT_MIN;
}
きっとできます。最初に、表示するセルのtableViewの数に戻り、次に呼び出しsuper
てストーリーボードから特定のセルを取得し、tableViewに返します。
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.mode.numberOfCells()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
return cell
}
あなたの細胞が異なる高さを持っている場合もそれを返します:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}
@Saleh Masumソリューションに加えて:
あなたが取得する場合、自動レイアウトエラーを、あなただけの制約を削除することができますtableViewCell.contentView
スウィフト3:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let tableViewCell = super.tableView(tableView, cellForRowAt: indexPath)
if tableViewCell.isHidden == true
{
tableViewCell.contentView.removeConstraints(tableViewCell.contentView.constraints)
return 0
}
else{
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
このソリューションは、アプリのフローに依存します。同じView Controllerインスタンスでセルを表示/非表示にする場合は、制約が削除されるため、これは最良の選択ではない可能性があります。
静的なセルとセクションさえも、ハックなしで動的に非表示にするより良い方法を得ました。
行の高さを0に設定すると行を非表示にすることができますが、すべての行を非表示にしても一部のスペースを保持するセクション全体を非表示にする場合は機能しません。
私のアプローチは、静的セルのセクション配列を構築することです。次に、テーブルビューのコンテンツはセクション配列によって駆動されます。
ここにいくつかのサンプルコードがあります:
var tableSections = [[UITableViewCell]]()
private func configTableSections() {
// seciton A
tableSections.append([self.cell1InSectionA, self.cell2InSectionA])
// section B
if shouldShowSectionB {
tableSections.append([self.cell1InSectionB, self.cell2InSectionB])
}
// section C
if shouldShowCell1InSectionC {
tableSections.append([self.cell1InSectionC, self.cell2InSectionC, self.cell3InSectionC])
} else {
tableSections.append([self.cell2InSectionC, self.cell3InSectionC])
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return tableSections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableSections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableSections[indexPath.section][indexPath.row]
}
このように、行とセクションの数を計算する厄介なコードを記述する必要なく、すべての構成コードをまとめることができます。そしてもちろん、いいえ0
もはや高さはありません。
このコードは、メンテナンスも非常に簡単です。たとえば、さらにセルまたはセクションを追加/削除する場合などです。
同様に、セクションヘッダータイトル配列とセクションフッタータイトル配列を作成して、セクションタイトルを動的に構成できます。