2016-08-27 3 views
1

Ich versuche ein UITableView programmgesteuert zu erstellen (d. H. KEIN Storyboards/Interface Builder). Ich habe eine Liste mit Hinweisen (ein einfaches Modell, das solche Daten wie Titel, Autor und einige Inhalte enthält). Ich möchte, dass die Zeilen vertikal dynamisch vergrößert werden (ich gebe nur für iOS> = 8.0 frei, so dass UITableViewAutomaticDimension die Höhe für meine Zeilen ist). Für jetzt sollten die Zeilen sehr einfach sein. Es gibt drei UILabels. Jeder von ihnen zeigt einen Titel, einen Autor und einen Inhalt in dieser Reihenfolge an, wobei jedes über dem anderen liegt. Ich erhalte jedoch immer wieder die Warnung: "Es wurde ein Fall entdeckt, in dem Zwänge zweideutig auf eine Höhe von Null hinweisen". Was ich darunter verstehe ist, dass meine LayoutConstraints nicht korrekt eingerichtet sind; Ich habe jedoch jede Kombination von Einschränkungen ausprobiert, die mir einfällt, und nichts scheint diese Warnung zu beheben! HierDynamische Zeilenhöhen in iOS/Swift, die aufgrund von AutoLayout auf 0 reduziert werden

ist die Zelle Definition:

import UIKit 

public class NoticeCellView : UITableViewCell { 
    public static let NOTICE_CELL_REUSE_IDENTIFIER = "noticeCell" 

    private let titleLabel = UILabel() 
    private let authorLabel = UILabel() 
    private let contentLabel = UILabel() 

    public func setNotice(notice: Notice) { 
     titleLabel.text = notice.getTitle() 
     authorLabel.text = notice.getAuthorFullName() 
     contentLabel.text = notice.getContent() 
    } 

    public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 

     self.contentView.translatesAutoresizingMaskIntoConstraints = false 

     titleLabel.translatesAutoresizingMaskIntoConstraints = false 
     self.contentView.addSubview(titleLabel) 

     authorLabel.translatesAutoresizingMaskIntoConstraints = false 
     self.contentView.addSubview(authorLabel) 

     contentLabel.translatesAutoresizingMaskIntoConstraints = false 
     contentLabel.numberOfLines = 0; 
     self.contentView.addSubview(contentLabel) 

     self.addConstraints([ 
      NSLayoutConstraint(
       item: self.contentView, 
       attribute: .Top, 
       relatedBy: .Equal, 
       toItem: titleLabel, 
       attribute: .Top, 
       multiplier: 1, 
       constant: 0 
      ), 
      NSLayoutConstraint(
       item: titleLabel, 
       attribute: .Bottom, 
       relatedBy: .Equal, 
       toItem: authorLabel, 
       attribute: .Top, 
       multiplier: 1, 
       constant: 0 
      ), 

      NSLayoutConstraint(
       item: authorLabel, 
       attribute: .Bottom, 
       relatedBy: .Equal, 
       toItem: contentLabel, 
       attribute: .Top, 
       multiplier: 1, 
       constant: 0 
      ), 
      NSLayoutConstraint(
       item: contentLabel, 
       attribute: .Bottom, 
       relatedBy: .Equal, 
       toItem: self.contentView, 
       attribute: .Bottom, 
       multiplier: 1, 
       constant: 0 
      ), 
      NSLayoutConstraint(
       item: self.contentView, 
       attribute: .Bottom, 
       relatedBy: .Equal, 
       toItem: self, 
       attribute: .Bottom, 
       multiplier: 1, 
       constant: 0 
      ), 

      NSLayoutConstraint(
       item: contentLabel, 
       attribute: .Width, 
       relatedBy: .LessThanOrEqual, 
       toItem: self.contentView, 
       attribute: .Width, 
       multiplier: 1, 
       constant: 0 
      ), 
     ]) 
    } 

    required public init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

Und hier ist der entsprechende Ausschnitt aus dem UITableViewController Code:

public override func viewDidLoad() { 
    super.viewDidLoad() 

    self.tableView.registerClass(NoticeCellView.classForCoder(), forCellReuseIdentifier: NoticeCellView.NOTICE_CELL_REUSE_IDENTIFIER) 

    self.tableView.estimatedRowHeight = 200 
} 

public override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return 1 
} 

public override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return TEST_NOTICES.count 
} 

public override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier(NoticeCellView.NOTICE_CELL_REUSE_IDENTIFIER) as! NoticeCellView 
    cell.setNotice(TEST_NOTICES[indexPath.row]) 
    return cell 
} 

Zur Klarstellung: alles funktioniert (Ansichten richtig angelegt, mit der Einschränkungen erfüllt, usw.), außer für die Höhe, die nicht dynamisch eingestellt wird. Es gibt eine Einschränkung, die ich vermeide, um die contentView auf eine Höhe ungleich Null zu erweitern. Bitte sagen Sie mir, was diese Einschränkung ist, bevor ich meine Haare ausziehe.

Danke !!

Antwort

0

Ich habe, was das gleiche Problem zu sein scheint

Wo Sie Ihre Körpergröße für die Tabellenansicht Zelle erklären als

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 

Sie benötigen eine geschätzte Höhe als statische Zahl hinzuzufügen, wie ein ausfallsicher.

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return 60 // or whatever number you choose 
} 

Dies sollte den Fehler

+0

Leider glaube ich nicht, dass das das Problem ist. Siehe den aktualisierten Code. –

1

Denken Sie immer an Einschränkungen wie diese lösen. Jede Ansicht hat vier Merkmale: ihre x-Position, ihre y-Position, ihre Breite und ihre Höhe. Sehen Sie sich jede Ansicht an und fragen Sie sich: Liefern ich genug Informationen, um alle vier dieser Funktionen zu bestimmen? Wenn nicht, sind Ihre Einschränkungen nicht ausreichend.

Ihre Einschränkungen sind grob unzureichend. Du hast deine Aufmerksamkeit nur auf die Höhe gerichtet - die vertikale Dimension. Es gibt keinerlei Informationen über die horizontale Dimension! Wohin sollte der linke Rand dieser Etiketten gehen (die leading Kante)? Sie müssen mindestens so viele Informationen für alle drei zur Verfügung stellen!

Ich würde vorschlagen, auch Informationen für die richtige Kante bereitzustellen. Der einfachste Weg wäre, die Vorderkanten an die Vorderkante der Inhaltsansicht und die Hinterkanten an die Hinterkante der Inhaltsansicht anzunähern. (Sie können dann Ihre Ungleichheitsbedingung löschen.)

Schließlich sollten Sie die Integritätsbedingung mit item: self.contentView und toItem: self löschen. Es sollte keine Einschränkungen für die Zelle selbst geben - nur für ihre contentView. Löschen Sie auf ähnliche Weise die Zeile self.contentView.translatesAutoresizingMaskIntoConstraints = false. Die Größe/Position der Inhaltsansicht liegt nicht bei Ihnen, und Sie sollten nichts tun, um sich damit zu befassen, wie sie ermittelt werden.

+0

Verwenden Sie den View Debugger, um sich über die Einschränkungen Ihrer laufenden App zu informieren. Sie werden erstaunt sein, wie viel es Ihnen sagen kann (besonders in Xcode 8). – matt

Verwandte Themen