Warum gibt es am oberen Rand von UITableView eine zusätzliche Auffüllung mit dem Style UITableViewStyleGrouped in iOS7




(25)

Ich wurde von folgenden geholfen:

YouStoryboard.storyboard> YouViewController> Attribute-Inspektor> Uncheck - Passen Sie die Bildlaufeinschübe an.

Ab iOS7 gibt es oben auf meinen UITableView einen zusätzlichen Speicherplatz, der einen Style UITableViewStyleGrouped .

Hier ist ein Beispiel:

Die Tabellenansicht beginnt mit dem ersten Pfeil, es gibt 35 Pixel ungeklärter Auffüllung, dann ist der grüne Header ein UIView von viewForHeaderInSection (wobei der Abschnitt 0 ist).

Kann mir jemand erklären, woher diese 35-Pixel-Menge kommt und wie ich sie loswerden kann, ohne zu UITableViewStylePlain wechseln zu UITableViewStylePlain ?


Sie können feststellen, ob Ihre App iOS7 oder höher ausführt, und diese beiden Methoden in Ihrem Tabellenansichtsdelegaten hinzufügen (normalerweise in Ihrem UIViewController-Code).

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN;
}

Dies ist vielleicht keine elegante Lösung, aber funktioniert für mich


Ich habe etwas mehr damit herumgespielt und es scheint, als wäre dies ein Nebeneffekt der Einstellung von tableHeaderView = nil der tableHeaderView = nil .

Weil meine TableView eine dynamisch erscheinende tableHeaderView , wenn ich die tableHeaderView ausblenden tableHeaderView , anstatt self.tableView.tableHeaderView = nil; , Ich mache:

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];

Ich mag diese Lösung besser, als ein etwas willkürliches contentInset.top weil ich auch contentInset.top dynamisch verwende. Ich contentInset.top daran denken, extra 35px zu entfernen, wenn ich contentInset.top neu contentInset.top .


Ich habe gerade UITableView vom Interface Builder , es wieder einmal erstellt und seltsames 35px weg gegangen.

Es scheint, dass es einen seltsamen Fehler im Interface Builder .


In meinem Fall hat mir das geholfen. Ich unterstütze auch ios6.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

Viele der obigen Antworten sind zu hackig. Sie würden jederzeit in der Zukunft brechen, wenn Apple beschließt, dieses unerwartete Verhalten zu beheben.

Wurzel des Problems:

  1. Ein UITableView keine Kopfzeile mit einer Höhe von 0.0 haben. Wenn Sie versuchen, einen Header mit einer Höhe von 0 zu haben, können Sie zur Lösung springen.

  2. Auch wenn Sie später Ihrer Kopfzeile eine Höhe von nicht 0.0 zuweisen, UITableView ein UITableView nicht zuerst eine Kopfzeile mit einer Höhe von 0.0 zugewiesen werden.

Lösung:

Die einfachste und zuverlässigste Lösung besteht dann darin, sicherzustellen, dass Ihre Kopfhöhe nicht 0 ist, wenn Sie sie der Tabellenansicht zuweisen.

So etwas würde funktionieren:

// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, CGFLOAT_MIN)];
self.tableView.tableHeaderView = tableViewHeaderView;

So etwas würde zu einem bestimmten Zeitpunkt (normalerweise nach einem Scroll) zu dem Problem führen:

// Replace UIView with whatever class you're using as your header below:
UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
self.tableView.tableHeaderView = tableViewHeaderView;

Ich hatte den gleichen Fehler wie Arielyz. Sobald ich das UITableView verschoben habe, um nicht die erste Unteransicht der Elternansicht zu sein, ging es weg. Mein Platz war 20 px, nicht 35.

Ich konnte es nicht in einem Portrait Xib, nur einem Landscape Xib neu erstellen. Ich werde später einen Radarbug einreichen, wenn ich ihn in einer einfachen Demo-App reproduzieren kann.


Ich habe meinen Kopf gegen diesen auch geschlagen. Ziemlich sicher, das ist ein iOS7 Bug. Was mir letztendlich geholfen hat, ist die Reihenfolge der Ansichten in der XIB. Ich hatte eine Ansicht, in der die Tabellenansicht korrekt angezeigt wurde, und eine andere, in der die Tabellenansicht über diesen zusätzlichen 35-Pixel-Platz verfügte. Der einzige Unterschied zwischen den beiden (UITableView) ist, dass UITableView in der schlecht darstellenden Ansicht das erste Kind war, während es in der Ansicht, die korrekt angezeigt wurde, die zweite war.

Das hat den Trick für mich gemacht, nur die Reihenfolge der Ansichten zu ändern. Ich bevorzuge es, keine zusätzlichen Codezeilen für eine Problemumgehung hinzuzufügen ...


Versuchen Sie, die contentInset Eigenschaft zu ändern, die contentInset UITableView erbt.

self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);

Es ist ein Workaround, aber es funktioniert


Noch ein kurzer Kommentar ... sogar in XCode 6.1 gibt es einen Fehler mit vertikalen Leerzeichen, die oben in UIScrollViews , UITextViews und UITableViews .

