When utilizing a UIButton
, with a UIButton.Configuration
to set its title and picture, inside a UICollectionViewCell
the button itself breaks the picture/label positioning when rotating.
That is what it appears like initially:
Then after rotating as soon as
After which when rotating again
Code:
import UIKit
ultimate class ViewController: UIViewController {
non-public let cellRegistration = UICollectionView.CellRegistration<ButtonCollectionViewCell, String> { _, _, _ in }
non-public lazy var dataSource = UICollectionViewDiffableDataSource<String, String>(
collectionView: collectionView,
cellProvider: { collectionView, indexPath, identifier in
collectionView.dequeueConfiguredReusableCell(
utilizing: self.cellRegistration,
for: indexPath,
merchandise: ""
)
}
)
non-public lazy var collectionView: UICollectionView = {
let collectionViewLayout = UICollectionViewCompositionalLayout { _, _ in
let layoutSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(30)
)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: layoutSize,
subitems: [
NSCollectionLayoutItem(layoutSize: layoutSize)
]
)
let format = NSCollectionLayoutSection(group: group)
format.contentInsetsReference = .safeArea
format.contentInsets = NSDirectionalEdgeInsets(high: 24, main: 12, backside: 0, trailing: 12)
return format
}
return UICollectionView(body: .zero, collectionViewLayout: collectionViewLayout)
}()
override func viewDidLoad() {
tremendous.viewDidLoad()
var snapshot = NSDiffableDataSourceSnapshot<String, String>()
snapshot.appendSections(["section"])
snapshot.appendItems(["item"], toSection: "part")
dataSource.apply(snapshot)
view.addSubview(collectionView)
}
override func viewDidLayoutSubviews() {
tremendous.viewDidLayoutSubviews()
collectionView.body = view.bounds
}
}
ultimate class ButtonView: UIView {
non-public lazy var button: UIButton = {
let picture = UIImage(systemName: "headphones")!
.withTintColor(.white)
.withRenderingMode(.alwaysOriginal)
let title = AttributedString(NSAttributedString(string: "Hear", attributes: [
.foregroundColor: UIColor.white
]))
var configuration = UIButton.Configuration.plain()
configuration.attributedTitle = title
configuration.picture = picture
configuration.titleAlignment = .heart
configuration.imagePadding = 4
configuration.background.backgroundColor = .blue
configuration.background.cornerRadius = 8
return UIButton(configuration: configuration)
}()
override init(body: CGRect) {
tremendous.init(body: body)
addSubview(button)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been applied")
}
override func layoutSubviews() {
tremendous.layoutSubviews()
button.body = bounds
}
override func sizeThatFits(_ measurement: CGSize) -> CGSize {
button.sizeThatFits(measurement)
}
}
ultimate class ButtonCollectionViewCell: UICollectionViewCell {
non-public let buttonView = ButtonView()
override init(body: CGRect) {
tremendous.init(body: body)
contentView.addSubview(buttonView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been applied")
}
override func layoutSubviews() {
tremendous.layoutSubviews()
buttonView.body = contentView.bounds
}
override func sizeThatFits(_ measurement: CGSize) -> CGSize {
buttonView.sizeThatFits(measurement)
}
}
The view inspector does not yield something helpful both
The one factor I’ve discovered that helps is setting the autoresizingMask
of the UIButton
and its container view, which a) make no sense in any respect b) does not work exterior this pattern app to breed it (e.g. the answer is just not fully dependable)
Additionally utilizing the “previous” APIs, setTitle("Title", for: .regular)
/ setImage(picture, for: .regular)
doesn’t trigger this bug.
Anybody seen this earlier than and have any clue what might potential be incorrect right here?