Commit 6ced633b authored by Carola Nitz's avatar Carola Nitz

MediaSubcategoryController: moved classes into separate files

Moved setup code into ButtonBarView,
remove not needed code out of various files
parent 623f1972
<?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>
<?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">
......
......@@ -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";
......
......@@ -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
}
//
// 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)
......
......@@ -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
})
}
}
......
/*****************************************************************************
* 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