mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-24 21:33:09 +09:00
113 lines
5.8 KiB
Swift
113 lines
5.8 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
import Foundation
|
|
|
|
class TopTabsLayoutDelegate: NSObject, UICollectionViewDelegateFlowLayout {
|
|
weak var tabSelectionDelegate: TabSelectionDelegate?
|
|
let HeaderFooterWidth = TopTabsUX.SeparatorWidth + TopTabsUX.FaderPading
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
|
|
return TopTabsUX.SeparatorWidth
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
|
return CGSize(width: TopTabsUX.TabWidth, height: collectionView.frame.height)
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
|
|
return UIEdgeInsets.zero
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
|
|
return TopTabsUX.SeparatorWidth
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
|
tabSelectionDelegate?.didSelectTabAtIndex(indexPath.row)
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
|
return CGSize(width: HeaderFooterWidth, height: 0)
|
|
}
|
|
|
|
@objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
|
|
return CGSize(width: HeaderFooterWidth, height: 0)
|
|
}
|
|
|
|
}
|
|
|
|
class TopTabsViewLayout: UICollectionViewFlowLayout {
|
|
var decorationAttributeArr: [Int: UICollectionViewLayoutAttributes?] = [:]
|
|
let separatorYOffset = TopTabsUX.SeparatorYOffset
|
|
let separatorSize = TopTabsUX.SeparatorHeight
|
|
let SeparatorZIndex = -2 ///Prevent the header/footer from appearing above the Tabs
|
|
|
|
override var collectionViewContentSize: CGSize {
|
|
let tabsWidth = ((CGFloat(collectionView!.numberOfItems(inSection: 0))) * (TopTabsUX.TabWidth + TopTabsUX.SeparatorWidth)) - TopTabsUX.SeparatorWidth
|
|
return CGSize(width: tabsWidth + (TopTabsUX.TopTabsBackgroundShadowWidth * 2), height: collectionView!.bounds.height)
|
|
}
|
|
|
|
override func prepare() {
|
|
super.prepare()
|
|
self.minimumLineSpacing = TopTabsUX.SeparatorWidth
|
|
scrollDirection = UICollectionViewScrollDirection.horizontal
|
|
register(TopTabsSeparator.self, forDecorationViewOfKind: TopTabsSeparatorUX.Identifier)
|
|
}
|
|
|
|
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
|
|
decorationAttributeArr = [:]
|
|
return true
|
|
}
|
|
|
|
// MARK: layoutAttributesForElementsInRect
|
|
override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
|
guard indexPath.row < self.collectionView!.numberOfItems(inSection: 0) else {
|
|
let separatorAttr = UICollectionViewLayoutAttributes(forDecorationViewOfKind: TopTabsSeparatorUX.Identifier, with: indexPath)
|
|
separatorAttr.frame = CGRect.zero
|
|
separatorAttr.zIndex = SeparatorZIndex
|
|
return separatorAttr
|
|
}
|
|
|
|
if let attr = self.decorationAttributeArr[indexPath.item] {
|
|
return attr
|
|
} else {
|
|
// Compute the separator if it does not exist in the cache
|
|
let separatorAttr = UICollectionViewLayoutAttributes(forDecorationViewOfKind: TopTabsSeparatorUX.Identifier, with: indexPath)
|
|
let x = TopTabsUX.TopTabsBackgroundShadowWidth + ((CGFloat(indexPath.row) * (TopTabsUX.TabWidth + TopTabsUX.SeparatorWidth)) - TopTabsUX.SeparatorWidth)
|
|
separatorAttr.frame = CGRect(x: x, y: separatorYOffset, width: TopTabsUX.SeparatorWidth, height: separatorSize)
|
|
separatorAttr.zIndex = SeparatorZIndex
|
|
return separatorAttr
|
|
}
|
|
}
|
|
|
|
override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
|
let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
|
|
attributes?.zIndex = SeparatorZIndex
|
|
return attributes
|
|
}
|
|
|
|
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
|
var attributes = super.layoutAttributesForElements(in: rect)!
|
|
|
|
// Create attributes for the Tab Separator.
|
|
for i in attributes {
|
|
guard i.representedElementKind != UICollectionElementKindSectionHeader && i.representedElementKind != UICollectionElementKindSectionFooter else {
|
|
i.zIndex = SeparatorZIndex
|
|
continue
|
|
}
|
|
let sep = UICollectionViewLayoutAttributes(forDecorationViewOfKind: TopTabsSeparatorUX.Identifier, with: i.indexPath)
|
|
sep.frame = CGRect(x: i.frame.origin.x - TopTabsUX.SeparatorWidth, y: separatorYOffset, width: TopTabsUX.SeparatorWidth, height: separatorSize)
|
|
sep.zIndex = SeparatorZIndex
|
|
i.zIndex = 10
|
|
|
|
// Only add the seperator if it will be shown.
|
|
if i.indexPath.row != 0 && i.indexPath.row < self.collectionView!.numberOfItems(inSection: 0) {
|
|
attributes.append(sep)
|
|
decorationAttributeArr[i.indexPath.item] = sep
|
|
}
|
|
}
|
|
|
|
return attributes
|
|
}
|
|
}
|