Ios 当出现contextMenu时,约束将重新激活
我正在集合视图单元格上使用UIContextMenuConfiguration执行操作。一切都完全按照预期工作,但是如果我的单元格已经(解除)激活了来自nib的约束,它会在长按时刷新 为了演示这个问题,我创建了一个新项目,在故事板中有一个Ios 当出现contextMenu时,约束将重新激活,ios,swift,uicollectionview,autolayout,uicontextmenuconfiguration,Ios,Swift,Uicollectionview,Autolayout,Uicontextmenuconfiguration,我正在集合视图单元格上使用UIContextMenuConfiguration执行操作。一切都完全按照预期工作,但是如果我的单元格已经(解除)激活了来自nib的约束,它会在长按时刷新 为了演示这个问题,我创建了一个新项目,在故事板中有一个collectionView。集合视图中的自定义单元格有一个带有两个约束的标签,一个约束将其固定在单元格底部(最初处于活动状态),另一个约束将其居中对齐(最初禁用) 这是我的密码 import UIKit class ViewController: UIVie
collectionView
。集合视图中的自定义单元格有一个带有两个约束的标签,一个约束将其固定在单元格底部(最初处于活动状态),另一个约束将其居中对齐(最初禁用)
这是我的密码
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.configure()
return cell
}
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration.init(identifier: nil, previewProvider: nil) { (array) -> UIMenu? in
return UIMenu(title: "Hello", image: nil, identifier: nil, options: .destructive, children: [UIAction(title: "Share", image: UIImage(systemName: "tray.and.arrow.up"), identifier: nil) { _ in
print("HelloWorld!")
}])
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 265, height: 128)
}
}
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
@IBOutlet weak var centerConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func configure() {
bottomConstraint.isActive = false
centerConstraint.isActive = true
}
}
该问题似乎与以下方面直接相关:
- 情节提要中创建的两个约束相互冲突
- 将一个约束设置为未安装
- 取消激活已安装的约束,并激活未安装的约束
使用
previewProvider:nil
初始化UIContextMenuConfiguration
时,它告诉UIKit自动生成预览视图-重置约束的“已安装”状态
一种解决方法是:
不要将中心约束标记为“未安装”,而是将其优先级设置为998,并将底部约束的优先级设置为999(这将防止IB抱怨)
然后,您可以将configure()
func保留为:
func configure() {
bottomConstraint.isActive = false
centerConstraint.isActive = true
}
标签的中心约束将在单元格和关联菜单的预览中保持活动状态
但是,如果您想让预览视图看起来与单元格不同,最好的选择(可能是一个更好的开始方法)是使用自定义的
previewProvider
,您需要提供更多细节。用你的代码快速测试,我看不到你得到的结果。哦,谢谢你让我知道,现在信息足够了吗?你想在显示上下文菜单时标签降到底部吗?不,我不想(我想它保持上下文菜单演示前的状态),但当显示上下文菜单时,框架似乎隐式地重新激活了我出于某种原因取消激活的约束。我想你是在自找麻烦。在脚本创建的约束上设置.isActive
,通常不是一个好主意。您试图执行的是什么操作需要此操作?当使用previewProvider:nil
初始化UIContextMenuConfiguration
时,它告诉UIKit
自动生成预览视图-重置约束的“已安装”状态。你能详细说明一下吗,我的意思是UIKit如何保持一切就绪,但只重置约束的“已安装”状态。此外,您提出的解决方案的影响与我想要的略有不同。configure
功能的功能不会对上下文菜单预览产生任何影响,自动布局将尝试同时满足这两个约束,从而导致标签放大。基本上,您对冲突约束的假设有点误导,因为约束可能不冲突,但它们旨在以互斥方式激活。将重置约束的“已安装”状态。。。这是通过观察得出的。使用Debug View Hierarchy
我们可以很容易地看到UIKit正在使用故事板集约束的“已安装”状态。我所说的“冲突约束”是指它们是否都处于活动状态——不管您的代码是否会在某个时刻将它们设置为相互排斥的。我曾问过“当显示上下文菜单时,是否希望标签降到底部?”而您说不。。。但听起来您确实希望预览与单元格的外观不同。在这种情况下,您最好使用自己的previewProvider
——或者,至少不要尝试使用未安装的约束。哦,不。很抱歉造成混淆,非常感谢您尝试帮助我。基本上,我正在寻找一个上下文菜单,应该看起来完全像细胞。但是,单元可以在不同的状态下显示(不同的已安装约束集)。关于“冲突约束”的问题,我想强调一个事实,即在我们当前的示例中,将两个约束都设置为活动将以不同的状态查看视图,而不是显示冲突约束警告,因为UIKit将通过增加标签的高度(而不是预期的输出)同时满足这两个约束