Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当出现contextMenu时,约束将重新激活_Ios_Swift_Uicollectionview_Autolayout_Uicontextmenuconfiguration - Fatal编程技术网

Ios 当出现contextMenu时,约束将重新激活

Ios 当出现contextMenu时,约束将重新激活,ios,swift,uicollectionview,autolayout,uicontextmenuconfiguration,Ios,Swift,Uicollectionview,Autolayout,Uicontextmenuconfiguration,我正在集合视图单元格上使用UIContextMenuConfiguration执行操作。一切都完全按照预期工作,但是如果我的单元格已经(解除)激活了来自nib的约束,它会在长按时刷新 为了演示这个问题,我创建了一个新项目,在故事板中有一个collectionView。集合视图中的自定义单元格有一个带有两个约束的标签,一个约束将其固定在单元格底部(最初处于活动状态),另一个约束将其居中对齐(最初禁用) 这是我的密码 import UIKit class ViewController: UIVie

我正在集合视图单元格上使用UIContextMenuConfiguration执行操作。一切都完全按照预期工作,但是如果我的单元格已经(解除)激活了来自nib的约束,它会在长按时刷新

为了演示这个问题,我创建了一个新项目,在故事板中有一个
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将通过增加标签的高度(而不是预期的输出)同时满足这两个约束