Преглед на файлове

MediaSubcategoryController: moved classes into separate files

Moved setup code into ButtonBarView,
remove not needed code out of various files
Carola Nitz преди 7 години
родител
ревизия
6ced633bb4

+ 0 - 50
ButtonCell.xib

@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14092" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina4_7" orientation="portrait">
-        <adaptation id="fullscreen"/>
-    </device>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14081.1"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="zg4-fX-zUF">
-            <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
-                <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <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="s7f-rk-sQl">
-                        <rect key="frame" x="22" y="12" width="37.5" height="17"/>
-                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
-                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <nil key="highlightedColor"/>
-                    </label>
-                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tFG-yJ-6Th">
-                        <rect key="frame" x="22.5" y="2.5" width="35" height="35"/>
-                        <constraints>
-                            <constraint firstAttribute="width" constant="35" id="VRw-5F-5WY"/>
-                            <constraint firstAttribute="height" constant="35" id="ojk-Ug-Lgh"/>
-                        </constraints>
-                    </imageView>
-                </subviews>
-            </view>
-            <color key="backgroundColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="tFG-yJ-6Th" firstAttribute="centerY" secondItem="zg4-fX-zUF" secondAttribute="centerY" id="5so-ZP-gRs"/>
-                <constraint firstItem="tFG-yJ-6Th" firstAttribute="centerX" secondItem="zg4-fX-zUF" secondAttribute="centerX" id="9em-NR-hoa"/>
-                <constraint firstItem="s7f-rk-sQl" firstAttribute="centerY" secondItem="zg4-fX-zUF" secondAttribute="centerY" id="ZeP-6I-AXE"/>
-                <constraint firstItem="s7f-rk-sQl" firstAttribute="centerX" secondItem="zg4-fX-zUF" secondAttribute="centerX" id="c15-bZ-hPG"/>
-            </constraints>
-            <connections>
-                <outlet property="imageView" destination="tFG-yJ-6Th" id="Odb-dR-tf4"/>
-                <outlet property="label" destination="s7f-rk-sQl" id="4gU-tb-BMB"/>
-            </connections>
-            <point key="canvasLocation" x="307" y="541"/>
-        </collectionViewCell>
-    </objects>
-</document>

+ 2 - 2
LabelCell.xib

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
@@ -11,7 +11,7 @@
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <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="LabelCell" customModule="VLC_iOS" customModuleProvider="target">
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" 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"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
             <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">

+ 9 - 4
Resources/en.lproj/Localizable.strings

@@ -51,7 +51,9 @@
 "CONTINUE_PLAYBACK" = "Continue playback?";
 "CONTINUE_PLAYBACK_LONG" = "Would you like to continue playback of \"%@\" where you left off?";
 
+"BUTTON_ALL" = "Select All";
 "BUTTON_BACK" = "Back";
+"BUTTON_EDIT" = "Edit";
 "BUTTON_DONE" = "Done";
 "BUTTON_CANCEL" = "Cancel";
 "BUTTON_SAVE" = "Save";
@@ -95,6 +97,7 @@
 "DOWNLOAD_FROM_HTTP_HELP" = "Enter an address to download the file to your %@.";
 "DOWNLOAD_FROM_HTTP" = "Downloads";
 "ERROR_NUMBER" = "Error %i occured";
+"DOWNLOAD_FAILED" = "Download failed";
 "FILE_NOT_SUPPORTED" = "File format not supported";
 "FILE_NOT_SUPPORTED_LONG" = "The file format used by %@ is not supported by this version of VLC for iOS.";
 "SCHEME_NOT_SUPPORTED" = "Address scheme not supported";
@@ -105,6 +108,7 @@
 "LIBRARY_SINGLE_EPISODE" = "%i Episode, %i unread";
 "LIBRARY_TRACK_N" = "Track %i";
 "LIBRARY_MINUTES_LEFT" = "%@m left";
+"RENAME_MEDIA_TO" = "Enter new name for %@";
 
 
 "SHARING_ACTION_SHEET_TITLE_CHOOSE_FILE" = "Choose a file to open:";
@@ -282,6 +286,10 @@
 // Insert %@ where play-pause-glyph should be placed
 "DELETE_ITEM_HINT" = "Press %@ to Delete"; /* Insert %@ where play-pause-glyph should be placed */
 
+"DELETE_INVALID_MESSAGE" = "The selection can't be deleted";
+"DELETE_INVALID_TITLE" = "Invalid Selection";
+"DELETE_MESSAGE" = "Confirm the deletion of the selected files";
+"DELETE_TITLE" = "Delete Selected Files";
 
 //Drag and Drop
 "THIS_FILE" = "This file";
@@ -298,10 +306,7 @@
 "SORT_BY" = "Sort by";
 "VIDEO" = "Video";
 
-/* New strings */
-"FOLDER_EMPTY" = "FOLDER_EMPTY";
-
-/* New strings */
+// MediaViewController Swipable Header
 "ALBUMS" = "Albums";
 "ARTISTS" = "Artists";
 "AUDIO_PLAYLISTS" = "Playlists";

+ 23 - 380
Sources/BaseButtonBarPagerTabStripViewController.swift

@@ -12,7 +12,7 @@
 
 import Foundation
 
