iOS 15中的ubieview单元格的高度约束的奇怪行为15
升级iOS 15后,我以前的代码开始工作很奇怪。
我有带有嵌入式视图的单元格的Uitable视图。当它在ViewDidload Cell的高度约束中加载时,我在情节板中设置的高度限制会变得活跃,并且单元格变得接近。点击单元格使高度约束变得不活跃并打开单元格。 foldView的高度约束
,但在iOS 15中,加载时始终打开。即使高度约束是活跃的。
在这里,我的代码使其打开或关闭:
var expanded: Bool = false {
didSet {
let duration = CATransaction.animationDuration()
UIView.animate(withDuration: duration) {
self.arrow.transform = self.expanded ? CGAffineTransform(rotationAngle: .pi / 2) : .identity
self.height.priority = .defaultHigh
self.height.isActive = !self.expanded
self.foldView.alpha = self.expanded ? 1 : 0
self.container.layoutIfNeeded()
}
}
}
这就是我添加嵌入式视图的方式:
func addEmbeddedView(_ view: UIView) {
self.foldView.subviews.forEach { $0.removeFromSuperview() }
self.foldView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
view.leadingAnchor.constraint(equalTo: self.foldView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: self.foldView.trailingAnchor),
view.topAnchor.constraint(equalTo: self.foldView.topAnchor),
view.bottomAnchor.constraint(equalTo: self.foldView.bottomAnchor, constant: -9)
]
constraints[3].priority = .defaultHigh
NSLayoutConstraint.activate(constraints)
}
但是!如果我从预期的所有作品中点击所有单元
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? TableViewCell else { return }
tableView.beginUpdates()
cell.expanded.toggle()
tableView.fixCellBounds()
tableView.endUpdates()
}
,并且在iOS 15中也打开和关闭单元格。
有什么建议是什么? 正如我在iOS 15中的假设,自动层上的一些变化可能会影响我的代码。
在这里我的完整自定义单元类别:
import UIKit
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var headerLabel: UILabel!
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var arrowImage: UIImageView!
@IBOutlet weak var container: UIView!
@IBOutlet weak var foldView: UIView!
@IBOutlet weak var arrow: UIImageView!
let layer1 = CALayer(), layer2 = CALayer(), layer3 = CALayer()
var expanded: Bool = false {
didSet {
let duration = CATransaction.animationDuration()
UIView.animate(withDuration: duration) {
self.arrow.transform = self.expanded ? CGAffineTransform(rotationAngle: .pi / 2) : .identity
self.height.priority = .defaultHigh
self.height.isActive = !self.expanded
self.foldView.alpha = self.expanded ? 1 : 0
self.container.layoutIfNeeded()
}
}
}
@IBOutlet weak var height: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
self.expanded = false
container.layer.cornerRadius = 8
container.layer.cornerCurve = .continuous
container.backgroundColor = Colors_8_5.offWhite.color
self.contentView.backgroundColor = .clear
self.container.clipsToBounds = true
self.contentView.clipsToBounds = false
self.clipsToBounds = false
self.selectionStyle = .none
self.backgroundColor = .clear
[layer1, layer2, layer3].forEach {
$0.masksToBounds = false
$0.backgroundColor = UIColor.clear.cgColor
self.contentView.layer.insertSublayer($0, at: 0)
}
}
func configure(with model: CustomCellModel) {
self.headerLabel.attributedText = model.header
self.descriptionLabel.attributedText = model.text
self.descriptionLabel.isHidden = model.text == nil
}
override func setSelected(_ selected: Bool, animated: Bool) {
}
func addEmbeddedView(_ view: UIView) {
self.foldView.subviews.forEach { $0.removeFromSuperview() }
self.foldView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
view.leadingAnchor.constraint(equalTo: self.foldView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: self.foldView.trailingAnchor),
view.topAnchor.constraint(equalTo: self.foldView.topAnchor),
view.bottomAnchor.constraint(equalTo: self.foldView.bottomAnchor, constant: -9)
]
constraints[3].priority = .defaultHigh
NSLayoutConstraint.activate(constraints)
}
override func layoutSubviews() {
super.layoutSubviews()
[layer1, layer2, layer3].forEach {
$0.frame = container.frame
}
layer1.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 4, blur: 8, spread: 0)
layer2.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 16, blur: 24, spread: 0)
layer3.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 24, blur: 32, spread: 0)
}
}
extension CALayer {
func CustomapplySketchShadow(
color: UIColor = .black,
alpha: Float = 0.2,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2
if spread == 0 {
shadowPath = UIBezierPath(rect: self.bounds).cgPath
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
After upgrade on IOS 15 my previous code start works strange.
I have UITableView with cells with embedded views. When it loads in viewDidLoad cell's height constrain that I setup in storyboard become active and cell become close. Tap on cell makes height constraint become not active and cell open.
Height constraint for foldView
But in IOS 15 cell always open when loading. Even if height constraint is active.
here my code that makes it open or close:
var expanded: Bool = false {
didSet {
let duration = CATransaction.animationDuration()
UIView.animate(withDuration: duration) {
self.arrow.transform = self.expanded ? CGAffineTransform(rotationAngle: .pi / 2) : .identity
self.height.priority = .defaultHigh
self.height.isActive = !self.expanded
self.foldView.alpha = self.expanded ? 1 : 0
self.container.layoutIfNeeded()
}
}
}
and this is how I add embedded view:
func addEmbeddedView(_ view: UIView) {
self.foldView.subviews.forEach { $0.removeFromSuperview() }
self.foldView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
view.leadingAnchor.constraint(equalTo: self.foldView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: self.foldView.trailingAnchor),
view.topAnchor.constraint(equalTo: self.foldView.topAnchor),
view.bottomAnchor.constraint(equalTo: self.foldView.bottomAnchor, constant: -9)
]
constraints[3].priority = .defaultHigh
NSLayoutConstraint.activate(constraints)
}
BUT! if I tap on cell from
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? TableViewCell else { return }
tableView.beginUpdates()
cell.expanded.toggle()
tableView.fixCellBounds()
tableView.endUpdates()
}
all works as expected and cell open and close in IOS 15 too.
Any suggestions what it could be?
As I assume in IOS 15 was some changes in AutoLayout that may affect my code..
Here my full custom cell class:
import UIKit
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var headerLabel: UILabel!
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var arrowImage: UIImageView!
@IBOutlet weak var container: UIView!
@IBOutlet weak var foldView: UIView!
@IBOutlet weak var arrow: UIImageView!
let layer1 = CALayer(), layer2 = CALayer(), layer3 = CALayer()
var expanded: Bool = false {
didSet {
let duration = CATransaction.animationDuration()
UIView.animate(withDuration: duration) {
self.arrow.transform = self.expanded ? CGAffineTransform(rotationAngle: .pi / 2) : .identity
self.height.priority = .defaultHigh
self.height.isActive = !self.expanded
self.foldView.alpha = self.expanded ? 1 : 0
self.container.layoutIfNeeded()
}
}
}
@IBOutlet weak var height: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
self.expanded = false
container.layer.cornerRadius = 8
container.layer.cornerCurve = .continuous
container.backgroundColor = Colors_8_5.offWhite.color
self.contentView.backgroundColor = .clear
self.container.clipsToBounds = true
self.contentView.clipsToBounds = false
self.clipsToBounds = false
self.selectionStyle = .none
self.backgroundColor = .clear
[layer1, layer2, layer3].forEach {
$0.masksToBounds = false
$0.backgroundColor = UIColor.clear.cgColor
self.contentView.layer.insertSublayer($0, at: 0)
}
}
func configure(with model: CustomCellModel) {
self.headerLabel.attributedText = model.header
self.descriptionLabel.attributedText = model.text
self.descriptionLabel.isHidden = model.text == nil
}
override func setSelected(_ selected: Bool, animated: Bool) {
}
func addEmbeddedView(_ view: UIView) {
self.foldView.subviews.forEach { $0.removeFromSuperview() }
self.foldView.addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
view.leadingAnchor.constraint(equalTo: self.foldView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: self.foldView.trailingAnchor),
view.topAnchor.constraint(equalTo: self.foldView.topAnchor),
view.bottomAnchor.constraint(equalTo: self.foldView.bottomAnchor, constant: -9)
]
constraints[3].priority = .defaultHigh
NSLayoutConstraint.activate(constraints)
}
override func layoutSubviews() {
super.layoutSubviews()
[layer1, layer2, layer3].forEach {
$0.frame = container.frame
}
layer1.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 4, blur: 8, spread: 0)
layer2.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 16, blur: 24, spread: 0)
layer3.CustomapplySketchShadow(color: .black, alpha: 0.04, x: 0, y: 24, blur: 32, spread: 0)
}
}
extension CALayer {
func CustomapplySketchShadow(
color: UIColor = .black,
alpha: Float = 0.2,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2
if spread == 0 {
shadowPath = UIBezierPath(rect: self.bounds).cgPath
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论