[英]How to trigger UIImageView animation in a UITableViewHeaderFooterView when pressing on a tableView section?
I want to create an expandable/collapsable tableView
cells behaviour with a custom header view from xib using UITableViewHeaderFooterView
.我想使用UITableViewHeaderFooterView
使用来自 xib 的自定义 header 视图创建可扩展/可折叠的tableView
单元格行为。
I have the following CustomHeaderView
xib
setup: UILabel, UIButton (to press on the header and trigger expandable/collapsable behaviour and chevron as UIImageView
to represent a current section state: I have the following CustomHeaderView
xib
setup: UILabel, UIButton (to press on the header and trigger expandable/collapsable behaviour and chevron as UIImageView
to represent a current section state:
Here is how a CustomHeaderView
class looks.这是CustomHeaderView
class 的外观。 It has some outlets, method for rotating the chevron
and simple protocol
to tell my ViewController
that certain section
was tapped (button's tag == section)它有一些出口、旋转chevron
的方法和简单的protocol
来告诉我的ViewController
某个section
被点击(按钮的标签 == 部分)
import UIKit
protocol HeaderViewDelegate: AnyObject {
func expandedSection(button: UIButton)
}
class CustomHeaderView: UITableViewHeaderFooterView {
weak var delegate: HeaderViewDelegate?
@IBOutlet weak var lable: UILabel!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var headerButton: UIButton!
func configure(title: String, section: Int) {
lable.text = title
headerButton.tag = section
}
func rotateImage(_ expanded: Bool) {
if expanded {
UIView.animate(withDuration: 0.3) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi / 2)
}
} else {
UIView.animate(withDuration: 0.3) {
self.imageView.transform = .identity
}
}
}
@IBAction func tapHeader(_ sender: UIButton) {
delegate?.expandedSection(button: sender)
}
}
Here is how my ViewController looks like:这是我的 ViewController 的样子:
import UIKit
struct ExpandedModel {
var isExpanded: Bool
let title: String
let array: [String]
}
class TableViewController: UITableViewController {
let headerID = String(describing: CustomHeaderView.self)
var arrayOfData = [ExpandedModel]()
override func viewDidLoad() {
super.viewDidLoad()
arrayOfData = [
ExpandedModel(isExpanded: true, title: "Words", array: ["One", "Two", "Three", "Four", "Five"]),
ExpandedModel(isExpanded: true, title: "Numbers", array: ["6", "7", "8", "9", "10"])
]
tableViewConfig()
}
private func tableViewConfig() {
let nib = UINib(nibName: headerID, bundle: nil)
tableView.register(nib, forHeaderFooterViewReuseIdentifier: headerID)
}
override func numberOfSections(in tableView: UITableView) -> Int {
arrayOfData.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !arrayOfData[section].isExpanded {
return 0
} else {
return arrayOfData[section].array.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "dataCell", for: indexPath) as! DataTableViewCell
cell.label.text = arrayOfData[indexPath.section].array[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerID) as! CustomHeaderView
header.configure(title: arrayOfData[section].title, section: section)
header.rotateImage(arrayOfData[section].isExpanded)
header.delegate = self
return header
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return tableView.estimatedSectionHeaderHeight
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return tableView.estimatedSectionFooterHeight
}
}
extension TableViewController: HeaderViewDelegate {
func expandedSection(button: UIButton) {
let section = button.tag
let indexPaths = (0..<(arrayOfData[section].array.count)).map { IndexPath(row: $0, section: section)}
arrayOfData[section].isExpanded.toggle()
if !arrayOfData[section].isExpanded {
tableView.beginUpdates()
tableView.deleteRows(at: indexPaths, with: .fade)
tableView.endUpdates()
} else {
tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .fade)
tableView.endUpdates()
}
}
}
The main goal is ok - I can collapse and expand cells.主要目标是好的 - 我可以折叠和展开单元格。 But the problem is how to animate the chevron
in CustomHeaderView
?但问题是如何为CustomHeaderView
中的chevron
设置动画?
If I'll use a reloading section method, then the chevron
animation will be skipped:如果我将使用重新加载部分方法,则将跳过chevron
animation:
tableView.reloadSections(IndexSet(integer: section), with: .none)
If I will add a delay with DispatchQueue.main.asyncAfter
, it will be animated in, but skipped when out:如果我将使用DispatchQueue.main.asyncAfter
添加延迟,它将被动画化,但在退出时会被跳过:
func rotateImage(_ expanded: Bool) {
if expanded {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
UIView.animate(withDuration: 0.2) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi / 2)
}
}
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
UIView.animate(withDuration: 0.2) {
self.imageView.transform = .identity
}
}
}
}
What is a most sufficient way to achieve a proper chevron
animation?什么是获得适当chevron
animation 的最充分方法?
Using your first block of code, do you get the animation you want if you change your expandedSection(button: UIButton)
func to this:使用你的第一个代码块,如果你改变你的expandedSection(button: UIButton)
函数,你得到你想要的animation:
extension TableViewController: HeaderViewDelegate {
func expandedSection(button: UIButton) {
let section = button.tag
let indexPaths = (0..<(arrayOfData[section].array.count)).map { IndexPath(row: $0, section: section)}
arrayOfData[section].isExpanded.toggle()
// get a reference to the section's header view
if let v = tableView.headerView(forSection: section) as? SomeCustomHeaderView {
v.rotateImage(arrayOfData[section].isExpanded)
}
if !arrayOfData[section].isExpanded {
tableView.beginUpdates()
tableView.deleteRows(at: indexPaths, with: .fade)
tableView.endUpdates()
} else {
tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .fade)
tableView.endUpdates()
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.