Разверните tableview и увеличьте размер содержимого scrollview соответствующей разницей при нажатии кнопки внутри ячейки таблицы

У меня есть UITableView, который был добавлен в UIScrollView как часть контроллера представления, который придерживается части макета, показанного ниже: -

Часть макета

Как вы можете видеть на макете, UITableView расположен между меткой «Популярные предприятия» и представлением, содержащим подвиды зеленого и розового цветов.

Кроме того, если вы заметили, каждая ячейка в представлении таблицы имеет кнопку, которая при нажатии переключает представление карты, содержащее список деталей. Высота вида карты варьируется в зависимости от количества деталей.

Я могу расширять и сжимать ячейку, чтобы отобразить представление карты, которое является частью ячейки представления таблицы, как показано на макете.

Проблема заключается в расширении и сжатии родительского табличного представления таким образом, чтобы были видны все ячейки в этом табличном представлении (предполагается, что табличное представление не должно быть прокручиваемым, и ни одна из ячеек не должна быть скрыта) и что прокручивается только просмотр прокрутки.

Вот мой код для ячейки представления таблицы, который включает расширение ячейки, а также изменение размеров (высоты) таблицы и размера содержимого представления прокрутки: -

func toggleBusinessesTable() {
    var businessTableHeight = self.parent!.businessTable.frame.height
    if self.parent!.indexOfCellToExpand > -1 {
        self.parent!.businessTable.snp.remakeConstraints { (make) in
            make.top.equalTo(self.parent!.featuredBusinessesHeading.snp.bottom).offset(3.5)
            make.left.equalTo(self.parent!.scroll.snp.left)
            make.width.equalTo(self.parent!.view.bounds.width)
            make.height.equalTo(CGFloat(businessTableHeight) + CGFloat(self.tableHeight))
        }
        self.parent!.scroll.layoutIfNeeded()
        self.parent!.scroll.contentSize.height = self.parent!.usersCollectionView.frame.maxY + 75
    }
    else if self.parent!.indexOfCellToExpand == -1 {
        self.parent!.businessTable.snp.remakeConstraints { (make) in
            make.top.equalTo(self.parent!.featuredBusinessesHeading.snp.bottom).offset(3.5)
            make.left.equalTo(self.parent!.scroll.snp.left)
            make.width.equalTo(self.parent!.view.bounds.width)
            make.height.equalTo(CGFloat(businessTableHeight) - CGFloat(self.tableHeight))
        }
        self.parent!.scroll.layoutIfNeeded()
        self.parent!.scroll.contentSize.height = self.parent!.usersCollectionView.frame.maxY + 75
    }
}

func expandCell(_ sender: UI.Button) {
    if self.parent!.indexOfCellToExpand != self.tag {
        print("EXPANDING...")
        self.parent!.indexOfCellToExpand = self.tag
        self.parent!.businessTable.reloadRows(at: [IndexPath(row: self.tag, section: 0)], with: .fade)
        self.parent!.businessTable.scrollToRow(at: IndexPath(row: self.tag, section: 0), at: .top, animated: true)
    }
    else if self.parent!.indexOfCellToExpand == self.tag {
        print("CONTRACTING...")
        self.parent!.indexOfCellToExpand = -1
        self.parent!.businessTable.reloadRows(at: [IndexPath(row: self.tag, section: 0)], with: .fade)
        self.parent!.businessTable.scrollToRow(at: IndexPath(row: self.tag, section: 0), at: .top, animated: true)
    }
    //        self.toggleBusinessesTable()
}

parent - это контроллер представления, который имеет представление прокрутки и представление таблицы.

businessTable - это UITableView - это рассматриваемая таблица, а scroll - это UIScrollView, который содержит представление таблицы

Я использую тег ячейки табличного представления, чтобы отслеживать indexPath

