Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITableView当更改约束时,会在退出队列后影响单元格的高度,最终导致约束被破坏_Ios_Swift_Uitableview_Constraints - Fatal编程技术网

Ios UITableView当更改约束时,会在退出队列后影响单元格的高度,最终导致约束被破坏

Ios UITableView当更改约束时,会在退出队列后影响单元格的高度,最终导致约束被破坏,ios,swift,uitableview,constraints,Ios,Swift,Uitableview,Constraints,此代码块试图触及问题的核心。如果在单元出列后(通过配置),约束发生更改,从而单元高度发生更改,则最终会出现一条中断的约束警告(无法同时满足约束…)。但是,它显示正确 import UIKit class ViewController: UIViewController { @IBOutlet var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad()

此代码块试图触及问题的核心。如果在单元出列后(通过
配置
),约束发生更改,从而单元高度发生更改,则最终会出现一条中断的约束警告(
无法同时满足约束
…)。但是,它显示正确

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.
2016-04-28 22:56:29.831测试约束更改[51059:3776208]无法同时满足约束。
可能下面列表中至少有一个约束是您不想要的。
试试这个:
(1) 看看每一个约束,试着找出你不期望的;
(2) 找到添加了不需要的约束的代码,然后修复它。
(
"",
"",
""
)
将尝试通过打破约束进行恢复
在UIViewAlertForUnsatifiableConstraints处创建一个符号断点,以便在调试器中捕获该断点。
中列出的UIView上UIConstraintBasedLayoutDebugging类别中的方法也可能会有所帮助。

将约束的优先级设置为999。与现在一样,它将正确显示。

您得到的错误是什么?请向我们显示确切的堆栈跟踪和错误消息。完成,但这3个约束在技术上没有问题。同时,他们应该强制单元高度变大(单元高度是动态的)。细胞正在从“中间”型向“顶部”型生长。感谢您的回复。。。我相信这会奏效的。但是感觉有点不舒服。想找到一个干净的方法来做这件事。(我也可以忽略警告)这是最干净的解决方案,与自动布局的工作方式有关。使用自动调整表格单元格大小,系统会隐式添加高度约束(
UIView-enclosed-Layout-height
),设置优先级允许自动布局优雅地解决这些冲突。看:好吧,我认为这只与动态高度有关。我们也注意到了宽度的完全相同的问题(不同的场景)。尽管周围的工作很有效,但仍然感觉像是自动布局的bug。你认为呢?它对tableView的开始和结束更新非常有效。
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,
]