-class LabelCell: UICollectionViewCell {
+class VLCLabelCell: UICollectionViewCell {
 
     @IBOutlet weak var iconLabel: UILabel!
 
@@ -44,7 +44,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
 
     public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)?
 
-    @IBOutlet public weak var buttonBarView: ButtonBarView!
+    public var buttonBarView: ButtonBarView!
 
     lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in
         return self.calculateWidths()
@@ -64,42 +64,31 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
     open override func viewDidLoad() {
         super.viewDidLoad()
 
-        let buttonBarViewAux = buttonBarView ?? {
-            let flowLayout = UICollectionViewFlowLayout()
-            flowLayout.scrollDirection = .horizontal
-            let buttonBar = ButtonBarView(frame: .zero, collectionViewLayout: flowLayout)
-            buttonBar.backgroundColor = .white
-            buttonBar.selectedBar.backgroundColor = PresentationTheme.current.colors.orangeUI
-            buttonBar.scrollsToTop = false
-            buttonBar.showsHorizontalScrollIndicator = false
-            buttonBar.selectedBarHeight = 4.0
-            return buttonBar
-            }()
-        buttonBarView = buttonBarViewAux
-
-        if buttonBarView.superview == nil {
-            buttonBarView.translatesAutoresizingMaskIntoConstraints = false
-            view.addSubview(buttonBarView)
-            NSLayoutConstraint.activate([
-                buttonBarView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor),
-                buttonBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
-                buttonBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
-                buttonBarView.heightAnchor.constraint(equalToConstant: 35)
-                ])
-            NSLayoutConstraint.activate([
-                containerView.topAnchor.constraint(equalTo: buttonBarView.bottomAnchor),
-                containerView.rightAnchor.constraint(equalTo: view.rightAnchor),
-                containerView.leftAnchor.constraint(equalTo: view.leftAnchor),
-                containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
-                ]
-            )
-        }
+        let flowLayout = UICollectionViewFlowLayout()
+        flowLayout.scrollDirection = .horizontal
+        buttonBarView = ButtonBarView(frame: .zero, collectionViewLayout: flowLayout)
+
+        buttonBarView.translatesAutoresizingMaskIntoConstraints = false
+        view.addSubview(buttonBarView)
+        NSLayoutConstraint.activate([
+            buttonBarView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor),
+            buttonBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
+            buttonBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
+            buttonBarView.heightAnchor.constraint(equalToConstant: 35)
+            ])
+        NSLayoutConstraint.activate([
+            containerView.topAnchor.constraint(equalTo: buttonBarView.bottomAnchor),
+            containerView.rightAnchor.constraint(equalTo: view.rightAnchor),
+            containerView.leftAnchor.constraint(equalTo: view.leftAnchor),
+            containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+            ]
+        )
 
         buttonBarView.delegate = self
         buttonBarView.dataSource = self
 
         // register button bar item cell
-        buttonBarView.register(UINib(nibName: "LabelCell", bundle: .main), forCellWithReuseIdentifier:"Cell")
+        buttonBarView.register(UINib(nibName: "VLCLabelCell", bundle: .main), forCellWithReuseIdentifier:"Cell")
     }
 
     open override func viewWillAppear(_ animated: Bool) {
@@ -249,7 +238,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollect
 
         var minimumCellWidths = [CGFloat]()
         var collectionViewContentWidth: CGFloat = 0
-        let indicatorWidth:CGFloat = 70.0
+        let indicatorWidth: CGFloat = 70.0
 
         viewControllers.forEach { _ in
             minimumCellWidths.append(indicatorWidth)
@@ -298,350 +287,4 @@ public protocol PagerTabStripDataSource: class {
     func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController]
 }
 
-// MARK: PagerTabStripViewController
-
-open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
-
-    @IBOutlet weak public var containerView: UIScrollView!
-
-    open weak var delegate: PagerTabStripIsProgressiveDelegate?
-    open weak var datasource: PagerTabStripDataSource?
-
-    open private(set) var viewControllers = [UIViewController]()
-    open 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
-
-    open var pageWidth: CGFloat {
-        return containerView.bounds.width
-    }
-
-    open var scrollPercentage: CGFloat {
-        if swipeDirection != .right {
-            let module = fmod(containerView.contentOffset.x, pageWidth)
-            return module == 0.0 ? 1.0 : module / pageWidth
-        }
-        return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth
-    }
-
-    open var swipeDirection: SwipeDirection {
-        if containerView.contentOffset.x > lastContentOffset {
-            return .left
-        } else if containerView.contentOffset.x < lastContentOffset {
-            return .right
-        }
-        return .none
-    }
-
-    override open func viewDidLoad() {
-        super.viewDidLoad()
-        let containerViewAux = containerView ?? {
-            return UIScrollView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
-            }()
-        containerView = containerViewAux
-        if containerView.superview == nil {
-            containerView.translatesAutoresizingMaskIntoConstraints = false
-            view.addSubview(containerView)
-        }
-        containerView.bounces = true
-        containerView.alwaysBounceHorizontal = true
-        containerView.alwaysBounceVertical = false
-        containerView.scrollsToTop = false
-        containerView.delegate = self
-        containerView.showsVerticalScrollIndicator = false
-        containerView.showsHorizontalScrollIndicator = false
-        containerView.isPagingEnabled = true
-        containerView.backgroundColor = PresentationTheme.current.colors.background
-        reloadViewControllers()
-
-        let childController = viewControllers[currentIndex]
-        addChildViewController(childController)
-        childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
-        containerView.addSubview(childController.view)
-        childController.didMove(toParentViewController: self)
-    }
-
-    open override func viewWillAppear(_ animated: Bool) {
-        super.viewWillAppear(animated)
-        isViewAppearing = true
-        childViewControllers.forEach { $0.beginAppearanceTransition(true, animated: animated) }
-    }
-
-    override open func viewDidAppear(_ animated: Bool) {
-        super.viewDidAppear(animated)
-        lastSize = containerView.bounds.size
-        updateIfNeeded()
-        let needToUpdateCurrentChild = preCurrentIndex != currentIndex
-        if needToUpdateCurrentChild {
-            moveToViewController(at: preCurrentIndex)
-        }
-        isViewAppearing = false
-        childViewControllers.forEach { $0.endAppearanceTransition() }
-    }
-
-    open override func viewWillDisappear(_ animated: Bool) {
-        super.viewWillDisappear(animated)
-        childViewControllers.forEach { $0.beginAppearanceTransition(false, animated: animated) }
-    }
-
-    open override func viewDidDisappear(_ animated: Bool) {
-        super.viewDidDisappear(animated)
-        childViewControllers.forEach { $0.endAppearanceTransition() }
-    }
-
-    override open func viewDidLayoutSubviews() {
-        super.viewDidLayoutSubviews()
-        updateIfNeeded()
-    }
-
-    open override var shouldAutomaticallyForwardAppearanceMethods: Bool {
-        return false
-    }
-
-    open func moveToViewController(at index: Int, animated: Bool = true) {
-        guard isViewLoaded && view.window != nil && currentIndex != index else {
-            preCurrentIndex = index
-            return
-        }
-
-        if animated && abs(currentIndex - index) > 1 {
-            var tmpViewControllers = viewControllers
-            let currentChildVC = viewControllers[currentIndex]
-            let fromIndex = currentIndex < index ? index - 1 : index + 1
-            let fromChildVC = viewControllers[fromIndex]
-            tmpViewControllers[currentIndex] = fromChildVC
-            tmpViewControllers[fromIndex] = currentChildVC
-            pagerTabStripChildViewControllersForScrolling = tmpViewControllers
-            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: fromIndex), y: 0), animated: false)
-            (navigationController?.view ?? view).isUserInteractionEnabled = !animated
-            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: true)
-        } else {
-            (navigationController?.view ?? view).isUserInteractionEnabled = !animated
-            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: animated)
-        }
-    }
 
