Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
VLC-iOS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
311
Issues
311
List
Boards
Labels
Service Desk
Milestones
Merge Requests
6
Merge Requests
6
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
VideoLAN
VLC-iOS
Commits
cb77dc7e
Commit
cb77dc7e
authored
Apr 19, 2018
by
Soomin Lee
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Chromecast: Initial integration
parent
6c02f625
Changes
42
Show whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
1024 additions
and
28 deletions
+1024
-28
Resources/VLCTimeNavigationTitleView.xib
Resources/VLCTimeNavigationTitleView.xib
+6
-6
Resources/en.lproj/Localizable.strings
Resources/en.lproj/Localizable.strings
+5
-0
SharedSources/Coordinators/AppCoordinator.swift
SharedSources/Coordinators/AppCoordinator.swift
+1
-0
Sources/MediaViewController.swift
Sources/MediaViewController.swift
+19
-1
Sources/VLCActionSheet/VLCActionSheet.swift
Sources/VLCActionSheet/VLCActionSheet.swift
+265
-0
Sources/VLCActionSheet/VLCActionSheetCell.swift
Sources/VLCActionSheet/VLCActionSheetCell.swift
+75
-0
Sources/VLCActionSheet/VLCActionSheetSectionHeader.swift
Sources/VLCActionSheet/VLCActionSheetSectionHeader.swift
+70
-0
Sources/VLCMovieViewController.h
Sources/VLCMovieViewController.h
+4
-0
Sources/VLCMovieViewController.m
Sources/VLCMovieViewController.m
+101
-16
Sources/VLCPlaybackController.h
Sources/VLCPlaybackController.h
+4
-0
Sources/VLCPlaybackController.m
Sources/VLCPlaybackController.m
+10
-1
Sources/VLCPlayerDisplayController.h
Sources/VLCPlayerDisplayController.h
+8
-0
Sources/VLCPlayerDisplayController.m
Sources/VLCPlayerDisplayController.m
+9
-3
Sources/VLCRendererDiscovererManager.swift
Sources/VLCRendererDiscovererManager.swift
+274
-0
Sources/VLCTabBarCoordinator.swift
Sources/VLCTabBarCoordinator.swift
+2
-1
VLC-iOS-Bridging-Header.h
VLC-iOS-Bridging-Header.h
+1
-0
VLC.xcodeproj/project.pbxproj
VLC.xcodeproj/project.pbxproj
+26
-0
vlc-ios/Images.xcassets/Movie View/Renderer/Contents.json
vlc-ios/Images.xcassets/Movie View/Renderer/Contents.json
+6
-0
vlc-ios/Images.xcassets/Movie View/Renderer/renderer.imageset/Contents.json
...ssets/Movie View/Renderer/renderer.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/renderer.imageset/renderer_normal.png
...Movie View/Renderer/renderer.imageset/renderer_normal.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/renderer.imageset/renderer_normal@2x.png
...ie View/Renderer/renderer.imageset/renderer_normal@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/renderer.imageset/renderer_normal@3x.png
...ie View/Renderer/renderer.imageset/renderer_normal@3x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlack.imageset/Contents.json
.../Movie View/Renderer/rendererBlack.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlack.imageset/renderer_normal_black.png
...Renderer/rendererBlack.imageset/renderer_normal_black.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlack.imageset/renderer_normal_black@2x.png
...derer/rendererBlack.imageset/renderer_normal_black@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlack.imageset/renderer_normal_black@3x.png
...derer/rendererBlack.imageset/renderer_normal_black@3x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlackFull.imageset/Contents.json
...ie View/Renderer/rendererBlackFull.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlackFull.imageset/renderer_full_normal_black.png
...rendererBlackFull.imageset/renderer_full_normal_black.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlackFull.imageset/renderer_full_normal_black@2x.png
...dererBlackFull.imageset/renderer_full_normal_black@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererBlackFull.imageset/renderer_full_normal_black@3x.png
...dererBlackFull.imageset/renderer_full_normal_black@3x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererFull.imageset/Contents.json
...s/Movie View/Renderer/rendererFull.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererFull.imageset/renderer_full_normal.png
...w/Renderer/rendererFull.imageset/renderer_full_normal.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererFull.imageset/renderer_full_normal@2x.png
...enderer/rendererFull.imageset/renderer_full_normal@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererFull.imageset/renderer_full_normal@3x.png
...enderer/rendererFull.imageset/renderer_full_normal@3x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererGray.imageset/Contents.json
...s/Movie View/Renderer/rendererGray.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererGray.imageset/group95.png
...ets/Movie View/Renderer/rendererGray.imageset/group95.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererGray.imageset/group95@2x.png
.../Movie View/Renderer/rendererGray.imageset/group95@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererGray.imageset/group95@3x.png
.../Movie View/Renderer/rendererGray.imageset/group95@3x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererOrangeFull.imageset/Contents.json
...e View/Renderer/rendererOrangeFull.imageset/Contents.json
+23
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererOrangeFull.imageset/icRemoveCircleWhite24Dp.png
...r/rendererOrangeFull.imageset/icRemoveCircleWhite24Dp.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererOrangeFull.imageset/icRemoveCircleWhite24Dp@2x.png
...endererOrangeFull.imageset/icRemoveCircleWhite24Dp@2x.png
+0
-0
vlc-ios/Images.xcassets/Movie View/Renderer/rendererOrangeFull.imageset/icRemoveCircleWhite24Dp@3x.png
...endererOrangeFull.imageset/icRemoveCircleWhite24Dp@3x.png
+0
-0
No files found.
Resources/VLCTimeNavigationTitleView.xib
View file @
cb77dc7e
<?xml version="1.0" encoding="UTF-8"?>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.XIB"
version=
"3.0"
toolsVersion=
"1
3189.4
"
targetRuntime=
"iOS.CocoaTouch"
propertyAccessControl=
"none"
useAutolayout=
"YES"
useTraitCollections=
"YES"
colorMatched=
"YES"
>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.XIB"
version=
"3.0"
toolsVersion=
"1
4109
"
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=
"1
3165.3
"
/>
<plugIn
identifier=
"com.apple.InterfaceBuilder.IBCocoaTouchPlugin"
version=
"1
4088
"
/>
<capability
name=
"documents saved in the Xcode 8 format"
minToolsVersion=
"8.0"
/>
</dependencies>
<objects>
...
...
@@ -21,7 +21,7 @@
<autoresizingMask
key=
"autoresizingMask"
flexibleMinX=
"YES"
flexibleMaxX=
"YES"
flexibleMinY=
"YES"
flexibleMaxY=
"YES"
/>
<subviews>
<button
opaque=
"NO"
contentMode=
"scaleToFill"
contentHorizontalAlignment=
"center"
contentVerticalAlignment=
"center"
lineBreakMode=
"middleTruncation"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"Sdb-a5-RTT"
>
<rect
key=
"frame"
x=
"6
62
"
y=
"5"
width=
"30"
height=
"30"
/>
<rect
key=
"frame"
x=
"6
70
"
y=
"5"
width=
"30"
height=
"30"
/>
<constraints>
<constraint
firstAttribute=
"height"
constant=
"30"
id=
"Ap6-VL-6UH"
/>
<constraint
firstAttribute=
"width"
constant=
"30"
id=
"dEx-l7-vH3"
/>
...
...
@@ -40,7 +40,7 @@
</connections>
</button>
<button
opaque=
"NO"
contentMode=
"scaleToFill"
contentHorizontalAlignment=
"center"
contentVerticalAlignment=
"center"
lineBreakMode=
"middleTruncation"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"x1t-3m-s0G"
>
<rect
key=
"frame"
x=
"6
18
"
y=
"5"
width=
"44"
height=
"30"
/>
<rect
key=
"frame"
x=
"6
26
"
y=
"5"
width=
"44"
height=
"30"
/>
<constraints>
<constraint
firstAttribute=
"height"
constant=
"30"
id=
"fv5-Cp-MOv"
/>
</constraints>
...
...
@@ -76,7 +76,7 @@
</connections>
</button>
<slider
opaque=
"NO"
contentMode=
"scaleToFill"
semanticContentAttribute=
"playback"
insetsLayoutMarginsFromSafeArea=
"NO"
contentHorizontalAlignment=
"center"
contentVerticalAlignment=
"center"
value=
"0.5"
minValue=
"0.0"
maxValue=
"1"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"axb-6M-lSX"
userLabel=
"Position Slider"
customClass=
"VLCOBSlider"
>
<rect
key=
"frame"
x=
"28"
y=
"5"
width=
"5
84
"
height=
"31"
/>
<rect
key=
"frame"
x=
"28"
y=
"5"
width=
"5
92
"
height=
"31"
/>
<accessibility
key=
"accessibilityConfiguration"
>
<accessibilityTraits
key=
"traits"
updatesFrequently=
"YES"
/>
</accessibility>
...
...
@@ -99,7 +99,7 @@
<constraint
firstItem=
"axb-6M-lSX"
firstAttribute=
"trailing"
secondItem=
"x1t-3m-s0G"
secondAttribute=
"leading"
constant=
"-8"
id=
"l05-q4-Dha"
/>
<constraint
firstItem=
"x1t-3m-s0G"
firstAttribute=
"centerY"
secondItem=
"SbC-6V-aXT"
secondAttribute=
"centerY"
id=
"mIZ-5x-1r6"
/>
<constraint
firstItem=
"SBq-Am-6MD"
firstAttribute=
"leading"
secondItem=
"SbC-6V-aXT"
secondAttribute=
"leading"
id=
"mf3-NF-cwy"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"Sdb-a5-RTT"
secondAttribute=
"trailing"
constant=
"8"
id=
"uI1-3o-gyT"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"Sdb-a5-RTT"
secondAttribute=
"trailing"
id=
"uI1-3o-gyT"
/>
<constraint
firstItem=
"axb-6M-lSX"
firstAttribute=
"leading"
secondItem=
"SBq-Am-6MD"
secondAttribute=
"trailing"
id=
"zQP-Wv-QPC"
/>
</constraints>
<nil
key=
"simulatedStatusBarMetrics"
/>
...
...
Resources/en.lproj/Localizable.strings
View file @
cb77dc7e
...
...
@@ -25,6 +25,7 @@
"ONE_SPU_TRACK" = "One subtitles track";
"PLAYING_EXTERNALLY_TITLE" = "TV Connected";
"PLAYING_EXTERNALLY_TITLE_CHROMECAST" = "Chromecast Connected";
"PLAYING_EXTERNALLY_DESC" = "This video is playing on the TV";
"VFILTER_HUE" = "Hue";
...
...
@@ -70,6 +71,9 @@
"PRIVATE_PLAYBACK_TOGGLE" = "Private Playback";
"SCAN_SUBTITLE_TOGGLE" = "Scan for Subtitles (http-only)";
"BUTTON_RENDERER" = "Casting devices";
"BUTTON_RENDERER_HINT" = "Show a menu of available casting devices";
"UPGRADING_LIBRARY" = "Upgrading Media Library";
"UNTITLED_SHOW" = "Untitled Show";
"UNKNOWN" = "Unknown";
...
...
@@ -115,6 +119,7 @@
"SECTION_HEADER_LIBRARY" = "Media Library";
"STREAMVC_DETAILTEXT" = "Play streams directly without downloading";
"DOWNLOADVC_DETAILTEXT" = "Download files directly to your device";
"HEADER_TITLE_RENDERER" = "Select a casting device";
"LOCAL_NETWORK" = "Local Network";
"CONNECT_TO_SERVER" = "Connect to Server";
...
...
SharedSources/Coordinators/AppCoordinator.swift
View file @
cb77dc7e
...
...
@@ -14,6 +14,7 @@ import Foundation
@objc
(
VLCService
)
public
class
Services
:
NSObject
{
@objc
let
mediaDataSource
=
VLCMediaDataSource
()
@objc
let
rendererDiscovererManager
=
VLCRendererDiscovererManager
(
presentingViewController
:
nil
)
}
@objc
class
AppCoordinator
:
NSObject
{
...
...
Sources/MediaViewController.swift
View file @
cb77dc7e
...
...
@@ -24,6 +24,8 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
private
var
searchController
:
UISearchController
?
private
let
searchDataSource
=
VLCLibrarySearchDisplayDataSource
()
private
var
mediaType
:
VLCMediaType
private
var
rendererButton
:
UIButton
public
weak
var
delegate
:
VLCMediaViewControllerDelegate
?
@available
(
iOS
11.0
,
*
)
...
...
@@ -49,6 +51,7 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
init
(
services
:
Services
,
type
:
VLCMediaType
)
{
self
.
services
=
services
mediaType
=
type
self
.
rendererButton
=
services
.
rendererDiscovererManager
.
setupRendererButton
()
super
.
init
(
collectionViewLayout
:
UICollectionViewFlowLayout
())
NotificationCenter
.
default
.
addObserver
(
self
,
selector
:
#selector(
themeDidChange
)
,
name
:
.
VLCThemeDidChangeNotification
,
object
:
nil
)
if
mediaType
.
category
==
.
video
{
...
...
@@ -73,9 +76,20 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
setupCollectionView
()
setupSearchController
()
setupNavigationBar
()
setupRendererButton
()
_
=
(
MLMediaLibrary
.
sharedMediaLibrary
()
as!
MLMediaLibrary
)
.
libraryDidAppear
()
}
public
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
let
manager
=
services
.
rendererDiscovererManager
if
manager
.
discoverers
.
isEmpty
{
// Either didn't start or stopped before
manager
.
start
()
}
manager
.
presentingViewController
=
self
}
@objc
func
themeDidChange
()
{
collectionView
?
.
backgroundColor
=
PresentationTheme
.
current
.
colors
.
background
}
...
...
@@ -128,6 +142,11 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
collectionView
?
.
backgroundView
=
collectionView
?
.
numberOfItems
(
inSection
:
0
)
==
0
?
emptyView
:
nil
}
// MARK: Renderer
private
func
setupRendererButton
()
{
navigationItem
.
rightBarButtonItem
=
UIBarButtonItem
(
customView
:
rendererButton
)
}
@objc
func
sort
()
{
delegate
?
.
mediaViewControllerDidSelectSort
(
self
)
}
...
...
@@ -154,5 +173,4 @@ public class VLCMediaViewController: UICollectionViewController, UISearchResults
public
func
didDismissSearchController
(
_
searchController
:
UISearchController
)
{
collectionView
?
.
dataSource
=
mediaDataSourceAndDelegate
}
}
Sources/VLCActionSheet/VLCActionSheet.swift
0 → 100644
View file @
cb77dc7e
/*****************************************************************************
* VLCActionSheet.swift
*
* Copyright © 2018 VLC authors and VideoLAN
* Copyright © 2018 Videolabs
*
* Authors: Soomin Lee <bubu@mikan.io>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
import
Foundation
import
UIKit
@objc
protocol
VLCActionSheetDataSource
{
@objc
func
numberOfRows
()
->
Int
@objc
func
actionSheet
(
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
}
@objc
protocol
VLCActionSheetDelegate
{
@objc
optional
func
headerViewTitle
()
->
String
?
@objc
func
itemAtIndexPath
(
_
indexPath
:
IndexPath
)
->
Any
?
@objc
func
actionSheet
(
collectionView
:
UICollectionView
,
didSelectItem
item
:
Any
,
At
indexPath
:
IndexPath
)
}
// MARK: VLCActionSheet
class
VLCActionSheet
:
UIViewController
{
private
let
cellHeight
:
CGFloat
=
50
@objc
weak
var
dataSource
:
VLCActionSheetDataSource
?
@objc
weak
var
delegate
:
VLCActionSheetDelegate
?
var
action
:
((
_
item
:
Any
)
->
Void
)?
lazy
var
backgroundView
:
UIView
=
{
let
backgroundView
=
UIView
()
backgroundView
.
isHidden
=
true
backgroundView
.
autoresizingMask
=
[
.
flexibleHeight
,
.
flexibleWidth
]
backgroundView
.
backgroundColor
=
UIColor
.
black
.
withAlphaComponent
(
0.6
)
backgroundView
.
addGestureRecognizer
(
UITapGestureRecognizer
(
target
:
self
,
action
:
#selector(
self.removeActionSheet
)
))
return
backgroundView
}()
lazy
var
collectionViewLayout
:
UICollectionViewFlowLayout
=
{
let
collectionViewLayout
=
UICollectionViewFlowLayout
()
collectionViewLayout
.
minimumLineSpacing
=
1
collectionViewLayout
.
minimumInteritemSpacing
=
0
return
collectionViewLayout
}()
lazy
var
collectionView
:
UICollectionView
=
{
let
collectionView
=
UICollectionView
(
frame
:
UIScreen
.
main
.
bounds
,
collectionViewLayout
:
collectionViewLayout
)
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
backgroundColor
=
PresentationTheme
.
current
.
colors
.
background
collectionView
.
alwaysBounceVertical
=
true
collectionView
.
showsVerticalScrollIndicator
=
false
collectionView
.
register
(
VLCActionSheetCell
.
self
,
forCellWithReuseIdentifier
:
VLCActionSheetCell
.
identifier
)
collectionView
.
translatesAutoresizingMaskIntoConstraints
=
false
return
collectionView
}()
lazy
var
headerView
:
VLCActionSheetSectionHeader
=
{
let
headerView
=
VLCActionSheetSectionHeader
()
headerView
.
title
.
text
=
delegate
?
.
headerViewTitle
?()
??
"Default header title"
headerView
.
title
.
textColor
=
PresentationTheme
.
current
.
colors
.
cellTextColor
headerView
.
backgroundColor
=
PresentationTheme
.
current
.
colors
.
background
headerView
.
translatesAutoresizingMaskIntoConstraints
=
false
return
headerView
}()
lazy
var
bottomBackgroundView
:
UIView
=
{
let
bottomBackgroundView
=
UIView
()
bottomBackgroundView
.
backgroundColor
=
PresentationTheme
.
current
.
colors
.
background
bottomBackgroundView
.
translatesAutoresizingMaskIntoConstraints
=
false
return
bottomBackgroundView
}()
lazy
var
mainStackView
:
UIStackView
=
{
let
mainStackView
=
UIStackView
()
mainStackView
.
spacing
=
0
mainStackView
.
axis
=
.
vertical
mainStackView
.
alignment
=
.
center
mainStackView
.
translatesAutoresizingMaskIntoConstraints
=
false
return
mainStackView
}()
fileprivate
lazy
var
maxCollectionViewHeightConstraint
:
NSLayoutConstraint
=
{
let
maxCollectionViewHeightConstraint
=
collectionView
.
heightAnchor
.
constraint
(
lessThanOrEqualToConstant
:
(
view
.
bounds
.
height
/
2
)
-
cellHeight
)
return
maxCollectionViewHeightConstraint
}()
fileprivate
lazy
var
collectionViewHeightConstraint
:
NSLayoutConstraint
=
{
guard
let
dataSource
=
dataSource
else
{
preconditionFailure
(
"VLCActionSheet: Data source not set correctly!"
)
}
let
collectionViewHeightConstraint
=
collectionView
.
heightAnchor
.
constraint
(
equalToConstant
:
CGFloat
(
dataSource
.
numberOfRows
())
*
cellHeight
)
collectionViewHeightConstraint
.
priority
=
.
required
-
1
return
collectionViewHeightConstraint
}()
fileprivate
lazy
var
bottomBackgroundViewHeightConstraint
:
NSLayoutConstraint
=
{
let
bottomBackgroundViewHeightConstraint
=
bottomBackgroundView
.
heightAnchor
.
constraint
(
equalToConstant
:
cellHeight
)
return
bottomBackgroundViewHeightConstraint
}()
@objc
func
removeActionSheet
()
{
UIView
.
transition
(
with
:
backgroundView
,
duration
:
0.01
,
options
:
.
transitionCrossDissolve
,
animations
:
{
[
weak
self
]
in
self
?
.
backgroundView
.
isHidden
=
true
},
completion
:
{
[
weak
self
]
finished
in
self
?
.
presentingViewController
?
.
dismiss
(
animated
:
true
,
completion
:
nil
)
})
}
// MARK: Private methods
fileprivate
func
setuplHeaderViewConstraints
()
{
NSLayoutConstraint
.
activate
([
headerView
.
heightAnchor
.
constraint
(
equalToConstant
:
cellHeight
),
headerView
.
widthAnchor
.
constraint
(
equalTo
:
view
.
widthAnchor
),
])
}
fileprivate
func
setupCollectionViewConstraints
()
{
NSLayoutConstraint
.
activate
([
collectionViewHeightConstraint
,
maxCollectionViewHeightConstraint
,
collectionView
.
widthAnchor
.
constraint
(
equalTo
:
view
.
widthAnchor
),
])
}
fileprivate
func
setupBottomBackgroundView
()
{
NSLayoutConstraint
.
activate
([
bottomBackgroundViewHeightConstraint
,
bottomBackgroundView
.
widthAnchor
.
constraint
(
equalTo
:
view
.
widthAnchor
)
])
}
fileprivate
func
setupMainStackViewConstraints
()
{
NSLayoutConstraint
.
activate
([
mainStackView
.
bottomAnchor
.
constraint
(
equalTo
:
view
.
bottomAnchor
),
mainStackView
.
leadingAnchor
.
constraint
(
equalTo
:
view
.
leadingAnchor
),
mainStackView
.
widthAnchor
.
constraint
(
equalTo
:
view
.
widthAnchor
),
mainStackView
.
trailingAnchor
.
constraint
(
equalTo
:
view
.
trailingAnchor
)
])
}
override
func
updateViewConstraints
()
{
super
.
updateViewConstraints
()
if
let
presentingViewController
=
presentingViewController
,
let
dataSource
=
dataSource
{
collectionViewHeightConstraint
.
constant
=
CGFloat
(
dataSource
.
numberOfRows
())
*
cellHeight
maxCollectionViewHeightConstraint
.
constant
=
presentingViewController
.
view
.
frame
.
size
.
height
/
2
collectionView
.
setNeedsLayout
()
collectionView
.
layoutIfNeeded
()
}
}
@available
(
iOS
11.0
,
*
)
override
func
viewSafeAreaInsetsDidChange
()
{
bottomBackgroundViewHeightConstraint
.
constant
=
view
.
safeAreaInsets
.
bottom
}
// MARK: UIViewController
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
view
.
addSubview
(
backgroundView
)
view
.
addSubview
(
mainStackView
)
mainStackView
.
addArrangedSubview
(
headerView
)
mainStackView
.
addArrangedSubview
(
collectionView
)
mainStackView
.
addArrangedSubview
(
bottomBackgroundView
)
backgroundView
.
frame
=
UIScreen
.
main
.
bounds
setupMainStackViewConstraints
()
setupCollectionViewConstraints
()
setuplHeaderViewConstraints
()
setupBottomBackgroundView
()
}
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
mainStackView
.
isHidden
=
true
collectionView
.
reloadData
()
updateViewConstraints
()
}
override
func
viewDidAppear
(
_
animated
:
Bool
)
{
super
.
viewDidAppear
(
animated
)
// This is to avoid a horrible visual glitch!
mainStackView
.
isHidden
=
false
UIView
.
transition
(
with
:
backgroundView
,
duration
:
0.2
,
options
:
.
transitionCrossDissolve
,
animations
:
{
[
weak
self
]
in
self
?
.
backgroundView
.
isHidden
=
false
},
completion
:
nil
)
let
realMainStackView
=
mainStackView
.
frame
mainStackView
.
frame
.
origin
.
y
+=
mainStackView
.
frame
.
origin
.
y
UIView
.
animate
(
withDuration
:
0.6
,
delay
:
0
,
usingSpringWithDamping
:
0.8
,
initialSpringVelocity
:
0
,
options
:
.
curveEaseOut
,
animations
:
{
[
mainStackView
]
in
mainStackView
.
frame
=
realMainStackView
},
completion
:
nil
)
}
override
func
viewWillTransition
(
to
size
:
CGSize
,
with
coordinator
:
UIViewControllerTransitionCoordinator
)
{
super
.
viewWillTransition
(
to
:
size
,
with
:
coordinator
)
coordinator
.
animate
(
alongsideTransition
:
{
[
weak
self
]
_
in
self
?
.
maxCollectionViewHeightConstraint
.
constant
=
size
.
height
/
2
self
?
.
collectionView
.
layoutIfNeeded
()
})
}
override
func
viewWillLayoutSubviews
()
{
super
.
viewWillLayoutSubviews
()
collectionView
.
collectionViewLayout
.
invalidateLayout
()
}
@objc
func
setAction
(
closure
action
:
@escaping
(
_
item
:
Any
)
->
Void
)
{
self
.
action
=
action
}
}
// MARK: UICollectionViewDelegateFlowLayout
extension
VLCActionSheet
:
UICollectionViewDelegateFlowLayout
{
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
sizeForItemAt
indexPath
:
IndexPath
)
->
CGSize
{
return
CGSize
(
width
:
collectionView
.
frame
.
width
,
height
:
cellHeight
)
}
}
// MARK: UICollectionViewDelegate
extension
VLCActionSheet
:
UICollectionViewDelegate
{
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
if
let
delegate
=
delegate
,
let
item
=
delegate
.
itemAtIndexPath
(
indexPath
)
{
delegate
.
actionSheet
(
collectionView
:
collectionView
,
didSelectItem
:
item
,
At
:
indexPath
)
action
?(
item
)
}
removeActionSheet
()
}
}
// MARK: UICollectionViewDataSource
extension
VLCActionSheet
:
UICollectionViewDataSource
{
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
numberOfItemsInSection
section
:
Int
)
->
Int
{
if
let
dataSource
=
dataSource
{
return
dataSource
.
numberOfRows
()
}
preconditionFailure
(
"VLCActionSheet: No data source"
)
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
if
let
dataSource
=
dataSource
{
return
dataSource
.
actionSheet
(
collectionView
:
collectionView
,
cellForItemAt
:
indexPath
)
}
preconditionFailure
(
"VLCActionSheet: No data source"
)
}
}
Sources/VLCActionSheet/VLCActionSheetCell.swift
0 → 100644
View file @
cb77dc7e
/*****************************************************************************
* VLCActionSheetCell.swift
*
* Copyright © 2018 VLC authors and VideoLAN
* Copyright © 2018 Videolabs
*
* Authors: Soomin Lee <bubu@mikan.io>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
class
VLCActionSheetCell
:
UICollectionViewCell
{
static
let
identifier
=
"VLCActionSheetCell"
let
icon
:
UIImageView
=
{
let
icon
=
UIImageView
()
icon
.
translatesAutoresizingMaskIntoConstraints
=
false
icon
.
contentMode
=
.
scaleAspectFit
return
icon
}()
let
name
:
UILabel
=
{
let
name
=
UILabel
()
name
.
textColor
=
PresentationTheme
.
current
.
colors
.
cellTextColor
name
.
font
=
UIFont
.
systemFont
(
ofSize
:
15
)
name
.
translatesAutoresizingMaskIntoConstraints
=
false
return
name
}()
let
stackView
:
UIStackView
=
{
let
stackView
=
UIStackView
()
stackView
.
spacing
=
15.0
stackView
.
axis
=
.
horizontal
stackView
.
alignment
=
.
center
stackView
.
translatesAutoresizingMaskIntoConstraints
=
false
return
stackView
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setupViews
()
}
required
init
?(
coder
aDecoder
:
NSCoder
)
{
super
.
init
(
coder
:
aDecoder
)
setupViews
()
}
private
func
setupViews
()
{
backgroundColor
=
PresentationTheme
.
current
.
colors
.
background
stackView
.
addArrangedSubview
(
icon
)
stackView
.
addArrangedSubview
(
name
)
addSubview
(
stackView
)
var
guide
:
LayoutAnchorContainer
=
self
if
#available(iOS 11.0, *)
{
guide
=
safeAreaLayoutGuide
}
NSLayoutConstraint
.
activate
([
icon
.
heightAnchor
.
constraint
(
equalToConstant
:
25
),
icon
.
widthAnchor
.
constraint
(
equalTo
:
icon
.
heightAnchor
),
name
.
trailingAnchor
.
constraint
(
equalTo
:
stackView
.
trailingAnchor
),
name
.
centerYAnchor
.
constraint
(
equalTo
:
stackView
.
centerYAnchor
),
stackView
.
leadingAnchor
.
constraint
(
equalTo
:
guide
.
leadingAnchor
,
constant
:
20
),
stackView
.
trailingAnchor
.
constraint
(
equalTo
:
guide
.
trailingAnchor
,
constant
:
-
20
),
stackView
.
heightAnchor
.
constraint
(
equalTo
:
heightAnchor
),
stackView
.
topAnchor
.
constraint
(
equalTo
:
topAnchor
)
])
}
}
Sources/VLCActionSheet/VLCActionSheetSectionHeader.swift
0 → 100644
View file @
cb77dc7e
/*****************************************************************************
* VLCActionSheetSectionHeader.swift
*
* Copyright © 2018 VLC authors and VideoLAN
* Copyright © 2018 Videolabs
*
* Authors: Soomin Lee <bubu@mikan.io>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
class
VLCActionSheetSectionHeader
:
UIView
{
static
let
identifier
=
"VLCActionSheetSectionHeader"
let
title
:
UILabel
=
{
let
title
=
UILabel
()
title
.
font
=
UIFont
.
systemFont
(
ofSize
:
13
)
title
.
translatesAutoresizingMaskIntoConstraints
=
false
return
title
}()
let
separator
:
UIView
=
{
let
separator
=
UIView
()
separator
.
backgroundColor
=
.
lightGray
separator
.
translatesAutoresizingMaskIntoConstraints
=
false
return
separator
}()
lazy
var
guide
:
LayoutAnchorContainer
=
{
var
guide
:
LayoutAnchorContainer
=
self
if
#available(iOS 11.0, *)
{
guide
=
safeAreaLayoutGuide
}
return
guide
}()
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setupTitle
()
setupSeparator
()
}
required
init
?(
coder
aDecoder
:
NSCoder
)
{
super
.
init
(
coder
:
aDecoder
)
setupTitle
()
setupSeparator
()
}
fileprivate
func
setupSeparator
()
{
addSubview
(
separator
)
NSLayoutConstraint
.
activate
([
separator
.
leadingAnchor
.
constraint
(
equalTo
:
guide
.
leadingAnchor
,
constant
:
20
),
separator
.
trailingAnchor
.
constraint
(
equalTo
:
guide
.
trailingAnchor
,
constant
:
-
20
),
separator
.
heightAnchor
.
constraint
(
equalToConstant
:
0.5
),
separator
.
topAnchor
.
constraint
(
equalTo
:
bottomAnchor
,
constant
:
-
1
)
])
}
fileprivate
func
setupTitle
()
{
addSubview
(
title
)
NSLayoutConstraint
.
activate
([
title
.
leadingAnchor
.
constraint
(
equalTo
:
guide
.
leadingAnchor
,
constant
:
20
),
title
.
centerYAnchor
.
constraint
(
equalTo
:
centerYAnchor
),
title
.
centerXAnchor
.
constraint
(
equalTo
:
centerXAnchor
),
title
.
topAnchor
.
constraint
(
equalTo
:
topAnchor
)
])
}
}
Sources/VLCMovieViewController.h
View file @
cb77dc7e
...
...
@@ -16,6 +16,7 @@
#import "VLCPlaybackController.h"
@class
OBSlider
;
@class
VLCService
;
@class
VLCStatusLabel
;
@class
VLCVerticalSwipeGestureRecognizer
;
@class
VLCTimeNavigationTitleView
;
...
...
@@ -80,6 +81,8 @@ typedef NS_ENUM(NSInteger, VLCMovieJumpState) {
@property
(
nonatomic
,
weak
)
id
<
VLCMovieViewControllerDelegate
>
delegate
;
-
(
instancetype
)
initWithServices
:(
VLCService
*
)
services
;
-
(
IBAction
)
closePlayback
:(
id
)
sender
;
-
(
IBAction
)
minimizePlayback
:(
id
)
sender
;
...
...
@@ -102,5 +105,6 @@ typedef NS_ENUM(NSInteger, VLCMovieJumpState) {
-
(
void
)
toggleUILock
;
-
(
void
)
toggleChapterAndTitleSelector
;
-
(
void
)
hideMenu
;
-
(
void
)
setupCastWithCurrentRenderer
;
@end
Sources/VLCMovieViewController.m
View file @
cb77dc7e
...
...
@@ -54,7 +54,7 @@ typedef NS_ENUM(NSInteger, VLCPanType) {
VLCPanTypeProjection
};
@interface
VLCMovieViewController
()
<
UIGestureRecognizerDelegate
,
VLCMultiSelectionViewDelegate
,
VLCEqualizerViewUIDelegate
,
VLCPlaybackControllerDelegate
,
VLCDeviceMotionDelegate
>
@interface
VLCMovieViewController
()
<
UIGestureRecognizerDelegate
,
VLCMultiSelectionViewDelegate
,
VLCEqualizerViewUIDelegate
,
VLCPlaybackControllerDelegate
,
VLCDeviceMotionDelegate
,
VLCRendererDiscovererManagerDelegate
>
{
BOOL
_controlsHidden
;
BOOL
_videoFiltersHidden
;
...
...
@@ -115,10 +115,15 @@ typedef NS_ENUM(NSInteger, VLCPanType) {
CGPoint
_saveLocation
;
CGSize
_screenPixelSize
;
UIInterfaceOrientation
_lockedOrientation
;
UIStackView
*
_navigationBarStackView
;
UIButton
*
_rendererButton
;
}
@property
(
nonatomic
,
strong
)
VLCMovieViewControlPanelView
*
controllerPanel
;
@property
(
nonatomic
,
strong
)
UIPopoverController
*
masterPopoverController
;
@property
(
nonatomic
,
strong
)
UIWindow
*
externalWindow
;
@property
(
nonatomic
,
strong
)
VLCService
*
services
;
@end
@implementation
VLCMovieViewController
...
...
@@ -130,6 +135,16 @@ typedef NS_ENUM(NSInteger, VLCPanType) {
[
defaults
registerDefaults
:
appDefaults
];
}
-
(
instancetype
)
initWithServices
:(
VLCService
*
)
services
{
self
=
[
super
initWithNibName
:
nil
bundle
:
nil
];
if
(
self
)
{
NSAssert
([
services
isKindOfClass
:[
VLCService
class
]],
@"VLCPlayerDisplayController: Injected services class issue"
);
_services
=
services
;
}
return
self
;