gpt4 book ai didi

ios - 如何使收藏 View 倒置?

转载 作者:行者123 更新时间:2023-12-01 22:18:05 25 4
gpt4 key购买 nike

我正在为我的一个应用程序使用具有垂直滚动方向的 Collection View 。在这里,我想让我的 Collection View 在不使用任何 CGAffine 变换的情况下倒置显示。是否可以在 Flow Layout 的帮助下实现?

我喜欢使用 Collection View 来实现聊天

提前致谢

最佳答案

class ChatCollectionViewFlowLayout: UICollectionViewFlowLayout {

private var topMostVisibleItem = Int.max
private var bottomMostVisibleItem = -Int.max

private var offset: CGFloat = 0.0
private var visibleAttributes: [UICollectionViewLayoutAttributes]?

private var isInsertingItemsToTop = false
private var isInsertingItemsToBottom = false


override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

// Reset each time all values to recalculate them
// ════════════════════════════════════════════════════════════

// Get layout attributes of all items
visibleAttributes = super.layoutAttributesForElements(in: rect)

// Erase offset
offset = 0.0

// Reset inserting flags
isInsertingItemsToTop = false
isInsertingItemsToBottom = false

return visibleAttributes
}

override func prepare(forCollectionViewUpdates updateItems: [UICollectionViewUpdateItem]) {

// Check where new items get inserted
// ════════════════════════════════════════════════════════════

// Get collection view and layout attributes as non-optional object
guard let collectionView = self.collectionView else { return }
guard let visibleAttributes = self.visibleAttributes else { return }


// Find top and bottom most visible item
// ────────────────────────────────────────────────────────────

bottomMostVisibleItem = -Int.max
topMostVisibleItem = Int.max

let container = CGRect(x: collectionView.contentOffset.x,
y: collectionView.contentOffset.y,
width: collectionView.frame.size.width,
height: (collectionView.frame.size.height - (collectionView.contentInset.top + collectionView.contentInset.bottom)))

for attributes in visibleAttributes {

// Check if cell frame is inside container frame
if attributes.frame.intersects(container) {
let item = attributes.indexPath.item
if item < topMostVisibleItem { topMostVisibleItem = item }
if item > bottomMostVisibleItem { bottomMostVisibleItem = item }
}
}


// Call super after first calculations
super.prepare(forCollectionViewUpdates: updateItems)


// Calculate offset of inserting items
// ────────────────────────────────────────────────────────────

var willInsertItemsToTop = false
var willInsertItemsToBottom = false

// Iterate over all new items and add their height if they go inserted
for updateItem in updateItems {
switch updateItem.updateAction {
case .insert:
if topMostVisibleItem + updateItems.count > updateItem.indexPathAfterUpdate!.item {
if let newAttributes = self.layoutAttributesForItem(at: updateItem.indexPathAfterUpdate!) {

offset += (newAttributes.size.height + self.minimumLineSpacing)
willInsertItemsToTop = true
}

} else if bottomMostVisibleItem <= updateItem.indexPathAfterUpdate!.item {
if let newAttributes = self.layoutAttributesForItem(at: updateItem.indexPathAfterUpdate!) {

offset += (newAttributes.size.height + self.minimumLineSpacing)
willInsertItemsToBottom = true
}
}

case.delete:
// TODO: Handle removal of items
break

default:
break
}
}


// Pass on information if items need more than one screen
// ────────────────────────────────────────────────────────────

// Just continue if one flag is set
if willInsertItemsToTop || willInsertItemsToBottom {

// Get heights without top and bottom
let collectionViewContentHeight = collectionView.contentSize.height
let collectionViewFrameHeight = collectionView.frame.size.height - (collectionView.contentInset.top + collectionView.contentInset.bottom)

// Continue only if the new content is higher then the frame
// If it is not the case the collection view can display all cells on one screen
if collectionViewContentHeight + offset > collectionViewFrameHeight {

if willInsertItemsToTop {
CATransaction.begin()
CATransaction.setDisableActions(true)
isInsertingItemsToTop = true

} else if willInsertItemsToBottom {
isInsertingItemsToBottom = true
}
}
}
}

override func finalizeCollectionViewUpdates() {

// Set final content offset with animation or not
// ════════════════════════════════════════════════════════════

// Get collection view as non-optional object
guard let collectionView = self.collectionView else { return }

if isInsertingItemsToTop {

// Calculate new content offset
let newContentOffset = CGPoint(x: collectionView.contentOffset.x,
y: collectionView.contentOffset.y + offset)

// Set new content offset without animation
collectionView.contentOffset = newContentOffset

// Commit/end transaction
CATransaction.commit()

} else if isInsertingItemsToBottom {

// Calculate new content offset
// Always scroll to bottom
let newContentOffset = CGPoint(x: collectionView.contentOffset.x,
y: collectionView.contentSize.height + offset - collectionView.frame.size.height + collectionView.contentInset.bottom)

// Set new content offset with animation
collectionView.setContentOffset(newContentOffset, animated: true)
}
}
}

也请检查,它可能会将收藏 View 设置为像颠倒的聊天行为
https://gist.github.com/jochenschoellig/04ffb26d38ae305fa81aeb711d043068

关于ios - 如何使收藏 View 倒置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50269821/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com