-    open func moveTo(viewController: UIViewController, animated: Bool = true) {
-        moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated)
-    }
-
-    // MARK: - PagerTabStripDataSource
-
-    open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
-        assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method")
-        return []
-    }
-
-    // MARK: - Helpers
-
-    open func updateIfNeeded() {
-        if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) {
-            updateContent()
-        }
-    }
-
-    open func canMoveTo(index: Int) -> Bool {
-        return currentIndex != index && viewControllers.count > index
-    }
-
-    open func pageOffsetForChild(at index: Int) -> CGFloat {
-        return CGFloat(index) * containerView.bounds.width
-    }
-
-    open func offsetForChild(at index: Int) -> CGFloat {
-        return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5)
-    }
-
-    public enum PagerTabStripError: Error {
-        case viewControllerOutOfBounds
-    }
-
-    open func offsetForChild(viewController: UIViewController) throws -> CGFloat {
-        guard let index = viewControllers.index(of: viewController) else {
-            throw PagerTabStripError.viewControllerOutOfBounds
-        }
-        return offsetForChild(at: index)
-    }
-
-    open func pageFor(contentOffset: CGFloat) -> Int {
-        let result = virtualPageFor(contentOffset: contentOffset)
-        return pageFor(virtualPage: result)
-    }
-
-    open func virtualPageFor(contentOffset: CGFloat) -> Int {
-        return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1
-    }
-
-    open func pageFor(virtualPage: Int) -> Int {
-        if virtualPage < 0 {
-            return 0
-        }
-        if virtualPage > viewControllers.count - 1 {
-            return viewControllers.count - 1
-        }
-        return virtualPage
-    }
-
-    open func updateContent() {
-        if lastSize.width != containerView.bounds.size.width {
-            lastSize = containerView.bounds.size
-            containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
-        }
-        lastSize = containerView.bounds.size
-
-        let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers
-        containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(pagerViewControllers.count), height: containerView.contentSize.height)
-
-        for (index, childController) in pagerViewControllers.enumerated() {
-            let pageOffsetForChild = self.pageOffsetForChild(at: index)
-            if fabs(containerView.contentOffset.x - pageOffsetForChild) < containerView.bounds.width {
-                if childController.parent != nil {
-                    childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
-                    childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
-                } else {
-                    childController.beginAppearanceTransition(true, animated: false)
-                    addChildViewController(childController)
-                    childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
-                    childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
-                    containerView.addSubview(childController.view)
-                    childController.didMove(toParentViewController: self)
-                    childController.endAppearanceTransition()
-                }
-            } else {
-                if childController.parent != nil {
-                    childController.beginAppearanceTransition(false, animated: false)
-                    childController.willMove(toParentViewController: nil)
-                    childController.view.removeFromSuperview()
-                    childController.removeFromParentViewController()
-                    childController.endAppearanceTransition()
-                }
-            }
-        }
-
-        let oldCurrentIndex = currentIndex
-        let virtualPage = virtualPageFor(contentOffset: containerView.contentOffset.x)
-        let newCurrentIndex = pageFor(virtualPage: virtualPage)
-        currentIndex = newCurrentIndex
-        preCurrentIndex = currentIndex
-        let changeCurrentIndex = newCurrentIndex != oldCurrentIndex
-
-        if let progressiveDelegate = self as? PagerTabStripIsProgressiveDelegate {
-
-            let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage)
-            progressiveDelegate.updateIndicator(for: self, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex)
-        }
-    }
-
-    open func reloadPagerTabStripView() {
-        guard isViewLoaded else { return }
-        for childController in viewControllers where childController.parent != nil {
-            childController.beginAppearanceTransition(false, animated: false)
-            childController.willMove(toParentViewController: nil)
-            childController.view.removeFromSuperview()
-            childController.removeFromParentViewController()
-            childController.endAppearanceTransition()
-        }
-        reloadViewControllers()
-        containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(viewControllers.count), height: containerView.contentSize.height)
-        if currentIndex >= viewControllers.count {
-            currentIndex = viewControllers.count - 1
-        }
-        preCurrentIndex = currentIndex
-        containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
-        updateContent()
-    }
-
-    // MARK: - UIScrollViewDelegate
-
-    open func scrollViewDidScroll(_ scrollView: UIScrollView) {
-        if containerView == scrollView {
-            updateContent()
-            lastContentOffset = scrollView.contentOffset.x
-        }
-    }
-
-    open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
-        if containerView == scrollView {
-            lastPageNumber = pageFor(contentOffset: scrollView.contentOffset.x)
-        }
-    }
-
-    open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
-        if containerView == scrollView {
-            pagerTabStripChildViewControllersForScrolling = nil
-            (navigationController?.view ?? view).isUserInteractionEnabled = true
-            updateContent()
-        }
-    }
-
-    // MARK: - Orientation
-
-    open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
-        super.viewWillTransition(to: size, with: coordinator)
-        isViewRotating = true
-        pageBeforeRotate = currentIndex
-        coordinator.animate(alongsideTransition: nil) { [weak self] _ in
-            guard let me = self else { return }
-            me.isViewRotating = false
-            me.currentIndex = me.pageBeforeRotate
-            me.preCurrentIndex = me.currentIndex
-            me.updateIfNeeded()
-        }
-    }
-
-    // MARK: Private
-
-    private func progressiveIndicatorData(_ virtualPage: Int) -> (Int, Int, CGFloat) {
-        let count = viewControllers.count
-        var fromIndex = currentIndex
-        var toIndex = currentIndex
-        let direction = swipeDirection
-
-        if direction == .left {
-            if virtualPage > count - 1 {
-                fromIndex = count - 1
-                toIndex = count
-            } else {
-                if self.scrollPercentage >= 0.5 {
-                    fromIndex = max(toIndex - 1, 0)
-                } else {
-                    toIndex = fromIndex + 1
-                }
-            }
-        } else if direction == .right {
-            if virtualPage < 0 {
-                fromIndex = 0
-                toIndex = -1
-            } else {
-                if self.scrollPercentage > 0.5 {
-                    fromIndex = min(toIndex + 1, count - 1)
-                } else {
-                    toIndex = fromIndex - 1
-                }
-            }
-        }
-
-        return (fromIndex, toIndex, self.scrollPercentage)
-    }
-
-    private func reloadViewControllers() {
-        guard let dataSource = datasource else {
-            fatalError("dataSource must not be nil")
-        }
-        viewControllers = dataSource.viewControllers(for: self)
-        // viewControllers
-        guard !viewControllers.isEmpty else {
-            fatalError("viewControllers(for:) should provide at least one child view controller")
-        }
-        viewControllers.forEach { if !($0 is IndicatorInfoProvider) { fatalError("Every view controller provided by PagerTabStripDataSource's viewControllers(for:) method must conform to IndicatorInfoProvider") }}
-
-    }
-
-    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)
-    internal var isViewRotating = false
-    internal var isViewAppearing = false
-
-}

