TableView Automatic Dimension Tableview Inside Tableview
Asked Answered
L

4

6

I have Tableview for showing food orders placed by clients. which contains Horizontal UIStackview. In UIStackView

In UIStackview There is few one / two lined label and one UITableView which is used to show orderItems. Inner tableview has fixed height constant (greater then or equal + 750 Priority) and will be changed with content size. height and scrolling disabled.

inner tableview has two labels. and heigh is automatic Dimension

I want main tableview cell height should be increased automatically as per inner tableview items. so I apply to main tableview

    self.tblOrders.rowHeight = UITableViewAutomaticDimension
    self.tblOrders.estimatedRowHeight = 45

and In tableview cell subclass

override func awakeFromNib() {
    super.awakeFromNib()
    self.tblOrderMaster.dataSource = self
    self.tblOrderMaster.delegate = self

    self.tblOrderMaster.estimatedRowHeight = 45
    self.tblOrderMaster.rowHeight = UITableViewAutomaticDimension
    self.selectionStyle = .none
    self.layoutIfNeeded()

    self.tblOrderMaster.isScrollEnabled = false

}

Inner tableview datasource array

var orderData:[ODOrderDataMaster] = [] {
        didSet {
            self.tblOrderMaster.reloadData()
            self.layoutIfNeeded()
            self.const_Height_tblOrderMaster.constant = self.tblOrderMaster.contentSize.height
            self.layoutIfNeeded()

        }
    }

Question: When I scroll main tableview it is not correctly resized as per subitems.while initially it is showing correct.

I have almost tried everything like layoutIfNeeded. layoutSubviews. setNeedsDisplay.

I have also implemented willDisplayCell but not success.

I think issue is when I reload inner tableview. and when it is finished reload how can i inform to main tableview and how can i update height constant of inner tableview

Please let me know if anyone need more info.

I appreciate any help or suggestion

Limoges answered 30/12, 2017 at 7:35 Comment(5)
You said height of inner tableView is static and in code it's dynamicStepfather
Nope !! @Sh_Khan Everything is dynamic. Inner tabelview data is not staticLimoges
Do you mean inner tableView is initially hidden and when tap say a button in main cell it's shown OR it's shown from the beginningStepfather
@Sh_Khan No tableview is hidden. I have both tableview visible on screen. and when I scroll main tableview then cell height is not increasing exact as per content size of inner tableviewLimoges
Can you create minimal sample project that reproduces the same behavior. it will be a good start to debug the issueHus
L
1

I have tried almost all the possible solutions but each has some problems. So I have found another workaround to fix this It can not be called perfect solution but yes it works for me

In tableview cell, I have added One Hidden Label which is Top : 0 , Bottom : 0 , left : 0 and right : 0

enter image description here

Now

    // This is temp label which help to calulate height to tableview
    if let orderMaster = restObj.orderDataMaster {

        var tempText = ""
        for orderMasterObject in orderMaster {

            tempText += (orderMasterObject.item?.name ?? "") + "\n" + "  "

            if let subItems = orderMasterObject.masterSubitem {

                let result = subItems.reduce("", { (result, subItem) -> String in
                    return result +  (subItem.subitem?.name ?? "") + ","
                })
                tempText += result + "\n" + "  "

            }
            tempText += "\n"
        }
        cell.lblTemp.text = tempText
    }

    self.view.layoutIfNeeded()
    cell.setNeedsLayout()
    cell.delegate = self 

What here done is, Inner tableview's cell has labels which grow as per text. So That temp label has same text (masterSubitem) in my case, in short I have replicated inner tableview cell in that label as we have provided All Four constrains to label so when it will grow our tableview cell will grow along with it.

Hope it is helpful to someone who is facing the same issue If any of you can post another working solution I will happily accept it :)

Limoges answered 20/6, 2018 at 5:15 Comment(0)
S
1

Add these 2 lines before the end of cellForRowAt in main & inner tableViews

  cell.layoutSubviews()

  cell.layoutIfNeeded()

  return cell

Also you may try add layoutSubviews method in main cell subclass and do this

  self.tblOrderMaster.layoutIfNeeded()

and in viewDidLayoutSubviews of controller of the main tableView and do this

  self.tblOrders.layoutIfNeeded()
Stepfather answered 30/12, 2017 at 9:20 Comment(4)
can u comment code inside orderData didSet and test ??Stepfather
It is code to reload inner tableview !! and set content sizeLimoges
you set this array in cellForRowAt in main TableView?Stepfather
try to set fixed height for inner tableView cells as i think there is a problem in dynamic height sync between outer and inner tableviews if other solutions failedStepfather
J
1

Try adding this to the tblOrders :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.contentView.setNeedsLayout()
    cell.contentView.layoutIfNeeded()
}
Jespersen answered 19/6, 2018 at 16:20 Comment(0)
L
1

I have tried almost all the possible solutions but each has some problems. So I have found another workaround to fix this It can not be called perfect solution but yes it works for me

In tableview cell, I have added One Hidden Label which is Top : 0 , Bottom : 0 , left : 0 and right : 0

enter image description here

Now

    // This is temp label which help to calulate height to tableview
    if let orderMaster = restObj.orderDataMaster {

        var tempText = ""
        for orderMasterObject in orderMaster {

            tempText += (orderMasterObject.item?.name ?? "") + "\n" + "  "

            if let subItems = orderMasterObject.masterSubitem {

                let result = subItems.reduce("", { (result, subItem) -> String in
                    return result +  (subItem.subitem?.name ?? "") + ","
                })
                tempText += result + "\n" + "  "

            }
            tempText += "\n"
        }
        cell.lblTemp.text = tempText
    }

    self.view.layoutIfNeeded()
    cell.setNeedsLayout()
    cell.delegate = self 

What here done is, Inner tableview's cell has labels which grow as per text. So That temp label has same text (masterSubitem) in my case, in short I have replicated inner tableview cell in that label as we have provided All Four constrains to label so when it will grow our tableview cell will grow along with it.

Hope it is helpful to someone who is facing the same issue If any of you can post another working solution I will happily accept it :)

Limoges answered 20/6, 2018 at 5:15 Comment(0)
T
1

Why don't you do it based on the rowcount of the inner tableView for example let's say your inner tableview has a rowheight of 30 points than to set the parenttableview rowheight all you have to do is to multiply the rowcount of the child tableview by the rowheight and you will get exactly what you want.

Taligrade answered 25/6, 2018 at 10:57 Comment(2)
None of the answers worked for me except this hack! Thank you so much :)Interpretative
I am glad you found it useful.Taligrade

© 2022 - 2024 — McMap. All rights reserved.