我想讓我的UICollectionView的右側單元格淡出,因爲它們的滾動類似於Apple的消息應用程序,但不會影響collectionView中其他單元格的顏色或透明度。有沒有辦法根據它的滾動位置調整UICollectionViewCell的透明度以達到這種效果?我怎樣才能使一個iOS collectionView的特定單元格作爲collectionView滾動而淡出?
回答
當然!請注意,UICollectionView是UIScrollView的子類,並且您的UICollectionViewController已經是集合視圖的delegate
。這意味着它也符合UIScrollViewDelegate協議,該協議包括一系列通知您滾動位置更改的方法。
最讓我感興趣的是scrollViewDidScroll(_:)
,當集合視圖中的contentOffset
發生變化時將會調用它。您可能會實現該方法來遍歷集合視圖的visibleCells
,您可以自己調整單元的alpha
或向單元發送一些消息,以通知它根據其幀和偏移量調整自己的Alpha。
我可以想出最簡單的可能實現方式 - 尊重僅限右側的需求 - 如下所示。請注意,這可能會在視圖的頂部或底部附近出現一些毛刺,因爲單元格的alpha值只能在滾動上進行調整,而不是在初始出列或重用時調整。
class FadingCollectionViewController: UICollectionViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 500
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let collectionView = collectionView else {
return
}
let offset = collectionView.contentOffset.y
let height = collectionView.frame.size.height
let width = collectionView.frame.size.width
for cell in collectionView.visibleCells {
let left = cell.frame.origin.x
if left >= width/2 {
let top = cell.frame.origin.y
let alpha = (top - offset)/height
cell.alpha = alpha
} else {
cell.alpha = 1
}
}
}
}
你可以做很多有趣的東西收集意見。我喜歡UICollectionViewFlowLayout的子類。以下是一個示例,根據距離中心的距離淡出收集視圖的頂部和底部。我可以對其進行修改以僅褪去邊緣,但在查看代碼後應該看清它。
import UIKit
class FadingLayout: UICollectionViewFlowLayout,UICollectionViewDelegateFlowLayout {
//should be 0<fade<1
private let fadeFactor: CGFloat = 0.5
private let cellHeight : CGFloat = 60.0
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init(scrollDirection:UICollectionViewScrollDirection) {
super.init()
self.scrollDirection = scrollDirection
}
override func prepare() {
setupLayout()
super.prepare()
}
func setupLayout() {
self.itemSize = CGSize(width: self.collectionView!.bounds.size.width,height:cellHeight)
self.minimumLineSpacing = 0
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
func scrollDirectionOver() -> UICollectionViewScrollDirection {
return UICollectionViewScrollDirection.vertical
}
//this will fade both top and bottom but can be adjusted
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributesSuper: [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: rect) as [UICollectionViewLayoutAttributes]!
if let attributes = NSArray(array: attributesSuper, copyItems: true) as? [UICollectionViewLayoutAttributes]{
var visibleRect = CGRect()
visibleRect.origin = collectionView!.contentOffset
visibleRect.size = collectionView!.bounds.size
for attrs in attributes {
if attrs.frame.intersects(rect) {
let distance = visibleRect.midY - attrs.center.y
let normalizedDistance = abs(distance)/(visibleRect.height * fadeFactor)
let fade = 1 - normalizedDistance
attrs.alpha = fade
}
}
return attributes
}else{
return nil
}
}
//appear and disappear at 0
override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItem(at: itemIndexPath)! as UICollectionViewLayoutAttributes
attributes.alpha = 0
return attributes
}
override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItem(at: itemIndexPath)! as UICollectionViewLayoutAttributes
attributes.alpha = 0
return attributes
}
}
而在您的控制器與您的設置集合視圖它看起來像這樣。
let layout = FadingLayout(scrollDirection: .vertical)
collectionView.delegate = self
collectionView.dataSource = self
self.collectionView.setCollectionViewLayout(layout, animated: false)
我可以告訴你如何修改它,如果我知道用例更好一點。
這很簡單,如果你繼承UICollectionViewFlowLayout。你需要做的第一件事是確保當界限變化/滾動發生在
shouldInvalidateLayout(forBoundsChange newBounds:的CGRect)返回true可見屬性被重新計算layoutAttributesForElements
然後(直接:CGRect)委託調用,獲取由超類計算出的屬性,並根據可見邊界中項目的偏移量修改alpha值,就是這樣。 區分左側/右側項目可以在控制器中使用任何邏輯進行處理,並傳遞給佈局類以避免對左側項目應用此效果。 (我使用'CustomLayoutDelegate'作爲在控制器中實現的那種,它簡單地標識具有奇數indexPath.row的項目作爲左側單元格)
這是一個演示,該項目使用偶數indexPath.row跳過奇數行
import UIKit
class ViewController: UIViewController {
/// Custom flow layout
lazy var layout: CustomFlowLayout = {
let l: CustomFlowLayout = CustomFlowLayout()
l.itemSize = CGSize(width: self.view.bounds.width/1.5, height: 100)
l.delegate = self
return l
}()
/// The collectionView if you're not using UICollectionViewController
lazy var collectionView: UICollectionView = {
let cv: UICollectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: self.layout)
cv.backgroundColor = UIColor.lightGray
cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
cv.dataSource = self
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
}
}
extension ViewController: UICollectionViewDataSource, CustomLayoutDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
cell.backgroundColor = UIColor.black
return cell
}
// MARK: CustomLayoutDelegate
func cellSide(forIndexPath indexPath: IndexPath) -> CellSide {
// TODO: Your implementation to distinguish left/right indexPath
// Even rows are .right and Odds .left
if indexPath.row % 2 == 0 {
return .right
} else {
return .left
}
}
}
public enum CellSide {
case right
case left
}
protocol CustomLayoutDelegate: class {
func cellSide(forIndexPath indexPath: IndexPath) -> CellSide
}
class CustomFlowLayout: UICollectionViewFlowLayout {
/// Delegates distinguishing between left and right items
weak var delegate: CustomLayoutDelegate!
/// Maximum alpha value
let kMaxAlpha: CGFloat = 1
/// Minimum alpha value. The alpha value you want the first visible item to have
let kMinAlpha: CGFloat = 0.3
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let cv = collectionView, let rectAtts = super.layoutAttributesForElements(in: rect) else { return nil }
for atts in rectAtts {
// Skip left sides
if delegate.cellSide(forIndexPath: atts.indexPath) == .left {
continue
}
// Offset Y on visible bounds. you can use
// ´cv.bounds.height - (atts.frame.origin.y - cv.contentOffset.y)´
// To reverse the effect
let offset_y = (atts.frame.origin.y - cv.contentOffset.y)
let alpha = offset_y * kMaxAlpha/cv.bounds.height
atts.alpha = alpha + kMinAlpha
}
return rectAtts
}
// Invalidate layout when scroll happens. Otherwise atts won't be recalculated
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
}
謝謝!我失蹤的關鍵是返回true for shouldInvalidateLayout –
我很高興我可以提供幫助。感謝您的投票! – Lukas
- 1. CollectionView與UIScrollView作爲一個單元格
- 2. 控制collectionView從collectionView中滾動單元格
- 3. 我怎樣才能顯示在單元格上的每一行的單元格collectionView
- 4. 滾動查看CollectionView
- 5. Xamarin CollectionView突出顯示不正確的單元格當滾動
- 6. CollectionView中的空單元格
- 7. 我們怎樣才能給一個簡單的滑塊淡入淡出效果?
- 8. CollectionView單元格移動時選中
- 9. collectionView單元格重疊
- 10. CollectionView單元格不顯示
- 11. collectionview - 滾動前的中心單元格的縮放
- 12. 居中對齊單個collectionview單元格
- 13. CollectionView scrollToItem不滾動
- 14. 我怎樣才能使這個淡入淡出成爲幻燈片?
- 15. 如何在我的動態CollectionView單元格後添加靜態CollectionView單元格? (Swift)
- 16. 每次滾動視圖結束時居中顯示一個collectionView的單元格
- 17. 我怎樣才能繼續正常滾動滾動溢出DIV
- 18. 我怎樣才能使使用過渡功能時div元素的淡出慢
- 19. 如何將特定樣式設置爲XAML中CollectionView中的第一個元素?
- 20. 我怎樣才能在iOS
- 21. 如何滾動collectionview水平?
- 22. 我怎樣才能變出一個班?
- 23. 我怎樣才能使一個按鈕淡出動畫,然後使用swift淡入功能3
- 24. 更新CollectionView未選中的單元格?
- 25. Collectionview單元格打開新視圖
- 26. CollectionView中的日誌單元格
- 27. 我怎樣才能在iOS上的燈箱滾動?
- 28. 我怎樣才能點擊特定的表格行使用Geb
- 29. 我怎樣才能使單元格中可選的按鈕?
- 30. 我怎樣才能淡入淡出出現(使用.bind命令的列表?
嘗試搜索漸變效果 這可能有助於http:// stackoverflow。com/questions/22726103/ios-uitableview-fade-bottom-cell-and-top-cell-as-you-scroll –
我喜歡使用漸變遮罩的想法,但我相信會影響scrollView的所有內容而不僅僅是正確的細胞。 – alionthego
你黯淡的底部還是兩者? – agibson007