2016-08-27 51 views
1

我試圖以編程方式創建UITableView(即NO Storyboards/Interface Builder)。我有一個Notices列表(一個簡單的模型,包含標題,作者和一些內容等數據)。我希望這些行能夠垂直動態調整大小(我只爲iOS> = 8.0發佈,所以UITableViewAutomaticDimension是我行的高度)。現在,行應該非常簡單。有三個UILabels。其中每一個都按順序顯示標題,作者和內容之一,並且每個都佈置在另一個之上;然而,我不斷收到警告:「檢測到約束含糊不清地表明零高度的情況」。我理解這意味着我的LayoutConstraints設置不正確;然而,我已經嘗試過所有我能想到的約束組合,而且似乎沒有什麼能解決這個警告!由於AutoLayout,iOS/Swift中的動態行高降爲0

這裏是小區的定義:

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") 
    } 
} 

這裏是的UITableViewController代碼的相關片段:

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 
} 

澄清:一切工作(視圖佈局正確,與約束條件滿足等),除非動態設置高度。清除有一些限制,我錯過了強制contentView擴展到非零高度。請把我的頭髮拉出來之前告訴我那是什麼限制。

謝謝!

回答

0

我有什麼似乎是同樣的問題

如果你宣佈你的高度表視圖小區

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

您需要添加一個預測的高度爲靜態數字,作爲失敗安全。

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

這應該解決錯誤

+0

不幸的是,我不認爲這是問題。查看更新的代碼。 –

1

經常思考這樣的限制。每個視圖都有四個特徵:x位置,y位置,寬度和高度。看看每一個觀點並問問自己:我是否提供足夠的信息來確定這四個的這些功能?如果沒有,你的約束是不夠的。

您的約束條件是嚴重不足。您只注意到高度 - 垂直尺寸。沒有關於橫向維度的信息!這些標籤的左邊緣應該在哪裏(leading邊緣)?你需要爲他們三人提供至少那麼多的信息!

我建議也提供右邊的信息。最簡單的方法是將前沿固定到內容視圖的前沿,將後沿固定到內容視圖的後沿。 (然後可以刪除不等式約束。)

最後,您應該刪除約束item: self.contentViewtoItem: self。電池本身不應有任何限制 - 僅限於其contentView。同樣,刪除表示self.contentView.translatesAutoresizingMaskIntoConstraints = false的行。內容視圖的大小/位置不取決於您,您不應該做任何事情來弄亂它們如何確定。

+0

考慮使用View Debugger來了解您正在運行的應用程序的限制條件。你會驚訝於它能告訴你多少(特別是在Xcode 8中)。 – matt