我正在创建一个应用程序,它将在UILabel中有一个问题,并在UITableView中显示多项选择的答案,每行显示多项选择。问题和答案会有所不同,所以我需要这个UITableView的高度是动态的。
我想为桌子周围找一个合适的尺寸。其中,表的框架被设置为所有内容的高度。
有人能给我一些建议吗?
我正在创建一个应用程序,它将在UILabel中有一个问题,并在UITableView中显示多项选择的答案,每行显示多项选择。问题和答案会有所不同,所以我需要这个UITableView的高度是动态的。
我想为桌子周围找一个合适的尺寸。其中,表的框架被设置为所有内容的高度。
有人能给我一些建议吗?
当前回答
您可以尝试这个自定义AGTableView
使用故事板或编程方式设置TableView高度约束。(这个类自动获取一个高度约束,并将内容视图高度设置为你的tableview高度)。
class AGTableView: UITableView {
fileprivate var heightConstraint: NSLayoutConstraint!
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame: frame, style: style)
self.associateConstraints()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.associateConstraints()
}
override open func layoutSubviews() {
super.layoutSubviews()
if self.heightConstraint != nil {
self.heightConstraint.constant = self.contentSize.height
}
else{
self.sizeToFit()
print("Set a heightConstraint to Resizing UITableView to fit content")
}
}
func associateConstraints() {
// iterate through height constraints and identify
for constraint: NSLayoutConstraint in constraints {
if constraint.firstAttribute == .height {
if constraint.relation == .equal {
heightConstraint = constraint
}
}
}
}
}
注意:如果设置高度有任何问题,请使用yourTableView.layoutSubviews()。
其他回答
我在滚动视图中有一个表格视图,必须计算tableView的高度并相应地调整它的大小。这些是我已经采取的步骤:
0)添加一个UIView到你的scrollView(可能会工作没有这一步,但我这样做是为了避免任何可能的冲突)-这将是一个容器视图为您的表视图。如果你采取了这一步,然后将视图的边界设置为tableview的边界。
1)创建UITableView的子类:
class IntrinsicTableView: UITableView {
override var contentSize:CGSize {
didSet {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
self.layoutIfNeeded()
return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
}
}
2)在Storyboard中设置一个表视图的类为IntrinsicTableView:截图:http://joxi.ru/a2XEENpsyBWq0A
3)设置heightConstraint到你的表视图
4)拖动你的表的IBoutlet到你的ViewController
5)拖动你的表高度约束的IBoutlet到你的ViewController
6)将这个方法添加到你的ViewController中:
override func viewWillLayoutSubviews() {
super.updateViewConstraints()
self.yourTableViewsHeightConstraint?.constant = self.yourTableView.intrinsicContentSize.height
}
希望这能有所帮助
作为Anooj VM回答的扩展,我建议仅在内容大小发生变化时才刷新。
这种方法还适当地禁用滚动,并支持更大的列表和旋转。不需要dispatch_async,因为contentSize的更改是在主线程上分派的。
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:NULL];
}
- (void)resizeTableAccordingToContentSize:(CGSize)newContentSize {
CGRect superviewTableFrame = self.tableView.superview.bounds;
CGRect tableFrame = self.tableView.frame;
BOOL shouldScroll = newContentSize.height > superviewTableFrame.size.height;
tableFrame.size = shouldScroll ? superviewTableFrame.size : newContentSize;
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
self.tableView.frame = tableFrame;
} completion: nil];
self.tableView.scrollEnabled = shouldScroll;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([change[NSKeyValueChangeKindKey] unsignedIntValue] == NSKeyValueChangeSetting &&
[keyPath isEqualToString:@"contentSize"] &&
!CGSizeEqualToSize([change[NSKeyValueChangeOldKey] CGSizeValue], [change[NSKeyValueChangeNewKey] CGSizeValue])) {
[self resizeTableAccordingToContentSize:[change[NSKeyValueChangeNewKey] CGSizeValue]];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[self resizeTableAccordingToContentSize:self.tableView.contentSize]; }
- (void)dealloc {
[self.tableView removeObserver:self forKeyPath:@"contentSize"];
}
Swift 5解决方案
遵循以下四个步骤:
从故事板中为tableview设置高度约束。 从故事板中拖动高度约束,并在视图控制器文件中为它创建@IBOutlet。 @IBOutlet var tableViewHeightConstraint: NSLayoutConstraint! 在覆盖函数viewDidLoad()上为contentSize属性添加一个观察者
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
}
Then you can change the height for the table dynamicaly using this code: override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if(keyPath == "contentSize"){ if let newvalue = change?[.newKey] { DispatchQueue.main.async { let newsize = newvalue as! CGSize self.tableViewHeightConstraint.constant = newsize.height } } } }
在swift 3中解决这个问题的方法:在viewDidAppear中调用这个方法
func UITableView_Auto_Height(_ t : UITableView)
{
var frame: CGRect = t.frame;
frame.size.height = t.contentSize.height;
t.frame = frame;
}
快速解决方案
遵循以下步骤:
从故事板中为表设置高度约束。 从故事板中拖动高度约束,并在视图控制器文件中为它创建@IBOutlet。 @IBOutlet var tableHeight: NSLayoutConstraint! 然后你可以使用下面的代码动态地改变表的高度: override func viewWillLayoutSubviews() { super.updateViewConstraints () self.tableHeight ?。常量= self.table.contentSize.height }
如果最后一行被切断,尝试在willDisplay单元格函数中调用viewWillLayoutSubviews():
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.viewWillLayoutSubviews()
}