- Working on Song listing, Reworked
- Added a global handling of timer and cell reuse. - Fixed the issue of song timer. Made the AvPlayer Optional to handle multiple instances - Made a logic to handle the player stop. matched the current time with the total time.
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
</dict>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
</dict>
|
||||
|
||||
@@ -9,6 +9,7 @@ import UIKit
|
||||
import Lottie
|
||||
import IQKeyboardManagerSwift
|
||||
import JWPlayerKit
|
||||
import AVFAudio
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -40,10 +41,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
configureSideBar()
|
||||
|
||||
JWPlayerKitLicense.setLicenseKey("Lgok1t7H4PKY+M8FZqmCx54ibUF+NeCTn+xgd+/LVTaRdc+L")
|
||||
|
||||
setupAudioSession()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func setupAudioSession() {
|
||||
let session = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try session.setCategory(.playback, mode: .default)
|
||||
try session.setActive(true)
|
||||
} catch {
|
||||
print("Failed to set up audio session")
|
||||
}
|
||||
}
|
||||
|
||||
// var myOrientation: UIInterfaceOrientationMask = .portrait
|
||||
//
|
||||
// func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
<rect key="frame" x="0.0" y="58" width="414" height="729"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="49" translatesAutoresizingMaskIntoConstraints="NO" id="5wC-Rc-bx0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="567"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="569"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="WokaLogo" translatesAutoresizingMaskIntoConstraints="NO" id="qyO-EY-Xz8">
|
||||
<rect key="frame" x="15" y="10" width="384" height="50"/>
|
||||
@@ -225,16 +225,16 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="SlR-If-pxh" userLabel="Subject">
|
||||
<rect key="frame" x="15" y="278" width="384" height="76"/>
|
||||
<rect key="frame" x="15" y="278" width="384" height="77"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Subject" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k7q-3i-LMr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="384" height="21"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="384" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3td-Os-A3X">
|
||||
<rect key="frame" x="0.0" y="26" width="384" height="50"/>
|
||||
<rect key="frame" x="0.0" y="27" width="384" height="50"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Select Subject" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CoP-oH-nkk">
|
||||
<rect key="frame" x="15" y="10" width="329" height="30"/>
|
||||
@@ -259,16 +259,16 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="gXQ-Yb-IGC" userLabel="Message">
|
||||
<rect key="frame" x="15" y="403" width="384" height="154"/>
|
||||
<rect key="frame" x="15" y="404" width="384" height="155"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Message" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="csz-ff-Kvd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="384" height="21"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="384" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PNw-eT-0fE" customClass="RSKPlaceholderTextView" customModule="RSKPlaceholderTextView">
|
||||
<rect key="frame" x="0.0" y="26" width="384" height="128"/>
|
||||
<rect key="frame" x="0.0" y="27" width="384" height="128"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="tintColor" name="TextDarkBlue"/>
|
||||
<constraints>
|
||||
@@ -378,10 +378,10 @@
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="726"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="35" translatesAutoresizingMaskIntoConstraints="NO" id="uGa-bS-ctr">
|
||||
<rect key="frame" x="0.0" y="30" width="414" height="726.5"/>
|
||||
<rect key="frame" x="0.0" y="30" width="414" height="730.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Hvk-Z2-3ji">
|
||||
<rect key="frame" x="20" y="0.0" width="374" height="115.5"/>
|
||||
<rect key="frame" x="20" y="0.0" width="374" height="116.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rbx-B4-wDn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="80"/>
|
||||
@@ -403,7 +403,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="USER" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="clP-p2-fQj">
|
||||
<rect key="frame" x="0.0" y="85" width="374" height="30.5"/>
|
||||
<rect key="frame" x="0.0" y="85" width="374" height="31.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="26"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -411,16 +411,16 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="GK8-Ov-3Lf" userLabel="NAME">
|
||||
<rect key="frame" x="20" y="150.5" width="374" height="99"/>
|
||||
<rect key="frame" x="20" y="151.5" width="374" height="99.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="FULL NAME" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dWX-YE-TV0" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="19"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="19.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter your name" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="arD-av-w7V" customClass="TextFieldShadow" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="34" width="374" height="50"/>
|
||||
<rect key="frame" x="0.0" y="34.5" width="374" height="50"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="tintColor" name="TextDarkBlue"/>
|
||||
<constraints>
|
||||
@@ -439,7 +439,7 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Avp-CK-Tfh">
|
||||
<rect key="frame" x="0.0" y="99" width="374" height="0.0"/>
|
||||
<rect key="frame" x="0.0" y="99.5" width="374" height="0.0"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -447,16 +447,16 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="mF6-Ik-pdq" userLabel="EMAIL">
|
||||
<rect key="frame" x="20" y="284.5" width="374" height="99"/>
|
||||
<rect key="frame" x="20" y="286" width="374" height="99.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="EMAIL" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lss-KC-4LQ" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="19"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="19.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter your email" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="fZS-d6-t0h" customClass="TextFieldShadow" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="34" width="374" height="50"/>
|
||||
<rect key="frame" x="0.0" y="34.5" width="374" height="50"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="tintColor" name="TextDarkBlue"/>
|
||||
<constraints>
|
||||
@@ -475,7 +475,7 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JVa-mg-KVN">
|
||||
<rect key="frame" x="0.0" y="99" width="374" height="0.0"/>
|
||||
<rect key="frame" x="0.0" y="99.5" width="374" height="0.0"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -483,28 +483,28 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="dTX-xS-I84" userLabel="GENDER">
|
||||
<rect key="frame" x="20" y="418.5" width="374" height="137"/>
|
||||
<rect key="frame" x="20" y="420.5" width="374" height="138"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="YOUR GENDER" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DEA-gr-l2e" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="21"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="60" translatesAutoresizingMaskIntoConstraints="NO" id="KhR-hP-jeC">
|
||||
<rect key="frame" x="0.0" y="37" width="374" height="100"/>
|
||||
<rect key="frame" x="0.0" y="38" width="374" height="100"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hhf-2M-dfy">
|
||||
<rect key="frame" x="30" y="0.0" width="127" height="100"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="evt-gm-S0p">
|
||||
<rect key="frame" x="39" y="10" width="49.5" height="76"/>
|
||||
<rect key="frame" x="39" y="10" width="49.5" height="77"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Boy" translatesAutoresizingMaskIntoConstraints="NO" id="bty-6i-uBA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="49.5" height="50"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="BOY" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y4t-AQ-VlC" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="55" width="49.5" height="21"/>
|
||||
<rect key="frame" x="0.0" y="55" width="49.5" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -522,13 +522,13 @@
|
||||
<rect key="frame" x="217" y="0.0" width="127" height="100"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="9Tk-3P-f19">
|
||||
<rect key="frame" x="39.5" y="10" width="48.5" height="76"/>
|
||||
<rect key="frame" x="39.5" y="10" width="48.5" height="77"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Girl" translatesAutoresizingMaskIntoConstraints="NO" id="m4x-et-VAb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="48.5" height="50"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GIRL" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="225-qf-t1b" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="55" width="48.5" height="21"/>
|
||||
<rect key="frame" x="0.0" y="55" width="48.5" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -551,16 +551,16 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="tlL-6r-4eb" userLabel="DOB">
|
||||
<rect key="frame" x="20" y="590.5" width="374" height="136"/>
|
||||
<rect key="frame" x="20" y="593.5" width="374" height="137"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="WHEN IS YOUR BIRTHDAY?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="b73-2Y-tGO" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="21"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="22"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<datePicker contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" datePickerMode="date" style="wheels" translatesAutoresizingMaskIntoConstraints="NO" id="kau-8K-eQs">
|
||||
<rect key="frame" x="0.0" y="36" width="374" height="100"/>
|
||||
<rect key="frame" x="0.0" y="37" width="374" height="100"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="100" id="QOf-a4-wdZ"/>
|
||||
</constraints>
|
||||
@@ -687,16 +687,16 @@
|
||||
</scenes>
|
||||
<designables>
|
||||
<designable name="arD-av-w7V">
|
||||
<size key="intrinsicContentSize" width="168" height="20.5"/>
|
||||
<size key="intrinsicContentSize" width="169.5" height="21"/>
|
||||
</designable>
|
||||
<designable name="fZS-d6-t0h">
|
||||
<size key="intrinsicContentSize" width="166" height="20.5"/>
|
||||
<size key="intrinsicContentSize" width="169" height="21"/>
|
||||
</designable>
|
||||
<designable name="fiK-Gg-JDj">
|
||||
<size key="intrinsicContentSize" width="168" height="20.5"/>
|
||||
<size key="intrinsicContentSize" width="169.5" height="21"/>
|
||||
</designable>
|
||||
<designable name="zMI-2r-pRQ">
|
||||
<size key="intrinsicContentSize" width="166" height="20.5"/>
|
||||
<size key="intrinsicContentSize" width="169" height="21"/>
|
||||
</designable>
|
||||
</designables>
|
||||
<resources>
|
||||
|
||||
@@ -481,16 +481,16 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="U0W-18-4oe">
|
||||
<rect key="frame" x="0.0" y="45" width="393" height="224"/>
|
||||
<rect key="frame" x="0.0" y="45" width="393" height="214"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Coming Soon on WOKA" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D2p-c5-usH" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="373" height="24"/>
|
||||
<rect key="frame" x="10" y="10" width="373" height="14"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UKc-92-GPa">
|
||||
<rect key="frame" x="10" y="44" width="373" height="180"/>
|
||||
<rect key="frame" x="10" y="34" width="373" height="180"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="180" id="gwN-aD-t1t"/>
|
||||
@@ -500,7 +500,7 @@
|
||||
<edgeInsets key="layoutMargins" top="10" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Qcq-yj-AzB">
|
||||
<rect key="frame" x="0.0" y="269" width="393" height="189"/>
|
||||
<rect key="frame" x="0.0" y="259" width="393" height="199"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="BLOGS" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lW0-W4-2hl" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="10" width="373" height="24"/>
|
||||
@@ -509,10 +509,10 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="xup-gW-Kjh">
|
||||
<rect key="frame" x="10" y="39" width="373" height="150"/>
|
||||
<rect key="frame" x="10" y="39" width="373" height="160"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="150" id="fTZ-PQ-nXX"/>
|
||||
<constraint firstAttribute="height" constant="160" id="fTZ-PQ-nXX"/>
|
||||
</constraints>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="6G1-Uh-Pwt">
|
||||
<size key="itemSize" width="128" height="128"/>
|
||||
@@ -757,7 +757,7 @@
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGreenColor">
|
||||
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -16,7 +16,8 @@ class MoreVC: UIViewController {
|
||||
@IBOutlet weak var songTableView: UITableView!
|
||||
|
||||
var vm = MoreVM()
|
||||
|
||||
var timeObserverToken: Any?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
@@ -24,7 +25,7 @@ class MoreVC: UIViewController {
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
vm.player.pause()
|
||||
vm.player?.pause()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,22 +37,16 @@ extension MoreVC : TableViewSRC{
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.Home.songListCell) as! SongListCell
|
||||
let data = vm.songData[indexPath.row]
|
||||
cell.setData(data: data,playerStatus: vm.playerStatus)
|
||||
// if let playingIndex = vm.currentIndexPlayingSong {
|
||||
// if indexPath.row == playingIndex{
|
||||
// if vm.onGoingTime != nil{ // if index is nil that means its just paused
|
||||
// cell.setData(data: data,playerStatus: vm.playerStatus,onGoingTime: vm.onGoingTime)
|
||||
// }else{ // if index is there it means song is playing and needs to be paused
|
||||
// cell.setData(data: data,playerStatus: .resume,onGoingTime: vm.onGoingTime)
|
||||
// }
|
||||
// }else{
|
||||
// cell.setData(data: data,playerStatus: vm.playerStatus,onGoingTime: nil)
|
||||
// }
|
||||
// }else{
|
||||
// cell.setData(data: data,playerStatus: .stopped ,onGoingTime: nil)
|
||||
// }
|
||||
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "SongListCell", for: indexPath) as! SongListCell
|
||||
let songData = vm.songData[indexPath.row]
|
||||
let isActive = (indexPath.row == vm.currentIndexPlayingSong)
|
||||
if let index = vm.currentIndexPlayingSong , index == indexPath.row{
|
||||
cell.setData(data: songData,playerStatus: vm.playerStatus, active: true, currentTime: currentTimePlayer)
|
||||
}else{
|
||||
cell.setData(data: songData,playerStatus: .stopped , active: false, currentTime: 0)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
@@ -85,11 +80,15 @@ extension MoreVC : TableViewSRC{
|
||||
if indexPath.row == playingIndex{ // if same row is selected pause the row
|
||||
print(vm.playerStatus)
|
||||
switch vm.playerStatus{
|
||||
case .play:
|
||||
case .play: // if player is playing pause it.
|
||||
print("Player is playing")
|
||||
vm.player.pause()
|
||||
vm.player?.pause()
|
||||
vm.playerStatus = .pause
|
||||
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
|
||||
case .pause:
|
||||
print("Player is pause")
|
||||
vm.player?.play()
|
||||
vm.playerStatus = .resume
|
||||
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
|
||||
case .loading:
|
||||
print("Player is loading")
|
||||
case .resume:
|
||||
@@ -102,16 +101,27 @@ extension MoreVC : TableViewSRC{
|
||||
this means other cell was playing now stop it and play this new cell
|
||||
first reload the playing cell and pause the audio
|
||||
*/
|
||||
//Reset Old Cell
|
||||
vm.playerStatus = .stopped
|
||||
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
|
||||
|
||||
//Update new cell
|
||||
vm.currentIndexPlayingSong = indexPath.row
|
||||
vm.playerStatus = .loading
|
||||
currentTimePlayer = 0
|
||||
tableView.reloadRows(at: [indexPath], with: .none)
|
||||
let data = vm.songData[indexPath.row]
|
||||
startPlaying(song: data, at: indexPath)
|
||||
print("Other cell playing")
|
||||
}
|
||||
}else{
|
||||
// if there is no playing audio before
|
||||
vm.playerStatus = .play
|
||||
vm.playerStatus = .loading
|
||||
vm.currentIndexPlayingSong = indexPath.row
|
||||
currentTimePlayer = 0
|
||||
tableView.reloadRows(at: [indexPath], with: .none)
|
||||
let data = vm.songData[indexPath.row]
|
||||
playSong(url: data.contentMoreDetails?.first?.url)
|
||||
startPlaying(song: data, at: indexPath)
|
||||
print("First Play")
|
||||
}
|
||||
}
|
||||
@@ -130,11 +140,46 @@ extension MoreVC : TableViewSRC{
|
||||
})
|
||||
}
|
||||
|
||||
func playSong(url : String?){
|
||||
if let url {
|
||||
vm.player = AVPlayer(url: URL(string: url)!)
|
||||
func startPlaying(song: SongBlogDM.PaintDatum, at indexPath: IndexPath) {
|
||||
// Set up and start the player
|
||||
stopPlaying()
|
||||
if let urlString = song.contentMoreDetails?.first?.url , let url = URL(string: urlString){
|
||||
vm.player = AVPlayer(url: url)
|
||||
vm.player?.play()
|
||||
vm.playerStatus = .play
|
||||
vm.currentIndexPlayingSong = indexPath.row
|
||||
addPeriodicTimeObserver()
|
||||
vm.observePlayer()
|
||||
vm.player.play()
|
||||
}
|
||||
}
|
||||
|
||||
func stopPlaying() {
|
||||
// Remove the periodic time observer
|
||||
removePeriodicTimeObserver()
|
||||
|
||||
// Stop the player
|
||||
vm.player?.pause()
|
||||
// vm.player = nil
|
||||
vm.playerStatus = .stopped
|
||||
vm.currentIndexPlayingSong = nil
|
||||
}
|
||||
|
||||
func removePeriodicTimeObserver() {
|
||||
if let token = timeObserverToken {
|
||||
vm.player?.removeTimeObserver(token)
|
||||
timeObserverToken = nil
|
||||
}
|
||||
}
|
||||
|
||||
func addPeriodicTimeObserver() {
|
||||
let interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
|
||||
timeObserverToken = vm.player?.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] time in
|
||||
guard let self = self else { return }
|
||||
currentTimePlayer = Int(CMTimeGetSeconds(time))
|
||||
if let currentPlayingIndex = self.vm.currentIndexPlayingSong,
|
||||
let cell = self.songTableView.cellForRow(at: IndexPath(row: vm.currentIndexPlayingSong ?? 0, section: 0)) as? SongListCell {
|
||||
cell.updateCurrentTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
<rect key="frame" x="10" y="10" width="204" height="170"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5yh-us-azT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="204" height="100"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="204" height="90"/>
|
||||
<color key="backgroundColor" red="0.5450980392" green="0.67450980390000004" blue="0.17254901959999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="100" id="jAA-Oz-JN4"/>
|
||||
<constraint firstAttribute="height" constant="90" id="LZS-Hb-uCN"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="qgR-zD-wKz">
|
||||
<rect key="frame" x="0.0" y="105" width="204" height="65"/>
|
||||
<rect key="frame" x="0.0" y="95" width="204" height="75"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FXy-A6-Huz">
|
||||
<rect key="frame" x="0.0" y="0.0" width="204" height="47"/>
|
||||
|
||||
@@ -16,27 +16,11 @@ class SongListCell: UITableViewCell {
|
||||
@IBOutlet weak var playPauseImage: UIImageView!
|
||||
@IBOutlet weak var indicatorView: UIView!
|
||||
|
||||
// typealias btnTappedBlock = (String?) -> Void
|
||||
// var btnTapped : btnTappedBlock!
|
||||
|
||||
var timer: Timer?
|
||||
private var currentTime: Int = 0
|
||||
var totalTime: Int = 0
|
||||
// var timer: Timer?
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
// self.addTapGesture { [weak self] in
|
||||
// guard let self else{return}
|
||||
// UIView.animate(withDuration: 0.1, animations: {
|
||||
// self.outerStack.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
|
||||
// }) { _ in
|
||||
// UIView.animate(withDuration: 0.1) {
|
||||
// self.outerStack.transform = .identity
|
||||
// self.btnTapped(self.ongoingTimeLabel.text)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
@@ -47,89 +31,57 @@ class SongListCell: UITableViewCell {
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
// Invalidate the timer when the cell is reused
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
ongoingTimeLabel.text = "0:00"
|
||||
currentTimePlayer = 0
|
||||
// self.timer?.invalidate()
|
||||
// self.timer = nil
|
||||
}
|
||||
|
||||
func setData(data: SongBlogDM.PaintDatum, playerStatus: PlayerStatus) {
|
||||
ongoingTimeLabel.text = "00:00"
|
||||
totalTime = 0
|
||||
currentTime = 0
|
||||
func setData(data: SongBlogDM.PaintDatum, playerStatus: PlayerStatus, active: Bool, currentTime: Int) {
|
||||
totalTime = data.songDuration?.timeStringToSeconds() ?? 0
|
||||
ongoingTimeLabel.text = formatTime(currentTime)
|
||||
playPauseImage.image = UIImage(systemName: "play.fill")
|
||||
|
||||
|
||||
switch playerStatus{
|
||||
case .stopped:
|
||||
playPauseImage.image = UIImage(systemName: "play.fill")
|
||||
case .pause:
|
||||
playPauseImage.image = UIImage(systemName: "play.fill")
|
||||
case .play:
|
||||
playPauseImage.image = UIImage(systemName: "pause.fill")
|
||||
totalTime = data.songDuration?.timeStringToSeconds() ?? 0
|
||||
|
||||
// if let onGoingTime{
|
||||
// currentTime = onGoingTime.timeStringToSeconds() ?? 0
|
||||
// ongoingTimeLabel.text = onGoingTime
|
||||
// }else{
|
||||
// currentTime = 0
|
||||
// }
|
||||
startCountdown()
|
||||
|
||||
case .resume:
|
||||
playPauseImage.image = UIImage(systemName: "pause.fill")
|
||||
totalTime = data.songDuration?.timeStringToSeconds() ?? 0
|
||||
// if let onGoingTime{
|
||||
// currentTime = onGoingTime.timeStringToSeconds() ?? 0
|
||||
// ongoingTimeLabel.text = onGoingTime
|
||||
// }else{
|
||||
// currentTime = 0
|
||||
// }
|
||||
startCountdown()
|
||||
case .loading:
|
||||
break
|
||||
if active {
|
||||
ongoingTimeLabel.text = formatTime(currentTime)
|
||||
switch playerStatus {
|
||||
case .stopped:
|
||||
showHideLoading(show: false)
|
||||
playPauseImage.image = UIImage(systemName: "play.fill")
|
||||
case .pause:
|
||||
showHideLoading(show: false)
|
||||
playPauseImage.image = UIImage(systemName: "play.fill")
|
||||
case .play, .resume:
|
||||
showHideLoading(show: false)
|
||||
playPauseImage.image = UIImage(systemName: "pause.fill")
|
||||
case .loading:
|
||||
showHideLoading(show: true)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
showHideLoading(show: false)
|
||||
}
|
||||
|
||||
// Set total time label and song title
|
||||
if let totalDuration = data.songDuration{
|
||||
//Check of the hour is zero removing it
|
||||
if let totalDuration = data.songDuration {
|
||||
let totalTimeFiltered = totalDuration.checkHourZero()
|
||||
totalTimeLabel.text = "/" + totalTimeFiltered
|
||||
}else{
|
||||
} else {
|
||||
totalTimeLabel.text = "/" + (data.songDuration ?? "00:00")
|
||||
}
|
||||
|
||||
songTitle.text = data.title ?? "Unknown Title"
|
||||
}
|
||||
|
||||
private func startCountdown() {
|
||||
// Invalidate any existing timer
|
||||
timer?.invalidate()
|
||||
|
||||
// Schedule a new timer
|
||||
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCountdown), userInfo: nil, repeats: true)
|
||||
func showHideLoading(show : Bool){
|
||||
show ? self.indicatorView.showLoading() : self.indicatorView.hideLoading()
|
||||
self.indicatorView.isHidden = !show
|
||||
self.playPauseImage.isHidden = show
|
||||
}
|
||||
|
||||
@objc private func updateCountdown() {
|
||||
// Update the timer label
|
||||
if currentTime < totalTime {
|
||||
currentTime += 1
|
||||
ongoingTimeLabel.text = formatTime(currentTime)
|
||||
} else {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
func updateCurrentTime() {
|
||||
let timeInSeconds = Int(currentTimePlayer)
|
||||
currentTimePlayer = timeInSeconds
|
||||
ongoingTimeLabel.text = formatTime(currentTimePlayer)
|
||||
}
|
||||
// @objc private func updateCountdown() {
|
||||
// // Update countdown label
|
||||
// if totalTime > 0 {
|
||||
// totalTime -= 1
|
||||
// ongoingTimeLabel.text = formatTime(totalTime)
|
||||
// } else {
|
||||
// timer?.invalidate()
|
||||
// timer = nil
|
||||
// ongoingTimeLabel.text = "0:00"
|
||||
// }
|
||||
// }
|
||||
|
||||
private func formatTime(_ seconds: Int) -> String {
|
||||
// Format time as MM:SS
|
||||
|
||||
@@ -15,6 +15,10 @@ enum PlayerStatus{
|
||||
case resume
|
||||
case stopped
|
||||
}
|
||||
|
||||
var currentTimePlayer = Int()
|
||||
var totalTime = Int()
|
||||
|
||||
class MoreVM{
|
||||
|
||||
weak var vc : MoreVC!
|
||||
@@ -23,7 +27,7 @@ class MoreVM{
|
||||
|
||||
var songData = [SongBlogDM.PaintDatum]()
|
||||
|
||||
var player = AVPlayer()
|
||||
var player : AVPlayer?
|
||||
var playerObserver: NSKeyValueObservation?
|
||||
var playerStatus = PlayerStatus.loading
|
||||
|
||||
@@ -38,28 +42,37 @@ class MoreVM{
|
||||
vc.homeBtn.addTapGesture {
|
||||
self.vc.dismiss(animated: true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
func observePlayer() {
|
||||
playerObserver = self.player.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
|
||||
playerObserver = self.player?.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
|
||||
guard let self = self else { return }
|
||||
switch player.timeControlStatus {
|
||||
case .playing:
|
||||
print("Player is playing")
|
||||
print("Player is playing OOO")
|
||||
self.playerStatus = .play
|
||||
vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong ?? 0, section: 0)], with: .none)
|
||||
case .paused:
|
||||
print("Player is paused")
|
||||
self.playerStatus = .pause
|
||||
print("Player is paused OOO")
|
||||
// self.playerStatus = .pause
|
||||
if self.player?.currentTime() == self.player?.currentItem?.duration {
|
||||
print("Player finished playing")
|
||||
self.playerStatus = .stopped
|
||||
self.vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong!, section: 0)], with: .none)
|
||||
currentIndexPlayingSong = nil
|
||||
} else {
|
||||
print("Player is paused")
|
||||
self.playerStatus = .pause
|
||||
}
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
print("Player is waiting to play at specified rate")
|
||||
print("Player is waiting to play at specified rate OOO")
|
||||
self.playerStatus = .loading
|
||||
@unknown default:
|
||||
print("Unknown player status")
|
||||
print("Unknown player status OOO")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// func playSong(urlString: String) {
|
||||
// guard let url = URL(string: urlString) else {
|
||||
@@ -141,3 +154,83 @@ class MoreVM{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIView {
|
||||
|
||||
private struct AssociatedKeys {
|
||||
static var loadingView = "loadingView"
|
||||
}
|
||||
|
||||
private var loadingView: LoadingView? {
|
||||
get {
|
||||
return objc_getAssociatedObject(self, AssociatedKeys.loadingView) as? LoadingView
|
||||
}
|
||||
set {
|
||||
objc_setAssociatedObject(self, AssociatedKeys.loadingView, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
}
|
||||
|
||||
func showLoading() {
|
||||
if loadingView == nil {
|
||||
let newLoadingView = LoadingView(frame: self.bounds)
|
||||
newLoadingView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.addSubview(newLoadingView)
|
||||
NSLayoutConstraint.activate([
|
||||
newLoadingView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||
newLoadingView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
|
||||
newLoadingView.topAnchor.constraint(equalTo: self.topAnchor),
|
||||
newLoadingView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
|
||||
])
|
||||
loadingView = newLoadingView
|
||||
}
|
||||
loadingView?.startLoading()
|
||||
}
|
||||
|
||||
func hideLoading() {
|
||||
loadingView?.stopLoading()
|
||||
}
|
||||
}
|
||||
|
||||
class LoadingView: UIView {
|
||||
|
||||
private var activityIndicator: UIActivityIndicatorView!
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupView()
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
self.backgroundColor = .clear
|
||||
|
||||
activityIndicator = UIActivityIndicatorView(style: .medium)
|
||||
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
|
||||
activityIndicator.color = .white
|
||||
self.addSubview(activityIndicator)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
activityIndicator.centerXAnchor.constraint(equalTo: self.centerXAnchor),
|
||||
activityIndicator.centerYAnchor.constraint(equalTo: self.centerYAnchor),
|
||||
activityIndicator.heightAnchor.constraint(equalToConstant: self.frame.height - 10),
|
||||
activityIndicator.widthAnchor.constraint(equalToConstant: self.frame.width - 10)
|
||||
])
|
||||
}
|
||||
|
||||
func startLoading() {
|
||||
activityIndicator.startAnimating()
|
||||
self.isHidden = false
|
||||
}
|
||||
|
||||
func stopLoading() {
|
||||
activityIndicator.stopAnimating()
|
||||
self.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user