代码之家  ›  专栏  ›  技术社区  ›  mackeee

DispatchQueue.main中的自动布局不工作

  •  0
  • mackeee  · 技术社区  · 7 年前

    我有一个关于自动布局的问题。

    background=>我希望在uiTableViewCell中排列uiImageView,使uiImageView异步获取图像,并通过图像的纵横比自动布局动态更改单元格的高度。 其中,uiImageView位于我的自定义uiView的顶部,而uiView又打开了单元格的ContentView。

    自动布局与此代码一起工作良好,没有任何错误。

    private var contentHeightConstraint = NSLayoutConstraint()
    
    // this method called in constructor 
    func setupAutolayout() {
      NSLayoutConstraint.activate([
        messageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
        messageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 16),
        messageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
        messageView.widthAnchor.constraint(equalToConstant: 240),
    
    
        contentImageView.topAnchor.constraint(equalTo: messageView.topAnchor),
        contentImageView.leftAnchor.constraint(equalTo: messageView.leftAnchor),
        contentImageView.rightAnchor.constraint(equalTo: messageView.rightAnchor),
        contentImageView.bottomAnchor.constraint(equalTo: messageView.bottomAnchor)
      ])
    }
    
    // After view loaded, this method called
    func something() {
      contentHeightConstraint = contentImageView.heightAnchor.constraint(equalToConstant: 150)
      contentHeightConstraint.isActive = true
    }
    

    但是,将dispatchqueue.main中的代码用作异步任务(将在主线程中执行)时,autolayout不能很好地工作。
    这导致 [LayoutConstraints] Unable to simultaneously satisfy constraints 错误。

    private var contentHeightConstraint = NSLayoutConstraint()
    
    // this method called in constructor 
    func setupAutolayout() {
      NSLayoutConstraint.activate([
        messageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
        messageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 16),
        messageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
        messageView.widthAnchor.constraint(equalToConstant: 240),
    
    
        contentImageView.topAnchor.constraint(equalTo: messageView.topAnchor),
        contentImageView.leftAnchor.constraint(equalTo: messageView.leftAnchor),
        contentImageView.rightAnchor.constraint(equalTo: messageView.rightAnchor),
        contentImageView.bottomAnchor.constraint(equalTo: messageView.bottomAnchor)
      ])
    }
    
    // After view loaded, this method called
    func something() {
      DispatchQueue.main.async {
        // of course, exec in MainThread
        self.contentHeightConstraint = contentImageView.heightAnchor.constraint(equalToConstant: 150)
        self.contentHeightConstraint.isActive = true
      }
    }
    

    这是错误消息(此错误消息仅在异步运行时出现)。

    2019-03-31 13:10:06.791758+0900 app[42515:4243718] [LayoutConstraints] 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:0x600002a3dbd0 V:|-(8)-[UIView:0x7fe775f3f830]   (active, names: '|':UITableViewCellContentView:0x7fe775f3c210 )>",
        "<NSLayoutConstraint:0x600002a3f1b0 UIView:0x7fe775f3f830.bottom == UITableViewCellContentView:0x7fe775f3c210.bottom - 8   (active)>",
        "<NSLayoutConstraint:0x600002a32a80 V:|-(0)-[UIImageView:0x7fe775f40690]   (active, names: '|':UIView:0x7fe775f3f830 )>",
        "<NSLayoutConstraint:0x600002a32350 UIImageView:0x7fe775f40690.bottom == UIView:0x7fe775f3f830.bottom   (active)>",
        "<NSLayoutConstraint:0x600002a2c190 UIImageView:0x7fe775f40690.height == 150   (active)>",
        "<NSLayoutConstraint:0x600002a2d310 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fe775f3c210.height == 116   (active)>"
    )
    
    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x600002a2c190 UIImageView:0x7fe775f40690.height == 150   (active)>
    


    需要注意的一点是,如果在uiImageView的heigtanchor之后正常添加约束,那么它将按预期工作,但是异步添加约束将不能正常工作。

    附加信息
    *表设置

    table.estimatedRowHeight = 800
    table.rowHeight = UITableView.automaticDimension
    
    0 回复  |  直到 7 年前
        1
  •  1
  •   Santosh Maharjan    7 年前

    你同时使用底部约束和高度吗?如果是这样的话,那就行不通了。

    您可以尝试删除的高度约束 UIImageView 或的底部约束 UIIVIEVIEW UIView .

    注: 不要在后台线程中使用与视图相关的代码。