我有一个可展开的
我的目标是:我需要具有标题和单元格的可展开的UITableView。当用户点击标题时,单元格需要使用
额外奖励:如果我可以在用户点击标题时使箭头动画,那就太好了,但我认为这会导致另一个错误,因为我们在同一线程上运行了很多动画(主线程)。
我的问题是,当用户点击标题时,tableView内容插入会更改,并且整个标题都会进入负Y位置。因此,发生了奇怪的动画。(例如,标题看起来像单元格的中心)。但是,在动画完成后,一切看起来都正确。
此外:我设置标题和单元格的高度如下。
在下图中,可以清楚地看到错误。当“Some Data”和“Another City”打开并点击“Some Data”时,会出现动画错误。“Another city”会移到其单元格上方,然后向上移动。应该做的是,“Another city”应该保持在原位,然后在关闭“Some Data”单元格时向上移动。
示例项目:https://github.com/emreond/tableViewLayoutIssue
UITableView
。当用户点击标题时,相关单元格将以动画形式显示(RowAnimation.Fade),然后UITableView
滚动到该标题(扩展标题)。当用户再次点击该标题时,它会折叠。我的目标是:我需要具有标题和单元格的可展开的UITableView。当用户点击标题时,单元格需要使用
RowAnimation.Fade
打开,然后滚动到该标题。额外奖励:如果我可以在用户点击标题时使箭头动画,那就太好了,但我认为这会导致另一个错误,因为我们在同一线程上运行了很多动画(主线程)。
我的问题是,当用户点击标题时,tableView内容插入会更改,并且整个标题都会进入负Y位置。因此,发生了奇怪的动画。(例如,标题看起来像单元格的中心)。但是,在动画完成后,一切看起来都正确。
func toggleSection(header: DistrictTableViewHeader, section: Int) {
self.selectedHeaderIndex = section
self.cities[section].isCollapsed = !self.cities[section].isCollapsed
let contentOffset = self.tableView.contentOffset
self.tableView.reloadSections(IndexSet(integer: section), with: UITableView.RowAnimation.fade)
self.tableView.scrollToRow(at: IndexPath(row: NSNotFound, section: section) /* you can pass NSNotFound to scroll to the top of the section even if that section has 0 rows */, at: UITableView.ScrollPosition.top, animated: true)
}
此外:我设置标题和单元格的高度如下。
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 140
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header: DistrictTableViewHeader = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! DistrictTableViewHeader
//let header = DistrictTableViewHeader()
header.customInit(title: self.cities[section].name, section: section, delegate: self,isColapsed: self.cities[section].isCollapsed,isSelectedHeader: section == selectedHeaderIndex ? true : false)
return header
}
我的自定义headerView类:
protocol ExpandableHeaderViewDelegate {
func toggleSection(header: DistrictTableViewHeader, section: Int)
}
class DistrictTableViewHeader: UITableViewHeaderFooterView {
var delegate: ExpandableHeaderViewDelegate?
var section: Int!
let nameLabel: UILabel = {
let l = UILabel()
l.textColor = Color.DistrictsPage.headerTextColor
return l
}()
private let arrowImage: UIImageView = {
let i = UIImageView()
let image = UIImage(named: "ileri")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
i.image = image
i.contentMode = .scaleAspectFit
return i
}()
var willAnimate: Bool = false
var isColapsed: Bool!{
didSet{
expandCollapseHeader()
}
}
private func expandCollapseHeader(){
if(willAnimate){
if(!self.isColapsed){
let degrees : Double = 90 //the value in degrees
self.nameLabel.textColor = Color.Common.garantiLightGreen
self.arrowImage.tintColor = Color.Common.garantiLightGreen
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
}else{
let degrees : Double = 0 //the value in degrees
self.nameLabel.textColor = Color.DistrictsPage.headerTextColor
self.arrowImage.tintColor = UIColor.black
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor.white
}
}else{
if(!isColapsed){
let degrees : Double = 90 //the value in degrees
self.nameLabel.textColor = Color.Common.garantiLightGreen
self.arrowImage.tintColor = Color.Common.garantiLightGreen
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor(red:0.97, green:0.97, blue:0.97, alpha:1.0)
}else{
let degrees : Double = 0 //the value in degrees
self.nameLabel.textColor = Color.DistrictsPage.headerTextColor
self.arrowImage.tintColor = UIColor.black
self.arrowImage.transform = CGAffineTransform.init(rotationAngle: CGFloat(degrees * .pi/180))
self.contentView.backgroundColor = UIColor.white
}
layoutSubviews()
}
}
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(selectHeaderAction)))
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.font = UIFont.systemFont(ofSize: 22)
nameLabel.textColor = Color.DistrictsPage.headerTextColor
contentView.addSubview(nameLabel)
nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
nameLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 15).isActive = true
arrowImage.tintColor = UIColor(red:0.32, green:0.36, blue:0.36, alpha:1.0)
arrowImage.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(arrowImage)
arrowImage.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
arrowImage.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -20).isActive = true
arrowImage.widthAnchor.constraint(equalToConstant: 20).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func rotate(_ toValue: CGFloat) {
self.transform = CGAffineTransform.init(rotationAngle: toValue)
}
@objc func selectHeaderAction(gestureRecognizer: UITapGestureRecognizer) {
let cell = gestureRecognizer.view as! DistrictTableViewHeader
delegate?.toggleSection(header: self, section: cell.section)
}
func customInit(title: String, section: Int, delegate: ExpandableHeaderViewDelegate,isColapsed: Bool, isSelectedHeader: Bool) {
self.nameLabel.text = title
self.nameLabel.accessibilityIdentifier = title
self.section = section
self.delegate = delegate
self.willAnimate = isSelectedHeader
self.isColapsed = isColapsed
}
override func layoutSubviews() {
super.layoutSubviews()
self.contentView.backgroundColor = UIColor.white
}
}
在下图中,可以清楚地看到错误。当“Some Data”和“Another City”打开并点击“Some Data”时,会出现动画错误。“Another city”会移到其单元格上方,然后向上移动。应该做的是,“Another city”应该保持在原位,然后在关闭“Some Data”单元格时向上移动。
![enter image description here](https://istack.dev59.com/ZiRMr.webp)