+ 24 - 19
Sources/ButtonBarView.swift

@@ -1,39 +1,44 @@
-//
-//  ButtonBarView.swift
-//  VLC-iOS
-//
-//  Created by Carola Nitz on 6/1/18.
-//  Copyright © 2018 VideoLAN. All rights reserved.
-//
+/*****************************************************************************
+ * ButtonBarView.Swift
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2018 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Carola Nitz <nitz.carola # googlemail.com>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
 
 import Foundation
 
 open class ButtonBarView: UICollectionView {
 
-    open lazy var selectedBar: UIView = { [unowned self] in
-        let bar  = UIView(frame: CGRect(x: 0, y: self.frame.size.height - CGFloat(self.selectedBarHeight), width: 0, height: CGFloat(self.selectedBarHeight)))
-        bar.layer.zPosition = 9999
-        return bar
-        }()
+    open var selectedBar: UIView!
 
-    internal var selectedBarHeight: CGFloat = 4 {
-        didSet {
-            updateSelectedBarYPosition()
-        }
-    }
+    internal var selectedBarHeight: CGFloat = 4
 
     var selectedIndex = 0
 
+    @available(*, unavailable, message: "use init(frame:)")
     required public init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        addSubview(selectedBar)
+        fatalError()
     }
 
     public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
         super.init(frame: frame, collectionViewLayout: layout)
+        setup()
         addSubview(selectedBar)
     }
 
+    func setup() {
+        backgroundColor = .white
+        scrollsToTop = false
+        showsHorizontalScrollIndicator = false
+        selectedBar = UIView(frame: CGRect(x: 0, y: self.frame.size.height - CGFloat(self.selectedBarHeight), width: 0, height: CGFloat(self.selectedBarHeight)))
+        selectedBar.backgroundColor = PresentationTheme.current.colors.orangeUI
+    }
+
     open func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) {
         selectedIndex = index
         updateSelectedBarPosition(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll)

+ 8 - 10
Sources/MediaSubcategoryViewController.swift

@@ -12,20 +12,18 @@
 
 import UIKit
 
-class VLCVideoSubcategoryViewController: VLCMediaSubcategoryViewController
-{
+class VLCVideoSubcategoryViewController: VLCMediaSubcategoryViewController {
     override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
         let movies = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .allVideos))
         let episodes = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .episodes))
         let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .video, subcategory: .videoPlaylists))
         let viewControllers = [movies, episodes, playlists]
-        viewControllers.forEach{ $0.delegate = self.mediaDelegate }
+        viewControllers.forEach { $0.delegate = self.mediaDelegate }
         return viewControllers
     }
 }
 
-class VLCAudioSubcategoryViewController: VLCMediaSubcategoryViewController
-{
+class VLCAudioSubcategoryViewController: VLCMediaSubcategoryViewController {
     override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
         let tracks = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .tracks))
         let genres = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .genres))
@@ -33,12 +31,12 @@ class VLCAudioSubcategoryViewController: VLCMediaSubcategoryViewController
         let albums = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .albums))
         let playlists = VLCMediaViewController(services: services, type: VLCMediaType(category: .audio, subcategory: .audioPlaylists))
         let viewControllers = [tracks, genres, artists, albums, playlists]
-        viewControllers.forEach{ $0.delegate = self.mediaDelegate }
+        viewControllers.forEach { $0.delegate = self.mediaDelegate }
         return viewControllers
     }
 }
 
-class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewController<LabelCell> {
+class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewController<VLCLabelCell> {
 
     internal var services: Services
     public weak var mediaDelegate: VLCMediaViewControllerDelegate?
@@ -50,7 +48,7 @@ class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewControlle
 
     override func viewDidLoad() {
 
-        changeCurrentIndexProgressive = { (oldCell: LabelCell?, newCell: LabelCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) in
+        changeCurrentIndexProgressive = { (oldCell: VLCLabelCell?, newCell: VLCLabelCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) in
             guard changeCurrentIndex == true else { return }
             oldCell?.iconLabel.textColor = PresentationTheme.current.colors.cellDetailTextColor
             newCell?.iconLabel.textColor = PresentationTheme.current.colors.orangeUI
@@ -67,7 +65,7 @@ class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewControlle
         fatalError("this should only be used as subclass")
     }
 
-    override func configure(cell: LabelCell, for indicatorInfo: IndicatorInfo) {
+    override func configure(cell: VLCLabelCell, for indicatorInfo: IndicatorInfo) {
         cell.iconLabel.text = indicatorInfo.title
     }
 
@@ -77,7 +75,7 @@ class VLCMediaSubcategoryViewController: BaseButtonBarPagerTabStripViewControlle
             let child = viewControllers[toIndex] as! IndicatorInfoProvider
             UIView.performWithoutAnimation({ [weak self] in
                 guard let me = self else { return }
-                me.navigationItem.leftBarButtonItem?.title =  child.indicatorInfo(for: me).title
+                me.navigationItem.leftBarButtonItem?.title = child.indicatorInfo(for: me).title
             })
         }
     }

+ 356 - 0
Sources/PagerStripViewController.swift

@@ -0,0 +1,356 @@
+/*****************************************************************************
+ * PagerTabStripViewController.Swift
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2018 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Carola Nitz <nitz.carola # googlemail.com>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+import Foundation
+
+open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
+
+    public var containerView: UIScrollView!
+
+    open weak var delegate: PagerTabStripIsProgressiveDelegate?
+    open weak var datasource: PagerTabStripDataSource?
+
+    open private(set) var viewControllers = [UIViewController]()
+    open 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
+
+    open var pageWidth: CGFloat {
+        return containerView.bounds.width
+    }
+
+    open var scrollPercentage: CGFloat {
+        if swipeDirection != .right {
+            let module = fmod(containerView.contentOffset.x, pageWidth)
+            return module == 0.0 ? 1.0 : module / pageWidth
+        }
+        return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth
+    }
+
+    open var swipeDirection: SwipeDirection {
+        if containerView.contentOffset.x > lastContentOffset {
+            return .left
+        } else if containerView.contentOffset.x < lastContentOffset {
+            return .right
+        }
+        return .none
+    }
+
+    override open func viewDidLoad() {
+        super.viewDidLoad()
+
+        containerView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
+
+        containerView.translatesAutoresizingMaskIntoConstraints = false
+        containerView.bounces = true
+        containerView.alwaysBounceHorizontal = true
+        containerView.alwaysBounceVertical = false
+        containerView.scrollsToTop = false
+        containerView.delegate = self
+        containerView.showsVerticalScrollIndicator = false
+        containerView.showsHorizontalScrollIndicator = false
+        containerView.isPagingEnabled = true
+        containerView.backgroundColor = PresentationTheme.current.colors.background
+        view.addSubview(containerView)
+
+        reloadViewControllers()
+
+        let childController = viewControllers[currentIndex]
+        addChildViewController(childController)
+        childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+        containerView.addSubview(childController.view)
+        childController.didMove(toParentViewController: self)
+    }
+
+    open override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        isViewAppearing = true
+        childViewControllers.forEach { $0.beginAppearanceTransition(true, animated: animated) }
+    }
+
+    override open func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        lastSize = containerView.bounds.size
+        updateIfNeeded()
+        let needToUpdateCurrentChild = preCurrentIndex != currentIndex
+        if needToUpdateCurrentChild {
+            moveToViewController(at: preCurrentIndex)
+        }
+        isViewAppearing = false
+        childViewControllers.forEach { $0.endAppearanceTransition() }
+    }
+
+    open override func viewWillDisappear(_ animated: Bool) {
+        super.viewWillDisappear(animated)
+        childViewControllers.forEach { $0.beginAppearanceTransition(false, animated: animated) }
+    }
+
+    open override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+        childViewControllers.forEach { $0.endAppearanceTransition() }
+    }
+
+    override open func viewDidLayoutSubviews() {
+        super.viewDidLayoutSubviews()
+        updateIfNeeded()
+    }
+
+    open override var shouldAutomaticallyForwardAppearanceMethods: Bool {
+        return false
+    }
+
+    open func moveToViewController(at index: Int, animated: Bool = true) {
+        guard isViewLoaded && view.window != nil && currentIndex != index else {
+            preCurrentIndex = index
+            return
+        }
+
+        if animated && abs(currentIndex - index) > 1 {
+            var tmpViewControllers = viewControllers
+            let currentChildVC = viewControllers[currentIndex]
+            let fromIndex = currentIndex < index ? index - 1 : index + 1
+            let fromChildVC = viewControllers[fromIndex]
+            tmpViewControllers[currentIndex] = fromChildVC
+            tmpViewControllers[fromIndex] = currentChildVC
+            pagerTabStripChildViewControllersForScrolling = tmpViewControllers
+            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: fromIndex), y: 0), animated: false)
+            (navigationController?.view ?? view).isUserInteractionEnabled = !animated
+            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: true)
+        } else {
+            (navigationController?.view ?? view).isUserInteractionEnabled = !animated
+            containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: animated)
+        }
+    }
+
+    open func moveTo(viewController: UIViewController, animated: Bool = true) {
+        moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated)
+    }
+
+    // MARK: - PagerTabStripDataSource
+
+    open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
+        assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method")
+        return []
+    }
+
+    // MARK: - Helpers
+
+    open func updateIfNeeded() {
+        if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) {
+            updateContent()
+        }
+    }
+
+    open func canMoveTo(index: Int) -> Bool {
+        return currentIndex != index && viewControllers.count > index
+    }
+
+    open func pageOffsetForChild(at index: Int) -> CGFloat {
+        return CGFloat(index) * containerView.bounds.width
+    }
+
+    open func offsetForChild(at index: Int) -> CGFloat {
+        return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5)
+    }
+
+    public enum PagerTabStripError: Error {
+        case viewControllerOutOfBounds
+    }
+
+    open func offsetForChild(viewController: UIViewController) throws -> CGFloat {
+        guard let index = viewControllers.index(of: viewController) else {
+            throw PagerTabStripError.viewControllerOutOfBounds
+        }
+        return offsetForChild(at: index)
+    }
+
+    open func pageFor(contentOffset: CGFloat) -> Int {
+        let result = virtualPageFor(contentOffset: contentOffset)
+        return pageFor(virtualPage: result)
+    }
+
+    open func virtualPageFor(contentOffset: CGFloat) -> Int {
+        return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1
+    }
+
+    open func pageFor(virtualPage: Int) -> Int {
+        if virtualPage < 0 {
+            return 0
+        }
+        if virtualPage > viewControllers.count - 1 {
+            return viewControllers.count - 1
+        }
+        return virtualPage
+    }
+
+    open func updateContent() {
+        if lastSize.width != containerView.bounds.size.width {
+            lastSize = containerView.bounds.size
+            containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
+        }
+        lastSize = containerView.bounds.size
+
+        let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers
+        containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(pagerViewControllers.count), height: containerView.contentSize.height)
+
+        for (index, childController) in pagerViewControllers.enumerated() {
+            let pageOffsetForChild = self.pageOffsetForChild(at: index)
+            if fabs(containerView.contentOffset.x - pageOffsetForChild) < containerView.bounds.width {
+                if childController.parent != nil {
+                    childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
+                    childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+                } else {
+                    childController.beginAppearanceTransition(true, animated: false)
+                    addChildViewController(childController)
+                    childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
+                    childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+                    containerView.addSubview(childController.view)
+                    childController.didMove(toParentViewController: self)
+                    childController.endAppearanceTransition()
+                }
+            } else {
+                if childController.parent != nil {
+                    childController.beginAppearanceTransition(false, animated: false)
+                    childController.willMove(toParentViewController: nil)
+                    childController.view.removeFromSuperview()
+                    childController.removeFromParentViewController()
+                    childController.endAppearanceTransition()
+                }
+            }
+        }
+
+        let oldCurrentIndex = currentIndex
+        let virtualPage = virtualPageFor(contentOffset: containerView.contentOffset.x)
+        let newCurrentIndex = pageFor(virtualPage: virtualPage)
+        currentIndex = newCurrentIndex
+        preCurrentIndex = currentIndex
+        let changeCurrentIndex = newCurrentIndex != oldCurrentIndex
+
+        if let progressiveDelegate = self as? PagerTabStripIsProgressiveDelegate {
+
+            let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage)
+            progressiveDelegate.updateIndicator(for: self, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex)
+        }
+    }
+
+    open func reloadPagerTabStripView() {
+        guard isViewLoaded else { return }
+        for childController in viewControllers where childController.parent != nil {
+            childController.beginAppearanceTransition(false, animated: false)
+            childController.willMove(toParentViewController: nil)
+            childController.view.removeFromSuperview()
+            childController.removeFromParentViewController()
+            childController.endAppearanceTransition()
+        }
+        reloadViewControllers()
+        containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(viewControllers.count), height: containerView.contentSize.height)
+        if currentIndex >= viewControllers.count {
+            currentIndex = viewControllers.count - 1
+        }
+        preCurrentIndex = currentIndex
+        containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
+        updateContent()
+    }
+
+    // MARK: - UIScrollViewDelegate
+
+    open func scrollViewDidScroll(_ scrollView: UIScrollView) {
+        if containerView == scrollView {
+            updateContent()
+            lastContentOffset = scrollView.contentOffset.x
+        }
+    }
+
+    open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
+        if containerView == scrollView {
+            lastPageNumber = pageFor(contentOffset: scrollView.contentOffset.x)
+        }
+    }
+
+    open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
+        if containerView == scrollView {
+            pagerTabStripChildViewControllersForScrolling = nil
+            (navigationController?.view ?? view).isUserInteractionEnabled = true
+            updateContent()
+        }
+    }
+
+    // MARK: - Orientation
+
+    open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+        super.viewWillTransition(to: size, with: coordinator)
+        isViewRotating = true
+        pageBeforeRotate = currentIndex
+        coordinator.animate(alongsideTransition: nil) { [weak self] _ in
+            guard let me = self else { return }
+            me.isViewRotating = false
+            me.currentIndex = me.pageBeforeRotate
+            me.preCurrentIndex = me.currentIndex
+            me.updateIfNeeded()
+        }
+    }
+
+    // MARK: Private
+
+    private func progressiveIndicatorData(_ virtualPage: Int) -> (Int, Int, CGFloat) {
+        let count = viewControllers.count
+        var fromIndex = currentIndex
+        var toIndex = currentIndex
+        let direction = swipeDirection
+
+        if direction == .left {
+            if virtualPage > count - 1 {
+                fromIndex = count - 1
+                toIndex = count
+            } else {
+                if self.scrollPercentage >= 0.5 {
+                    fromIndex = max(toIndex - 1, 0)
+                } else {
+                    toIndex = fromIndex + 1
+                }
+            }
+        } else if direction == .right {
+            if virtualPage < 0 {
+                fromIndex = 0
+                toIndex = -1
+            } else {
+                if self.scrollPercentage > 0.5 {
+                    fromIndex = min(toIndex + 1, count - 1)
+                } else {
+                    toIndex = fromIndex - 1
+                }
+            }
+        }
+
+        return (fromIndex, toIndex, self.scrollPercentage)
+    }
+
+    private func reloadViewControllers() {
+        guard let dataSource = datasource else {
+            fatalError("dataSource must not be nil")
+        }
+        viewControllers = dataSource.viewControllers(for: self)
+
+        guard !viewControllers.isEmpty else {
+            fatalError("viewControllers(for:) should provide at least one child view controller")
+        }
+        viewControllers.forEach { if !($0 is IndicatorInfoProvider) { fatalError("Every view controller provided by PagerTabStripDataSource's viewControllers(for:) method must conform to IndicatorInfoProvider") }}
+
+    }
+
+    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)
+    internal var isViewRotating = false
+    internal var isViewAppearing = false
+}

+ 10 - 31
Sources/VLCMediaDataSource.swift

@@ -55,7 +55,6 @@ struct VLCMediaType {
         getAllAudio()
     }
 
-
     @objc
     func numberOfFiles(subcategory: VLCMediaSubcategory) -> Int {
         return array(for: subcategory).count
@@ -80,7 +79,6 @@ struct VLCMediaType {
         case .audioPlaylists:
             return audioPlaylist
         case .videoPlaylists:
-
             return videoPlaylist
         case .allVideos:
             return foundVideos
@@ -113,7 +111,6 @@ struct VLCMediaType {
 
     }
 
-
     @objc func object(at index: Int, subcategory: VLCMediaSubcategory) -> Any {
 
         guard index >= 0 else {
@@ -177,33 +174,28 @@ struct VLCMediaType {
 
     private func artistsFromAudio() {
         let albumtracks = MLAlbumTrack.allTracks() as! [MLAlbumTrack]
-        let tracksWithArtist = albumtracks.filter {
-            $0.artist != nil && $0.artist != ""
-            }
-        artists = tracksWithArtist.map{ $0.artist }
+        let tracksWithArtist = albumtracks.filter { $0.artist != nil && $0.artist != "" }
+        artists = tracksWithArtist.map { $0.artist }
     }
 
-    private func genresFromAudio(){
+    private func genresFromAudio() {
         let albumtracks = MLAlbumTrack.allTracks() as! [MLAlbumTrack]
-        let tracksWithArtist = albumtracks.filter {
-            $0.genre != nil && $0.genre != ""
-        }
-        genres = tracksWithArtist.map{ $0.genre }
+        let tracksWithArtist = albumtracks.filter { $0.genre != nil && $0.genre != "" }
+        genres = tracksWithArtist.map { $0.genre }
     }
 
     private func episodesFromVideos() {
         episodes = MLShowEpisode.allEpisodes() as! [MLShowEpisode]
-
     }
 
-    private func albumsFromAudio(){
+    private func albumsFromAudio() {
         albums = MLAlbum.allAlbums() as! [MLAlbum]
     }
 
     private func audioPlaylistsFromAudio() {
         let labels = MLLabel.allLabels() as! [MLLabel]
         audioPlaylist = labels.filter {
-            let audioFiles = $0.files.filter{
+            let audioFiles = $0.files.filter {
                 if let file = $0 as? MLFile {
                     return file.isSupportedAudioFile()
                 }
@@ -212,10 +204,11 @@ struct VLCMediaType {
             return !audioFiles.isEmpty
         }
     }
+
     private func videoPlaylistsFromVideos() {
         let labels = MLLabel.allLabels() as! [MLLabel]
         audioPlaylist = labels.filter {
-            let audioFiles = $0.files.filter{
+            let audioFiles = $0.files.filter {
                 if let file = $0 as? MLFile {
                     return file.isShowEpisode() || file.isMovie() || file.isClip()
                 }
@@ -226,22 +219,8 @@ struct VLCMediaType {
     }
 
     private func moviesFromVideos() {
-        movies = foundVideos.filter{ $0.isMovie() }
+        movies = foundVideos.filter { $0.isMovie() }
     }
-//    private func tracksFromAudio() {
-//        if tracks != foundAudio {
-//            tracks = foundAudio
-//            NotificationCenter.default.post(name: .VLCTracksDidChangeNotification, object: tracks)
-//        }
-//    }
-//
-//    private func allVideosFromVideos() {
-//        if allVideos != foundVideos {
-//            allVideos = foundVideos
-//            NotificationCenter.default.post(name: .VLCAllVideosDidChangeNotification, object: allVideos)
-//        }
-//    }
-
 }
 
 // Todo: implement the remove

+ 8 - 8
VLC.xcodeproj/project.pbxproj

@@ -47,14 +47,14 @@
 		41CD695C1A29D72600E60BCE /* VLCBoxController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CD69591A29D72600E60BCE /* VLCBoxController.m */; };
 		41CD695D1A29D72600E60BCE /* VLCBoxTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CD695B1A29D72600E60BCE /* VLCBoxTableViewController.m */; };
 		41D7DD0520C1853E00AD94F6 /* ButtonBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41D7DD0420C1853E00AD94F6 /* ButtonBarView.swift */; };
