Swift 如何在iOS 11上的单元取消期间重新实现以前在iOS 10上工作的清晰颜色UITableViewCell遮罩效果?
序言 我在iOS 10上有一个工作自定义的Swift 如何在iOS 11上的单元取消期间重新实现以前在iOS 10上工作的清晰颜色UITableViewCell遮罩效果?,swift,uitableview,ios10,calayer,ios11,Swift,Uitableview,Ios10,Calayer,Ios11,序言 我在iOS 10上有一个工作自定义的UITableViewCelldemission动画。其实施方式如下: 用户按下提交按钮 在UITableViewCell的子视图的索引零处(单元格的contentView下方)创建、定位并插入自定义视图 contentView在帧外设置动画,而自定义视图的alpha设置为1.0 当contentView完全超出框架时,将调用本机UITableView方法deleteRows(位于:[indexPath],带:.top)。UITableViewCell折
UITableViewCell
demission动画。其实施方式如下:
UITableViewCell
的子视图的索引零处(单元格的contentView
下方)创建、定位并插入自定义视图contentView
在帧外设置动画,而自定义视图的alpha设置为1.0contentView
完全超出框架时,将调用本机UITableView
方法deleteRows(位于:[indexPath],带:.top)
。UITableViewCell
折叠,自定义视图在折叠时隐藏在前一个UITableViewCell
后面tableView
具有清晰的背景色,允许在其后面显示自定义视图(蓝色)。每个单元格都有一个包含单元格所有内容的containerView
。containerView
和contentView
都有清晰的背景色。一切都很好
问题
将我的应用程序迁移到iOS 11时,此动画不再正常工作。下面是它不再工作的缓慢动画
正如您所看到的,自定义视图在单元撤销时覆盖在上一个单元的顶部,而不更改我的代码
到目前为止的调查
到目前为止,我已经确定,UITableView
的结构已经发生了变化:
UITableView
UITableViewWrapperView
cell
custom view
contentView
cell separator view
cell
cell
cell
UIView
UIImageView (scroll view indicator bottom)
UIImageView (scroll view indicator right)
对此:(UITableViewWrapperView
已被删除)
关于这个UITableWrapperView
我注意到的一点是,它的层的isOpaque
属性为true,而masksToBounds
属性为false,而UITableView
和所有UITableViewCell
则相反。由于这一观点在iOS 11中被删除,这可能是我产生错误效果的原因。我真的不知道
编辑:我发现的另一件事是,工作示例中的UITableWrapperView
在其子视图(所有UITableViewCell
s)的零索引处插入了一个神秘的UIView
,其中属性isOpaque
设置为true,并且它有一个compositingFilter
。动画完成后,该视图随后将被删除。由于在iOS 11中删除了UITableWrapperView
,因此根据关联,该视图也丢失了
问题
首先,有人知道为什么会发生这种行为变化吗?如果没有,是否有其他方法可以更好地实现iOS 10的效果?我想要clear
UITableViewCell
s,但在删除时每个单元格后面都会显示一个自定义视图,该视图在删除时会被另一个clearUITableViewCell
s遮挡,如上面的第一个gif示例所示。删除行之前,请将要删除的单元格发送到表视图子视图的后面
tableView.sendSubview(toBack: cell)
tableView.deleteRows(at: [indexPath], with: .top)
如果没有单元格,可以使用索引路径检索它
guard let cell = tableView.cell(for: indexPath) else { return }
// ...
这应该与视图层次的调整一起使用
CardTableViewController.swift
CardTableViewCell.swift
卡片。swift
首先,我不认为缺少
UITableViewWrapperView
是一个问题。
这是父视图,父视图不能隐藏子视图
请注意,问题是哪个单元格模糊了哪个单元格。在第一种情况下,行A遮挡行B,在第二行B遮挡行A(在这种情况下,自定义B单元格具有透明背景)
看来苹果的细胞之间的关系搞砸了。为了解决这个问题,我会尝试解决这个关系。所以在动画的第二部分开始之前,我会尝试:
这不应该破坏任何东西(在旧的iOS版本上),并且应该使用iOS 11解决问题 我花了很多天学习,但都失败了 iOS10 在
deleteRows
之后,TableViewCell
有一个具有compositingFilter
属性的视图,该值为copy
,该视图将所有视图隐藏在该属性后面
我们可以尝试删除deleteRows
时生成的TableViewCell
的子视图。那么iOS 10的行为将类似于iOS 11
然后我们可以再次尝试将视图(UIView()
)添加到TableViewCell
,并将compositingFilter
设置为copy
(字符串),它将再次在iOS10中实现
但是iOS11中的任何操作失败。它将在iOS11中生成黑色背景
我相信层的行为在iOS11上发生了改变
当TableViewCell
的背景是透明的时,我们可能不得不考虑暂时放弃在ios11
中使用up
动画。在iOS 11上查看应用程序后,我遇到了这样一个问题,问题是从表视图中删除行时的动画:
很明显,折叠动画是不合适的,因为要删除的行不止一行
以下是展开/折叠行的责任代码:
// inserting rows:
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .automatic)
tableView.endUpdates()
// deleting rows:
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .automatic)
tableView.endUpdates()
显然,还有一些代码可以编辑数据源数组
造成这一问题的原因很简单,就是分配给;我所做的只是将动画更改为“淡入淡出”:
// inserting rows:
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .fade)
tableView.endUpdates()
// deleting rows:
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .fade)
tableView.endUpdates()
输出已固定为:
同时
您可能需要检查以下可能与您的问题相关的问题:
我找到了UITableView的解决方案
@objc protocol CardTableViewCellDelegate {
func cardTableViewCell(_ cell: CardTableViewCell, didTouchUpInsideCheckmarkButton button: UIButton)
}
@IBDesignable class CardTableViewCell: UITableViewCell {
// MARK: Outlets
@IBOutlet var checkmarkButton: UIButton?
@IBOutlet var customView: CardCustomView?
@IBOutlet var delegate: CardTableViewCellDelegate?
@IBOutlet var taskTextLabel: UILabel?
// MARK: Properties
var card: Card? {
didSet {
updateOutlets()
}
}
// MARK: Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
checkmarkButton?.layer.borderColor = UIColor.black.cgColor
}
override func prepareForReuse() {
super.prepareForReuse()
card = nil
}
// MARK: Methods
private func updateOutlets() {
checkmarkButton?.isSelected = card?.isDone == true ? true : false
checkmarkButton?.superview?.transform = .identity
customView?.alpha = 0
customView?.dayCount = card?.dayCount
taskTextLabel?.text = card?.text
}
// MARK: Actions
@IBAction func didTouchUpInsideCheckButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
delegate?.cardTableViewCell(self, didTouchUpInsideCheckmarkButton: sender)
}
}
class CardCustomView: UIView {
// MARK: Outlets
@IBOutlet var countLabel: UILabel?
@IBOutlet var daysLabel: UILabel?
// MARK: Properties
var dayCount: Int? {
didSet {
updateOutlets()
}
}
override func awakeFromNib() {
super.awakeFromNib()
updateOutlets()
}
// MARK: Methods
private func updateOutlets() {
let count = dayCount.flatMap { $0 } ?? 0
countLabel?.text = "\(dayCount.flatMap { $0 } ?? 0)"
daysLabel?.text = "Day\(count == 1 ? "" : "s") in a row"
}
}
class Card: NSObject {
// MARK: Properties
var dayCount: Int = 0
var isDone: Bool = false
var text: String
// MARK: Lifecycle
init(text: String) {
self.text = text
}
}
cell.superview.sendSubview(toBack: cell)
// inserting rows:
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .automatic)
tableView.endUpdates()
// deleting rows:
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .automatic)
tableView.endUpdates()
// inserting rows:
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .fade)
tableView.endUpdates()
// deleting rows:
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 4 + count, section: 0), IndexPath(row: 5 + count, section: 0), IndexPath(row: 6 + count, section: 0)], with: .fade)
tableView.endUpdates()