Post

Replies

Boosts

Views

Activity

How To Make Equal Heights CollectionView Groups Using UICollectionViewCompositionalLayout
I have a UICollectionViewLayout grid with three columns. Each item in the column has a cell full of text. I would like all the columns to be the same height as the tallest item in the group. Using UICollectionViewCompositionalLayout I'm having a hard time getting the desired results. I created a EqualHeightsUICollectionViewCompositionalLayout subcalss to check the cell attributes in layoutAttributesForElements and stores the largest cell height in a row. This seems to work good intially, but when the collectionview invalidates, the cell sizes are not always correct. How can I fix this? Here is an example project, and here is a stack overflow post class EqualHeightsUICollectionViewCompositionalLayout: UICollectionViewCompositionalLayout{     var largestDict: [Int: CGFloat] = [:]     let columns = 3     override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {         let attributes = super.layoutAttributesForElements(in: rect)         if let attributes = attributes {             for attribute in attributes {                 let height = attribute.frame.height                 let row = attribute.indexPath.row / columns                                  if height > 1 {                     self.largestDict[row] = max(height, largestDict[row] ?? 0)                 }             }         }                  return attributes     }          override func invalidateLayout() {         super.invalidateLayout()         largestDict.removeAll()     } } class TextCell: UICollectionViewCell {     let label = UILabel()     let bottomLabel = UILabel()     let container = UIView()     weak var collectionView: UICollectionView?          override init(frame: CGRect) {         super.init(frame: frame)         configure()     }          required init?(coder: NSCoder) {         fatalError("not implemented")     }          override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {         let attribute = super.preferredLayoutAttributesFitting(layoutAttributes)                  if let layout = collectionView?.collectionViewLayout as? EqualHeightsUICollectionViewCompositionalLayout{             let row = attribute.indexPath.row / layout.columns                          if let height = layout.largestDict[row] {                 attribute.frame = .init(origin: attribute.frame.origin, size: .init(width: attribute.frame.width, height: height))             }         }                  return attribute     }          private func configure() {         label.numberOfLines = 0         label.font = UIFont.preferredFont(forTextStyle: .title1)         label.backgroundColor = .systemPurple         label.textColor = .white         label.translatesAutoresizingMaskIntoConstraints = false         label.setContentHuggingPriority(.defaultHigh, for: .vertical)                  bottomLabel.numberOfLines = 0         bottomLabel.font = UIFont.preferredFont(forTextStyle: .title1)         bottomLabel.text = "Bottom of cell"         bottomLabel.backgroundColor = .systemRed         bottomLabel.textColor = .white         bottomLabel.translatesAutoresizingMaskIntoConstraints = false         bottomLabel.setContentHuggingPriority(.defaultLow, for: .vertical)                  contentView.addSubview(label)         contentView.addSubview(bottomLabel)                  backgroundColor = .systemBlue.withAlphaComponent(0.75)                  let inset = CGFloat(0)         NSLayoutConstraint.activate([             label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: inset),             label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -inset),             label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: inset),                          bottomLabel.leadingAnchor.constraint(equalTo: label.leadingAnchor),             bottomLabel.trailingAnchor.constraint(equalTo: label.trailingAnchor),             bottomLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: inset),             bottomLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -inset),         ])     } }     func createLayout() -> UICollectionViewLayout {         let spacing = CGFloat(10)         let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),                                               heightDimension: .estimated(1))         let item = NSCollectionLayoutItem(layoutSize: itemSize)                  let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),                                                heightDimension: .estimated(1))         let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 3)         group.interItemSpacing = .fixed(spacing)                  let section = NSCollectionLayoutSection(group: group)         section.interGroupSpacing = spacing         section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)         return EqualHeightsUICollectionViewCompositionalLayout(section: section)     }
Topic: UI Frameworks SubTopic: UIKit Tags:
1
1
2.6k
Sep ’22
How To Always Hide UlSplitViewController Details View Controller
Is there anyway to hide the details view controller of a UISplitviewController in all circumstances? I have this requirement where the details VC needs to be hidden (or absent) at first and then slide in from the right when an initial selection is made. This needs to be the case even when a large iPad is in full screen mode. I know I can simply create my own version of this using a view controller with two child view controllers embed and manipulating constraints, however then I lose the push and pop functionally that you automatically get when in a compact size class.
0
0
837
Sep ’22
SwiftUI sheet automatically dismisses itself
I have a sheet thats being presented in SwiftUI and the first time it's opened it automatically dismisses itself half a second later. Reopening it from then on works properly. Has anyone else experienced this and perhaps come up with a solution? Stack Overflow post: https://stackoverflow.com/questions/62722308/swiftui-sheet-automatically-dismisses-itself          var window: UIWindow?               func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {         if let windowScene = scene as? UIWindowScene {             let window = UIWindow(windowScene: windowScene)             window.rootViewController = UIHostingController(rootView:                                                                 NavigationView{                                                                     List{                                                                         ForEach(0..<10){ value in                                                                             Text("Hello, World \(value)")                                                                         }                                                                     }                                                                     NavigationLink(destination: Test()) {                                                                         Text("Details")                                                                     }                                                                 }             )             self.window = window             window.makeKeyAndVisible()         }     } } struct Test : View{     @State  var show = false          var body : some View{         Text("Details")             .sheet(isPresented: $show, content: {                 Color.blue             })             .toolbar{                 ToolbarItem(placement: .navigationBarTrailing) {                     Button("Show Sheet"){                         show.toggle()                     }                 }             }     } }
8
1
8k
Apr ’22