2016-04-29 14 views
2

このコードブロックは、問題の中心に到達しようとします。セルをデキューした後(configure経由)、セルの高さが変更されるように制約が変更された場合、壊れた制約の警告(Unable to simultaneously satisfy constraints ...)が発生します。ただし、正しく表示されます。エラーメッセージがあるデキューした後にセルの高さに影響を与える制約を変更すると、UITableViewが壊れた制約で終了する

import UIKit 
class ViewController: UIViewController { 

    @IBOutlet var tableView: UITableView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     tableView.delegate = self 
     tableView.dataSource = self 
     tableView.registerClass(Cell.self, forCellReuseIdentifier: "cell") 
     tableView.estimatedRowHeight = 55.0 
     tableView.rowHeight = UITableViewAutomaticDimension 
    } 

} 

extension ViewController: UITableViewDelegate, UITableViewDataSource { 
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return array.count 
    } 

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! Cell 
     cell.configure(array[indexPath.row]) 
     return cell 
    } 

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    } 
} 

enum Position { 
    case Top 
    case Middle 
    case Bottom 
} 

class Cell: UITableViewCell { 

    private var topConstraint: NSLayoutConstraint! 
    private var bottomConstraint: NSLayoutConstraint! 

    private let label = UILabel() 
    private var previous: Position? 

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

     label.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5) 
     label.textColor = UIColor.blackColor() 
     label.translatesAutoresizingMaskIntoConstraints = false 
     contentView.addSubview(label) 
     label.leadingAnchor.constraintEqualToAnchor(contentView.leadingAnchor, constant: 30).active = true 
     label.trailingAnchor.constraintEqualToAnchor(contentView.trailingAnchor, constant: -30).active = true 
     topConstraint = label.topAnchor.constraintEqualToAnchor(contentView.topAnchor) 
     topConstraint.active = true 
     bottomConstraint = label.bottomAnchor.constraintEqualToAnchor(contentView.bottomAnchor) 
     bottomConstraint.active = true 
    } 

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

    func configure(position: Position) { 
     if previous != nil {print("previous \(previous!) new \(position)")} 
     topConstraint.constant = position == .Top ? 30 : 0 
     bottomConstraint.constant = position == .Bottom ? -30 : 0 
     label.text = String(position) 
     previous = position 
    } 
} 

let array: [Position] = [.Top, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Bottom, 
         .Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom, 
] 

...

2016-04-28 22:56:29.831 test-constraint-change[51059:3776208] Unable to simultaneously satisfy constraints. 
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(
"<NSLayoutConstraint:0x7c117c70 V:|-(30)-[UILabel:0x7c148770'Middle'] (Names: '|':UITableViewCellContentView:0x7c149b70)>", 
"<NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom>", 
"<NSLayoutConstraint:0x7c14a3f0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7c149b70(20.5)]>" 
) 

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom> 

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 
+0

エラーは何ですか?正確なスタックトレースとエラーメッセージを表示してください。 – ozgur

+0

完了しましたが、3つの制約には技術的に問題はありません。当時、彼らはセルの高さを大きくする必要があります(セルの高さは動的です)。セルは「中」から「上」のタイプに成長しています。 –

答えて

12

は、それが正しく表示されます、ちょうど今のように999までのあなたの制約の優先順位を設定します。

+0

あなたの応答をありがとう...私はこれがトリックを行うと確信しています。しかし、少しハッキリと感じる。これを行うためのきれいな方法を探したいと思った。 (私も警告を無視することができます) –

+0

これはあなたの最もクリーンな解決策であり、自動レイアウトの仕組みと関係があります。自動サイジングテーブルセルを使用すると、システムは暗黙的に高さ制約(UIView-Encapsulated-Layout-Height)を追加します。優先順位を設定すると、自動レイアウトでこれらの競合を正常に解決できます。参照してください:https://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift –

+0

これは動的な高さだけに関連していると思いました。我々はまた、幅と全く同じ問題に気づいた(別のシナリオ)。回避策と同じくらい、自動レイアウトのバグのような感じです。どう思いますか? –

関連する問題