+		41D7DD2120C1FC2D00AD94F6 /* VLCLabelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 41D7DD2020C1FC2D00AD94F6 /* VLCLabelCell.xib */; };
+		41D7DD2720C3060300AD94F6 /* PagerStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41D7DD2620C3060300AD94F6 /* PagerStripViewController.swift */; };
 		41E6BECD207E64E900E158BA /* RemoteNetworkCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E6BECC207E64E900E158BA /* RemoteNetworkCell.swift */; };
 		41EA74C120C02DFC001E5D57 /* VLCDropboxController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784AA183A9906009EE944 /* VLCDropboxController.m */; };
 		41EA74C320C02F8E001E5D57 /* VLCBoxController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CD69591A29D72600E60BCE /* VLCBoxController.m */; };
 		41EB91D71F7BE6F500821AA5 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 417D7F5F1F7BA26200DDF36A /* VLCRemoteControlService.m */; };
 		41EB91DD1F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
 		41EB91DE1F7BFF8500821AA5 /* VLCMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */; };
-		41EB94B4209B46E9002F4C30 /* ButtonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 41EB94B3209B46E9002F4C30 /* ButtonCell.xib */; };
-		41EB94B6209B4869002F4C30 /* LabelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 41EB94B5209B4869002F4C30 /* LabelCell.xib */; };
 		41F5C0781F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F5C0771F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m */; };
 		41F9BC7C1F4F20E400268461 /* VLCTrackSelectorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F9BC7B1F4F20E400268461 /* VLCTrackSelectorView.m */; };
 		41FCD2F820B565B600660AAB /* VLCAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41FCD2F720B565B500660AAB /* VLCAlertViewController.swift */; };