Manchmal besteht die einzige Möglichkeit, dieses Problem zu beheben, darin, in das Storyboard zu gehen und das Problemsteuerelement zu ziehen, damit es nicht länger die erste Unteransicht auf der Seite ist.

(Ich danke Oded, dass er mich in diese Richtung weist ... Ich poste diesen Kommentar, nur um ein paar Screenshots hinzuzufügen, um die Symptome zu demonstrieren und zu beheben.)


Für IOS 7, wenn Sie eine Tabellenansicht in einem View-Controller zuweisen, können Sie sich das ansehen

self.edgesForExtendedLayout = UIRectEdgeNone;

Dein Problem schien mir ähnlich zu sein

Aktualisieren:

Schnell in iOS 9.x:

self.edgesForExtendedLayout = UIRectEdge.None

Schnell 3:

self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)

Ich denke, UIEdInSenses -35 0 0 0 zu machen ist langweilig. In meinem Fall habe ich die Methode "tableView: heightForHeaderInSection:" implementiert und sie hat das Potenzial, 0 zurückzugeben.

Als ich 0 zu 0.1f änderte, ging das Problem einfach weg.


Ich gehe davon aus, dass dies nur ein Teil des neuen UITableViewStyleGrouped Stylings ist. Es ist in allen gruppierten Tabellenansichten und es scheint keinen direkten Weg zu geben, diesen Raum zu kontrollieren.

Wenn dieser Bereich durch eine UIView repräsentiert wird, ist es möglich, alle subviews von UITableView zu UITableView , um diese bestimmte Ansicht zu finden und direkt zu bearbeiten. Es gibt jedoch auch die Möglichkeit, dass dieser Bereich nur ein hartkodierter Offset ist, bevor Header und Zellen beginnen und es keine Möglichkeit gibt, ihn zu bearbeiten.

Um alle Untersichten zu durchsuchen (ich würde diesen Code ausführen, wenn die Tabelle keine Zellen enthält, um das Lesen der Ausgabe etwas einfacher zu machen):

- (void)listSubviewsOfView:(UIView *)view {

    // Get the subviews of the view
    NSArray *subviews = [view subviews];

    // Return if there are no subviews
    if ([subviews count] == 0) return;

    for (UIView *subview in subviews) {

        NSLog(@"%@", subview);

        // List the subviews of subview
        [self listSubviewsOfView:subview];
    }
}

nutze diese, ich denke, diese Hilfe ...

 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
 {
    return 0.005f;// set this according to that you want...
 }

Meine Antwort wird allgemeinere Antwort sein, kann aber auch darauf angewendet werden.

Wenn die Stammansicht (des ViewControllers ) oder die erste untergeordnete Ansicht (Unteransicht) der Stammansicht eine Unterklasse von UIScrollView (oder UIScrollView selbst) ist und if

self.navigationController.navigationBar.translucent = YES;

Rahmen wird automatisch vorberechnet contentInset setzen .

Um dies zu vermeiden, können Sie tun

self.automaticallyAdjustsScrollViewInsets = NO;

aber in meinem Fall war ich nicht in der Lage, dies zu tun, weil ich SDK mit UIView-Komponente implementierte, die von anderen Entwicklern verwendet werden kann. Diese UIView-Komponente enthält UIWebView (mit UIScrollView als erster Unteransicht). Wenn diese Komponente als erstes untergeordnetes Element in der Ansichtshierarchie des UIViewControllers hinzugefügt wird, werden automatische Einfügungen vom System angewendet.

Ich habe dies behoben, indem ich Dummy-View mit Frame (0,0,0,0) hinzugefügt habe, bevor ich UIWebView hinzufüge.

In diesem Fall hat das System die Unterklasse von UIScrollView nicht als erste Untersicht gefunden und keine Einsätze angewendet


override func viewWillAppear(animated: Bool) {
        self.edgesForExtendedLayout = UIRectEdge.None

 //  OR

self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);

   //OR

 self.automaticallyAdjustsScrollViewInsets = false
        }

Danke an die Antwort von @Aurelien Porte. Hier ist meine Lösung

Ursache dieses Problems: -

  1. Ein UITableView möchte keine Kopfzeile mit einer Höhe von 0.0 haben. Wenn Sie versuchen, einen Header mit einer Höhe von 0 zu haben, können Sie zur Lösung springen.
  2. Auch wenn Sie später Ihrer Kopfzeile eine Höhe von nicht 0.0 zuweisen, möchte ein UITableView nicht zuerst eine Kopfzeile mit einer Höhe von 0.0 zugewiesen werden.

In ViewDidLoad: -

self.edgesForExtendedLayout = UIRectEdge.None

self.automaticallyAdjustsScrollViewInsets = false

Keine Notwendigkeit für so etwas: -

self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)

Im heightForHeaderInSection Delegat: -

if section == 0
    {
        return 1
    }
    else
    {
        return 40; // your other headers height value
    }

In viewForHeaderInSection Delegat: -

