After watching this years Demystifying SwiftUI session I revisited my project for usage of AnyView. A common pattern that I used was using AnyView at the screen boundary to allow dynamic routing.
Screen boundaries are for me new views that are modally presented or pushed in navigation stacks for example.
So a common pattern in my code base looks like this
class FooPresenter {
@Published var isPresenting = false
@Published var presentedView: AnyView
}
struct FooView {
@StateObject var presenter = FooPresenter()
var body: some View {
Text("hello")
.sheet(isPresented: $presenter.isPresenting) {
presenter.presentedView
}
}
}
Now I understand that SwiftUI uses the type system to diff views, animate and more. And I can fully understand that on a single screen it is advisable to use as few AnyViews as possible. However I am wondering is there a performance difference when using it across screen boundaries? Furthermore, is the SwiftUI system "resetting" its type data at AnyView and then can do it's normal diffing until the next AnyView. Something like this
RootView
Text
Button
SheetPresentation
AnyView
Text
Button
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
When using UICollectionViewCompositionalLayout and creating a layout that supports pinned supplementary items and additionally having a section that has orthogonalScrollingBehavior the pinned header will disappear as soon as you scroll over the section with the orthogonalScrollingBehavior. A simple layout that demonstrates how it breaks looks like this
func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(44))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 5
section.orthogonalScrollingBehavior = .continuous
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44)),
elementKind: PinnedSectionHeaderFooterViewController.sectionHeaderElementKind,
alignment: .top)
let sectionFooter = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44)),
elementKind: PinnedSectionHeaderFooterViewController.sectionFooterElementKind,
alignment: .bottom)
sectionHeader.pinToVisibleBounds = true
sectionHeader.zIndex = 2
section.boundarySupplementaryItems = [sectionHeader, sectionFooter]
let layout = UICollectionViewCompositionalLayout(section: section)
let layoutHeaderHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44)),
elementKind: PinnedSectionHeaderFooterViewController.layoutHeaderElementKind,
alignment: .top)
let configuration = UICollectionViewCompositionalLayoutConfiguration()
layoutHeaderHeader.pinToVisibleBounds = true
configuration.boundarySupplementaryItems = [layoutHeaderHeader]
layout.configuration = configuration
return layout
}
This is an adapted part of the code provided by this example: https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views