В приведенном ниже коде рассчитывается разница, на которую должна расширяться ячейка представления таблицы: -

    // tableHeight is initially 0 at the beginning
    if self.business_service_charges.count <= 4 {
        for each in self.business_service_charges {
            self.tableHeight += 80 + each.sub_service_charges.count*80
        }
    } else if self.business_service_charges.count > 4 {
        for each in self.business_service_charges[0...3] {
            self.tableHeight += 80 + each.sub_service_charges.count*80
        }
    }

переменная tableHeight ячейки табличного представления используется для вычисления того, насколько табличное представление должно расширяться / сжиматься.

Но при выполнении self.toggleBusinessesTable() табличное представление расширяется больше, чем должно расширяться, добавляя лишний интервал между нижним представлением и табличным представлением, а при сокращении табличное представление становится меньше, скрывая другие ячейки, что делает табличное представление прокручиваемым.

Подпрограмма UITableView для размера: -

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.row == indexOfCellToExpand {
        var tableHeight = 0
        if self.featuredBusinesses[indexPath.row].businessServiceCharges.count <= 4 {
            for each in self.featuredBusinesses[indexPath.row].businessServiceCharges {
                tableHeight += 80 + each.sub_service_charges.count*80
            }
        } else if self.featuredBusinesses[indexPath.row].businessServiceCharges.count > 4 {
            for each in self.featuredBusinesses[indexPath.row].businessServiceCharges[0...3] {
                tableHeight += 80 + each.sub_service_charges.count*80
            }
        }
        return CGFloat(250 + tableHeight)
    }
    return 250
}

indexOfCellToExpand - это переменная, которая отслеживает расширенную ячейку табличного представления.

Короче говоря, есть ли способ развернуть и свернуть представление таблицы и соответствующим образом изменить размер содержимого представления прокрутки, чтобы получить желаемый эффект в качестве макета?

Любая помощь будет принята с благодарностью.

Кроме того, я использовал snapkit для настройки макета ячейки


person Pavan Vasan    schedule 21.06.2019    source источник
comment
Почему вы даже добавили scrollView (tableView) в другой scrollView?   -  person PGDev    schedule 21.06.2019
comment
@PGDev Количество компаний, которые мне нужно показать, может варьироваться. Мне нужно было табличное представление, чтобы справиться с этим. Если есть лучшие способы получить пользовательский интерфейс, как показано в макетах, поделитесь ими.   -  person Pavan Vasan    schedule 21.06.2019
comment
@PGDev Это лишь часть макета, который я только что показал. Над и под показанным макетом есть еще много видов.   -  person Pavan Vasan    schedule 21.06.2019


Ответы (2)


Вместо вычисления высоты и изменения .contentSize вида прокрутки вы можете использовать автоматическую компоновку с подклассом UITableView, который определяет свою собственную высоту:

final class ContentSizedTableView: UITableView {

    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }

}

При изменении представления таблицы - добавлении / удалении строк или разделов или изменении высоты строк - intrinsicContentSize представления таблицы будет автоматически обновляться, а его высота будет увеличиваться или уменьшаться, как многострочный UILabel.

При правильной настройке ограничений автоматический макет будет обрабатывать размер содержимого прокрутки за вас.

person DonMag    schedule 21.06.2019

Попробуй это

func expandCell(_ sender: UI.Button) {
    if self.parent!.indexOfCellToExpand != self.tag {
        print("EXPANDING...")
        self.parent!.indexOfCellToExpand = self.tag
        self.parent!.businessTable.reloadRows(at: [IndexPath(row: self.tag, section: 0)], with: .fade)
        self.parent!.businessTable.scrollToRow(at: IndexPath(row: self.tag, section: 0), at: .top, animated: true)
    }
    else if self.parent!.indexOfCellToExpand == self.tag {
        print("CONTRACTING...")
        self.parent!.indexOfCellToExpand = -1
        self.parent!.businessTable.reloadRows(at: [IndexPath(row: self.tag, section: 0)], with: .fade)
        self.parent!.businessTable.scrollToRow(at: IndexPath(row: self.tag, section: 0), at: .top, animated: true)
    }
    //        self.toggleBusinessesTable()
    yourTableView.reloadData()
}
person steveSarsawa    schedule 21.06.2019