@@ -582,11 +582,11 @@
 		41CD695A1A29D72600E60BCE /* VLCBoxTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCBoxTableViewController.h; path = Sources/VLCBoxTableViewController.h; sourceTree = SOURCE_ROOT; };
 		41CD695B1A29D72600E60BCE /* VLCBoxTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCBoxTableViewController.m; path = Sources/VLCBoxTableViewController.m; sourceTree = SOURCE_ROOT; };
 		41D7DD0420C1853E00AD94F6 /* ButtonBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ButtonBarView.swift; path = Sources/ButtonBarView.swift; sourceTree = "<group>"; };
+		41D7DD2020C1FC2D00AD94F6 /* VLCLabelCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VLCLabelCell.xib; path = Resources/VLCLabelCell.xib; sourceTree = "<group>"; };
+		41D7DD2620C3060300AD94F6 /* PagerStripViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PagerStripViewController.swift; path = Sources/PagerStripViewController.swift; sourceTree = "<group>"; };
 		41E6BECC207E64E900E158BA /* RemoteNetworkCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteNetworkCell.swift; sourceTree = "<group>"; };
 		41EB91DB1F7BFF8400821AA5 /* VLCMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCMetadata.h; sourceTree = "<group>"; };
 		41EB91DC1F7BFF8400821AA5 /* VLCMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCMetadata.m; sourceTree = "<group>"; };
-		41EB94B3209B46E9002F4C30 /* ButtonCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ButtonCell.xib; sourceTree = "<group>"; };
-		41EB94B5209B4869002F4C30 /* LabelCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LabelCell.xib; sourceTree = "<group>"; };
 		41F5C0761F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCLibrarySearchDisplayDataSource.h; path = Sources/VLCLibrarySearchDisplayDataSource.h; sourceTree = SOURCE_ROOT; };
 		41F5C0771F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VLCLibrarySearchDisplayDataSource.m; path = Sources/VLCLibrarySearchDisplayDataSource.m; sourceTree = SOURCE_ROOT; };
 		41F9BC7A1F4F20E400268461 /* VLCTrackSelectorView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCTrackSelectorView.h; path = Sources/VLCTrackSelectorView.h; sourceTree = SOURCE_ROOT; };
@@ -1552,9 +1552,8 @@
 				41F5C0771F41ED55005EB9CB /* VLCLibrarySearchDisplayDataSource.m */,
 				4170152B209A1D3600802E44 /* MediaSubcategoryViewController.swift */,
 				41701545209B36E800802E44 /* BaseButtonBarPagerTabStripViewController.swift */,
