Commit e7dc6290 authored by Carola Nitz's avatar Carola Nitz

MediaSubcategoryViewcontroller: various code fixes

removed publics, opens and internalsi, move variables to top
added a cellidentifier to VLClabelCell
removed code that was the default like bounces etc
BaseButtonBarPageerTabStripViewController: adjust height of the subcategorybar
parent 8da49e4e
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="2CI-9N-dP3" userLabel="Icon Label Cell" customClass="VLCLabelCell" customModule="VLC_iOS" customModuleProvider="target"> <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="VLCLabelCell" id="2CI-9N-dP3" userLabel="Icon Label Cell" customClass="VLCLabelCell" customModule="VLC_iOS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="74" height="70"/> <rect key="frame" x="0.0" y="0.0" width="74" height="70"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
...@@ -19,19 +19,19 @@ ...@@ -19,19 +19,19 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rwk-fy-4KB"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rwk-fy-4KB">
<rect key="frame" x="0.0" y="45" width="74" height="20"/> <rect key="frame" x="0.0" y="25" width="74" height="20"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="20" id="kWi-HY-P6M"/> <constraint firstAttribute="height" constant="20" id="kWi-HY-P6M"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
</view> </view>
<constraints> <constraints>
<constraint firstItem="rwk-fy-4KB" firstAttribute="centerY" secondItem="2CI-9N-dP3" secondAttribute="centerY" id="GxY-Zz-FHR"/>
<constraint firstItem="rwk-fy-4KB" firstAttribute="leading" secondItem="2CI-9N-dP3" secondAttribute="leading" id="HFm-qh-fCk"/> <constraint firstItem="rwk-fy-4KB" firstAttribute="leading" secondItem="2CI-9N-dP3" secondAttribute="leading" id="HFm-qh-fCk"/>
<constraint firstAttribute="bottom" secondItem="rwk-fy-4KB" secondAttribute="bottom" constant="5" id="Q0g-pb-bbf"/>
<constraint firstAttribute="trailing" secondItem="rwk-fy-4KB" secondAttribute="trailing" id="YuE-x9-9EY"/> <constraint firstAttribute="trailing" secondItem="rwk-fy-4KB" secondAttribute="trailing" id="YuE-x9-9EY"/>
</constraints> </constraints>
<size key="customSize" width="74" height="50"/> <size key="customSize" width="74" height="50"/>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
import Foundation import Foundation
class VLCLabelCell: UICollectionViewCell { class VLCLabelCell: UICollectionViewCell {
static let cellIdentifier = "VLCLabelCell"
@IBOutlet weak var iconLabel: UILabel! @IBOutlet weak var iconLabel: UILabel!
} }
...@@ -25,10 +25,10 @@ public enum SwipeDirection { ...@@ -25,10 +25,10 @@ public enum SwipeDirection {
public struct IndicatorInfo { public struct IndicatorInfo {
public var title: String? var title: String?
public var accessibilityLabel: String? var accessibilityLabel: String?
public init(title: String) { init(title: String) {
self.title = title self.title = title
self.accessibilityLabel = title self.accessibilityLabel = title
} }
...@@ -37,31 +37,32 @@ public struct IndicatorInfo { ...@@ -37,31 +37,32 @@ public struct IndicatorInfo {
public enum PagerScroll { public enum PagerScroll {
case no case no
case yes case yes
case scrollOnlyIfOutOfScreen case onlyIfOutOfScreen
} }
open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollectionViewCell>: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollectionViewCell>: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)?
public var buttonBarView: ButtonBarView! var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)?
var buttonBarView: ButtonBarView!
let buttonbarViewHeight: CGFloat = 45.0
lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in
return self.calculateWidths() return self.calculateWidths()
}() }()
private var shouldUpdateButtonBarView = true
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self delegate = self
datasource = self datasource = self
} }
@available(*, unavailable, message: "use init(nibName:)") @available(*, unavailable, message: "use init(nibName:)")
required public init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
fatalError() fatalError()
} }
open override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout() let flowLayout = UICollectionViewFlowLayout()
...@@ -74,7 +75,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -74,7 +75,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
buttonBarView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor), buttonBarView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor),
buttonBarView.rightAnchor.constraint(equalTo: view.rightAnchor), buttonBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
buttonBarView.leftAnchor.constraint(equalTo: view.leftAnchor), buttonBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
buttonBarView.heightAnchor.constraint(equalToConstant: 35) buttonBarView.heightAnchor.constraint(equalToConstant: buttonbarViewHeight)
]) ])
//make sure that top and bottom are not covered by tabbar and navigationbar //make sure that top and bottom are not covered by tabbar and navigationbar
let bottomGuide: NSLayoutConstraint let bottomGuide: NSLayoutConstraint
...@@ -93,23 +94,20 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -93,23 +94,20 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
buttonBarView.delegate = self buttonBarView.delegate = self
buttonBarView.dataSource = self buttonBarView.dataSource = self
// register button bar item cell
buttonBarView.register(UINib(nibName: "VLCLabelCell", bundle: .main), forCellWithReuseIdentifier:"Cell")
} }
open override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
buttonBarView.layoutIfNeeded() buttonBarView.layoutIfNeeded()
isViewAppearing = true isViewAppearing = true
} }
open override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
isViewAppearing = false isViewAppearing = false
} }
open override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
guard isViewAppearing || isViewRotating else { return } guard isViewAppearing || isViewRotating else { return }
...@@ -129,13 +127,13 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -129,13 +127,13 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
// When the view first appears or is rotated we also need to ensure that the barButtonView's // When the view first appears or is rotated we also need to ensure that the barButtonView's
// selectedBar is resized and its contentOffset/scroll is set correctly (the selected // selectedBar is resized and its contentOffset/scroll is set correctly (the selected
// tab/cell may end up either skewed or off screen after a rotation otherwise) // tab/cell may end up either skewed or off screen after a rotation otherwise)
buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen) buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .onlyIfOutOfScreen)
buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: []) buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: [])
} }
// MARK: - Public Methods // MARK: - Public Methods
open override func reloadPagerTabStripView() { override func reloadPagerTabStripView() {
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
guard isViewLoaded else { return } guard isViewLoaded else { return }
buttonBarView.reloadData() buttonBarView.reloadData()
...@@ -143,7 +141,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -143,7 +141,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes) buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes)
} }
open func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat { func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat {
var numberOfLargeCells = 0 var numberOfLargeCells = 0
var totalWidthOfLargeCells: CGFloat = 0 var totalWidthOfLargeCells: CGFloat = 0
...@@ -165,12 +163,12 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -165,12 +163,12 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells) return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells)
} }
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) {
guard shouldUpdateButtonBarView else { return } guard shouldUpdateButtonBarView else { return }
buttonBarView.moveTo(index: toIndex, animated: true, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes) buttonBarView.moveTo(index: toIndex, animated: true, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes)
} }
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
guard shouldUpdateButtonBarView else { return } guard shouldUpdateButtonBarView else { return }
buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes) buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes)
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
...@@ -182,14 +180,14 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -182,14 +180,14 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
// MARK: - UICollectionViewDelegateFlowLayut // MARK: - UICollectionViewDelegateFlowLayut
@objc open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { @objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { guard let cellWidthValue = cachedCellWidths?[indexPath.row] else {
fatalError("cachedCellWidths for \(indexPath.row) must not be nil") fatalError("cachedCellWidths for \(indexPath.row) must not be nil")
} }
return CGSize(width: cellWidthValue, height: collectionView.frame.size.height) return CGSize(width: cellWidthValue, height: collectionView.frame.size.height)
} }
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard indexPath.item != currentIndex else { return } guard indexPath.item != currentIndex else { return }
buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes) buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes)
...@@ -206,12 +204,12 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -206,12 +204,12 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
// MARK: - UICollectionViewDataSource // MARK: - UICollectionViewDataSource
open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewControllers.count return viewControllers.count
} }
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarCellType else { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: VLCLabelCell.cellIdentifier, for: indexPath) as? ButtonBarCellType else {
fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell")
} }
let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast
...@@ -228,14 +226,14 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -228,14 +226,14 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
// MARK: - UIScrollViewDelegate // MARK: - UIScrollViewDelegate
open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
super.scrollViewDidEndScrollingAnimation(scrollView) super.scrollViewDidEndScrollingAnimation(scrollView)
guard scrollView == containerView else { return } guard scrollView == containerView else { return }
shouldUpdateButtonBarView = true shouldUpdateButtonBarView = true
} }
open func configure(cell: ButtonBarCellType, for indicatorInfo: IndicatorInfo) { func configure(cell: ButtonBarCellType, for indicatorInfo: IndicatorInfo) {
fatalError("You must override this method to set up ButtonBarView cell accordingly") fatalError("You must override this method to set up ButtonBarView cell accordingly")
} }
...@@ -272,19 +270,17 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect ...@@ -272,19 +270,17 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
return stretchedCellWidths return stretchedCellWidths
} }
} }
private var shouldUpdateButtonBarView = true
} }
// MARK: Protocols // MARK: Protocols
public protocol IndicatorInfoProvider { protocol IndicatorInfoProvider {
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo
} }
public protocol PagerTabStripIsProgressiveDelegate: class { protocol PagerTabStripIsProgressiveDelegate: class {
func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool)
} }
......
...@@ -14,11 +14,11 @@ import Foundation ...@@ -14,11 +14,11 @@ import Foundation
open class ButtonBarView: UICollectionView { open class ButtonBarView: UICollectionView {
open var selectedBar: UIView! var selectedBar: UIView!
open var separatorView: UIView! var separatorView: UIView!
internal let selectedBarHeight: CGFloat = 4 let selectedBarHeight: CGFloat = 4
internal let separatorHeight: CGFloat = 1.5 let separatorHeight: CGFloat = 1.5
var selectedIndex = 0 var selectedIndex = 0
...@@ -27,7 +27,7 @@ open class ButtonBarView: UICollectionView { ...@@ -27,7 +27,7 @@ open class ButtonBarView: UICollectionView {
fatalError() fatalError()
} }
public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout) super.init(frame: frame, collectionViewLayout: layout)
setup() setup()
NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .VLCThemeDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .VLCThemeDidChangeNotification, object: nil)
...@@ -37,6 +37,7 @@ open class ButtonBarView: UICollectionView { ...@@ -37,6 +37,7 @@ open class ButtonBarView: UICollectionView {
func setup() { func setup() {
scrollsToTop = false scrollsToTop = false
showsHorizontalScrollIndicator = false showsHorizontalScrollIndicator = false
register(UINib(nibName: "VLCLabelCell", bundle: .main), forCellWithReuseIdentifier:VLCLabelCell.cellIdentifier)
separatorView = UIView(frame: CGRect(x: 0, y: self.frame.size.height - separatorHeight, width: self.frame.size.width, height: separatorHeight)) separatorView = UIView(frame: CGRect(x: 0, y: self.frame.size.height - separatorHeight, width: self.frame.size.width, height: separatorHeight))
addSubview(separatorView) addSubview(separatorView)
...@@ -53,12 +54,12 @@ open class ButtonBarView: UICollectionView { ...@@ -53,12 +54,12 @@ open class ButtonBarView: UICollectionView {
separatorView.backgroundColor = PresentationTheme.current.colors.mediaCategorySeparatorColor separatorView.backgroundColor = PresentationTheme.current.colors.mediaCategorySeparatorColor
} }
open func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) { func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) {
selectedIndex = index selectedIndex = index
updateSubviewPositions(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll) updateSubviewPositions(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll)
} }
open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat, pagerScroll: PagerScroll) { func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat, pagerScroll: PagerScroll) {
selectedIndex = progressPercentage > 0.5 ? toIndex : fromIndex selectedIndex = progressPercentage > 0.5 ? toIndex : fromIndex
let fromFrame = layoutAttributesForItem(at: IndexPath(item: fromIndex, section: 0))!.frame let fromFrame = layoutAttributesForItem(at: IndexPath(item: fromIndex, section: 0))!.frame
...@@ -96,7 +97,7 @@ open class ButtonBarView: UICollectionView { ...@@ -96,7 +97,7 @@ open class ButtonBarView: UICollectionView {
setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: false) setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: false)
} }
open func updateSubviewPositions(_ animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) { func updateSubviewPositions(_ animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) {
var selectedBarFrame = selectedBar.frame var selectedBarFrame = selectedBar.frame
let selectedCellIndexPath = IndexPath(item: selectedIndex, section: 0) let selectedCellIndexPath = IndexPath(item: selectedIndex, section: 0)
...@@ -124,7 +125,7 @@ open class ButtonBarView: UICollectionView { ...@@ -124,7 +125,7 @@ open class ButtonBarView: UICollectionView {
// MARK: - Helpers // MARK: - Helpers
private func updateContentOffset(animated: Bool, pagerScroll: PagerScroll, toFrame: CGRect, toIndex: Int) { private func updateContentOffset(animated: Bool, pagerScroll: PagerScroll, toFrame: CGRect, toIndex: Int) {
guard pagerScroll != .no || (pagerScroll != .scrollOnlyIfOutOfScreen && (toFrame.origin.x < contentOffset.x || toFrame.origin.x >= (contentOffset.x + frame.size.width - contentInset.left))) else { return } guard pagerScroll != .no || (pagerScroll != .onlyIfOutOfScreen && (toFrame.origin.x < contentOffset.x || toFrame.origin.x >= (contentOffset.x + frame.size.width - contentInset.left))) else { return }
let targetContentOffset = contentSize.width > frame.size.width ? contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) : 0 let targetContentOffset = contentSize.width > frame.size.width ? contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) : 0
setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated) setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated)
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
import UIKit import UIKit
class VLCRemoteNetworkCell: UITableViewCell { class VLCRemoteNetworkCell: UITableViewCell {
@objc static var cellIdentifier = "RemoteNetworkCell" @objc static let cellIdentifier = "RemoteNetworkCell"
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
......
...@@ -18,7 +18,7 @@ class VLCVideoSubcategoryViewController: VLCMediaSubcategoryViewController { ...@@ -18,7 +18,7 @@ class VLCVideoSubcategoryViewController: VLCMediaSubcategoryViewController {
let episodes = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .episodes)) let episodes = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .episodes))
let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .videoPlaylists)) let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .videoPlaylists))
let viewControllers = [movies, episodes, playlists] let viewControllers = [movies, episodes, playlists]
viewControllers.forEach { $0.delegate = self.mediaDelegate } viewControllers.forEach { $0.delegate = mediaDelegate }
return viewControllers return viewControllers
} }
} }
...@@ -31,15 +31,15 @@ class VLCAudioSubcategoryViewController: VLCMediaSubcategoryViewController { ...@@ -31,15 +31,15 @@ class VLCAudioSubcategoryViewController: VLCMediaSubcategoryViewController {
let albums = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .albums)) let albums = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .albums))
let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .audioPlaylists)) let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .audioPlaylists))
let viewControllers = [tracks, genres, artists, albums, playlists] let viewControllers = [tracks, genres, artists, albums, playlists]
viewControllers.forEach { $0.delegate = self.mediaDelegate } viewControllers.forEach { $0.delegate = mediaDelegate }
return viewControllers return viewControllers
} }
} }
class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewController<VLCLabelCell> { class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewController<VLCLabelCell> {
internal var services: Services var services: Services
public weak var mediaDelegate: VLCMediaViewControllerDelegate? weak var mediaDelegate: VLCMediaViewControllerDelegate?
init(services: Services) { init(services: Services) {
self.services = services self.services = services
......
...@@ -14,20 +14,28 @@ import Foundation ...@@ -14,20 +14,28 @@ import Foundation
open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
public var containerView: UIScrollView! var containerView: UIScrollView!
open weak var delegate: PagerTabStripIsProgressiveDelegate? weak var delegate: PagerTabStripIsProgressiveDelegate?
open weak var datasource: PagerTabStripDataSource? weak var datasource: PagerTabStripDataSource?
open private(set) var viewControllers = [UIViewController]() private(set) var viewControllers = [UIViewController]()
open private(set) var currentIndex = 0 private(set) var currentIndex = 0
open private(set) var preCurrentIndex = 0 // used *only* to store the index to which move when the pager becomes visible private(set) var preCurrentIndex = 0 // used *only* to store the index to which move when the pager becomes visible
open var pageWidth: CGFloat { private var pagerTabStripChildViewControllersForScrolling: [UIViewController]?
private var lastPageNumber = 0
private var lastContentOffset: CGFloat = 0.0
private var pageBeforeRotate = 0
private var lastSize = CGSize(width: 0, height: 0)
var isViewRotating = false
var isViewAppearing = false
var pageWidth: CGFloat {
return containerView.bounds.width return containerView.bounds.width
} }
open var scrollPercentage: CGFloat { var scrollPercentage: CGFloat {
if swipeDirection != .right { if swipeDirection != .right {
let module = fmod(containerView.contentOffset.x, pageWidth) let module = fmod(containerView.contentOffset.x, pageWidth)
return module == 0.0 ? 1.0 : module / pageWidth return module == 0.0 ? 1.0 : module / pageWidth
...@@ -35,7 +43,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -35,7 +43,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth
} }
open var swipeDirection: SwipeDirection { var swipeDirection: SwipeDirection {
if containerView.contentOffset.x > lastContentOffset { if containerView.contentOffset.x > lastContentOffset {
return .left return .left
} else if containerView.contentOffset.x < lastContentOffset { } else if containerView.contentOffset.x < lastContentOffset {
...@@ -50,9 +58,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -50,9 +58,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
containerView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)) containerView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
containerView.translatesAutoresizingMaskIntoConstraints = false containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.bounces = true
containerView.alwaysBounceHorizontal = true containerView.alwaysBounceHorizontal = true
containerView.alwaysBounceVertical = false
containerView.scrollsToTop = false containerView.scrollsToTop = false
containerView.delegate = self containerView.delegate = self
containerView.showsVerticalScrollIndicator = false containerView.showsVerticalScrollIndicator = false
...@@ -81,7 +87,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -81,7 +87,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
childViewControllers.forEach { $0.beginAppearanceTransition(true, animated: animated) } childViewControllers.forEach { $0.beginAppearanceTransition(true, animated: animated) }
} }
override open func viewDidAppear(_ animated: Bool) { open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
lastSize = containerView.bounds.size lastSize = containerView.bounds.size
updateIfNeeded() updateIfNeeded()
...@@ -103,7 +109,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -103,7 +109,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
childViewControllers.forEach { $0.endAppearanceTransition() } childViewControllers.forEach { $0.endAppearanceTransition() }
} }
override open func viewDidLayoutSubviews() { open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
updateIfNeeded() updateIfNeeded()
} }
...@@ -112,7 +118,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -112,7 +118,7 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
return false return false
} }
open func moveToViewController(at index: Int, animated: Bool = true) { func moveToViewController(at index: Int, animated: Bool = true) {
guard isViewLoaded && view.window != nil && currentIndex != index else { guard isViewLoaded && view.window != nil && currentIndex != index else {
preCurrentIndex = index preCurrentIndex = index
return return
...@@ -135,58 +141,58 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { ...@@ -135,58 +141,58 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
} }
} }
open func moveTo(viewController: UIViewController, animated: Bool = true) { func moveTo(viewController: UIViewController, animated: Bool = true) {
moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated) moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated)
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method") assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method")
return [] return []
} }
// MARK: - Helpers // MARK: - Helpers
open func updateIfNeeded() { func updateIfNeeded() {
if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) { if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) {
updateContent() updateContent()
} }
} }
open func canMoveTo(index: Int) -> Bool { func canMoveTo(index: Int) -> Bool {
return currentIndex != index && viewControllers.count > index return currentIndex != index && viewControllers.count > index
} }
open func pageOffsetForChild(at index: Int) -> CGFloat { func pageOffsetForChild(at index: Int) -> CGFloat {
return CGFloat(index) * containerView.bounds.width return CGFloat(index) * containerView.bounds.width
} }
open func offsetForChild(at index: Int) -> CGFloat { func offsetForChild(at index: Int) -> CGFloat {
return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5) return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5)
} }
public enum PagerTabStripError: Error { enum PagerTabStripError: Error {
case viewControllerOutOfBounds case viewControllerOutOfBounds
} }
open func offsetForChild(viewController: UIViewController) throws -> CGFloat { func offsetForChild(viewController: UIViewController) throws -> CGFloat {
guard let index = viewControllers.index(of: viewController) else { guard let index = viewControllers.index(of: viewController) else {
throw PagerTabStripError.viewControllerOutOfBounds throw PagerTabStripError.viewControllerOutOfBounds
} }
return offsetForChild(at: index) return offsetForChild(at: index)
} }
open func pageFor(contentOffset: CGFloat) -> Int { func pageFor(contentOffset: CGFloat) -> Int {
let result = virtualPageFor(contentOffset: contentOffset) let result = virtualPageFor(contentOffset: contentOffset)
return pageFor(virtualPage: result) return pageFor(virtualPage: result)
} }
open func virtualPageFor(contentOffset: CGFloat) -> Int { func virtualPageFor(contentOffset: CGFloat) -> Int {
return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1 return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1
}