菜鸟教程小白 发表于 2022-12-11 18:53:18

iOS 11 : Adapt cell size to content with UITableViewAutomaticDimension


                                            <p><p>我希望 <code>UITableView</code> 的单元格能够适应其内容的大小<strong><em>在 iOS 10 和 11</em></strong> 中:</p>

<pre><code>tableView.estimatedRowHeight = UITableViewAutomaticDimension // default in iOS 11
tableView.rowHeight = UITableViewAutomaticDimension
</code></pre>

<p>没有将 <code>tableView.rowHeight</code> 设置为显式数值,这是 iOS 11 中的新默认值。</p>

<p><code>UIView</code> 没有内在的内容大小,因此我为其高度 anchor 设置了布局约束。但是,该 anchor 在运行时会中断。</p>

<p><code>UITableViewCell</code> 中的哪些内部约束是单元格适应其内容所必需的?</p>

<hr/>

<p>这仅适用于 <strong>iOS 11</strong>:</p>

<pre><code>class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    override func viewDidLoad() {
      super.viewDidLoad()

      let tableView = UITableView()
      tableView.register(UITableViewCell.self, forCellReuseIdentifier: &#34;cell&#34;)
      tableView.estimatedRowHeight = UITableViewAutomaticDimension
      tableView.rowHeight = UITableViewAutomaticDimension
      tableView.delegate = self
      tableView.dataSource = self
      tableView.translatesAutoresizingMaskIntoConstraints = false
      view.addSubview(tableView)

      NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
            tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
            ])
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {

      let cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: &#34;cell&#34;)

      let view = UIView()
      view.backgroundColor = .blue
      view.translatesAutoresizingMaskIntoConstraints = false
      cell.contentView.addSubview(view)

      NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
            view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
            view.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor),
            view.rightAnchor.constraint(equalTo: cell.contentView.rightAnchor),
            view.heightAnchor.constraint(equalToConstant: 300)
            ])

      return cell
    }

    func numberOfSections(in tableView: UITableView) -&gt; Int {
      return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return 1
    }
}
</code></pre>

<p>在 <strong>iOS 10</strong> 中会引发此运行时错误,并且单元格大小不适应:</p>

<blockquote>
<p> Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one
you don&#39;t want.   Try this:       (1) look at each constraint and try to
figure out which you don&#39;t expect;      (2) find the code that added the
unwanted constraint or constraints and fix it.(
      &#34;NSLayoutConstraint:0x17009c020 V:|-(0)-   (active, names: &#39;|&#39;:UITableViewCellContentView:0x11dd15220 )&#34;,
      &#34;NSLayoutConstraint:0x17009c160 test.MyView:0x11dd1acb0.bottom == UITableViewCellContentView:0x11dd15220.bottom   (active)&#34;,
      &#34;NSLayoutConstraint:0x17009c390 test.MyView:0x11dd1acb0.height == 300   (active)&#34;,
      &#34;NSLayoutConstraint:0x17009be40 &#39;UIView-Encapsulated-Layout-Height&#39;
UITableViewCellContentView:0x11dd15220.height == 43.6667   (active)&#34;
)</p>

<p>Will attempt to recover by breaking constraint
NSLayoutConstraint:0x17009c390 test.MyView:0x11dd1acb0.height == 300
(active)</p>

<p>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.</p>
</blockquote>

<hr/>

<p>这适用于 <strong>iOS 10 和 11</strong>,但不使用新的 iOS 11 方法,因为 <code>tableView.estimatedRowHeight</code> 不是 <code>UITableViewAutomaticDimension</code>:</p>

<pre><code>class ViewController_TableView: UIViewController, UITableViewDataSource, UITableViewDelegate {

    override func viewDidLoad() {
      super.viewDidLoad()

      let tableView = UITableView()
      tableView.register(UITableViewCell.self, forCellReuseIdentifier: &#34;cell&#34;)
      tableView.estimatedRowHeight = 30
      tableView.rowHeight = UITableViewAutomaticDimension
      tableView.delegate = self
      tableView.dataSource = self
      tableView.translatesAutoresizingMaskIntoConstraints = false
      view.addSubview(tableView)

      NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
            tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
            ])
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {

      let cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: &#34;cell&#34;)

      let view = MyView()
      view.backgroundColor = .blue
      view.translatesAutoresizingMaskIntoConstraints = false
      cell.contentView.addSubview(view)

      NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
            view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
            view.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor),
            view.rightAnchor.constraint(equalTo: cell.contentView.rightAnchor)
            ])

      return cell
    }

    func numberOfSections(in tableView: UITableView) -&gt; Int {
      return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return 1
    }
}

class MyView: UIView {

    override var intrinsicContentSize: CGSize {
      get {
            return CGSize(width: 300, height: 300)
      }
    }
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您没有使委托(delegate)符合您的 Controller 。然后使用代码</p>

<pre><code>class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let params : = [&#34;q&#34;: &#34;dd&#34;, &#34;format&#34;: &#34;json&#34;, &#34;pretty&#34;: 1,&#34;no_html&#34;: 1, &#34;skip_disambig&#34;: 1]
    Alamofire.request(&#34;https://api.duckduckgo.com&#34;, method: .get, parameters: params).responseJSON { (responseData) in
      print(responseData)
    }

    let tableView = UITableView()
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: &#34;cell&#34;)
    tableView.estimatedRowHeight = 40
    tableView.delegate = self
    tableView.dataSource = self
    tableView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(tableView)

    NSLayoutConstraint.activate([
      tableView.topAnchor.constraint(equalTo: view.topAnchor),
      tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
      tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
      tableView.rightAnchor.constraint(equalTo: view.rightAnchor)
      ])

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {

    let cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: &#34;cell&#34;)

    let view = UIView()
    view.backgroundColor = .blue
    view.translatesAutoresizingMaskIntoConstraints = false
    cell.contentView.addSubview(view)

    NSLayoutConstraint.activate([
      view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
      view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
      view.leftAnchor.constraint(equalTo: cell.contentView.leftAnchor),
      view.rightAnchor.constraint(equalTo: cell.contentView.rightAnchor),
      view.heightAnchor.constraint(equalToConstant: 300) // this breaks on run time
      ])

    return cell
}

func numberOfSections(in tableView: UITableView) -&gt; Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
    return 1
}
// use this delegate
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat {
    return UITableViewAutomaticDimension
}


}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于iOS 11 : Adapt cell size to content with UITableViewAutomaticDimension,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/46542029/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/46542029/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS 11 : Adapt cell size to content with UITableViewAutomaticDimension