我正在创建一个应用程序,它将在UILabel中有一个问题,并在UITableView中显示多项选择的答案,每行显示多项选择。问题和答案会有所不同,所以我需要这个UITableView的高度是动态的。
我想为桌子周围找一个合适的尺寸。其中,表的框架被设置为所有内容的高度。
有人能给我一些建议吗?
我正在创建一个应用程序,它将在UILabel中有一个问题,并在UITableView中显示多项选择的答案,每行显示多项选择。问题和答案会有所不同,所以我需要这个UITableView的高度是动态的。
我想为桌子周围找一个合适的尺寸。其中,表的框架被设置为所有内容的高度。
有人能给我一些建议吗?
当前回答
我的Swift 5实现是将tableView的高度约束设置为其内容的大小(contentSize.height)。此方法假定您正在使用自动布局。这段代码应该放在cellForRowAt tableView方法中。
tableView.heightAnchor.constraint(equalToConstant: tableView.contentSize.height).isActive = true
其他回答
如果你的contentSize是不正确的,这是因为它是基于估计的rowheight(自动),使用这个之前
tableView.estimatedRowHeight = 0;
来源:https://forums.developer.apple.com/thread/81895
基于 fl034的回答
斯威夫特5
var tableViewHeight: NSLayoutConstraint?
tableViewHeight = NSLayoutConstraint(item: servicesTableView,
attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute,
multiplier: 0.0, constant: 10)
tableViewHeight?.isActive = true
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
tableViewHeight?.constant = tableView.contentSize.height
tableView.layoutIfNeeded()
}
在表视图上为contentSize属性添加一个观察者,并相应地调整帧大小
[your_tableview addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];
然后在回调中:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
CGRect frame = your_tableview.frame;
frame.size = your_tableview.contentSize;
your_tableview.frame = frame;
}
希望这对你有所帮助。
我用了一点不同的方式,实际上我的TableView在scrollview内部,所以我必须给高度约束为0。
然后在运行时,我做了以下更改,
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.viewWillLayoutSubviews()
}
override func viewWillLayoutSubviews() {
super.updateViewConstraints()
DispatchQueue.main.async {
self.tableViewHeightConstraint?.constant = self.myTableView.contentSize.height
self.view.layoutIfNeeded()
}
}
基于fl034的答案。但为了萨玛林。iOS用户:
[Register("ContentSizedTableView")]
public class ContentSizedTableView : UITableView
{
public ContentSizedTableView(IntPtr handle) : base(handle)
{
}
public override CGSize ContentSize { get => base.ContentSize; set { base.ContentSize = value; InvalidateIntrinsicContentSize(); } }
public override CGSize IntrinsicContentSize
{
get
{
this.LayoutIfNeeded();
return new CGSize(width: NoIntrinsicMetric, height: ContentSize.Height);
}
}
}