if section == 0 
{  
   // Note CGFloat.min for swift
   // For Objective-c CGFLOAT_MIN 
   let headerView = UIView.init(frame: CGRectMake(0.0, 0.0, self.myShaadiTableview.bounds.size.width, CGFloat.min)) 
   return headerView
}
else
{ 
   // Construct your other headers here 
}

Dies ist die Lösung für iOS 10 mit Swift 3:

Sie können die oberen und unteren Paddings loswerden, indem Sie die folgenden Methoden aus dem UITableViewDelegate .

    func tableView( _ tableView: UITableView, heightForHeaderInSection section: Int ) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }

self.automaticallyAdjustsScrollViewInsets = NO;

Versuch, du kannst damit umgehen!


Wir haben mehrere Antworten dafür.

1) Sie können UIImageview bei view didload hinzufügen

UIImageView * imbBackground = [UIImageView new];
[self.view addSubview:imbBackground];

2) Sie können Kopf- und Fußzeilenhöhe 0,1 einstellen

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 0.1;
}

3) Sie können die Kopf- und Fußzeilenansicht mit der Höhe 0,1 hinzufügen

tblCampaigns.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];
tblCampaigns.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];

Ich habe die Ursache für meinen ursprünglichen Fehler gefunden und ein Beispielprojekt erstellt. Ich glaube es gibt einen iOS7 Bug.

Ab iOS7, wenn Sie ein UITableView mit dem gruppierten Stil erstellen, aber keinen Delegaten im ersten Layout festgelegt haben, dann setzen Sie einen Delegaten und rufen reloadData auf, es wird oben ein 35px-Speicherplatz sein, der niemals verschwindet.

Sehen Sie dieses Projekt, das ich gemacht habe, um den Fehler zu präsentieren: https://github.com/esilverberg/TableViewDelayedDelegateBug

Speziell diese Datei: https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

Wenn Zeile 24 aktiv ist,

[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];

Oben gibt es einen zusätzlichen 35 px Platz. Wenn Zeile 27 aktiv und 24 auskommentiert ist,

self.tableView.delegate = self;

kein Platz an der Spitze. Es ist so, als ob TableView ein Ergebnis irgendwo zwischenspeichert und sich nicht neu zeichnet, nachdem der Delegat gesetzt ist und reloadData aufgerufen wird.


Swift: iOS Ich hatte Tabellenansicht in der Bildlaufansicht .. als ich auf dem gleichen Bildschirm auf "Zurück" geklickt habe. Scroll-View nehmen mehr Platz an der Spitze .. um das zu lösen habe ich verwendet:

 self.automaticallyAdjustsScrollViewInsets = false

Ein boolescher Wert, der angibt, ob der Ansichtscontroller seine Bildlaufeinfügungen automatisch anpassen soll. Der Standardwert ist true, mit dem der Ansichtscontroller seine Bildlaufeinfügungen als Reaktion auf die von der Statusleiste, Navigationsleiste und Symbolleiste oder Registerleiste belegten Bildschirmbereiche anpassen kann. Setzen Sie den Wert auf "false", wenn Sie die Bildlaufversatzanpassungen selbst verwalten möchten, z. B. wenn in der Ansichtshierarchie mehrere Bildlaufansichten vorhanden sind.


So kann es leicht in iOS 11 und Xcode 9.1 über Storyboard behoben werden:

Wählen Sie Tabellenansicht> Größeninspektor> Inhaltseinfügungen: Nie


Deaktivieren Sie "Scroll View-Insert anpassen"


Inspiriert von @ marchinrams einziger Zielidee, ist dies die Lösung, die ich mir schließlich ausgedacht habe. Zwei Storyboards, eins für Federbeine und eins für Autolayout. In der Zielzusammenfassung habe ich das automatische Layout-Storyboard als Standard festgelegt. Dann überprüfe ich in der AppDelegate, ob ich das Storyboard für Stunts und Springs aus der Zeit vor 6.0 laden muss:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    Class cls = NSClassFromString (@"NSLayoutConstraint");
    if (cls == nil) {
        NSString *mainStoryboardName = nil;
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            mainStoryboardName = @"MainStoryboard_iPad_StrutsAndSprings";
        } else {
            mainStoryboardName = @"MainStoryboard_iPhone_StrutsAndSprings";
        }
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:mainStoryboardName bundle:nil];

        UIViewController *initialViewController = [mainStoryboard instantiateInitialViewController];
        self.window.rootViewController = initialViewController;
        [self.window makeKeyAndVisible];
    }

Außerdem habe ich das Implementierungsziel des Storyboards von Springs und Springs auf iOS 5.1 und das des automatischen Layouts auf Project SDK (iOS 6.0) festgelegt.

Ich wollte wirklich den Schalter tun, bevor der Standard im Storyboard geladen wird, in willFinishLaunchingWithOptions: aber das führt zu einer 'NSInvalidUnarchiveOperationException', Grund: 'Ich konnte die Klasse' NSLayoutConstraint 'nicht instanziieren, egal was ich versuchte.







ios uitableview ios7