Доступ к файлу представления из UICollectionViewListCell
У меня вопрос о разделителе списка представлений UICollectionLayoutGuide. Я увидел эту статью и понял, что мне нужно переопределить функцию updateConstraints(), чтобы обновить руководство по макету разделителя. нравится...
override func updateConstraints() {
super.updateConstraints()
separatorLayoutGuide.leadingAnchor.constraint(equalTo: otherView.leadingAnchor, constant: 0.0).isActive = true
}
Я вижу крошечное пространство между ведущим якорем ячейки и ведущим якорем seprateguide, как на изображении ниже, и я хочу это исправить. (как левая часть клетки)
Проблема, однако, в том, что я создал ячейку списка пользовательского представления коллекции, используя эту статью , и не могу изменить separatorLayoutGuide, ведущий к ведущему элементу настраиваемого представления. Я добавил
customListCell.separatorLayoutGuide.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
чтобы поместить ведущий элемент separatorLayoutGuide в ведущий элемент customView, и я получаю
"UILayoutGuide:0x2822d8b60'UICollectionViewListCellSeparatorLayoutGuide'.leading"> and <NSLayoutXAxisAnchor:0x280e9cac0 "ContentView:0x15960db90.leading"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
ошибка. После того, как я провел исследование, я решил, что не добавлял Subview для separatorLayoutGuide, но даже если я добавляю subview в настраиваемый вид, приложение вылетает. Есть ли способ изменить ведущую привязку направляющей разделителя при использовании пользовательского UIView?
class CustomListCell: UICollectionViewListCell {
var item: TestItem?
override func updateConfiguration(using state: UICellConfigurationState) {
// Create new configuration object
var newConfiguration = ContentConfiguration().updated(for: state)
newConfiguration.name = item.name
newConfiguration.state = item.state
// Set content configuration
contentConfiguration = newConfiguration
}
}
struct ContentConfiguration: UIContentConfiguration, Hashable {
var name: String?
var state: String?
func makeContentView() -> UIView & UIContentView {
return ContentView(configuration: self)
}
func updated(for state: UIConfigurationState) -> Self {
guard let state = state as? UICellConfigurationState else {
return self
}
// Updater self based on the current state
let updatedConfiguration = self
if state.isSelected {
print("is selected")
} else {
print("is deselected")
}
return updatedConfiguration
}
}
class ContentView: UIView, UIContentView {
let contentsView = UIView()
let customListCell = CustomListCell()
lazy var titleLabel: UILabel = {
let label = UILabel()
label.text = ""
return label
}()
lazy var statusLabel: UILabel = {
let label = UILabel()
label.text = ""
return label
}()
lazy var symbolImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
init(configuration: ContentConfiguration) {
// Custom initializer implementation here.
super.init(frame: .zero)
setupAllViews()
apply(configuration: configuration)
}
override func updateConstraints() {
super.updateConstraints()
customListCell.separatorLayoutGuide.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var currentConfiguration: ContentConfiguration!
var configuration: UIContentConfiguration {
get {
currentConfiguration
}
set {
guard let newConfiguration = newValue as? ContentConfiguration else {
return
}
apply(configuration: newConfiguration)
}
}
func setupAllViews() {
// add subviews and add constraints
}
func apply(configuration: ContentConfiguration) {
}
}
2 ответа
В вашем коде у вас есть
customListCell
переменная экземпляра, которая не является необходимой. Также не следует добавлять
separatorLayoutGuide
как подпредставление в любом месте.
Попробуйте получить доступ к ячейке
contentView
:
override func updateConstraints() {
super.updateConstraints()
if let customView = cell.contentView as? ContentView {
separatorLayoutGuide.leadingAnchor.constraint(equalTo: customView.leadingAnchor, constant: 0.0).isActive = true
}
}
Таким образом, вы можете получить доступ к любому подпредставлению в вашем
ContentView
.
Другой вопрос: нужно ли создавать новое ограничение каждый раз, когда вызывается? Сохраняются ли ограничения предыдущих вызовов? Согласно документации г.
updateConstraints
:
Ваша реализация должна быть максимально эффективной. Не отключайте все свои ограничения, а затем повторно активируйте те, которые вам нужны. Вместо этого ваше приложение должно каким-то образом отслеживать ваши ограничения и проверять их при каждом проходе обновления. Меняйте только те элементы, которые необходимо изменить. Во время каждого прохода обновления вы должны убедиться, что у вас есть соответствующие ограничения для текущего состояния приложения.
Поэтому я предлагаю такой подход:
class ContentView: UIView, UIContentView {
var separatorConstraint: NSLayoutConstraint?
func updateForCell(_ cell: CustomListCell) {
if separatorConstraint == nil {
separatorConstraint = cell.separatorLayoutGuide.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 30)
}
separatorConstraint?.isActive = true
}
}
class CustomListCell: UICollectionViewListCell {
...
override func updateConstraints() {
super.updateConstraints()
(contentView as? AlbumContentView)?.updateForCell(self)
}
}
путем переопределения updateConstraints в
UICollectionViewListCell
подкласс