-				41EB94B3209B46E9002F4C30 /* ButtonCell.xib */,
-				41EB94B5209B4869002F4C30 /* LabelCell.xib */,
 				41D7DD0420C1853E00AD94F6 /* ButtonBarView.swift */,
+				41D7DD2620C3060300AD94F6 /* PagerStripViewController.swift */,
 			);
 			name = "Everything Playlist";
 			sourceTree = "<group>";
@@ -1798,6 +1797,7 @@
 		7DADC55C1704FAA8001DAC63 /* XIBs */ = {
 			isa = PBXGroup;
 			children = (
+				41D7DD2020C1FC2D00AD94F6 /* VLCLabelCell.xib */,
 				41273A3B1A955C4100A2EF77 /* VLCMigrationViewController.xib */,
 				7DC19AF41868CDB800810BF7 /* First Steps */,
 				7D6BEF1D19E027A100DF3972 /* Cloud */,
@@ -2767,7 +2767,6 @@
 				419D7F051F54176900AF69A2 /* VLCTimeNavigationTitleView.xib in Resources */,
 				7D1516431868D7E0004B18F3 /* VLCFirstStepsFirstPageViewController~iphone.xib in Resources */,
 				7DF04F4E1961F2B8004A5429 /* web-download.png in Resources */,
-				41EB94B4209B46E9002F4C30 /* ButtonCell.xib in Resources */,
 				41B93C081A53853B00102E8B /* VLCCloudServiceCell.xib in Resources */,
 				29125E5617492219003F03E5 /* index.html in Resources */,
 				7DB638AB185BC0890003887C /* Images.xcassets in Resources */,
@@ -2780,11 +2779,11 @@
 				7D32B384185E293D006CA474 /* Raleway.woff in Resources */,
 				7D9870691A3E03D5009CF27D /* papasscode_marker@2x.png in Resources */,
 				7D5DD5C717590ABF001421E3 /* About Contents.html in Resources */,
-				41EB94B6209B4869002F4C30 /* LabelCell.xib in Resources */,
 				7DBBF19B183AB4300009A339 /* VLCCloudStorageTableViewCell~iphone.xib in Resources */,
 				7D92897B1877467E009108FD /* VLCFirstStepsFourthPageViewController~iphone.xib in Resources */,
 				7D1516461868D7E0004B18F3 /* VLCFirstStepsSixthPageViewController~iphone.xib in Resources */,
 				41273A3D1A955C4100A2EF77 /* VLCMigrationViewController.xib in Resources */,
+				41D7DD2120C1FC2D00AD94F6 /* VLCLabelCell.xib in Resources */,
 				7DBBF19D183AB4300009A339 /* VLCCloudStorageTableViewController.xib in Resources */,
 				7D9289761877459B009108FD /* VLCFirstStepsThirdPageViewController~iphone.xib in Resources */,
 				7DBBF19E183AB4300009A339 /* VLCEmptyLibraryView.xib in Resources */,
@@ -3169,6 +3168,7 @@
 				41251ED01FD0CF7900099110 /* AppCoordinator.swift in Sources */,
 				4184AA151A5492070063DF5A /* VLCCloudStorageController.m in Sources */,
 				9BE4D1CE183D76950006346C /* VLCCloudStorageTableViewCell.m in Sources */,
+				41D7DD2720C3060300AD94F6 /* PagerStripViewController.swift in Sources */,
 				413EC98B201B4F2C00BF412F /* PresentationTheme.swift in Sources */,
 				DD1CB0321BB9E005006EDDE6 /* VLCMovieViewControlPanelView.m in Sources */,
 				DDF908D01CF4CCAA00108B70 /* VLCNetworkLoginViewButtonCell.m in Sources */,