Runtime Height
ykorshev opened this issue · 4 comments
ykorshev commented
Hi everyone.
I added few subviews to TGLinearLayout. How can I get total calculated height of all layout? For using in UITableView
youngsoft commented
- If you use TGLinearLayout to the UITableView's tableHeaderView and want to get runtime height, you can coding like below:
let tableHeaderViewLayout = TGLinearLayout(.vert)
tableHeaderViewLayout.tg_padding = UIEdgeInsetsMake(10, 10, 10, 10)
//frame's width must be exact and height can be zero。
tableHeaderViewLayout.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: 0)
tableHeaderViewLayout.tg_width.equal(.fill)
tableHeaderViewLayout.tg_height.equal(.wrap) //height is wrap
let label1 = UILabel()
label1.text = NSLocalizedString("add tableHeaderView(please touch me)", comment: "")
label1.tg_centerX.equal(0)
label1.sizeToFit()
tableHeaderViewLayout.addSubview(label1)
let label2 = UILabel()
label2.text = NSLocalizedString(" if you use layout view to realize the dynamic height tableHeaderView, please use frame to set view's width and use wrapContentHeight to set view's height. the layoutIfNeeded method is needed to call before the layout view assignment to the UITableview's tableHeaderView.", comment: "")
label2.tg_leading.equal(5)
label2.tg_trailing.equal(5)
label2.tg_height.equal(.wrap)
label2.tg_top.equal(10)
tableHeaderViewLayout.addSubview(label2)
//Because tableHeaderViewLayout's height is wrap, so you must call layoutIfNeeded before to set to the tableView.tableHeaderView. layoutIfNeeded may calculate the TGLinearLayout's runtime frame.
tableHeaderViewLayout.layoutIfNeeded()
self.tableView.tableHeaderView = tableHeaderViewLayout
- If you use TGLinearLayout to the UITableViewCell and want to get runtime height, you can coding like below:
step 1: set the tableview's estimatedRowHeight and rowHeight
in the viewDidLoad
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableViewAutomaticDimension
step2: derive a class from UITableViewCell, and override init like below:
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.rootLayout = TGLinearLayout(.horz)
self.rootLayout.tg_width.equal(.fill)
self.rootLayout.tg_height.equal(.wrap) //set rooLayout' height is wrap
self.rootLayout.tg_cacheEstimatedRect = true //cache will improve performance.
self.contentView.addSubview(self.rootLayout)
// you can add any subviews to the self.rootLayout
}
step3: override the UITableViewCell's systemLayoutSizeFitting
:
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize
{
return self.rootLayout.sizeThatFits(targetSize)
}
then the UITableViewCell'height will be auto calculated!!
My English is poor, file: AllTest1ViewController.swift and AllTest1TableViewCell.swift are detailed introduction how to use TGLayout with UITableView.
SimonHolmeslm commented
nice shot
ykorshev commented
Here is the code:
Table view:
self.tableView.register(NotificationCell.self, forCellReuseIdentifier: "notification");
self.tableView.separatorStyle = .none;
let bgImageView = UIImageView(image: #imageLiteral(resourceName: "innerbg"));
bgImageView.contentMode = .scaleAspectFill
self.tableView.backgroundView = bgImageView;
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.numberOfSectionsIn {
return 1;
}
self.tableView.numberOfRows { section in
return self.notifications.count;
}
/*self.tableView.heightForRowAt { indexPath in
return self.configureHeight(for: indexPath);
}*/
self.tableView.cellForRow{ indexPath in
return self.configureCell(for: indexPath);
}
Cell:
https://pastebin.com/pX4bsUZz
Please help me. What I am doing wrong?
youngsoft commented
- First: in your
initView
method, if your root layout usetg_horzMargin(16)
means that the root layout's real width equal to self.contentView.frame.width - 32. It will conflict withtg_width.equal(.fill)
. The same if your root layout usetg_vertMargin(8) means that the root layout's height equal to self.contentView.frame.height - 8. It will conflict with
tg_height.equal(.wrap)`。 Because your cell's height will dynamic height。So you can change to :
func initViews(){
.....
let root = TGLinearLayout(.horz);
// root.tg_width.equal(.fill)
root.tg_height.equal(.wrap)
root.tg_horzMargin(16.0);
// root.tg_vertMargin(8.0);
root.tg_top.equal(8.0); //use tg_top instead to tg_horzMargin set the top margin.
.....
- Second: You must change
systemLayoutSizeFitting
as below:
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize
{
var targetSize2 = targetSize
//Because you root layout's real width is self.contentView.frame.width - 32, so you must sub 32.
targetSize2.width -= 32;
var size = self.root!.sizeThatFits(targetSize2)
size.height += 16 //The size is root layout's size not cell's size, so height must add 2*8 = 16。(top and bottom margin are 8)
return size;
}