使用 CGAffineTransform 缩放 tableView 单元格以覆盖整个屏幕
Scale tableView cell with CGAffineTransform to cover entire screen
我有一个 tableView,当用户点击该单元格时,我希望该单元格展开并用该颜色填充整个屏幕。目前,它确实会缩放以填满整个屏幕,但它上面的单元格也会显示。颜色来自 API,当用户点击 "Generate" 按钮时,每个单元格都会改变颜色。由于 API 的 JSON 文件的结构,我一次只想在屏幕上显示 5 种颜色。
我不明白为什么它上面的单元格不向上移动,或者如何将单击的单元格移动到屏幕顶部。我已经尝试偏移点击单元格的坐标并将其框架大小更改为 tableView tappedCell.bounds.size = CGSize(width: UIScreen.main.bounds.width, height: self.paletteTableView.bounds.height)
的高度但是当我从顶部单击第一个或第二个单元格时,屏幕不会一直填满至底部。
我也尝试过从 UIView(这里称为 colorDetailsView
)制作动画,但无法成功地让它从被点击的每个单元格的中心制作动画,只能从屏幕。
动画发生在这里:
@objc func userTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.ended {
let tapLocation = sender.location(in: self.paletteTableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
UIView.animate(withDuration: 0.5, animations: {
switch self.currentAnimation {
case 0:
tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)
//...
case 1:
tappedCell.transform = .identity
default: break
}
} )
currentAnimation += 1
if currentAnimation > 1 {
currentAnimation = 0
} } } } }
完整代码:
class PaletteController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
var colorPalette = [Color]()
var currentAnimation = 0
let colorDetailsView: UIView = {
let view = UIView()
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.isScrollEnabled = false
\...
view.addSubview(colorDetailsView)
}
//Color cell expands to fill the screen of that color when user taps on the cell
@objc func userTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.ended {
let tapLocation = sender.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
UIView.animate(withDuration: 0.5, animations: {
//When user taps on a cell, it is scaled to fill the screen with that color
switch self.currentAnimation {
case 0:
tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)
for i in 0..<self.colorPalette.count {
if tapIndexPath.row == i {
self.colorDetailsView.backgroundColor = UIColor(hexString: self.colorPalette[i])
}
}
case 1:
tappedCell.transform = .identity
default: break
}
} )
currentAnimation += 1
if currentAnimation > 1 {
currentAnimation = 0
}
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"ColorCell", for: indexPath)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userTap(sender:)))
cell.addGestureRecognizer(tapGesture)
cell.isUserInteractionEnabled = true
//Assigns a new color to each row. Colors are converted from HEX to RGB
for i in 0..<colorPalette.count {
if tapIndexPath.row == i {
cell.backgroundColor = UIColor(hexString: colorPalette[i])
}
}
return cell
}
}
当我将 tableView.isScrollEnabled
设置为 true 时,我知道单元格正在缩放,如下所示。每个单元格最终应该填满整个屏幕,而不是被任何其他单元格覆盖,比如最上面的单元格。理想情况下,我希望 tableView 不滚动,但我不确定如果禁用滚动,顶部单元格是否会 "move up"。
感谢任何帮助!
这些单元格毕竟是 table 视图的所有子视图。您需要将点击的单元格放在子视图列表的前面。
我建议添加
tableView.bringSubviewToFront(tappedCell)
就在行
之后
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
.
看看这是否有效!
我有一个 tableView,当用户点击该单元格时,我希望该单元格展开并用该颜色填充整个屏幕。目前,它确实会缩放以填满整个屏幕,但它上面的单元格也会显示。颜色来自 API,当用户点击 "Generate" 按钮时,每个单元格都会改变颜色。由于 API 的 JSON 文件的结构,我一次只想在屏幕上显示 5 种颜色。
我不明白为什么它上面的单元格不向上移动,或者如何将单击的单元格移动到屏幕顶部。我已经尝试偏移点击单元格的坐标并将其框架大小更改为 tableView tappedCell.bounds.size = CGSize(width: UIScreen.main.bounds.width, height: self.paletteTableView.bounds.height)
的高度但是当我从顶部单击第一个或第二个单元格时,屏幕不会一直填满至底部。
我也尝试过从 UIView(这里称为 colorDetailsView
)制作动画,但无法成功地让它从被点击的每个单元格的中心制作动画,只能从屏幕。
动画发生在这里:
@objc func userTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.ended {
let tapLocation = sender.location(in: self.paletteTableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
UIView.animate(withDuration: 0.5, animations: {
switch self.currentAnimation {
case 0:
tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)
//...
case 1:
tappedCell.transform = .identity
default: break
}
} )
currentAnimation += 1
if currentAnimation > 1 {
currentAnimation = 0
} } } } }
完整代码:
class PaletteController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
var colorPalette = [Color]()
var currentAnimation = 0
let colorDetailsView: UIView = {
let view = UIView()
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.isScrollEnabled = false
\...
view.addSubview(colorDetailsView)
}
//Color cell expands to fill the screen of that color when user taps on the cell
@objc func userTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.ended {
let tapLocation = sender.location(in: self.tableView)
if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
UIView.animate(withDuration: 0.5, animations: {
//When user taps on a cell, it is scaled to fill the screen with that color
switch self.currentAnimation {
case 0:
tappedCell.transform = CGAffineTransform(scaleX: 1, y: 50)
for i in 0..<self.colorPalette.count {
if tapIndexPath.row == i {
self.colorDetailsView.backgroundColor = UIColor(hexString: self.colorPalette[i])
}
}
case 1:
tappedCell.transform = .identity
default: break
}
} )
currentAnimation += 1
if currentAnimation > 1 {
currentAnimation = 0
}
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"ColorCell", for: indexPath)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userTap(sender:)))
cell.addGestureRecognizer(tapGesture)
cell.isUserInteractionEnabled = true
//Assigns a new color to each row. Colors are converted from HEX to RGB
for i in 0..<colorPalette.count {
if tapIndexPath.row == i {
cell.backgroundColor = UIColor(hexString: colorPalette[i])
}
}
return cell
}
}
当我将 tableView.isScrollEnabled
设置为 true 时,我知道单元格正在缩放,如下所示。每个单元格最终应该填满整个屏幕,而不是被任何其他单元格覆盖,比如最上面的单元格。理想情况下,我希望 tableView 不滚动,但我不确定如果禁用滚动,顶部单元格是否会 "move up"。
感谢任何帮助!
这些单元格毕竟是 table 视图的所有子视图。您需要将点击的单元格放在子视图列表的前面。
我建议添加
tableView.bringSubviewToFront(tappedCell)
就在行
之后if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) {
.
看看这是否有效!