Commit 763e6cee authored by yqz's avatar yqz

学英语

parent 29992f2f
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "image@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "dengluye@3x.png", "filename" : "Log_in_bg@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }
......
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "10000h+@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Welcome to SpeakEasy Learning@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon_send_off@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -5,12 +5,11 @@ ...@@ -5,12 +5,11 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Send@2x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "Send@3x.png", "filename" : "icon_send_on@3x.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }
......
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "bg_blue_home@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_guide_on@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_guide_on@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_no@3x(1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_no@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Google@2x 1@2x(1).png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
......
...@@ -18,7 +18,7 @@ extension AppDelegate { ...@@ -18,7 +18,7 @@ extension AppDelegate {
_ = SpeakCache.cache _ = SpeakCache.cache
SpeakDayEveryManager.manager.loadData(Date().toStr() ?? "") SpeakDayEveryManager.manager.loadData(Date().toStr() ?? "")
_ = SpeakLeassonData.data.leassionData _ = SpeakLeassonData.data.leassionData
// _ = SpeakVideoPlayer.share SpeakAIVideoPlayManager.share.loadVideo()
IAPViewModel.share.fetchProducts { product in // 初始化内购 IAPViewModel.share.fetchProducts { product in // 初始化内购
Print("内购列表\(product?.count ?? 0)") Print("内购列表\(product?.count ?? 0)")
} }
......
...@@ -89,7 +89,7 @@ func copyMatchingProperties<T, U>(from source: T, to destination: inout U) { ...@@ -89,7 +89,7 @@ func copyMatchingProperties<T, U>(from source: T, to destination: inout U) {
} }
func updateUserInformation() -> Void { func updateUserInformation(_ complate:((Bool)->Void)? = nil) -> Void {
if SpeakElePublicManager.share.userInfo.isLogin() { if SpeakElePublicManager.share.userInfo.isLogin() {
let name = SpeakElePublicManager.share.userInfo.userName ?? "" let name = SpeakElePublicManager.share.userInfo.userName ?? ""
let lanaguage = SpeakElePublicManager.share.userInfo.nativeLanguage ?? "" let lanaguage = SpeakElePublicManager.share.userInfo.nativeLanguage ?? ""
...@@ -104,7 +104,7 @@ func updateUserInformation() -> Void { ...@@ -104,7 +104,7 @@ func updateUserInformation() -> Void {
"targetLevel": level, "targetLevel": level,
"targetLanguage":en "targetLanguage":en
]) { su in ]) { su in
complate?(su)
} }
} }
} }
......
...@@ -37,6 +37,13 @@ extension UIColor { ...@@ -37,6 +37,13 @@ extension UIColor {
public func generate(_ size:CGSize = CGSize(width: 1, height: 1), public func generate(_ size:CGSize = CGSize(width: 1, height: 1),
_ cornerRadius:CGFloat = 0) -> UIImage? { _ cornerRadius:CGFloat = 0) -> UIImage? {
var size = size;
if size.width <= 0 {
size.width = 1
}
if size.height <= 0 {
size.height = 1
}
let rect = CGRect(origin: .zero, size: size) let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0) UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else { return nil } guard let context = UIGraphicsGetCurrentContext() else { return nil }
......
...@@ -51,6 +51,12 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD ...@@ -51,6 +51,12 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD
SpeakElePublicManager.share.userInfo.targetLanguage = "🇪🇸 Español" SpeakElePublicManager.share.userInfo.targetLanguage = "🇪🇸 Español"
self?.SpeakEnglistShow.setImage(UIImage(named: "sp-home-Es"), for: .normal) self?.SpeakEnglistShow.setImage(UIImage(named: "sp-home-Es"), for: .normal)
} }
updateUserInformation {[weak self] su in
if su {
self?.viewModel.fetchSesson()
self?.viewModel.fetchUserInfo()
}
}
} }
} }
return tip return tip
...@@ -101,7 +107,7 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD ...@@ -101,7 +107,7 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD
/// 改变学习的语言 /// 改变学习的语言
@IBAction func SpeakChangeLangu(_ sender: Any) { @IBAction func SpeakChangeLangu(_ sender: Any) {
if !IAPViewModel.share.isSubscribed { if IAPViewModel.share.isSubscribed {
self.view.bringSubviewToFront(tipView) self.view.bringSubviewToFront(tipView)
tipView.selectIdx = SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" ? 0 : 1 tipView.selectIdx = SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" ? 0 : 1
tipView.show() tipView.show()
...@@ -146,7 +152,6 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD ...@@ -146,7 +152,6 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
SpeakPermission.requestNotificationPermission()
titleView.isHidden = true titleView.isHidden = true
setAISer() setAISer()
viewModel.fetchSesson() viewModel.fetchSesson()
...@@ -156,13 +161,22 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD ...@@ -156,13 +161,22 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD
self?.SpeakDataUpdate() self?.SpeakDataUpdate()
} }
} }
SpeakAIVideoPlayManager.share.loadVideo()
if SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" { if SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" {
self.SpeakEnglistShow.setImage(UIImage(named: "sp-home-En"), for: .normal) self.SpeakEnglistShow.setImage(UIImage(named: "sp-home-En"), for: .normal)
}else{ }else{
self.SpeakEnglistShow.setImage(UIImage(named: "sp-home-Es"), for: .normal) self.SpeakEnglistShow.setImage(UIImage(named: "sp-home-Es"), for: .normal)
} }
/// 新用户直接进课程
if SpeakElePublicManager.share.userInfo.newUser ?? true {
SpeakElePublicManager.share.userInfo.newUser = false
let vc = SpeakNewUserViewCtr()
vc.isReStart = true
vc.isMute = false
vc.view.callblack = { [weak self] tip in
self?.TipsSign(tip as? Bool ?? false)
}
self.navigationController?.pushViewController(vc, animated: true)
}
} }
} }
...@@ -173,14 +187,15 @@ extension SpeakEleHomeViewCtr { ...@@ -173,14 +187,15 @@ extension SpeakEleHomeViewCtr {
for (v) in self.lessonDataSource { for (v) in self.lessonDataSource {
if v.isLocked == false { if v.isLocked == false {
lessonId = v.lessonId ?? 0 lessonId = v.lessonId ?? 0
}else{
break
} }
} }
for (i,v) in lessonViews.enumerated() { for (i,v) in lessonViews.enumerated() {
let data = lessonDataSource[safe: i] let data = lessonDataSource[safe: i]
v.data = data v.data = data
v.SpeakLessionStart.isHidden = !(data?.lessonId == lessonId) v.SpeakLessionStart.isHidden = !(data?.lessonId == lessonId)
if data?.lessonId == lessonId {
offsetY = v.y - 70.0
}
} }
} }
...@@ -293,8 +308,6 @@ extension SpeakEleHomeViewCtr { ...@@ -293,8 +308,6 @@ extension SpeakEleHomeViewCtr {
for (v) in self.lessonDataSource { for (v) in self.lessonDataSource {
if v.isLocked == false { if v.isLocked == false {
lessonId = v.lessonId ?? 0 lessonId = v.lessonId ?? 0
}else{
break
} }
} }
for i in 1...6 { for i in 1...6 {
......
...@@ -126,8 +126,11 @@ ...@@ -126,8 +126,11 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="REb-HE-Vml"> <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="REb-HE-Vml">
<rect key="frame" x="24" y="119" width="345" height="79"/> <rect key="frame" x="24" y="103" width="345" height="79"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_bg_blue_home" translatesAutoresizingMaskIntoConstraints="NO" id="7aS-Wk-Ktd">
<rect key="frame" x="0.0" y="0.0" width="345" height="79"/>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-home-headerivar" translatesAutoresizingMaskIntoConstraints="NO" id="pAk-N9-Dv6"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-home-headerivar" translatesAutoresizingMaskIntoConstraints="NO" id="pAk-N9-Dv6">
<rect key="frame" x="16" y="16" width="48" height="48"/> <rect key="frame" x="16" y="16" width="48" height="48"/>
<constraints> <constraints>
...@@ -147,7 +150,7 @@ ...@@ -147,7 +150,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="245" verticalHuggingPriority="245" horizontalCompressionResistancePriority="745" verticalCompressionResistancePriority="745" axis="vertical" alignment="top" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="EgX-1V-LiS"> <stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="245" verticalHuggingPriority="245" horizontalCompressionResistancePriority="745" verticalCompressionResistancePriority="745" axis="vertical" alignment="top" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="EgX-1V-LiS">
<rect key="frame" x="80" y="15.666666666666657" width="126" height="49"/> <rect key="frame" x="80" y="15.666666666666671" width="126" height="49"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Amelia" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GO5-4q-Wtk"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Amelia" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GO5-4q-Wtk">
<rect key="frame" x="0.0" y="0.0" width="59.333333333333336" height="24"/> <rect key="frame" x="0.0" y="0.0" width="59.333333333333336" height="24"/>
...@@ -156,7 +159,7 @@ ...@@ -156,7 +159,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lde-SU-5MS"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lde-SU-5MS">
<rect key="frame" x="0.0" y="29" width="126" height="20"/> <rect key="frame" x="0.0" y="28.999999999999986" width="126" height="20"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="20" id="iK8-oc-A1D"/> <constraint firstAttribute="height" constant="20" id="iK8-oc-A1D"/>
</constraints> </constraints>
...@@ -181,7 +184,7 @@ ...@@ -181,7 +184,7 @@
</subviews> </subviews>
</stackView> </stackView>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="255" verticalHuggingPriority="255" horizontalCompressionResistancePriority="755" verticalCompressionResistancePriority="755" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tji-S9-nFP"> <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="255" verticalHuggingPriority="255" horizontalCompressionResistancePriority="755" verticalCompressionResistancePriority="755" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tji-S9-nFP">
<rect key="frame" x="240" y="23.666666666666657" width="87" height="32"/> <rect key="frame" x="240" y="23.666666666666671" width="87" height="32"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="87" id="ayL-fl-zR2"/> <constraint firstAttribute="width" constant="87" id="ayL-fl-zR2"/>
...@@ -200,15 +203,19 @@ ...@@ -200,15 +203,19 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" red="0.22352941176470587" green="0.50196078431372548" blue="0.96470588235294119" alpha="1" colorSpace="calibratedRGB"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="tji-S9-nFP" secondAttribute="trailing" constant="18" id="12u-v5-UR0"/> <constraint firstAttribute="trailing" secondItem="tji-S9-nFP" secondAttribute="trailing" constant="18" id="12u-v5-UR0"/>
<constraint firstItem="pAk-N9-Dv6" firstAttribute="top" secondItem="REb-HE-Vml" secondAttribute="top" constant="16" id="3rQ-4P-EMq"/> <constraint firstItem="pAk-N9-Dv6" firstAttribute="top" secondItem="REb-HE-Vml" secondAttribute="top" constant="16" id="3rQ-4P-EMq"/>
<constraint firstItem="tji-S9-nFP" firstAttribute="centerY" secondItem="REb-HE-Vml" secondAttribute="centerY" id="Al5-9M-UVy"/> <constraint firstItem="tji-S9-nFP" firstAttribute="centerY" secondItem="REb-HE-Vml" secondAttribute="centerY" id="Al5-9M-UVy"/>
<constraint firstAttribute="bottom" secondItem="7aS-Wk-Ktd" secondAttribute="bottom" id="KMU-9T-dgH"/>
<constraint firstItem="EgX-1V-LiS" firstAttribute="centerY" secondItem="pAk-N9-Dv6" secondAttribute="centerY" id="MOK-MF-8ZK"/> <constraint firstItem="EgX-1V-LiS" firstAttribute="centerY" secondItem="pAk-N9-Dv6" secondAttribute="centerY" id="MOK-MF-8ZK"/>
<constraint firstItem="EgX-1V-LiS" firstAttribute="leading" secondItem="pAk-N9-Dv6" secondAttribute="trailing" constant="16" id="Ndk-uL-Uhq"/> <constraint firstItem="EgX-1V-LiS" firstAttribute="leading" secondItem="pAk-N9-Dv6" secondAttribute="trailing" constant="16" id="Ndk-uL-Uhq"/>
<constraint firstItem="pAk-N9-Dv6" firstAttribute="leading" secondItem="REb-HE-Vml" secondAttribute="leading" constant="16" id="OLG-nC-Uwh"/> <constraint firstItem="pAk-N9-Dv6" firstAttribute="leading" secondItem="REb-HE-Vml" secondAttribute="leading" constant="16" id="OLG-nC-Uwh"/>
<constraint firstItem="7aS-Wk-Ktd" firstAttribute="top" secondItem="REb-HE-Vml" secondAttribute="top" id="PFT-M8-wBt"/>
<constraint firstAttribute="trailing" secondItem="7aS-Wk-Ktd" secondAttribute="trailing" id="TzI-w3-0wo"/>
<constraint firstAttribute="bottom" secondItem="pAk-N9-Dv6" secondAttribute="bottom" constant="15" id="ha2-7J-HlX"/> <constraint firstAttribute="bottom" secondItem="pAk-N9-Dv6" secondAttribute="bottom" constant="15" id="ha2-7J-HlX"/>
<constraint firstItem="7aS-Wk-Ktd" firstAttribute="leading" secondItem="REb-HE-Vml" secondAttribute="leading" id="oPp-t1-H2p"/>
</constraints> </constraints>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="corners"> <userDefinedRuntimeAttribute type="number" keyPath="corners">
...@@ -221,7 +228,7 @@ ...@@ -221,7 +228,7 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstItem="REb-HE-Vml" firstAttribute="leading" secondItem="rqH-oW-agY" secondAttribute="leading" constant="24" id="Cvh-VK-8kb"/> <constraint firstItem="REb-HE-Vml" firstAttribute="leading" secondItem="rqH-oW-agY" secondAttribute="leading" constant="24" id="Cvh-VK-8kb"/>
<constraint firstItem="REb-HE-Vml" firstAttribute="top" secondItem="KYz-Od-c9d" secondAttribute="bottom" constant="26" id="FHQ-WP-3fM"/> <constraint firstItem="REb-HE-Vml" firstAttribute="top" secondItem="KYz-Od-c9d" secondAttribute="bottom" constant="10" id="FHQ-WP-3fM"/>
<constraint firstItem="KYz-Od-c9d" firstAttribute="top" secondItem="Ia2-3z-Nib" secondAttribute="top" constant="61" id="ISI-vx-5CZ"/> <constraint firstItem="KYz-Od-c9d" firstAttribute="top" secondItem="Ia2-3z-Nib" secondAttribute="top" constant="61" id="ISI-vx-5CZ"/>
<constraint firstAttribute="trailing" secondItem="KYz-Od-c9d" secondAttribute="trailing" constant="24" id="KEg-YG-8N8"/> <constraint firstAttribute="trailing" secondItem="KYz-Od-c9d" secondAttribute="trailing" constant="24" id="KEg-YG-8N8"/>
<constraint firstItem="KYz-Od-c9d" firstAttribute="leading" secondItem="Ia2-3z-Nib" secondAttribute="leading" constant="24" id="Kv8-Bt-b6l"/> <constraint firstItem="KYz-Od-c9d" firstAttribute="leading" secondItem="Ia2-3z-Nib" secondAttribute="leading" constant="24" id="Kv8-Bt-b6l"/>
...@@ -231,6 +238,7 @@ ...@@ -231,6 +238,7 @@
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="icon_bg_blue_home" width="354" height="82"/>
<image name="sp-home-En" width="28" height="28"/> <image name="sp-home-En" width="28" height="28"/>
<image name="sp-home-book" width="20.333333969116211" height="20"/> <image name="sp-home-book" width="20.333333969116211" height="20"/>
<image name="sp-home-clock" width="20" height="20"/> <image name="sp-home-clock" width="20" height="20"/>
......
//
// SpeakDialogueViewCtr.swift
// SpeakEasyLearnEnglish
//
// Created by edy on 2025/8/4.
//
import UIKit
class SpeakNewUserViewCtr: SpeakEleBaseViewCtr {
@IBOutlet weak var SpeakDialogTopPlayVideo: UIView!
@IBOutlet weak var SpeakVideoPPPPPP: UIView!
@IBOutlet weak var SpeakLeassonName: UILabel!
@IBOutlet weak var SpeakLeassonCollect: UIButton!
@IBOutlet weak var SpeakContentView: UIView!
@IBOutlet weak var SpeakLeassonTableView: UITableView!
@IBOutlet weak var SpeakTimes: UIButton!
@IBOutlet weak var SpeakInputView: UIView!
@IBOutlet weak var SentAudioSound: UIButton!
var dataSource:[SpeakDialogueModel] = []
@BoundedZeroNumber private var studyTm:Int = 300
private var studyTime:Int = 0
var isReStart = false
var isMute = false
private var Translates = NSMutableSet()
let viewModel = SpeakDialogueViewModel()
let homeModel = SpeakHomeViewModel()
var dataLesssion:SpeakLessonDescpModel?
private var isSing = false
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
// viewModel.DialogLeasson = self.dataLesssion
InputTextView.state = .defult
SpeakTimes.isHidden = IAPViewModel.share.isSubscribed
DispatchQueue.main.async {
let leaase = (SpeakElePublicManager.share.userInfo.targetLanguage == "🇬🇧 English" ? 185 : 1)
self.homeModel.fetchLeasson(leassonId: leaase) {[weak self] data in
self?.dataLesssion = data
self?.viewModel.DialogLeasson = data;
self?.viewModel.fetchHistroy(leassonId: self?.dataLesssion?.id ?? 0 ,isReStart: self?.isReStart ?? true)
self?.setLeasse()
}
}
}
private func setLeasse() -> Void {
self.SpeakLeassonName.text = "\(dataLesssion?.lessonId ?? ""): \(dataLesssion?.name ?? "")"
self.SpeakLeassonCollect.isSelected = dataLesssion?.isCollect ?? false
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.SpeakUpdate = { [weak self] data in
if data is SpeakNetBaseDeflutMode {
self?.SpeakLeassonCollect.isSelected = !(self?.SpeakLeassonCollect.isSelected ?? false)
}else if let d = data as? [SpeakDialogueModel] {
self?.dataSource = d
self?.SpeakLeassonTableView.reloadData()
self?.SpeakLeassonTableView.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01, execute: {
self?.SpeakLeassonTableView.reloadData()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self?.tipsAnimateFinish()
self?.scrollTop()
}
})
}else if let dsta = data as? SpeakdialogueTalkModel {
self?.isSing = true
DispatchQueue.global().async {
var Audioplay:[Data] = []
var duration = 0.0
for save in (dsta.contentList ?? []){
if let d = save.video {
duration += save.videoTime ?? 0
Audioplay.append(d)
SpeakCache.cache.saveData(data: d, fileName: "\(save.recordId ?? 0)")
}
}
DispatchQueue.main.async {
if Audioplay.count > 0 {
AudioPlayerManager.shared.setupAudioPlayer(with: Audioplay.first! ,isMuted: self?.isMute ?? false)
Audioplay.remove(at: 0)
AudioPlayerManager.shared.task = Audioplay
let speed = SpeakElePublicManager.share.PublicData.speed
SpeakAIVideoPlayManager.share.PlaySpeak(duration / speed)
}
}
}
}
}
if self.dataSource.count != viewModel.dialogLeassAsk.count {
self.dataSource = viewModel.dialogLeassAsk
self.SpeakLeassonTableView.reloadData()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.tipsAnimateFinish()
self.scrollTop()
}
}
audioText()
titleView.isHidden = true
self.didddd.isPaused = false
studyTm = SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm ?? 0
studyTime = SpeakDayEveryManager.manager.SpeakDayData.studytime ?? 0
SentAudioSound.isSelected = isMute
if isReStart {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
let vc = SpeakDialogTipsViewCtr()
vc.show()
}
}
SpeakVideoPPPPPP.addSubview(SpeakAIVideoPlayManager.share)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
SpeakAIVideoPlayManager.share.PlayBg()
}
}
override func setup() {
SpeakLeassonTableView.delegate = self
SpeakLeassonTableView.dataSource = self
SpeakLeassonTableView.sectionHeaderTopPadding = 0
SpeakLeassonTableView.sectionHeaderHeight = 0.01
SpeakLeassonTableView.sectionFooterHeight = 0.01
SpeakLeassonTableView.contentInsetAdjustmentBehavior = .never
SpeakLeassonTableView.contentInset = UIEdgeInsets()
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogSenderCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogSenderCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIerCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIerCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogLoadingCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogLoadingCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIReviewCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogQuReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogQuReviewCell.id)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
SpeakContentView.cornerRect(radius: 16, [.topLeft,.topRight])
SpeakAIVideoPlayManager.share.frame = self.SpeakVideoPPPPPP.bounds
}
@IBAction func SpeakFavatorTaps(_ sender: UIButton) {
viewModel.collect(id: self.dataLesssion?.id ?? 0, isCollect: !sender.isSelected)
}
@IBAction func SoundTapCloseTaps(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
isMute = sender.isSelected
AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
for (i,_) in self.dataSource.enumerated() {
if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
cell.isMute = isMute
}
}
}
@IBAction func SpeakDialogCloseTaps(_ sender: Any) {
let configs = SpeakPublicTipsViewCtr.PublicTipsModel(icon: UIImage(named: "img_wanliu"),title: "The teacher is waiting for you",descAttr: "Are you sure you want to quit? Continuous learning is more efficient",sureAction: "Return to the classroom", cancel: "Persist in withdrawing")
let alert = SpeakPublicTipsViewCtr(configs: configs)
alert.show()
alert.view.callblack = {[weak self] data in
if let b = data as? Bool ,
b == true{
self?.didddd.isPaused = true
self?.didddd.invalidate()
self?.display.isPaused = true
self?.display.invalidate()
SpeakAIVideoPlayManager.share.removeFromSuperview()
SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
SpeakDayEveryManager.manager.update()
if let call = self?.view.callblack {
call(self?.isSing)
}
AudioPlayerManager.shared.stop()
self?.navigationController?.popViewController(animated: true)
}
}
}
@IBAction func SpeakDialogueSet(_ sender: Any) {
let vc = SpeakDialogueSetViewCtr()
vc.show { [weak self] in
if self?.InputTextView.state == .defult {
self?.InputTextView.state = .defult
}
if let last = self?.dataSource.last,
last.role == .AI ,
let len = self?.dataSource.count, len > 0 {
if SpeakElePublicManager.share.PublicData.Smarttips {
self?.dataSource[len-1].AniState = .final
}else{
self?.dataSource[len-1].AniState = .ANone
}
self?.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: len-1, section: 0)], with: .bottom)
}
}
}
override func SpeakUpdate() {
InputTextView.update()
}
private lazy var InputTextView: SpeakDialogueInputTextView = {
let input = SpeakDialogueInputTextView.xib()
input.delegate = self
self.SpeakInputView.addSubview(input)
input.callblack = {[weak self] bt in
if SpeakAudioRecorder.shared.hasPermission {
let call = SpeakEleCallAIViewCtr(viewModel: self?.viewModel)
call.isMate = self?.isMute ?? false
call.leasses = self?.dataLesssion?.id
SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
SpeakDayEveryManager.manager.update()
call.view.callblack = {[weak self] data in
if let isMate = data as? Bool {
self?.isMute = isMate
self?.dataSource = self?.viewModel.dialogLeassAsk ?? []
self?.scrollTop()
self?.tipsAnimateFinish()
}
}
self?.navigationController?.pushViewController(call, animated: true)
}else{
let alert = UIAlertController(title: nil, message: "Microphone permission not enabled", preferredStyle: .alert)
SpWindow.rootViewController?.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
alert.dismiss(animated: true)
}
}
}
input.snp.makeConstraints { make in
make.left.right.bottom.top.equalToSuperview()
}
return input
}()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
SpeakAIVideoPlayManager.share.stop()
}
private lazy var didddd: CADisplayLink = {
let ddd = CADisplayLink(target: self, selector: #selector(uuuup))
ddd.preferredFramesPerSecond = 1
ddd.add(to: .main, forMode: .common )
return ddd
}()
deinit {
self.display.invalidate()
self.didddd.invalidate()
self.view.callblack = nil
}
}
// MARK: - sender
extension SpeakNewUserViewCtr {
@objc private func uuuup() -> Void {
if !IAPViewModel.share.isSubscribed {
studyTm -= 1
let min = studyTm / 60
let sec = studyTm % 60
SpeakTimes.setTitle(String(format: "%02d:%02d", min,sec), for: .normal)
}
studyTime += 1
}
private func tipsAnimateFinish() {
self.view.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
if let last = self.dataSource.last,
last.AniState == .loading,
last.role == .AI {
let len = self.dataSource.count - 1
self.dataSource[len].AniState = SpeakDialogueRoleAnimation.final
self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: len, section: 0)], with: .none)
self.SpeakLeassonTableView.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.scrollTop()
}
}
}
}
@objc private func scrollTop() -> Void {
self.SpeakLeassonTableView.reloadData()
self.SpeakLeassonTableView.layoutIfNeeded()
if self.SpeakLeassonTableView.contentSize.height > self.SpeakLeassonTableView.height {
self.SpeakLeassonTableView.beginUpdates()
self.SpeakLeassonTableView.scrollToRow(at: IndexPath(row: self.dataSource.count-1, section: 0), at: .bottom, animated: true)
self.SpeakLeassonTableView.endUpdates()
self.SpeakLeassonTableView.reloadData()
}
}
}
// MARK: - TableViewDelegate
extension SpeakNewUserViewCtr : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = dataSource[indexPath.row]
if data.role == .AI {
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogAIerCell.id, for: indexPath) as! SpeakDialogAIerCell
cell.isTranslate = self.Translates.contains(indexPath.row)
cell.data = data
cell.isMute = isMute
cell.callblack = { [weak self] idx in
if let ask = idx as? String {
if self?.Translates.contains(indexPath.row) ?? false{
self?.Translates.remove(indexPath.row)
cell.isTranslate = false
tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}else{
self?.Translates.add(indexPath.row)
if data.translate?.count ?? 0 <= 0 {
self?.viewModel.translate(msg: ask) { t in
self?.dataSource[indexPath.row].translate = t
tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}
}else{
tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}
}
}
}
return cell
}else if data.role == .User{
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogSenderCell.id, for: indexPath) as! SpeakDialogSenderCell
cell.data = data
cell.leasession = self.dataLesssion?.id
return cell
}else if data.role == .AIReview {
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogAIReviewCell.id, for: indexPath) as! SpeakDialogAIReviewCell
cell.data = data
return cell
}else if data.role == .review {
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogQuReviewCell.id, for: indexPath) as! SpeakDialogQuReviewCell
return cell
}else{
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakDialogLoadingCell.id, for: indexPath) as! SpeakDialogLoadingCell
return cell
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = cell as? SpeakDialogAIerCell{
cell.reload()
}else if let cell = cell as? SpeakDialogLoadingCell{
cell.LoadingView.stopAnimating()
cell.LoadingView.startAnimating()
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return UIView()
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView()
}
}
// MARK: - input
extension SpeakNewUserViewCtr : SpeakDialogueInputDelegate {
func SpeakTipComplate() {
if let last = self.dataSource.last,
last.role == .AI {
if last.AniState == .ANone {
self.dataSource[self.dataSource.count-1].AniState = .loading
self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: self.dataSource.count-1, section: 0)], with: .bottom)
self.SpeakLeassonTableView.reloadData()
self.view.layoutIfNeeded()
tipsAnimateFinish()
}else{
self.dataSource[self.dataSource.count-1].AniState = .ANone
self.SpeakLeassonTableView.reloadRows(at: [IndexPath(row: self.dataSource.count-1, section: 0)], with: .bottom)
self.SpeakLeassonTableView.reloadData()
self.view.layoutIfNeeded()
}
}
}
func speakSendMessage(message: String) {
if !IAPViewModel.share.isSubscribed && studyTm <= 0{
let iap = SpeakEleIAPViewCtr()
iap.state = .other
self.navigationController?.AnimationState = .present
self.navigationController?.pushViewController(iap, animated: true)
return
}
AudioPlayerManager.shared.stop()
if message.count > 0 {
var talk = SpeakDialogueModel()
talk.content = message
talk.role = .User
talk.AniState = .ANone
viewModel.dialogLeassAsk.append(talk)
viewModel.AIAsk(lessonId: self.dataLesssion?.id ?? 0, userAnswer: message)
var loading = SpeakDialogueModel()
loading.role = .loading
viewModel.dialogLeassAsk.append(loading)
}else if message.count == 0 {
self.display.isPaused = true
InputTextView.state = .record
SpeakAudioRecorder.shared.stopRecording { url, error in
if error == nil ,
let urls = url {
SpeakAudioToTextConverter.share.recognizeAudioFile(at: urls)
}
}
}
}
private func audioText() -> Void {
SpeakAudioToTextConverter.share.onResult = { [weak self] text in
if text.count > 0 {
var talk = SpeakDialogueModel()
talk.content = text
talk.role = .User
talk.AniState = .ANone
self?.viewModel.dialogLeassAsk.append(talk)
self?.viewModel.AIAsk(lessonId: self?.dataLesssion?.id ?? 0, userAnswer: text)
var loading = SpeakDialogueModel()
loading.role = .loading
self?.viewModel.dialogLeassAsk.append(loading)
}
}
SpeakAudioToTextConverter.share.onError = { error in
}
}
func startRecord() {
self.display.isPaused = false
SpeakAudioRecorder.shared.startRecording { su, error in
if su {}
}
}
func cancelRecord() {
SpeakAudioRecorder.shared.stopRecording()
self.display.isPaused = true
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakNewUserViewCtr">
<connections>
<outlet property="SentAudioSound" destination="d5C-Mh-a6g" id="vcX-86-HkZ"/>
<outlet property="SpeakContentView" destination="UgV-e9-vtV" id="lPL-lx-0Sw"/>
<outlet property="SpeakDialogTopPlayVideo" destination="MTv-a8-TN9" id="kkx-Wg-z8w"/>
<outlet property="SpeakInputView" destination="f1C-9w-UIB" id="9FT-0O-qSH"/>
<outlet property="SpeakLeassonCollect" destination="efB-Ol-igt" id="zqm-il-le9"/>
<outlet property="SpeakLeassonName" destination="Ev6-ZQ-XEj" id="7cz-7B-Ouu"/>
<outlet property="SpeakLeassonTableView" destination="RaO-i9-B0n" id="6Og-5T-Da6"/>
<outlet property="SpeakTimes" destination="FO0-Oc-uMs" id="kt7-tq-z8d"/>
<outlet property="SpeakVideoPPPPPP" destination="WYo-1u-mT0" id="Cxl-3h-cl6"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon-CallAI-bg" translatesAutoresizingMaskIntoConstraints="NO" id="cQI-MC-pEk">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WYo-1u-mT0">
<rect key="frame" x="0.0" y="0.0" width="393" height="330"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MTv-a8-TN9">
<rect key="frame" x="0.0" y="0.0" width="393" height="330"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Odw-pW-euv">
<rect key="frame" x="10" y="50" width="30" height="32"/>
<inset key="contentEdgeInsets" minX="5" minY="5" maxX="5" maxY="5"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="Close2"/>
<connections>
<action selector="SpeakDialogCloseTaps:" destination="-1" eventType="touchUpInside" id="Hvc-fi-uP5"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d5C-Mh-a6g">
<rect key="frame" x="10" y="263" width="42" height="42"/>
<inset key="contentEdgeInsets" minX="5" minY="5" maxX="5" maxY="5"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="Silent"/>
<state key="selected" image="Silent_off"/>
<connections>
<action selector="SoundTapCloseTaps:" destination="-1" eventType="touchUpInside" id="j5u-b8-qed"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Bhq-Vr-wnR">
<rect key="frame" x="339" y="50" width="30" height="32"/>
<inset key="contentEdgeInsets" minX="5" minY="5" maxX="5" maxY="5"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="dialog-Gear"/>
<connections>
<action selector="SpeakDialogueSet:" destination="-1" eventType="touchUpInside" id="rLF-Ca-MJ8"/>
</connections>
</button>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FO0-Oc-uMs">
<rect key="frame" x="261" y="53" width="68" height="26"/>
<color key="backgroundColor" red="0.10980392156862745" green="0.14901960784313725" blue="0.20392156862745098" alpha="0.30274766156462585" colorSpace="calibratedRGB"/>
<inset key="contentEdgeInsets" minX="5" minY="2" maxX="5" maxY="2"/>
<inset key="titleEdgeInsets" minX="2" minY="0.0" maxX="-2" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="5:00" image="dialog-Time"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="0"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="14"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="corners">
<real key="value" value="13"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="d5C-Mh-a6g" firstAttribute="leading" secondItem="Odw-pW-euv" secondAttribute="leading" id="4kv-J4-iWy"/>
<constraint firstItem="Odw-pW-euv" firstAttribute="top" secondItem="MTv-a8-TN9" secondAttribute="top" constant="50" id="Cew-5M-jEV"/>
<constraint firstItem="Odw-pW-euv" firstAttribute="leading" secondItem="MTv-a8-TN9" secondAttribute="leading" constant="10" id="DLL-tl-5zW"/>
<constraint firstAttribute="bottom" secondItem="d5C-Mh-a6g" secondAttribute="bottom" constant="25" id="EBQ-61-Oeq"/>
<constraint firstAttribute="height" constant="330" id="IYL-Nx-hRv"/>
<constraint firstItem="Bhq-Vr-wnR" firstAttribute="leading" secondItem="FO0-Oc-uMs" secondAttribute="trailing" constant="10" id="JvT-k8-4PL"/>
<constraint firstItem="Bhq-Vr-wnR" firstAttribute="centerY" secondItem="Odw-pW-euv" secondAttribute="centerY" id="Q40-jE-RhE"/>
<constraint firstItem="FO0-Oc-uMs" firstAttribute="centerY" secondItem="Odw-pW-euv" secondAttribute="centerY" id="RPt-7N-HaQ"/>
<constraint firstAttribute="trailing" secondItem="Bhq-Vr-wnR" secondAttribute="trailing" constant="24" id="pg5-fU-iJH"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UgV-e9-vtV">
<rect key="frame" x="0.0" y="310" width="393" height="428"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ev6-ZQ-XEj">
<rect key="frame" x="194.33333333333334" y="16" width="4.6666666666666572" height="21.666666666666671"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="18"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="efB-Ol-igt">
<rect key="frame" x="341" y="13" width="28" height="28"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="sp-pra-heart"/>
<state key="selected" image="sp-pra-heart-s"/>
<connections>
<action selector="SpeakFavatorTaps:" destination="-1" eventType="touchUpInside" id="5i5-YC-Qat"/>
</connections>
</button>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="grouped" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" estimatedSectionHeaderHeight="-1" sectionFooterHeight="18" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="RaO-i9-B0n">
<rect key="frame" x="0.0" y="47.666666666666686" width="393" height="380.33333333333331"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</tableView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="efB-Ol-igt" firstAttribute="centerY" secondItem="Ev6-ZQ-XEj" secondAttribute="centerY" id="FYT-km-ebg"/>
<constraint firstItem="RaO-i9-B0n" firstAttribute="leading" secondItem="UgV-e9-vtV" secondAttribute="leading" id="No0-Mg-lfQ"/>
<constraint firstItem="Ev6-ZQ-XEj" firstAttribute="centerX" secondItem="UgV-e9-vtV" secondAttribute="centerX" id="RMS-h8-dlS"/>
<constraint firstAttribute="trailing" secondItem="efB-Ol-igt" secondAttribute="trailing" constant="24" id="Z3p-JP-3mp"/>
<constraint firstItem="RaO-i9-B0n" firstAttribute="top" secondItem="Ev6-ZQ-XEj" secondAttribute="bottom" constant="10" id="bDb-Fk-6GT"/>
<constraint firstItem="Ev6-ZQ-XEj" firstAttribute="top" secondItem="UgV-e9-vtV" secondAttribute="top" constant="16" id="h7s-ay-Ew1"/>
<constraint firstAttribute="bottom" secondItem="RaO-i9-B0n" secondAttribute="bottom" id="hGK-6g-wBD"/>
<constraint firstAttribute="trailing" secondItem="RaO-i9-B0n" secondAttribute="trailing" id="nua-Un-siB"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="f1C-9w-UIB">
<rect key="frame" x="0.0" y="738" width="393" height="114"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5Ee-ty-Zpg">
<rect key="frame" x="0.0" y="0.0" width="393" height="0.66666666666666663"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.12056228741496598" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="0.59999999999999998" id="3lA-kj-1so"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="5Ee-ty-Zpg" firstAttribute="leading" secondItem="f1C-9w-UIB" secondAttribute="leading" id="VpP-FT-aoo"/>
<constraint firstAttribute="trailing" secondItem="5Ee-ty-Zpg" secondAttribute="trailing" id="ZQk-kY-2bR"/>
<constraint firstItem="5Ee-ty-Zpg" firstAttribute="top" secondItem="f1C-9w-UIB" secondAttribute="top" id="aon-Mr-ViX"/>
<constraint firstAttribute="height" constant="114" id="w2P-Q5-ija"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="MTv-a8-TN9" firstAttribute="trailing" secondItem="fnl-2z-Ty3" secondAttribute="trailing" id="3B1-8w-b95"/>
<constraint firstItem="WYo-1u-mT0" firstAttribute="trailing" secondItem="MTv-a8-TN9" secondAttribute="trailing" id="3oG-72-5Mg"/>
<constraint firstItem="UgV-e9-vtV" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="9BZ-9f-nFc"/>
<constraint firstItem="MTv-a8-TN9" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="G9T-lR-Gn1"/>
<constraint firstItem="f1C-9w-UIB" firstAttribute="top" secondItem="UgV-e9-vtV" secondAttribute="bottom" id="N38-rR-v3p"/>
<constraint firstItem="UgV-e9-vtV" firstAttribute="top" secondItem="MTv-a8-TN9" secondAttribute="bottom" constant="-20" id="SVl-xz-iO5"/>
<constraint firstItem="cQI-MC-pEk" firstAttribute="trailing" secondItem="fnl-2z-Ty3" secondAttribute="trailing" id="Vlk-Uu-730"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="UgV-e9-vtV" secondAttribute="trailing" id="X0p-3L-ESX"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="f1C-9w-UIB" secondAttribute="trailing" id="dwH-O1-dSH"/>
<constraint firstItem="f1C-9w-UIB" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="ey2-cX-FlQ"/>
<constraint firstAttribute="bottom" secondItem="f1C-9w-UIB" secondAttribute="bottom" id="fLj-I4-WMc"/>
<constraint firstItem="cQI-MC-pEk" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="iFU-kq-wEu"/>
<constraint firstItem="WYo-1u-mT0" firstAttribute="top" secondItem="MTv-a8-TN9" secondAttribute="top" id="jdv-Qf-xiE"/>
<constraint firstAttribute="bottom" secondItem="cQI-MC-pEk" secondAttribute="bottom" id="kbV-65-dzH"/>
<constraint firstItem="MTv-a8-TN9" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="oV6-0D-tdX"/>
<constraint firstItem="cQI-MC-pEk" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="qRI-qk-swj"/>
<constraint firstItem="WYo-1u-mT0" firstAttribute="bottom" secondItem="MTv-a8-TN9" secondAttribute="bottom" id="wMo-z9-qs4"/>
<constraint firstItem="WYo-1u-mT0" firstAttribute="leading" secondItem="MTv-a8-TN9" secondAttribute="leading" id="xnj-gO-XGc"/>
</constraints>
<point key="canvasLocation" x="75.572519083969468" y="-12.67605633802817"/>
</view>
</objects>
<resources>
<image name="Close2" width="20" height="20"/>
<image name="Silent" width="32" height="32"/>
<image name="Silent_off" width="32" height="32"/>
<image name="dialog-Gear" width="20" height="20"/>
<image name="dialog-Time" width="20" height="20"/>
<image name="icon-CallAI-bg" width="402" height="874"/>
<image name="sp-pra-heart" width="28" height="28"/>
<image name="sp-pra-heart-s" width="28" height="28"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
...@@ -77,6 +77,7 @@ class SpeakChangeStuLanguesView: UIView { ...@@ -77,6 +77,7 @@ class SpeakChangeStuLanguesView: UIView {
@IBAction func TOIjkjdklsf(_ sender: UIButton) { @IBAction func TOIjkjdklsf(_ sender: UIButton) {
if !sender.isSelected { if !sender.isSelected {
SpeakCache.cache.SaveModel(cache: SpeakPracticeLesLocalModel(lesson: [] ,select: 0), state: .PracticeCache, name: "Lesson")
if let call = callblack { if let call = callblack {
call( sender == SpeakChangeBtns.first ? 0 : 1) call( sender == SpeakChangeBtns.first ? 0 : 1)
} }
......
...@@ -103,7 +103,7 @@ class SpeakEleLessionView: UIView { ...@@ -103,7 +103,7 @@ class SpeakEleLessionView: UIView {
} }
SpeakLessionStart.snp.makeConstraints { make in SpeakLessionStart.snp.makeConstraints { make in
make.bottom.equalTo(self.snp.top) make.bottom.equalTo(self.button.snp.top).offset(5.adapterH())
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
} }
......
...@@ -15,7 +15,7 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr { ...@@ -15,7 +15,7 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr {
@IBOutlet var SpeakItemBtns: [UIButton]! @IBOutlet var SpeakItemBtns: [UIButton]!
private let viewModel = SpeakPracticeNetViewModel() private let viewModel = SpeakPracticeNetViewModel()
private let collectViewModel = SpeakEleProfileNetViewModel()
private var startStudyT:Date = Date() private var startStudyT:Date = Date()
@IBOutlet weak var SpeakTipsRight: UIView! @IBOutlet weak var SpeakTipsRight: UIView!
@IBOutlet weak var SpeakTipsLeft: UIView! @IBOutlet weak var SpeakTipsLeft: UIView!
...@@ -53,6 +53,17 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr { ...@@ -53,6 +53,17 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr {
} }
} }
override func PopViewCtr() {
let name = SpeakElePublicManager.share.userInfo.targetLanguage ?? ""
let saveData = self.datasource.map { bt in
var temp = bt
temp.isFront = nil
return temp
}
SpeakCache.cache.SaveModel(cache: saveData, state: .PracticeCache, name: name)
super.PopViewCtr()
}
@objc private func tipsHide(_ res:UIGestureRecognizer) -> Void { @objc private func tipsHide(_ res:UIGestureRecognizer) -> Void {
let view = res.view let view = res.view
if view == SpeakTipsLeft { if view == SpeakTipsLeft {
...@@ -127,6 +138,17 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr { ...@@ -127,6 +138,17 @@ class SpeakElePracticeReviewViewCtr: SpeakEleBaseViewCtr {
extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{ extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
private func setFavaret(_ fw:Bool , indexPath:IndexPath) -> Void {
let d = self.datasource[indexPath.row].wordId
collectViewModel.collect(param: ["businessId":d,
"type":2,
"isCollect":fw]) {[weak self] su, data in
self?.datasource[indexPath.row].isCollected = su ? fw : !fw
let cell = self?.SpeakCollectionV.cellForItem(at: indexPath) as? SpeakPracticeReviewCell
cell?.data = self?.datasource[indexPath.row]
}
}
private func StrangeFamilar(state:SpeakPracticeReviewCell.SpeakPracticeReviewState) -> Void { private func StrangeFamilar(state:SpeakPracticeReviewCell.SpeakPracticeReviewState) -> Void {
let cell = SpeakCollectionV.cellForItem(at: IndexPath(row: currentIdx, section: 0)) let cell = SpeakCollectionV.cellForItem(at: IndexPath(row: currentIdx, section: 0))
...@@ -199,7 +221,7 @@ extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionV ...@@ -199,7 +221,7 @@ extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionV
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SpeakPracticeReviewCell.id, for: indexPath) as! SpeakPracticeReviewCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SpeakPracticeReviewCell.id, for: indexPath) as! SpeakPracticeReviewCell
cell.isHidden = (indexPath.row < currentIdx ? true : false) cell.isHidden = (indexPath.row < currentIdx ? true : false)
cell.data = datasource[indexPath.row] cell.data = datasource[indexPath.row]
cell.clipsToBounds = true // cell.clipsToBounds = true
cell.SpeakCallblack = { [weak self] state in cell.SpeakCallblack = { [weak self] state in
self?.StrangeFamilar(state: state) self?.StrangeFamilar(state: state)
} }
...@@ -214,6 +236,8 @@ extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionV ...@@ -214,6 +236,8 @@ extension SpeakElePracticeReviewViewCtr : UICollectionViewDelegate,UICollectionV
}else{ }else{
self?.SpeakItemBtns.forEach({$0.isSelected = false}) self?.SpeakItemBtns.forEach({$0.isSelected = false})
} }
}else if let fav = state as? Bool {
self?.setFavaret( fav,indexPath: indexPath)
} }
} }
return cell return cell
......
...@@ -19,6 +19,7 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr { ...@@ -19,6 +19,7 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr {
/// 课程 /// 课程
private var Session:[SpeakPracticeLessonModel] = [] private var Session:[SpeakPracticeLessonModel] = []
private var currentLess:SpeakPracticeLessonModel? private var currentLess:SpeakPracticeLessonModel?
private var selectIdx:Int = -1
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -41,6 +42,12 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr { ...@@ -41,6 +42,12 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr {
learnedW.view.callblack = { [weak self] data in learnedW.view.callblack = { [weak self] data in
if let da = data as? SpeakPracticeLessonModel { if let da = data as? SpeakPracticeLessonModel {
if self?.currentLess?.lessonId != da.lessonId { if self?.currentLess?.lessonId != da.lessonId {
for (i,v) in (self?.Session ?? []).enumerated() {
if v.lessonId == da.lessonId {
self?.selectIdx = i
break
}
}
self?.currentLess = da self?.currentLess = da
self?.SpeakselectSession() self?.SpeakselectSession()
} }
...@@ -51,7 +58,11 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr { ...@@ -51,7 +58,11 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr {
@IBAction func SpeakReviewTaps(_ sender: Any) { @IBAction func SpeakReviewTaps(_ sender: Any) {
if self.currentLess != nil { if self.currentLess != nil {
let review = SpeakElePracticeReviewViewCtr() let review = SpeakElePracticeReviewViewCtr()
review.datasource = dataSource review.datasource = dataSource.map({ bd in
var temp = bd
temp.isFront = nil
return temp
})
review.leassion = self.currentLess?.lessonId ?? 0 review.leassion = self.currentLess?.lessonId ?? 0
self.parent?.navigationController?.pushViewController(review, animated: true) self.parent?.navigationController?.pushViewController(review, animated: true)
} }
...@@ -60,20 +71,33 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr { ...@@ -60,20 +71,33 @@ class SpeakElePracticeViewCtr: SpeakEleBaseViewCtr {
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
titleView.isHidden = true titleView.isHidden = true
let model:SpeakPracticeLesLocalModel? = SpeakCache.cache.LoadMode(state: .PracticeCache, name: "Lesson")
self.Session = model?.lesson ?? []
self.selectIdx = model?.select ?? 0
if self.selectIdx >= 0 && self.selectIdx < (model?.lesson?.count ?? 0) && (model?.lesson?.count ?? 0) > 0 {
self.currentLess = self.Session[self.selectIdx]
}
let name = SpeakElePublicManager.share.userInfo.targetLanguage ?? "" let name = SpeakElePublicManager.share.userInfo.targetLanguage ?? ""
let data:[SpeakPracticeWordModel] = SpeakCache.cache.LoadMode(state: .MessageCache, name: name) ?? [] let data:[SpeakPracticeWordModel] = SpeakCache.cache.LoadMode(state: .PracticeCache, name: name) ?? []
if data.count <= 0 { if self.Session.count <= 0 {
self.getLeasion() self.getLeasion()
}else{ }else{
SpeakSectionL.text = currentLess?.lessonName
if data.count != self.dataSource.count { if data.count != self.dataSource.count {
self.dataSource = data self.dataSource = data
setPage(current: 1)
self.SpeakCollection.reloadData() self.SpeakCollection.reloadData()
}else{
for (i,var v) in self.dataSource.enumerated() {
if let cell = SpeakCollection.cellForItem(at: IndexPath(row: i, section: 0)) as? SpeakElePracticeViewCell {
v.isCollected = data[i].isCollected
cell.data = v
}
}
} }
} }
} }
private var dataSource:[SpeakPracticeWordModel] = [] private var dataSource:[SpeakPracticeWordModel] = []
} }
extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout { extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
...@@ -93,7 +117,7 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData ...@@ -93,7 +117,7 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData
viewModel.learnedLesson {[weak self] (success, data:[SpeakPracticeLessonModel]?) in viewModel.learnedLesson {[weak self] (success, data:[SpeakPracticeLessonModel]?) in
if success { if success {
self?.Session = data ?? [] self?.Session = data ?? []
self?.currentLess = data?.first self?.currentLess = data?[safe:self?.selectIdx ?? 0]
self?.SpeakselectSession() self?.SpeakselectSession()
} }
} }
...@@ -104,10 +128,14 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData ...@@ -104,10 +128,14 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData
viewModel.leassionWord(param: ["lessonId":self.currentLess?.lessonId ?? ""]) {[weak self] (su, data:[SpeakPracticeWordModel]? ) in viewModel.leassionWord(param: ["lessonId":self.currentLess?.lessonId ?? ""]) {[weak self] (su, data:[SpeakPracticeWordModel]? ) in
if su { if su {
self?.dataSource = data ?? [] self?.dataSource = data ?? []
let point = self?.SpeakCollection.contentOffset ?? CGPoint()
let name = SpeakElePublicManager.share.userInfo.targetLanguage ?? "" let name = SpeakElePublicManager.share.userInfo.targetLanguage ?? ""
SpeakCache.cache.SaveModel(cache: self?.dataSource, state: .PracticeCache, name: name) SpeakCache.cache.SaveModel(cache: self?.dataSource, state: .PracticeCache, name: name)
self?.setPage(current: ( Int(round(point.x/(self?.SpeakCollection.width ?? 1))) + 1) )
let model = SpeakPracticeLesLocalModel(lesson: self?.Session, select: self?.selectIdx)
SpeakCache.cache.SaveModel(cache: model, state: .PracticeCache, name: "Lesson")
self?.setPage(current: 1 )
self?.SpeakCollection.reloadData() self?.SpeakCollection.reloadData()
} }
} }
...@@ -125,10 +153,9 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData ...@@ -125,10 +153,9 @@ extension SpeakElePracticeViewCtr :UICollectionViewDelegate,UICollectionViewData
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SpeakElePracticeViewCell.id, for: indexPath) as! SpeakElePracticeViewCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SpeakElePracticeViewCell.id, for: indexPath) as! SpeakElePracticeViewCell
var data = self.dataSource[indexPath.row] var data = self.dataSource[indexPath.row]
cell.data = data cell.data = data
cell.SpeakPracticeNormal.SpeakPracticeIcon.image = UIImage(named: "sp-Practicebg-\(((data.wordId ?? 0)%14)+1)")
cell.callblack = {[weak self] fw in cell.callblack = {[weak self] fw in
if let i = fw as? Int { if let i = fw as? String {
data.isFront = (i == 1 ? true : false) data.isFront = (i == "1" ? true : false)
self?.dataSource[indexPath.row] = data self?.dataSource[indexPath.row] = data
}else{ }else{
self?.setFavaret( (fw as? Bool ?? false) ,indexPath: indexPath) self?.setFavaret( (fw as? Bool ?? false) ,indexPath: indexPath)
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
import UIKit import UIKit
struct SpeakPracticeLesLocalModel : Codable {
var lesson:[SpeakPracticeLessonModel]?
var select:Int?
}
struct SpeakPracticeLessonModel: Codable { struct SpeakPracticeLessonModel: Codable {
var lessonId : Int? var lessonId : Int?
var lessonName : String? var lessonName : String?
......
...@@ -40,6 +40,7 @@ class SpeakElePracticeViewCell: UICollectionViewCell { ...@@ -40,6 +40,7 @@ class SpeakElePracticeViewCell: UICollectionViewCell {
}else if !isShow{ }else if !isShow{
self.HideDescp() self.HideDescp()
} }
SpeakPracticeNormal.SpeakPracticeIcon.image = UIImage(named: "sp-Practicebg-\(((data?.wordId ?? 0)%14)+1)")
} }
} }
...@@ -84,7 +85,6 @@ class SpeakElePracticeViewCell: UICollectionViewCell { ...@@ -84,7 +85,6 @@ class SpeakElePracticeViewCell: UICollectionViewCell {
call(fw) call(fw)
} }
} }
} }
override func layoutSubviews() { override func layoutSubviews() {
...@@ -107,7 +107,7 @@ class SpeakElePracticeViewCell: UICollectionViewCell { ...@@ -107,7 +107,7 @@ class SpeakElePracticeViewCell: UICollectionViewCell {
completion: { [weak self] _ in completion: { [weak self] _ in
self?.isShowingFront.toggle() self?.isShowingFront.toggle()
guard let call = self?.callblack else { return } guard let call = self?.callblack else { return }
call( (self?.isShowingFront ?? true ? 1 : 0) ) call( (self?.isShowingFront ?? true ? "1" : "0") )
} }
) )
} }
......
...@@ -15,8 +15,14 @@ class SpeakPracticeReviewCell: UICollectionViewCell { ...@@ -15,8 +15,14 @@ class SpeakPracticeReviewCell: UICollectionViewCell {
@IBOutlet var SpeakRightTips: UIView! @IBOutlet var SpeakRightTips: UIView!
@IBOutlet weak var SpeakRightLabel: UILabel! @IBOutlet weak var SpeakRightLabel: UILabel!
private let viewmodel = SpeakPracticeNetViewModel()
static let id = "SpeakPracticeReviewCell" static let id = "SpeakPracticeReviewCell"
private let leftMax:Double = -70
private let rightMax:Double = 70
var isShowingFront = true
var wordDetail:SpeakPracticeWordDetailModel?
enum SpeakPracticeReviewState { enum SpeakPracticeReviewState {
case left case left
case right case right
...@@ -26,20 +32,51 @@ class SpeakPracticeReviewCell: UICollectionViewCell { ...@@ -26,20 +32,51 @@ class SpeakPracticeReviewCell: UICollectionViewCell {
private var beginP = CGPoint() private var beginP = CGPoint()
var SpeakCallblack: ((_ state:SpeakPracticeReviewState)-> Void)? var SpeakCallblack: ((_ state:SpeakPracticeReviewState)-> Void)?
private var isShow:Bool{
set {}
get {
return IAPViewModel.share.isSubscribed || SpeakDayEveryManager.manager.SpeakDayData.PracticeFreeNum ?? 0 > 0
}
}
var data:SpeakPracticeWordModel? { var data:SpeakPracticeWordModel? {
didSet{ didSet{
isShowingFront = data?.isFront ?? true
UIView.transition(with: isShowingFront ? Word : back , duration: 0, options: [.transitionFlipFromRight]) { }
Word.SpeakPracticeWord.text = data?.word Word.SpeakPracticeWord.text = data?.word
Word.setLabel(data?.markStatus == 1 ? 1 : (data?.markStatus == 2 ? 2 : 0 ) ) Word.setLabel(data?.markStatus == 1 ? 1 : (data?.markStatus == 2 ? 2 : 0 ) )
Word.SpeakPracticeIcon.image = UIImage(named: "sp-Practicebg-\(((data?.wordId ?? 0)%14)+1)") Word.SpeakPracticeIcon.image = UIImage(named: "sp-Practicebg-\(((data?.wordId ?? 0)%14)+1)")
Word.clipsToBounds = true Word.clipsToBounds = true
Word.corners = 16 Word.corners = 16
Word.backgroundColor = .clear Word.backgroundColor = .clear
Word.SpeakPracticeFavorites.isSelected = data?.isCollected ?? false
back.SpeakPracticeBackWord.text = data?.word
back.SpeakPracticeBackFavorites.isSelected = data?.isCollected ?? false
Word.isHidden = !isShowingFront
back.isHidden = isShowingFront
back.corners = 16
wordDetail = SpeakWordTranslateData.data.WordTranslate?[data?.wordId ?? 0]
if let translation = wordDetail?.translation {
translationFunc()
}else{
translationHide()
} }
} }
}
override func awakeFromNib() { override func awakeFromNib() {
super.awakeFromNib() super.awakeFromNib()
self.gesture(target: self, class: UIPanGestureRecognizer.self, selector: #selector(panGesture(_:))) self.gesture(target: self, class: UIPanGestureRecognizer.self, selector: #selector(panGesture(_:)))
self.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(FlipTaps))
back.snp.makeConstraints { make in
make.left.right.bottom.top.equalToSuperview()
}
Word.snp.makeConstraints { make in Word.snp.makeConstraints { make in
make.left.right.bottom.top.equalToSuperview() make.left.right.bottom.top.equalToSuperview()
} }
...@@ -53,10 +90,71 @@ class SpeakPracticeReviewCell: UICollectionViewCell { ...@@ -53,10 +90,71 @@ class SpeakPracticeReviewCell: UICollectionViewCell {
super.layoutSubviews() super.layoutSubviews()
contentView.bringSubviewToFront(SpeakLeftTips) contentView.bringSubviewToFront(SpeakLeftTips)
contentView.bringSubviewToFront(SpeakRightTips) contentView.bringSubviewToFront(SpeakRightTips)
self.layoutIfNeeded()
back.shadow(cornerRadius: 16, shadowColor: .init(hex: 0x000000), offset: CGSize(width: 0, height: 0), opacity: 0.06, radius: 4)
}
private lazy var Word: SpeakPracticeWordView = {
let w = SpeakPracticeWordView()
contentView.addSubview(w)
w.callblack = { [weak self] fw in
if let call = self?.callblack {
call(fw)
}
}
return w
}()
private lazy var back: SpeakPracticeBackView = {
let b = SpeakPracticeBackView.xib()
b.callblack = { [weak self] fw in
if let call = self?.callblack {
call(fw)
}
}
contentView.addSubview(b)
return b
}()
deinit {
SpeakCallblack = nil
}
}
extension SpeakPracticeReviewCell {
private func netwokng() -> Void {
viewmodel.cardTranslate(param: ["word":data?.word ?? ""]) {[weak self] (success, data:SpeakPracticeWordDetailModel?) in
if success {
self?.wordDetail = data
SpeakWordTranslateData.data.WordTranslate?[self?.data?.wordId ?? 0] = data
SpeakDayEveryManager.manager.SpeakDayData.PracticeFreeNum! -= 1
SpeakDayEveryManager.manager.update()
self?.translationHide()
}
}
} }
private let leftMax:Double = -70
private let rightMax:Double = 70 @objc private func FlipTaps() -> Void {
if wordDetail == nil && isShow == true {
self.netwokng()
}else if wordDetail == nil {
self.translationHide()
}
UIView.transition(
from: isShowingFront ? Word : back,
to: isShowingFront ? back : Word,
duration: 12/60.0,
options: [.transitionFlipFromRight, .showHideTransitionViews],
completion: { [weak self] _ in
self?.isShowingFront.toggle()
guard let call = self?.callblack else { return }
// call( (self?.isShowingFront ?? true ? 1 : 0) )
}
)
}
@objc private func panGesture(_ recognizer:UIGestureRecognizer) -> Void { @objc private func panGesture(_ recognizer:UIGestureRecognizer) -> Void {
let p = recognizer.location(in: self) let p = recognizer.location(in: self)
...@@ -99,13 +197,19 @@ class SpeakPracticeReviewCell: UICollectionViewCell { ...@@ -99,13 +197,19 @@ class SpeakPracticeReviewCell: UICollectionViewCell {
} }
} }
private lazy var Word: SpeakPracticeWordView = {
let w = SpeakPracticeWordView()
contentView.addSubview(w)
return w
}()
deinit { private func translationFunc() -> Void {
SpeakCallblack = nil back.SpeakPracticeBackWord1.text = wordDetail?.translation
back.SpeakPracticeBackUnlock.isHidden = true
let anto = "Antonym:".attributed().color(.init(hex: 0x3980F6)).build()
let Example = "Example sentence:".attributed().color(.init(hex: 0x3980F6)).build()
let att = "Synonyms:".attributed().color(.init(hex: 0x3980F6)).build().combined(with: [wordDetail?.synonyms,"\n\n",anto,wordDetail?.antonym,"\n\n" ,Example,wordDetail?.example])
back.SpeakPracticeBackDesc.attributedText = att
}
private func translationHide() -> Void {
back.SpeakPracticeBackWord1.text = wordDetail?.translation
back.SpeakPracticeBackUnlock.isHidden = false
back.SpeakPracticeBackDesc.attributedText = "".attributed().build()
} }
} }
...@@ -216,7 +216,7 @@ extension SpeakEleProfileViewCtr { ...@@ -216,7 +216,7 @@ extension SpeakEleProfileViewCtr {
SpeakElePublicManager.share.PublicData.state = .start SpeakElePublicManager.share.PublicData.state = .start
let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleLoginGuideCtr()) let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleLoginGuideCtr())
SpWindow.switchToController(nav) SpWindow.rootViewController = (nav)
} }
} }
...@@ -63,7 +63,7 @@ class SpeakProfileMoreViewCtr: SpeakEleBaseViewCtr { ...@@ -63,7 +63,7 @@ class SpeakProfileMoreViewCtr: SpeakEleBaseViewCtr {
get{ get{
if state == .TargetLanguage { if state == .TargetLanguage {
var iap = ["🇬🇧 English"] var iap = ["🇬🇧 English"]
if !IAPViewModel.share.isSubscribed { if IAPViewModel.share.isSubscribed {
iap.append("🇪🇸 Español") iap.append("🇪🇸 Español")
} }
return iap return iap
......
...@@ -39,6 +39,9 @@ class SpeakEleProgressViewCtr: SpeakEleBaseViewCtr { ...@@ -39,6 +39,9 @@ class SpeakEleProgressViewCtr: SpeakEleBaseViewCtr {
if let cell = self?.SpeakTableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? SpeakProgressStudyCell { if let cell = self?.SpeakTableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? SpeakProgressStudyCell {
cell.data = self?.dayStudy ?? [] cell.data = self?.dayStudy ?? []
} }
if let cell = self?.SpeakTableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? SpeakProgressSignCell {
cell.signList = speakSignListViewModel.share.signList
}
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// //
import UIKit import UIKit
import AVFAudio
class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
...@@ -57,7 +58,6 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -57,7 +58,6 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
} }
} }
private var studyTime = 0 private var studyTime = 0
private var offset:Int = 0 { private var offset:Int = 0 {
didSet{ didSet{
...@@ -75,7 +75,6 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -75,7 +75,6 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
SpeakAskContentV.isHidden = true SpeakAskContentV.isHidden = true
SpeakEleLoadingView.isHidden = true SpeakEleLoadingView.isHidden = true
SpeakLastMsg.isHidden = true SpeakLastMsg.isHidden = true
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
SpeakDisplayV.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(SpeakDisplayTaps)) SpeakDisplayV.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(SpeakDisplayTaps))
SpeakAskAgainV.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(SpeakAskAgain)) SpeakAskAgainV.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(SpeakAskAgain))
...@@ -100,6 +99,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -100,6 +99,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
SpeakCache.cache.saveData(data: d, fileName: "\(save.recordId ?? 0)") SpeakCache.cache.saveData(data: d, fileName: "\(save.recordId ?? 0)")
} }
} }
self?.SpeakLastMsgDescp.text = audio.contentList?.last?.content ?? ""
DispatchQueue.main.async { DispatchQueue.main.async {
if Audioplay.count > 0 { if Audioplay.count > 0 {
AudioPlayerManager.shared.setupAudioPlayer(with: Audioplay.first! ,isMuted: self?.isMate ?? false) AudioPlayerManager.shared.setupAudioPlayer(with: Audioplay.first! ,isMuted: self?.isMate ?? false)
...@@ -118,21 +118,16 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -118,21 +118,16 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
self?.startTime = 0 self?.startTime = 0
} }
if let ai = SpeakAIVideoPlayManager.share.SpeakAI.SpeakPlayerLayer , let dsts = SpeakAIVideoPlayManager.share
let bg = SpeakAIVideoPlayManager.share.backgoundAI.SpeakPlayerLayer{ dsts.removeFromSuperview()
ai.videoGravity = .resizeAspectFill self.SpeakAISer.addSubview(dsts)
self.SpeakAISer.layer.addSublayer(ai)
self.SpeakAISer.layer.addSublayer(bg)
bg.videoGravity = .resizeAspectFill
SpeakAIVideoPlayManager.share.PlayBg()
}
} }
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
SpeakAIVideoPlayManager.share.SpeakAI.SpeakPlayerLayer?.frame = SpeakAISer.bounds SpeakAIVideoPlayManager.share.frame = SpeakAISer.bounds
SpeakAIVideoPlayManager.share.backgoundAI.SpeakPlayerLayer?.frame = SpeakAISer.bounds
} }
override func SpeakUpdate() { override func SpeakUpdate() {
...@@ -151,7 +146,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -151,7 +146,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
} }
if isRecord { if isRecord {
self.startTime += 1 self.startTime += 1
if self.startTime > 5 { if self.startTime > 2 {
isRecord = false isRecord = false
if self.SpeakText.count > 0 { if self.SpeakText.count > 0 {
var talk = SpeakDialogueModel() var talk = SpeakDialogueModel()
...@@ -175,16 +170,20 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -175,16 +170,20 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
titleView.isHidden = true titleView.isHidden = true
SpeakSoundBtn.isSelected = isMate SpeakSoundBtn.isSelected = isMate
let aiser = viewModel.AIser() let aiser = viewModel.AIser()
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
let idx = SpeakElePublicManager.share.PublicData.AIerIndex let idx = SpeakElePublicManager.share.PublicData.AIerIndex
let icon = "img_" + (aiser[safe: idx]?.name.lowercased() ?? "") let icon = "img_" + (aiser[safe: idx]?.name.lowercased() ?? "")
self.SpeakCallIcon.image = UIImage(named: icon) self.SpeakCallIcon.image = UIImage(named: icon)
SpeakName.text = aiser[safe: idx]?.name SpeakName.text = aiser[safe: idx]?.name
do{
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playback)
try audioSession.setActive(true)
}catch{ }
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.display.isPaused = false self.display.isPaused = false
self.dataSource = self.netViewModel.dialogLeassAsk self.dataSource = self.netViewModel.dialogLeassAsk
// if self.netViewModel.isSpeech {
self.Ask() self.Ask()
// }
} }
} }
...@@ -194,7 +193,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -194,7 +193,7 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
SpeakCallIcon.isHidden = true SpeakCallIcon.isHidden = true
SpeakAskWaitL.isHidden = true SpeakAskWaitL.isHidden = true
SpeakAISer.isHidden = false SpeakAISer.isHidden = false
SpeakAIVideoPlayManager.share.PlayBg()
if netViewModel.isSpeech { if netViewModel.isSpeech {
SpeakAskT.isHidden = false SpeakAskT.isHidden = false
} }
...@@ -241,8 +240,8 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr { ...@@ -241,8 +240,8 @@ class SpeakEleCallAIViewCtr: SpeakEleBaseViewCtr {
} }
} }
override func viewDidDisappear(_ animated: Bool) { override func viewWillDisappear(_ animated: Bool) {
super.viewDidDisappear(animated) super.viewWillDisappear(animated)
display.isPaused = true display.isPaused = true
display.invalidate() display.invalidate()
AudioPlayerManager.shared.stop() AudioPlayerManager.shared.stop()
......
...@@ -30,6 +30,8 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate { ...@@ -30,6 +30,8 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate {
private var offset:Int = 0 private var offset:Int = 0
private var selectIdx:CGFloat = -1
private var SpeakPlanChilds:[SpeakEleGeneratePlanView] = [ private var SpeakPlanChilds:[SpeakEleGeneratePlanView] = [
SpeakEleGeneratePlanView(string: "Creating diverse topics"), SpeakEleGeneratePlanView(string: "Creating diverse topics"),
SpeakEleGeneratePlanView(string: "Preparing interactive dialogues"), SpeakEleGeneratePlanView(string: "Preparing interactive dialogues"),
...@@ -39,12 +41,11 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate { ...@@ -39,12 +41,11 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
SpeakPlanChilds.forEach { plan in SpeakPlanChilds.forEach { plan in
SpeakStackView.addArrangedSubview(plan) SpeakStackView.addArrangedSubview(plan)
} }
timer.fire()
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
...@@ -128,8 +129,8 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate { ...@@ -128,8 +129,8 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate {
child2.startRotation() child2.startRotation()
child2.offset = offset-200 child2.offset = offset-200
break break
default:
default:
let child = SpeakPlanChilds[2] let child = SpeakPlanChilds[2]
child.stop() child.stop()
child.offset = 100 child.offset = 100
...@@ -151,6 +152,12 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate { ...@@ -151,6 +152,12 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate {
} }
} }
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if timer.isValid {
timer.invalidate()
}
}
private lazy var pagectrol: UIView = { private lazy var pagectrol: UIView = {
let p = UIView() let p = UIView()
p.corners = 3 p.corners = 3
...@@ -174,4 +181,22 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate { ...@@ -174,4 +181,22 @@ class SpeakEleGeneratePlanViewCtr: SpeakEleBaseViewCtr, UIScrollViewDelegate {
let offset = scrollView.contentOffset.x let offset = scrollView.contentOffset.x
setPages(Int(offset / scrollView.width) ) setPages(Int(offset / scrollView.width) )
} }
private lazy var timer: Timer = {
let tim = Timer(timeInterval: 3, repeats: true) {[weak self] tm in
Print("timer 1111111111")
self?.selectIdx += 1
if (self?.selectIdx ?? 3) < 3 {
UIView.animate(withDuration: 0.8) {
self?.SpeakScroll.contentOffset = CGPoint(x: (self?.SpeakScroll.width ?? 0.0) * (self?.selectIdx ?? 0), y: 0)
} completion: { su in
self?.setPages(Int(self?.selectIdx ?? 0))
}
}else{
tm.invalidate()
}
}
RunLoop.main.add(tim, forMode: .common)
return tim
}()
} }
...@@ -38,8 +38,10 @@ ...@@ -38,8 +38,10 @@
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="personalizing your learning plan···" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sU1-Vw-IvM"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sU1-Vw-IvM">
<rect key="frame" x="24" y="148" width="345" height="20.333333333333343"/> <rect key="frame" x="24" y="148" width="345" height="40.666666666666657"/>
<string key="text">personalizing your learning
plan···</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
...@@ -68,7 +70,7 @@ ...@@ -68,7 +70,7 @@
</constraints> </constraints>
</scrollView> </scrollView>
<scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CVG-XR-NSd"> <scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CVG-XR-NSd">
<rect key="frame" x="24" y="482.33333333333331" width="345" height="179.66666666666669"/> <rect key="frame" x="24" y="480.33333333333331" width="345" height="179.66666666666669"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="phv-6K-Lge"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="phv-6K-Lge">
<rect key="frame" x="0.0" y="0.0" width="1035" height="179.66666666666666"/> <rect key="frame" x="0.0" y="0.0" width="1035" height="179.66666666666666"/>
...@@ -148,7 +150,7 @@ ...@@ -148,7 +150,7 @@
<real key="value" value="14"/> <real key="value" value="14"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/> <integer key="value" value="2"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
...@@ -175,11 +177,11 @@ lesson contents are very suitable for my ...@@ -175,11 +177,11 @@ lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
level from 60% to almost 80%!</string> level from 60% to almost 80%!</string>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.90133397108843538" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="0"/> <integer key="value" value="1"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize"> <userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="14"/> <real key="value" value="14"/>
...@@ -278,7 +280,7 @@ level from 60% to almost 80%!</string> ...@@ -278,7 +280,7 @@ level from 60% to almost 80%!</string>
<real key="value" value="14"/> <real key="value" value="14"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/> <integer key="value" value="2"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
...@@ -305,7 +307,7 @@ lesson contents are very suitable for my ...@@ -305,7 +307,7 @@ lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
level from 60% to almost 80%!</string> level from 60% to almost 80%!</string>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.90133397108843538" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
...@@ -408,7 +410,7 @@ level from 60% to almost 80%!</string> ...@@ -408,7 +410,7 @@ level from 60% to almost 80%!</string>
<real key="value" value="14"/> <real key="value" value="14"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/> <integer key="value" value="2"/>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
...@@ -435,7 +437,7 @@ lesson contents are very suitable for my ...@@ -435,7 +437,7 @@ lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
level from 60% to almost 80%!</string> level from 60% to almost 80%!</string>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.90133397108843538" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
...@@ -487,8 +489,11 @@ level from 60% to almost 80%!</string> ...@@ -487,8 +489,11 @@ level from 60% to almost 80%!</string>
<constraint firstItem="phv-6K-Lge" firstAttribute="width" secondItem="CVG-XR-NSd" secondAttribute="width" multiplier="3" id="zyz-hj-bvq"/> <constraint firstItem="phv-6K-Lge" firstAttribute="width" secondItem="CVG-XR-NSd" secondAttribute="width" multiplier="3" id="zyz-hj-bvq"/>
</constraints> </constraints>
</scrollView> </scrollView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="X44-Ed-GVg">
<rect key="frame" x="16" y="670" width="361" height="64"/>
<subviews>
<button opaque="NO" alpha="0.0" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8IG-gE-laz"> <button opaque="NO" alpha="0.0" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8IG-gE-laz">
<rect key="frame" x="24" y="672" width="345" height="64"/> <rect key="frame" x="0.0" y="0.0" width="361" height="64"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Continue" backgroundImage="icon_Plan_NorButton"/> <state key="normal" title="Continue" backgroundImage="icon_Plan_NorButton"/>
<state key="highlighted" backgroundImage="icon_Plan_button_click"/> <state key="highlighted" backgroundImage="icon_Plan_button_click"/>
...@@ -504,8 +509,17 @@ level from 60% to almost 80%!</string> ...@@ -504,8 +509,17 @@ level from 60% to almost 80%!</string>
<action selector="SpeakCountiueTaps:" destination="-1" eventType="touchUpInside" id="xA0-5T-bS6"/> <action selector="SpeakCountiueTaps:" destination="-1" eventType="touchUpInside" id="xA0-5T-bS6"/>
</connections> </connections>
</button> </button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="8IG-gE-laz" secondAttribute="trailing" id="6wT-dd-Iwd"/>
<constraint firstAttribute="bottom" secondItem="8IG-gE-laz" secondAttribute="bottom" id="OWO-3p-m1t"/>
<constraint firstItem="8IG-gE-laz" firstAttribute="leading" secondItem="X44-Ed-GVg" secondAttribute="leading" id="YOg-d1-WQo"/>
<constraint firstAttribute="height" constant="64" id="kqp-Sf-bEm"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="hCv-lV-npz"> <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="hCv-lV-npz">
<rect key="frame" x="166.66666666666666" y="646" width="60" height="6"/> <rect key="frame" x="166.66666666666666" y="644" width="60" height="6"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Caj-hx-BeW"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Caj-hx-BeW">
<rect key="frame" x="0.0" y="0.0" width="20" height="6"/> <rect key="frame" x="0.0" y="0.0" width="20" height="6"/>
...@@ -588,21 +602,21 @@ level from 60% to almost 80%!</string> ...@@ -588,21 +602,21 @@ level from 60% to almost 80%!</string>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="X44-Ed-GVg" secondAttribute="bottom" constant="50" id="7vY-hb-gmZ"/>
<constraint firstItem="hCv-lV-npz" firstAttribute="bottom" secondItem="CVG-XR-NSd" secondAttribute="bottom" constant="-10" id="FM9-2h-dRM"/> <constraint firstItem="hCv-lV-npz" firstAttribute="bottom" secondItem="CVG-XR-NSd" secondAttribute="bottom" constant="-10" id="FM9-2h-dRM"/>
<constraint firstItem="8IG-gE-laz" firstAttribute="bottom" secondItem="fnl-2z-Ty3" secondAttribute="bottom" constant="-48" id="O1g-Dm-HQ8"/> <constraint firstItem="X44-Ed-GVg" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="16" id="HzT-AK-TbC"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="CVG-XR-NSd" secondAttribute="trailing" constant="24" id="PHb-gn-Hlt"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="CVG-XR-NSd" secondAttribute="trailing" constant="24" id="PHb-gn-Hlt"/>
<constraint firstItem="XWC-Q3-vW4" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="X8c-Uf-cEo"/> <constraint firstItem="XWC-Q3-vW4" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="X8c-Uf-cEo"/>
<constraint firstItem="sU1-Vw-IvM" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="30" id="XZQ-VA-vXg"/> <constraint firstItem="sU1-Vw-IvM" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="30" id="XZQ-VA-vXg"/>
<constraint firstItem="8IG-gE-laz" firstAttribute="top" secondItem="CVG-XR-NSd" secondAttribute="bottom" constant="10" id="ZOn-6v-fFs"/>
<constraint firstItem="CVG-XR-NSd" firstAttribute="top" secondItem="XWC-Q3-vW4" secondAttribute="bottom" constant="20" id="ZTb-Cm-MfF"/> <constraint firstItem="CVG-XR-NSd" firstAttribute="top" secondItem="XWC-Q3-vW4" secondAttribute="bottom" constant="20" id="ZTb-Cm-MfF"/>
<constraint firstItem="X44-Ed-GVg" firstAttribute="top" secondItem="hCv-lV-npz" secondAttribute="bottom" constant="20" id="fxK-RO-bzZ"/>
<constraint firstItem="sU1-Vw-IvM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="kB6-Tm-cGx"/> <constraint firstItem="sU1-Vw-IvM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="kB6-Tm-cGx"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="XWC-Q3-vW4" secondAttribute="trailing" constant="24" id="nCw-rb-IKC"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="XWC-Q3-vW4" secondAttribute="trailing" constant="24" id="nCw-rb-IKC"/>
<constraint firstItem="8IG-gE-laz" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="njY-IA-7La"/>
<constraint firstItem="hCv-lV-npz" firstAttribute="centerX" secondItem="CVG-XR-NSd" secondAttribute="centerX" id="pzc-6h-emF"/> <constraint firstItem="hCv-lV-npz" firstAttribute="centerX" secondItem="CVG-XR-NSd" secondAttribute="centerX" id="pzc-6h-emF"/>
<constraint firstItem="CVG-XR-NSd" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="qRa-Qz-zyl"/> <constraint firstItem="CVG-XR-NSd" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="qRa-Qz-zyl"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="sU1-Vw-IvM" secondAttribute="trailing" constant="24" id="tFi-0S-sxu"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="sU1-Vw-IvM" secondAttribute="trailing" constant="24" id="tFi-0S-sxu"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="8IG-gE-laz" secondAttribute="trailing" constant="24" id="xjF-kR-WkW"/>
<constraint firstItem="XWC-Q3-vW4" firstAttribute="top" secondItem="sU1-Vw-IvM" secondAttribute="bottom" constant="40" id="yLx-Vc-uxo"/> <constraint firstItem="XWC-Q3-vW4" firstAttribute="top" secondItem="sU1-Vw-IvM" secondAttribute="bottom" constant="40" id="yLx-Vc-uxo"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="X44-Ed-GVg" secondAttribute="trailing" constant="16" id="zdC-fn-OTv"/>
</constraints> </constraints>
<point key="canvasLocation" x="132" y="-11"/> <point key="canvasLocation" x="132" y="-11"/>
</view> </view>
......
...@@ -27,6 +27,7 @@ class SpeakEleGeneratePlanView: UIView { ...@@ -27,6 +27,7 @@ class SpeakEleGeneratePlanView: UIView {
}else if self.state == .start { }else if self.state == .start {
self.info.isHidden = false self.info.isHidden = false
self.SpeakOffsetL.text = "\(self.offset)%" self.SpeakOffsetL.text = "\(self.offset)%"
self.SpeakL.textColor = .init(hex: 0x000000,alpha: 0.54)
self.ProgressV.snp.remakeConstraints({ make in self.ProgressV.snp.remakeConstraints({ make in
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
make.top.equalTo(self.SpeakL.snp.bottom).offset(10) make.top.equalTo(self.SpeakL.snp.bottom).offset(10)
...@@ -36,6 +37,7 @@ class SpeakEleGeneratePlanView: UIView { ...@@ -36,6 +37,7 @@ class SpeakEleGeneratePlanView: UIView {
self.animationLayer.frame = CGRectMake(0, 0, self.ProgressV.width * (CGFloat(self.offset) / 100.0), self.ProgressV.height) self.animationLayer.frame = CGRectMake(0, 0, self.ProgressV.width * (CGFloat(self.offset) / 100.0), self.ProgressV.height)
} }
}else{ }else{
self.SpeakL.textColor = .init(hex: 0x000000,alpha: 0.9)
self.SpeakOffsetL.isHidden = true self.SpeakOffsetL.isHidden = true
self.ProgressV.snp.remakeConstraints({ make in self.ProgressV.snp.remakeConstraints({ make in
make.height.equalTo(12) make.height.equalTo(12)
...@@ -83,7 +85,7 @@ class SpeakEleGeneratePlanView: UIView { ...@@ -83,7 +85,7 @@ class SpeakEleGeneratePlanView: UIView {
private lazy var SpeakL: UILabel = { private lazy var SpeakL: UILabel = {
let l = UILabel() let l = UILabel()
l.font = UIFont.montserrat(.semiBold,size: 18) l.font = UIFont.montserrat(.semiBold,size: 18)
l.textColor = .init(hex: 0x000000 ,alpha: 0.9) l.textColor = .init(hex: 0x000000 ,alpha: 0.54)
l.text = Plan l.text = Plan
l.numberOfLines = 0 l.numberOfLines = 0
addSubview(l) addSubview(l)
......
...@@ -52,7 +52,7 @@ class SpeakEleGuideViewCtr: SpeakEleBaseViewCtr ,UIScrollViewDelegate { ...@@ -52,7 +52,7 @@ class SpeakEleGuideViewCtr: SpeakEleBaseViewCtr ,UIScrollViewDelegate {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
SpeakTrustContentVs.forEach { trust in SpeakTrustContentVs.forEach { trust in
trust.shadow(cornerRadius: 12, shadowColor: .init(hex: 0x49D9F9,alpha: 0.1), offset: CGSizeMake(0, 4), opacity: 1, radius: 2) trust.shadow(cornerRadius: 12, shadowColor: .init(hex: 0x49D9F9,alpha: 0.1), offset: CGSizeMake(0, 0), opacity: 1, radius: 3)
} }
} }
......
...@@ -36,19 +36,19 @@ ...@@ -36,19 +36,19 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xKo-Ae-XDM"> <scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xKo-Ae-XDM">
<rect key="frame" x="0.0" y="138" width="393" height="474"/> <rect key="frame" x="0.0" y="158" width="393" height="454"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Vmb-QG-1Wg"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Vmb-QG-1Wg">
<rect key="frame" x="0.0" y="0.0" width="1179" height="474"/> <rect key="frame" x="0.0" y="0.0" width="1179" height="454"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="d0L-QK-MCE"> <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="d0L-QK-MCE">
<rect key="frame" x="0.0" y="0.0" width="1179" height="474"/> <rect key="frame" x="0.0" y="0.0" width="1179" height="454"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tbc-bq-3rD"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tbc-bq-3rD">
<rect key="frame" x="0.0" y="0.0" width="393" height="474"/> <rect key="frame" x="0.0" y="0.0" width="393" height="454"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="b14-Xp-dTD"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="40" translatesAutoresizingMaskIntoConstraints="NO" id="b14-Xp-dTD">
<rect key="frame" x="24" y="0.0" width="345" height="474"/> <rect key="frame" x="24" y="0.0" width="345" height="454"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uTy-wS-Wcy"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uTy-wS-Wcy">
<rect key="frame" x="0.0" y="0.0" width="345" height="331.33333333333331"/> <rect key="frame" x="0.0" y="0.0" width="345" height="331.33333333333331"/>
...@@ -69,16 +69,16 @@ ...@@ -69,16 +69,16 @@
</constraints> </constraints>
</view> </view>
<scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jdc-29-4XW"> <scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jdc-29-4XW">
<rect key="frame" x="0.0" y="343.33333333333331" width="345" height="130.66666666666669"/> <rect key="frame" x="0.0" y="371.33333333333337" width="345" height="82.666666666666686"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dB1-z4-kNJ"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dB1-z4-kNJ">
<rect key="frame" x="0.0" y="0.0" width="1035" height="130.66666666666666"/> <rect key="frame" x="0.0" y="0.0" width="1035" height="184.66666666666666"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="B1i-Kg-X6p"> <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="B1i-Kg-X6p">
<rect key="frame" x="0.0" y="0.0" width="1035" height="130.66666666666666"/> <rect key="frame" x="0.0" y="0.0" width="1035" height="184.66666666666666"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="22n-LM-xqb"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="22n-LM-xqb">
<rect key="frame" x="0.0" y="0.0" width="337" height="130.66666666666666"/> <rect key="frame" x="0.0" y="0.0" width="337" height="184.66666666666666"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="V5N-S4-hPI"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="V5N-S4-hPI">
<rect key="frame" x="12" y="20" width="68" height="68"/> <rect key="frame" x="12" y="20" width="68" height="68"/>
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="96B-hY-bh5"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="96B-hY-bh5">
<rect key="frame" x="85" y="31.333333333333311" width="98.333333333333314" height="45.666666666666657"/> <rect key="frame" x="85" y="31.333333333333254" width="98.333333333333314" height="45.666666666666657"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9h4-SD-oUx"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9h4-SD-oUx">
<rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/> <rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/>
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
</subviews> </subviews>
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="czc-uZ-pZo"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="czc-uZ-pZo">
<rect key="frame" x="12" y="93.000000000000057" width="309" height="32.666666666666657"/> <rect key="frame" x="12" y="93" width="309" height="71.666666666666686"/>
<string key="text">I have used this app for two years. The <string key="text">I have used this app for two years. The
lesson contents are very suitable for my lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
...@@ -150,7 +150,7 @@ level from 60% to almost 80%!</string> ...@@ -150,7 +150,7 @@ level from 60% to almost 80%!</string>
<constraint firstItem="czc-uZ-pZo" firstAttribute="top" secondItem="V5N-S4-hPI" secondAttribute="bottom" constant="5" id="98R-eM-G1J"/> <constraint firstItem="czc-uZ-pZo" firstAttribute="top" secondItem="V5N-S4-hPI" secondAttribute="bottom" constant="5" id="98R-eM-G1J"/>
<constraint firstItem="96B-hY-bh5" firstAttribute="leading" secondItem="V5N-S4-hPI" secondAttribute="trailing" constant="5" id="ITm-S2-MPG"/> <constraint firstItem="96B-hY-bh5" firstAttribute="leading" secondItem="V5N-S4-hPI" secondAttribute="trailing" constant="5" id="ITm-S2-MPG"/>
<constraint firstItem="96B-hY-bh5" firstAttribute="centerY" secondItem="V5N-S4-hPI" secondAttribute="centerY" id="PCx-c9-zsW"/> <constraint firstItem="96B-hY-bh5" firstAttribute="centerY" secondItem="V5N-S4-hPI" secondAttribute="centerY" id="PCx-c9-zsW"/>
<constraint firstAttribute="bottom" secondItem="czc-uZ-pZo" secondAttribute="bottom" constant="5" id="apn-Hp-Cl2"/> <constraint firstAttribute="bottom" secondItem="czc-uZ-pZo" secondAttribute="bottom" constant="20" id="apn-Hp-Cl2"/>
<constraint firstItem="V5N-S4-hPI" firstAttribute="top" secondItem="22n-LM-xqb" secondAttribute="top" constant="20" id="tKx-gp-LXB"/> <constraint firstItem="V5N-S4-hPI" firstAttribute="top" secondItem="22n-LM-xqb" secondAttribute="top" constant="20" id="tKx-gp-LXB"/>
<constraint firstAttribute="trailing" secondItem="czc-uZ-pZo" secondAttribute="trailing" constant="16" id="vqT-UY-PGL"/> <constraint firstAttribute="trailing" secondItem="czc-uZ-pZo" secondAttribute="trailing" constant="16" id="vqT-UY-PGL"/>
<constraint firstItem="czc-uZ-pZo" firstAttribute="leading" secondItem="V5N-S4-hPI" secondAttribute="leading" id="xhG-Py-6fp"/> <constraint firstItem="czc-uZ-pZo" firstAttribute="leading" secondItem="V5N-S4-hPI" secondAttribute="leading" id="xhG-Py-6fp"/>
...@@ -162,7 +162,7 @@ level from 60% to almost 80%!</string> ...@@ -162,7 +162,7 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="g44-pa-Rjx"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="g44-pa-Rjx">
<rect key="frame" x="349" y="0.0" width="337" height="130.66666666666666"/> <rect key="frame" x="349" y="0.0" width="337" height="184.66666666666666"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="nJg-kC-Mam"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="nJg-kC-Mam">
<rect key="frame" x="12" y="20" width="68" height="68"/> <rect key="frame" x="12" y="20" width="68" height="68"/>
...@@ -177,7 +177,7 @@ level from 60% to almost 80%!</string> ...@@ -177,7 +177,7 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="w5E-dH-pkK"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="w5E-dH-pkK">
<rect key="frame" x="85" y="31.333333333333311" width="98.333333333333314" height="45.666666666666657"/> <rect key="frame" x="85" y="31.333333333333254" width="98.333333333333314" height="45.666666666666657"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rJa-TE-WMZ"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rJa-TE-WMZ">
<rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/> <rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/>
...@@ -210,7 +210,7 @@ level from 60% to almost 80%!</string> ...@@ -210,7 +210,7 @@ level from 60% to almost 80%!</string>
</subviews> </subviews>
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Syc-gZ-pvC"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Syc-gZ-pvC">
<rect key="frame" x="12" y="93.000000000000057" width="309" height="32.666666666666657"/> <rect key="frame" x="12" y="93" width="309" height="71.666666666666686"/>
<string key="text">I have used this app for two years. The <string key="text">I have used this app for two years. The
lesson contents are very suitable for my lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
...@@ -231,7 +231,7 @@ level from 60% to almost 80%!</string> ...@@ -231,7 +231,7 @@ level from 60% to almost 80%!</string>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="Syc-gZ-pvC" firstAttribute="leading" secondItem="nJg-kC-Mam" secondAttribute="leading" id="1rK-QB-ABD"/> <constraint firstItem="Syc-gZ-pvC" firstAttribute="leading" secondItem="nJg-kC-Mam" secondAttribute="leading" id="1rK-QB-ABD"/>
<constraint firstAttribute="bottom" secondItem="Syc-gZ-pvC" secondAttribute="bottom" constant="5" id="Bm6-fO-3RU"/> <constraint firstAttribute="bottom" secondItem="Syc-gZ-pvC" secondAttribute="bottom" constant="20" id="Bm6-fO-3RU"/>
<constraint firstAttribute="trailing" secondItem="Syc-gZ-pvC" secondAttribute="trailing" constant="16" id="LWh-l4-ovC"/> <constraint firstAttribute="trailing" secondItem="Syc-gZ-pvC" secondAttribute="trailing" constant="16" id="LWh-l4-ovC"/>
<constraint firstItem="w5E-dH-pkK" firstAttribute="leading" secondItem="nJg-kC-Mam" secondAttribute="trailing" constant="5" id="SXf-Fa-Fbd"/> <constraint firstItem="w5E-dH-pkK" firstAttribute="leading" secondItem="nJg-kC-Mam" secondAttribute="trailing" constant="5" id="SXf-Fa-Fbd"/>
<constraint firstItem="nJg-kC-Mam" firstAttribute="top" secondItem="g44-pa-Rjx" secondAttribute="top" constant="20" id="ZOT-zY-EBe"/> <constraint firstItem="nJg-kC-Mam" firstAttribute="top" secondItem="g44-pa-Rjx" secondAttribute="top" constant="20" id="ZOT-zY-EBe"/>
...@@ -246,7 +246,7 @@ level from 60% to almost 80%!</string> ...@@ -246,7 +246,7 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2oH-CY-qfu"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2oH-CY-qfu">
<rect key="frame" x="698" y="0.0" width="337" height="130.66666666666666"/> <rect key="frame" x="698" y="0.0" width="337" height="184.66666666666666"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="qEa-Qg-Mk4"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="qEa-Qg-Mk4">
<rect key="frame" x="12" y="20" width="68" height="68"/> <rect key="frame" x="12" y="20" width="68" height="68"/>
...@@ -261,7 +261,7 @@ level from 60% to almost 80%!</string> ...@@ -261,7 +261,7 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="fzy-9S-NBw"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="fzy-9S-NBw">
<rect key="frame" x="85" y="31.333333333333311" width="98.333333333333314" height="45.666666666666657"/> <rect key="frame" x="85" y="31.333333333333254" width="98.333333333333314" height="45.666666666666657"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xoe-un-0ZZ"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="nellie" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xoe-un-0ZZ">
<rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/> <rect key="frame" x="0.0" y="0.0" width="98.333333333333329" height="26.333333333333332"/>
...@@ -294,7 +294,7 @@ level from 60% to almost 80%!</string> ...@@ -294,7 +294,7 @@ level from 60% to almost 80%!</string>
</subviews> </subviews>
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cd0-QS-PCy"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cd0-QS-PCy">
<rect key="frame" x="12" y="93.000000000000057" width="309" height="32.666666666666657"/> <rect key="frame" x="12" y="93" width="309" height="71.666666666666686"/>
<string key="text">I have used this app for two years. The <string key="text">I have used this app for two years. The
lesson contents are very suitable for my lesson contents are very suitable for my
needs, which have helped increase my needs, which have helped increase my
...@@ -318,7 +318,7 @@ level from 60% to almost 80%!</string> ...@@ -318,7 +318,7 @@ level from 60% to almost 80%!</string>
<constraint firstItem="cd0-QS-PCy" firstAttribute="leading" secondItem="qEa-Qg-Mk4" secondAttribute="leading" id="8IH-3n-xKb"/> <constraint firstItem="cd0-QS-PCy" firstAttribute="leading" secondItem="qEa-Qg-Mk4" secondAttribute="leading" id="8IH-3n-xKb"/>
<constraint firstItem="cd0-QS-PCy" firstAttribute="top" secondItem="qEa-Qg-Mk4" secondAttribute="bottom" constant="5" id="9Zt-0m-Ff2"/> <constraint firstItem="cd0-QS-PCy" firstAttribute="top" secondItem="qEa-Qg-Mk4" secondAttribute="bottom" constant="5" id="9Zt-0m-Ff2"/>
<constraint firstItem="qEa-Qg-Mk4" firstAttribute="top" secondItem="2oH-CY-qfu" secondAttribute="top" constant="20" id="DLo-Nr-mOc"/> <constraint firstItem="qEa-Qg-Mk4" firstAttribute="top" secondItem="2oH-CY-qfu" secondAttribute="top" constant="20" id="DLo-Nr-mOc"/>
<constraint firstAttribute="bottom" secondItem="cd0-QS-PCy" secondAttribute="bottom" constant="5" id="YQa-mU-OX5"/> <constraint firstAttribute="bottom" secondItem="cd0-QS-PCy" secondAttribute="bottom" constant="20" id="YQa-mU-OX5"/>
<constraint firstItem="qEa-Qg-Mk4" firstAttribute="leading" secondItem="2oH-CY-qfu" secondAttribute="leading" constant="12" id="c72-L7-McZ"/> <constraint firstItem="qEa-Qg-Mk4" firstAttribute="leading" secondItem="2oH-CY-qfu" secondAttribute="leading" constant="12" id="c72-L7-McZ"/>
<constraint firstItem="fzy-9S-NBw" firstAttribute="centerY" secondItem="qEa-Qg-Mk4" secondAttribute="centerY" id="cef-xb-RCN"/> <constraint firstItem="fzy-9S-NBw" firstAttribute="centerY" secondItem="qEa-Qg-Mk4" secondAttribute="centerY" id="cef-xb-RCN"/>
<constraint firstAttribute="trailing" secondItem="cd0-QS-PCy" secondAttribute="trailing" constant="16" id="poV-NS-Od5"/> <constraint firstAttribute="trailing" secondItem="cd0-QS-PCy" secondAttribute="trailing" constant="16" id="poV-NS-Od5"/>
...@@ -362,16 +362,19 @@ level from 60% to almost 80%!</string> ...@@ -362,16 +362,19 @@ level from 60% to almost 80%!</string>
</constraints> </constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rdh-di-qri"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rdh-di-qri">
<rect key="frame" x="393" y="0.0" width="393" height="474"/> <rect key="frame" x="393" y="0.0" width="393" height="454"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="lVK-So-1pG"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="lVK-So-1pG">
<rect key="frame" x="24" y="0.0" width="345" height="474"/> <rect key="frame" x="24" y="0.0" width="345" height="454"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vSM-Yn-NkU"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vSM-Yn-NkU">
<rect key="frame" x="0.0" y="0.0" width="345" height="385"/> <rect key="frame" x="0.0" y="0.0" width="345" height="365"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="bottom" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="yindaoye2" translatesAutoresizingMaskIntoConstraints="NO" id="XNI-jz-HZE"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="bottom" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="yindaoye2" translatesAutoresizingMaskIntoConstraints="NO" id="XNI-jz-HZE">
<rect key="frame" x="-8.3333333333333144" y="-6.3333333333333428" width="362" height="398"/> <rect key="frame" x="-8.3333333333333144" y="-16.333333333333343" width="362" height="398"/>
<constraints>
<constraint firstAttribute="width" secondItem="XNI-jz-HZE" secondAttribute="height" multiplier="181:199" id="IWv-4E-kbA"/>
</constraints>
</imageView> </imageView>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
...@@ -381,7 +384,7 @@ level from 60% to almost 80%!</string> ...@@ -381,7 +384,7 @@ level from 60% to almost 80%!</string>
</constraints> </constraints>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="An APP for learning English" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ncj-Xn-x9Y"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="An APP for learning English" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ncj-Xn-x9Y">
<rect key="frame" x="0.0" y="401" width="345" height="21"/> <rect key="frame" x="0.0" y="381" width="345" height="21"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="21" id="UU1-ec-8DO"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="21" id="UU1-ec-8DO"/>
</constraints> </constraints>
...@@ -398,7 +401,7 @@ level from 60% to almost 80%!</string> ...@@ -398,7 +401,7 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Use the learning tools you need" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OqL-By-lhi"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Use the learning tools you need" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OqL-By-lhi">
<rect key="frame" x="0.0" y="438" width="345" height="36"/> <rect key="frame" x="0.0" y="418" width="345" height="36"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="36" id="CJg-8J-ZQ4"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="36" id="CJg-8J-ZQ4"/>
</constraints> </constraints>
...@@ -426,26 +429,30 @@ level from 60% to almost 80%!</string> ...@@ -426,26 +429,30 @@ level from 60% to almost 80%!</string>
</constraints> </constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="flT-gf-4KY"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="flT-gf-4KY">
<rect key="frame" x="786" y="0.0" width="393" height="474"/> <rect key="frame" x="786" y="0.0" width="393" height="454"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="4Mv-bg-BZ6"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="4Mv-bg-BZ6">
<rect key="frame" x="24" y="0.0" width="345" height="474"/> <rect key="frame" x="24" y="0.0" width="345" height="454"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bH1-7V-NdX"> <view contentMode="scaleToFill" horizontalHuggingPriority="245" verticalHuggingPriority="45" horizontalCompressionResistancePriority="45" verticalCompressionResistancePriority="45" translatesAutoresizingMaskIntoConstraints="NO" id="bH1-7V-NdX">
<rect key="frame" x="0.0" y="0.0" width="345" height="380.33333333333331"/> <rect key="frame" x="0.0" y="0.0" width="345" height="272.33333333333331"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="bottom" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="yindaoye3" translatesAutoresizingMaskIntoConstraints="NO" id="cYx-B6-AKp"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="bottom" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="yindaoye3" translatesAutoresizingMaskIntoConstraints="NO" id="cYx-B6-AKp">
<rect key="frame" x="-3" y="-38.666666666666686" width="351.33333333333331" height="458"/> <rect key="frame" x="20" y="-62.666666666666686" width="305" height="398"/>
<constraints>
<constraint firstAttribute="width" secondItem="cYx-B6-AKp" secondAttribute="height" multiplier="351:458" id="efA-Tq-ddT"/>
</constraints>
</imageView> </imageView>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="cYx-B6-AKp" firstAttribute="centerY" secondItem="bH1-7V-NdX" secondAttribute="centerY" id="Ff1-dg-wIX"/> <constraint firstItem="cYx-B6-AKp" firstAttribute="centerY" secondItem="bH1-7V-NdX" secondAttribute="centerY" id="Ff1-dg-wIX"/>
<constraint firstItem="cYx-B6-AKp" firstAttribute="centerX" secondItem="bH1-7V-NdX" secondAttribute="centerX" id="U6d-Ex-GPd"/> <constraint firstItem="cYx-B6-AKp" firstAttribute="leading" secondItem="bH1-7V-NdX" secondAttribute="leading" constant="20" id="Va5-oW-fyk"/>
<constraint firstAttribute="trailing" secondItem="cYx-B6-AKp" secondAttribute="trailing" constant="20" id="slp-3A-pZO"/>
</constraints> </constraints>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Higher learning efficiency" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I0J-HW-cdr"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Higher learning efficiency" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I0J-HW-cdr">
<rect key="frame" x="0.0" y="396.33333333333337" width="345" height="21"/> <rect key="frame" x="0.0" y="288.33333333333331" width="345" height="21"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="21" id="0mU-Ak-mkv"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="21" id="0mU-Ak-mkv"/>
</constraints> </constraints>
...@@ -461,8 +468,8 @@ level from 60% to almost 80%!</string> ...@@ -461,8 +468,8 @@ level from 60% to almost 80%!</string>
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nGG-WJ-GW4"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nGG-WJ-GW4">
<rect key="frame" x="0.0" y="433.33333333333337" width="345" height="40.666666666666686"/> <rect key="frame" x="0.0" y="325.33333333333331" width="345" height="128.66666666666669"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="36" id="1yO-Ve-n27"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="36" id="1yO-Ve-n27"/>
</constraints> </constraints>
...@@ -481,6 +488,9 @@ than other apps</string> ...@@ -481,6 +488,9 @@ than other apps</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
</subviews> </subviews>
<constraints>
<constraint firstItem="bH1-7V-NdX" firstAttribute="height" secondItem="4Mv-bg-BZ6" secondAttribute="height" multiplier="0.6" id="p4L-wA-3FQ"/>
</constraints>
</stackView> </stackView>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
...@@ -541,7 +551,7 @@ than other apps</string> ...@@ -541,7 +551,7 @@ than other apps</string>
<constraint firstItem="asw-k4-NNo" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="SrZ-DS-HaF"/> <constraint firstItem="asw-k4-NNo" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="SrZ-DS-HaF"/>
<constraint firstItem="xKo-Ae-XDM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="gZf-Gx-37g"/> <constraint firstItem="xKo-Ae-XDM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="gZf-Gx-37g"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="asw-k4-NNo" secondAttribute="bottom" constant="48" id="s3n-1c-0yg"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="asw-k4-NNo" secondAttribute="bottom" constant="48" id="s3n-1c-0yg"/>
<constraint firstItem="xKo-Ae-XDM" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="20" id="sql-Iq-k2y"/> <constraint firstItem="xKo-Ae-XDM" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="40" id="sql-Iq-k2y"/>
</constraints> </constraints>
<point key="canvasLocation" x="98" y="-11"/> <point key="canvasLocation" x="98" y="-11"/>
</view> </view>
......
...@@ -18,6 +18,9 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -18,6 +18,9 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
@IBOutlet weak var contiuneBtn: SpeakEleButton! @IBOutlet weak var contiuneBtn: SpeakEleButton!
@IBOutlet weak var SpeakTopVideoView: UIView! @IBOutlet weak var SpeakTopVideoView: UIView!
@IBOutlet weak var SpeakBottomTool: UIView!
@IBOutlet weak var ContiueContentV: UIView!
private var offsets = 0 private var offsets = 0
...@@ -32,7 +35,14 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -32,7 +35,14 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
private var isCountiue:Int = -1 { private var isCountiue:Int = -1 {
didSet { didSet {
contiuneBtn.isEnabled = !(isCountiue == -1) let enable = !(isCountiue == -1)
if !enable {
contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_no(1)"), for: .normal)
contiuneBtn.setBackgroundImage(UIImage(named: "button_guide_on-Heigiose"), for: .highlighted)
}else{
contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_guide_on"), for: .normal)
contiuneBtn.setBackgroundImage(UIImage(named: "icon-button_no-hight"), for: .highlighted)
}
SpeakTableView.reloadData() SpeakTableView.reloadData()
} }
} }
...@@ -40,6 +50,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -40,6 +50,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
private var step = 0 { private var step = 0 {
didSet{ didSet{
contiuneBtn.isHidden = step < 3 contiuneBtn.isHidden = step < 3
ContiueContentV.isHidden = contiuneBtn.isHidden
InputBoxContent.isHidden = !(step < 3) InputBoxContent.isHidden = !(step < 3)
SpeakInputBox.isUserInteractionEnabled = (step == 2) SpeakInputBox.isUserInteractionEnabled = (step == 2)
} }
...@@ -84,6 +95,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -84,6 +95,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
titleView.isHidden = true titleView.isHidden = true
isCountiue = -1
GetLostMessage() GetLostMessage()
} }
...@@ -98,6 +110,9 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -98,6 +110,9 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
} }
@IBAction func contineTaps(_ sender: Any) { @IBAction func contineTaps(_ sender: Any) {
if self.isCountiue < 0 {
return
}
if let last = viewModel.anwer.last { if let last = viewModel.anwer.last {
if last.speakMsg == "" { if last.speakMsg == "" {
let language = moreItem[safe:self.isCountiue] ?? "" let language = moreItem[safe:self.isCountiue] ?? ""
...@@ -175,7 +190,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -175,7 +190,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
display.isPaused = true display.isPaused = true
offsets = 0 offsets = 0
} }
if msg.messageType == .name && msg.speakMsg.isEmpty{ if msg.messageType == .name && msg.speakMsg.isEmpty {
}else{ }else{
viewModel.anwer.append(msg) viewModel.anwer.append(msg)
...@@ -204,6 +219,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr { ...@@ -204,6 +219,7 @@ class SpeakEleQAViewCtr: SpeakEleBaseViewCtr {
}else if msg.messageType == .finish { }else if msg.messageType == .finish {
self.isCountiue = 0 self.isCountiue = 0
self.contiuneBtn.setTitle("Start", for: .normal) self.contiuneBtn.setTitle("Start", for: .normal)
SpeakPermission.requestNotificationPermission()
} }
return return
} }
...@@ -270,8 +286,22 @@ extension SpeakEleQAViewCtr { ...@@ -270,8 +286,22 @@ extension SpeakEleQAViewCtr {
} }
private func update() -> Void { private func update() -> Void {
let v = Float(self.viewModel.anwer.count) / Float(self.viewModel.questionArrys.count) var pro = 0
self.SpeakProgres.value = v for v in self.viewModel.anwer {
if (v.role == .speakUser && v.speakMsg.count > 0){
pro += 1
}
}
if let last = self.viewModel.anwer.last {
if (last.role == .speakUser && last.speakMsg.count <= 0) || last.messageType == .name || last.messageType == .finish{
SpeakBottomTool.isHidden = false
}else{
SpeakBottomTool.isHidden = true
}
}else{
SpeakBottomTool.isHidden = true
}
self.SpeakProgres.value = Float(pro) / 9.0
self.SpeakTableView.reloadData() self.SpeakTableView.reloadData()
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
if self.viewModel.anwer.count > 0 { if self.viewModel.anwer.count > 0 {
...@@ -343,7 +373,8 @@ extension SpeakEleQAViewCtr : UITableViewDelegate,UITableViewDataSource { ...@@ -343,7 +373,8 @@ extension SpeakEleQAViewCtr : UITableViewDelegate,UITableViewDataSource {
} }
self?.selectSets = NSMutableSet(array: self?.selectSets.filter({($0 as! Int) < (self?.max ?? 0) }) ?? []) self?.selectSets = NSMutableSet(array: self?.selectSets.filter({($0 as! Int) < (self?.max ?? 0) }) ?? [])
} }
self?.contiuneBtn.isEnabled = (self?.selectSets.count ?? 0 > 0) // self?.contiuneBtn.isEnabled = (self?.selectSets.count ?? 0 > 0)
self?.isCountiue = (self?.selectSets.count ?? 0 > 0) ? 1 : -1
self?.SpeakTableView.reloadData() self?.SpeakTableView.reloadData()
} }
return cell return cell
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleQAViewCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleQAViewCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target">
<connections> <connections>
<outlet property="ContiueContentV" destination="ciK-R0-acp" id="uo5-cp-Ze1"/>
<outlet property="InputBoxContent" destination="uS5-tZ-Obr" id="E0N-dl-Lnr"/> <outlet property="InputBoxContent" destination="uS5-tZ-Obr" id="E0N-dl-Lnr"/>
<outlet property="SpeakBottomTool" destination="ly6-as-jqg" id="eoy-1H-eBq"/>
<outlet property="SpeakContentV" destination="lhO-rO-ci0" id="VH2-3v-YWq"/> <outlet property="SpeakContentV" destination="lhO-rO-ci0" id="VH2-3v-YWq"/>
<outlet property="SpeakInputBox" destination="n0s-ld-qq8" id="UMQ-9p-FAo"/> <outlet property="SpeakInputBox" destination="n0s-ld-qq8" id="UMQ-9p-FAo"/>
<outlet property="SpeakProgres" destination="ZV3-Si-Hef" id="ZBs-da-fiI"/> <outlet property="SpeakProgres" destination="ZV3-Si-Hef" id="ZBs-da-fiI"/>
...@@ -91,6 +93,7 @@ ...@@ -91,6 +93,7 @@
</constraints> </constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="sp-guide-Send"/> <state key="normal" image="sp-guide-Send"/>
<state key="highlighted" image="sp-guide-Send-Hight"/>
<connections> <connections>
<action selector="SpeakSendMsg:" destination="-1" eventType="touchUpInside" id="pSi-TS-fMS"/> <action selector="SpeakSendMsg:" destination="-1" eventType="touchUpInside" id="pSi-TS-fMS"/>
</connections> </connections>
...@@ -100,8 +103,12 @@ ...@@ -100,8 +103,12 @@
<constraint firstAttribute="height" constant="48" id="by7-wH-3pT"/> <constraint firstAttribute="height" constant="48" id="by7-wH-3pT"/>
</constraints> </constraints>
</stackView> </stackView>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jZV-J1-egY" customClass="SpeakEleButton" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ciK-R0-acp">
<rect key="frame" x="24" y="16.666666666666629" width="345" height="48"/> <rect key="frame" x="24" y="12.666666666666629" width="345" height="52"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jZV-J1-egY">
<rect key="frame" x="0.0" y="18" width="345" height="34"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Continue"/> <state key="normal" title="Continue"/>
<connections> <connections>
...@@ -111,17 +118,25 @@ ...@@ -111,17 +118,25 @@
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="jZV-J1-egY" firstAttribute="top" secondItem="uS5-tZ-Obr" secondAttribute="top" id="0bt-xh-P70"/> <constraint firstAttribute="bottom" secondItem="jZV-J1-egY" secondAttribute="bottom" id="6zT-87-MWy"/>
<constraint firstAttribute="height" constant="52" id="Igt-nt-xnN"/>
<constraint firstAttribute="trailing" secondItem="jZV-J1-egY" secondAttribute="trailing" id="Rxu-VC-zEZ"/>
<constraint firstItem="jZV-J1-egY" firstAttribute="leading" secondItem="ciK-R0-acp" secondAttribute="leading" id="iBs-uC-t0b"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="uS5-tZ-Obr" secondAttribute="trailing" constant="24" id="6cX-0K-4lq"/> <constraint firstAttribute="trailing" secondItem="uS5-tZ-Obr" secondAttribute="trailing" constant="24" id="6cX-0K-4lq"/>
<constraint firstItem="uS5-tZ-Obr" firstAttribute="top" secondItem="Pk3-rK-Odt" secondAttribute="bottom" constant="16" id="D3H-sA-sez"/> <constraint firstItem="uS5-tZ-Obr" firstAttribute="top" secondItem="Pk3-rK-Odt" secondAttribute="bottom" constant="16" id="D3H-sA-sez"/>
<constraint firstItem="jZV-J1-egY" firstAttribute="leading" secondItem="uS5-tZ-Obr" secondAttribute="leading" id="EWW-4z-5I0"/> <constraint firstItem="uS5-tZ-Obr" firstAttribute="trailing" secondItem="ciK-R0-acp" secondAttribute="trailing" id="N01-8f-ISZ"/>
<constraint firstItem="jZV-J1-egY" firstAttribute="bottom" secondItem="uS5-tZ-Obr" secondAttribute="bottom" id="QZd-ZE-Nd6"/> <constraint firstItem="uS5-tZ-Obr" firstAttribute="bottom" secondItem="ciK-R0-acp" secondAttribute="bottom" id="PRP-oR-LAN"/>
<constraint firstItem="Pk3-rK-Odt" firstAttribute="top" secondItem="ly6-as-jqg" secondAttribute="top" id="R6c-cV-kgx"/> <constraint firstItem="Pk3-rK-Odt" firstAttribute="top" secondItem="ly6-as-jqg" secondAttribute="top" id="R6c-cV-kgx"/>
<constraint firstItem="uS5-tZ-Obr" firstAttribute="leading" secondItem="ly6-as-jqg" secondAttribute="leading" constant="24" id="eRl-ls-UHL"/> <constraint firstItem="uS5-tZ-Obr" firstAttribute="leading" secondItem="ly6-as-jqg" secondAttribute="leading" constant="24" id="eRl-ls-UHL"/>
<constraint firstAttribute="bottom" secondItem="uS5-tZ-Obr" secondAttribute="bottom" constant="16" id="h5H-Xb-zyy"/> <constraint firstAttribute="bottom" secondItem="uS5-tZ-Obr" secondAttribute="bottom" constant="16" id="h5H-Xb-zyy"/>
<constraint firstItem="Pk3-rK-Odt" firstAttribute="leading" secondItem="ly6-as-jqg" secondAttribute="leading" id="jeu-9r-eGu"/> <constraint firstItem="Pk3-rK-Odt" firstAttribute="leading" secondItem="ly6-as-jqg" secondAttribute="leading" id="jeu-9r-eGu"/>
<constraint firstItem="uS5-tZ-Obr" firstAttribute="leading" secondItem="ciK-R0-acp" secondAttribute="leading" id="nkB-GL-DBD"/>
<constraint firstAttribute="trailing" secondItem="Pk3-rK-Odt" secondAttribute="trailing" id="oWt-sh-GoR"/> <constraint firstAttribute="trailing" secondItem="Pk3-rK-Odt" secondAttribute="trailing" id="oWt-sh-GoR"/>
<constraint firstItem="jZV-J1-egY" firstAttribute="trailing" secondItem="uS5-tZ-Obr" secondAttribute="trailing" id="rlN-TL-UlX"/>
</constraints> </constraints>
</view> </view>
</subviews> </subviews>
...@@ -156,11 +171,12 @@ ...@@ -156,11 +171,12 @@
</objects> </objects>
<resources> <resources>
<image name="sp-guide-Send" width="48" height="48"/> <image name="sp-guide-Send" width="48" height="48"/>
<image name="sp-guide-Send-Hight" width="48" height="48"/>
<systemColor name="systemBackgroundColor"> <systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor> </systemColor>
<systemColor name="systemGrayColor"> <systemColor name="systemGrayColor">
<color red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor> </systemColor>
</resources> </resources>
</document> </document>
...@@ -51,12 +51,13 @@ class SpeakEleMutabSelectBoxViewCell: SpeakEleQABaseViewCell { ...@@ -51,12 +51,13 @@ class SpeakEleMutabSelectBoxViewCell: SpeakEleQABaseViewCell {
btn.corners = 8 btn.corners = 8
btn.borderWidth = 1 btn.borderWidth = 1
btn.borderColor = .init(hex: 0x6B71E3) btn.borderColor = .init(hex: 0x6B71E3)
btn.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
btn.addTarget(self, action: #selector(btnTaps(_:)), for: .touchUpInside) btn.addTarget(self, action: #selector(btnTaps(_:)), for: .touchUpInside)
contentV.addSubview(btn) contentV.addSubview(btn)
items.append(btn) items.append(btn)
btn.tag = i btn.tag = i
let size = str.size(withFont: UIFont.montserrat(.regular,size: 16)) let size = str.size(withFont: UIFont.montserrat(.regular,size: 16))
let width = size.width + 10.0 let width = size.width + 10.0 + 16
if ((offsetX + width + content.right) > contentV.width) { if ((offsetX + width + content.right) > contentV.width) {
offsetX = content.left offsetX = content.left
...@@ -104,8 +105,7 @@ class SpeakEleMutabSelectBoxViewCell: SpeakEleQABaseViewCell { ...@@ -104,8 +105,7 @@ class SpeakEleMutabSelectBoxViewCell: SpeakEleQABaseViewCell {
make.left.right.bottom.top.equalToSuperview().inset(UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10)) make.left.right.bottom.top.equalToSuperview().inset(UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10))
} }
contentV.snp.makeConstraints { make in contentV.snp.makeConstraints { make in
make.right.top.bottom.equalToSuperview().inset(UIEdgeInsets(top: 2, left: 0, bottom: 16, right: (marginLR))) make.right.top.left.bottom.equalToSuperview().inset(UIEdgeInsets(top: 2, left: 40, bottom: 16, right: (marginLR)))
make.width.equalTo(Dev.screenW * 0.6 )
} }
} }
......
...@@ -103,8 +103,8 @@ class SpeakEleSelectBoxViewCell: SpeakEleQABaseViewCell { ...@@ -103,8 +103,8 @@ class SpeakEleSelectBoxViewCell: SpeakEleQABaseViewCell {
make.left.right.bottom.top.equalToSuperview().inset(UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10)) make.left.right.bottom.top.equalToSuperview().inset(UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10))
} }
contentV.snp.makeConstraints { make in contentV.snp.makeConstraints { make in
make.right.top.bottom.equalToSuperview().inset(UIEdgeInsets(top: 2, left: 0, bottom: 16, right: (marginLR))) make.right.left.top.bottom.equalToSuperview().inset(UIEdgeInsets(top: 2, left: 40, bottom: 16, right: (marginLR)))
make.width.equalTo(Dev.screenW * 0.6 ) // make.width.equalTo(338)
} }
} }
......
...@@ -13,12 +13,11 @@ class SpeakReviewViewModel: NSObject { ...@@ -13,12 +13,11 @@ class SpeakReviewViewModel: NSObject {
set {} set {}
get { get {
return [ return [
SpeakReviewModel(image: "img_1", name: "Lily Parker", country: "United States", descption: "Fragmented English practice is convenient! App drills work—greetings feel natural."), SpeakReviewModel(image: "img_1", name: "Lily Parker", country: "United States", descption: "Fragmented English practice fits my schedule! The app’s scenario drills work—after 2 weeks, greeting foreign interns feels natural, no pauses."),
SpeakReviewModel(image: "img_2", name: "Mia Davies", country: "United Kingdom", descption: "Café work: it helps practice ordering—customers praise fluency. "), SpeakReviewModel(image: "img_2", name: "Mia Davies", country: "United Kingdom", descption: "Working at the café lets me practice English easily! Daily chats with customers help, and a British customer said, “Your English is fluent—I can’t tell it’s not first!”"),
SpeakReviewModel(image: "img_3", name: "Chloe Wang", country: "Australia", descption: "Chats with foreign friend Detailed grammar feedback helps. ")
SpeakReviewModel(image: "img_3", name: "Chloe Wang", country: "Australia", descption: "Chatting weekly with friend Emma boosts my English! She gives great grammar feedback, and now I catch errors—my writing’s much more accurate.")
] ]
} }
} }
...@@ -27,11 +26,11 @@ class SpeakReviewViewModel: NSObject { ...@@ -27,11 +26,11 @@ class SpeakReviewViewModel: NSObject {
set{ } set{ }
get{ get{
return [ return [
SpeakReviewModel(image: "img_4", name: "James Scott", country: "", descption: "Business trips: plane listening with accents helps clients—English feels authentic."), SpeakReviewModel(image: "img_4", name: "James Scott", country: "", descption: "Practicing English on business planes helps! I learn accents, and a Sydney client said, “Your English is authentic—like you lived here!” It boosted rapport."),
SpeakReviewModel(image: "img_5", name: "Nora Hayes", country: "", descption: "App boosts vocabulary—English literature reading easier."), SpeakReviewModel(image: "img_5", name: "Nora Hayes", country: "", descption: "This English app helps my vocabulary! I once struggled with English lit, but now 500+ words later, I get tricky descriptions in Pride and Prejudice."),
SpeakReviewModel(image: "img_6", name: "Thomas Bennett", country: "", descption: "AI chat lets me speak—gentle corrections ease call nerves.")] SpeakReviewModel(image: "img_6", name: "Thomas Bennett", country: "", descption: "I used to panic about English calls! Now AI chat practice helps—after a month, I chatted with NY office smoothly, no fluster, even joked.")]
} }
} }
......
...@@ -37,6 +37,8 @@ class SpeakEleIAPViewCtr: SpeakEleBaseViewCtr { ...@@ -37,6 +37,8 @@ class SpeakEleIAPViewCtr: SpeakEleBaseViewCtr {
@IBOutlet weak var SpeakPayBut: SpeakEleButton! @IBOutlet weak var SpeakPayBut: SpeakEleButton!
@IBOutlet weak var SpeakBotDescription: UILabel! @IBOutlet weak var SpeakBotDescription: UILabel!
@IBOutlet weak var SpeakContentBg: UIView!
var Products:[SKProduct?] = [] var Products:[SKProduct?] = []
private let viewModel = IAPViewModel.share private let viewModel = IAPViewModel.share
...@@ -91,8 +93,10 @@ class SpeakEleIAPViewCtr: SpeakEleBaseViewCtr { ...@@ -91,8 +93,10 @@ class SpeakEleIAPViewCtr: SpeakEleBaseViewCtr {
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
self.view.layoutIfNeeded()
SpeakEasyV.shadow(cornerRadius: 16,shadowColor: .init(hex: 0x000000,alpha: 1),opacity: 0.06,radius: 2) SpeakEasyV.shadow(cornerRadius: 16,shadowColor: .init(hex: 0x000000,alpha: 1),opacity: 0.06,radius: 2)
SpeakPayContentV.shadow(cornerRadius: 8,shadowColor: .init(hex: 0x000000,alpha: 1),opacity: 0.06,radius: 2) SpeakPayContentV.shadow(cornerRadius: 8,shadowColor: .init(hex: 0x000000,alpha: 1),opacity: 0.06,radius: 2)
SpeakContentBg.gradient(colors: [.init(hex: 0xFFFFFF,alpha: 0),.init(hex: 0xFFFFFF,alpha: 0.76) ,.white],direction: .topToBottom)
} }
@IBAction func SpeakCloseTaps(_ sender: Any) { @IBAction func SpeakCloseTaps(_ sender: Any) {
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_0" orientation="portrait" appearance="light"/> <device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleIAPViewCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleIAPViewCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target">
<connections> <connections>
<outlet property="SpeakBotDescription" destination="NDv-gZ-gv3" id="8h9-6m-nD0"/> <outlet property="SpeakBotDescription" destination="NDv-gZ-gv3" id="8h9-6m-nD0"/>
<outlet property="SpeakContentBg" destination="KAC-AW-lO2" id="QgU-1C-VD7"/>
<outlet property="SpeakEasyV" destination="0P2-EJ-LIF" id="HkH-LB-QOe"/> <outlet property="SpeakEasyV" destination="0P2-EJ-LIF" id="HkH-LB-QOe"/>
<outlet property="SpeakFreeTL1" destination="oBS-z1-Wml" id="7qE-11-Sgh"/> <outlet property="SpeakFreeTL1" destination="oBS-z1-Wml" id="7qE-11-Sgh"/>
<outlet property="SpeakPayBut" destination="L5f-PZ-BQ5" id="fsY-he-sRY"/> <outlet property="SpeakPayBut" destination="L5f-PZ-BQ5" id="fsY-he-sRY"/>
...@@ -29,20 +30,43 @@ ...@@ -29,20 +30,43 @@
</placeholder> </placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-bg" translatesAutoresizingMaskIntoConstraints="NO" id="5SM-Lp-0MM"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-bg" translatesAutoresizingMaskIntoConstraints="NO" id="5SM-Lp-0MM">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
</imageView> </imageView>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aYT-y7-hf8"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aYT-y7-hf8">
<rect key="frame" x="0.0" y="230" width="320" height="338"/> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8r0-nd-l8p"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8r0-nd-l8p">
<rect key="frame" x="0.0" y="0.0" width="320" height="504.5"/> <rect key="frame" x="0.0" y="0.0" width="414" height="769.5"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Lsd-C8-IAe">
<rect key="frame" x="0.0" y="0.0" width="414" height="280"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_Iap_Top_bg" translatesAutoresizingMaskIntoConstraints="NO" id="Upf-la-fHD">
<rect key="frame" x="0.0" y="0.0" width="414" height="499"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KAC-AW-lO2">
<rect key="frame" x="0.0" y="269.5" width="414" height="229.5"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Upf-la-fHD" firstAttribute="top" secondItem="Lsd-C8-IAe" secondAttribute="top" id="8T0-t9-rUp"/>
<constraint firstAttribute="trailing" secondItem="KAC-AW-lO2" secondAttribute="trailing" id="CB6-0i-H8k"/>
<constraint firstItem="KAC-AW-lO2" firstAttribute="top" secondItem="Upf-la-fHD" secondAttribute="centerY" constant="20" id="FmV-SU-L1c"/>
<constraint firstItem="KAC-AW-lO2" firstAttribute="leading" secondItem="Lsd-C8-IAe" secondAttribute="leading" id="HmN-Gn-xQY"/>
<constraint firstAttribute="height" constant="280" id="IiK-63-fWh" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="KAC-AW-lO2" firstAttribute="bottom" secondItem="Upf-la-fHD" secondAttribute="bottom" id="UtK-AK-QPU"/>
<constraint firstAttribute="trailing" secondItem="Upf-la-fHD" secondAttribute="trailing" id="W0U-vh-nvS"/>
<constraint firstItem="Upf-la-fHD" firstAttribute="leading" secondItem="Lsd-C8-IAe" secondAttribute="leading" id="kho-kn-WoS"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Get Unlimited Access" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GRD-E5-C2J"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Get Unlimited Access" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GRD-E5-C2J">
<rect key="frame" x="24" y="0.0" width="272" height="20.5"/> <rect key="frame" x="24" y="280" width="366" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
...@@ -56,7 +80,7 @@ ...@@ -56,7 +80,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Learning, progress, improvement" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ynQ-dm-w6L"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Learning, progress, improvement" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ynQ-dm-w6L">
<rect key="frame" x="24" y="28.5" width="272" height="20.5"/> <rect key="frame" x="24" y="308.5" width="366" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54490858843537415" colorSpace="custom" customColorSpace="calibratedRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54490858843537415" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
...@@ -70,13 +94,13 @@ ...@@ -70,13 +94,13 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0P2-EJ-LIF"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0P2-EJ-LIF">
<rect key="frame" x="24" y="73" width="272" height="163"/> <rect key="frame" x="24" y="353" width="366" height="144"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Ud2-hm-liH"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Ud2-hm-liH">
<rect key="frame" x="16" y="16" width="240" height="131"/> <rect key="frame" x="16" y="16" width="334" height="112"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SpeakEasy Learn PRO" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CR0-x8-WDu"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SpeakEasy Learn PRO" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CR0-x8-WDu">
<rect key="frame" x="0.0" y="0.0" width="240" height="19.5"/> <rect key="frame" x="0.0" y="0.0" width="334" height="19.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="0.0" alpha="0.90000000000000002" colorSpace="calibratedWhite"/> <color key="textColor" white="0.0" alpha="0.90000000000000002" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
...@@ -90,7 +114,7 @@ ...@@ -90,7 +114,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kdQ-sC-7hd"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kdQ-sC-7hd">
<rect key="frame" x="0.0" y="35.5" width="240" height="95.5"/> <rect key="frame" x="0.0" y="35.5" width="334" height="76.5"/>
<string key="text">Unlimited Interactive Practice, PersonalizedStudy Plan, Real-time Al Feedback, Control &amp;Track Your ProgressFree for 3 Days, then $ 6.99/week</string> <string key="text">Unlimited Interactive Practice, PersonalizedStudy Plan, Real-time Al Feedback, Control &amp;Track Your ProgressFree for 3 Days, then $ 6.99/week</string>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="0.0" alpha="0.54166666666666663" colorSpace="custom" customColorSpace="calibratedWhite"/> <color key="textColor" white="0.0" alpha="0.54166666666666663" colorSpace="custom" customColorSpace="calibratedWhite"/>
...@@ -109,8 +133,8 @@ ...@@ -109,8 +133,8 @@
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstAttribute="bottom" secondItem="Ud2-hm-liH" secondAttribute="bottom" constant="16" id="52W-2b-oUx"/> <constraint firstAttribute="bottom" secondItem="Ud2-hm-liH" secondAttribute="bottom" constant="16" id="52W-2b-oUx" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="Ud2-hm-liH" firstAttribute="top" secondItem="0P2-EJ-LIF" secondAttribute="top" constant="16" id="L8s-sX-cYu"/> <constraint firstItem="Ud2-hm-liH" firstAttribute="top" secondItem="0P2-EJ-LIF" secondAttribute="top" constant="16" id="L8s-sX-cYu" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="Ud2-hm-liH" firstAttribute="leading" secondItem="0P2-EJ-LIF" secondAttribute="leading" constant="16" id="WDj-ZA-rr9"/> <constraint firstItem="Ud2-hm-liH" firstAttribute="leading" secondItem="0P2-EJ-LIF" secondAttribute="leading" constant="16" id="WDj-ZA-rr9"/>
<constraint firstAttribute="trailing" secondItem="Ud2-hm-liH" secondAttribute="trailing" constant="16" id="xun-vj-bhp"/> <constraint firstAttribute="trailing" secondItem="Ud2-hm-liH" secondAttribute="trailing" constant="16" id="xun-vj-bhp"/>
</constraints> </constraints>
...@@ -121,7 +145,7 @@ ...@@ -121,7 +145,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wxf-67-vlh"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wxf-67-vlh">
<rect key="frame" x="24" y="252" width="272" height="54"/> <rect key="frame" x="24" y="513" width="366" height="54"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Free Trial Enabled" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GN8-TT-2qb"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Free Trial Enabled" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GN8-TT-2qb">
<rect key="frame" x="16" y="17" width="135.5" height="20.5"/> <rect key="frame" x="16" y="17" width="135.5" height="20.5"/>
...@@ -138,7 +162,7 @@ ...@@ -138,7 +162,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8A2-JJ-q9U"> <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8A2-JJ-q9U">
<rect key="frame" x="207" y="11.5" width="51" height="31"/> <rect key="frame" x="301" y="11.5" width="51" height="31"/>
<color key="onTintColor" red="0.2235293984413147" green="0.50196081399917603" blue="0.96470588445663452" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="onTintColor" red="0.2235293984413147" green="0.50196081399917603" blue="0.96470588445663452" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</switch> </switch>
</subviews> </subviews>
...@@ -148,7 +172,7 @@ ...@@ -148,7 +172,7 @@
<constraint firstItem="GN8-TT-2qb" firstAttribute="centerY" secondItem="wxf-67-vlh" secondAttribute="centerY" id="B4d-7J-s5U"/> <constraint firstItem="GN8-TT-2qb" firstAttribute="centerY" secondItem="wxf-67-vlh" secondAttribute="centerY" id="B4d-7J-s5U"/>
<constraint firstItem="GN8-TT-2qb" firstAttribute="leading" secondItem="wxf-67-vlh" secondAttribute="leading" constant="16" id="MSN-UC-5a0"/> <constraint firstItem="GN8-TT-2qb" firstAttribute="leading" secondItem="wxf-67-vlh" secondAttribute="leading" constant="16" id="MSN-UC-5a0"/>
<constraint firstAttribute="trailing" secondItem="8A2-JJ-q9U" secondAttribute="trailing" constant="16" id="MeY-E0-Y9j"/> <constraint firstAttribute="trailing" secondItem="8A2-JJ-q9U" secondAttribute="trailing" constant="16" id="MeY-E0-Y9j"/>
<constraint firstAttribute="height" constant="54" id="zhE-fU-Zno"/> <constraint firstAttribute="height" constant="54" id="zhE-fU-Zno" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
</constraints> </constraints>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="corners"> <userDefinedRuntimeAttribute type="number" keyPath="corners">
...@@ -157,10 +181,10 @@ ...@@ -157,10 +181,10 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="VCy-0n-bSb"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="VCy-0n-bSb">
<rect key="frame" x="24" y="322" width="272" height="50"/> <rect key="frame" x="24" y="583" width="366" height="50"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h6Q-rP-Oe8"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h6Q-rP-Oe8">
<rect key="frame" x="0.0" y="0.0" width="272" height="25"/> <rect key="frame" x="0.0" y="0.0" width="366" height="25"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="L1M-6c-d8B"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="L1M-6c-d8B">
<rect key="frame" x="16" y="2.5" width="90" height="20"/> <rect key="frame" x="16" y="2.5" width="90" height="20"/>
...@@ -198,7 +222,7 @@ ...@@ -198,7 +222,7 @@
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="UGd-Rq-jXs"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="UGd-Rq-jXs">
<rect key="frame" x="120" y="2.5" width="136" height="20.5"/> <rect key="frame" x="214" y="2.5" width="136" height="20.5"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3 days free" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oBS-z1-Wml"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3 days free" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oBS-z1-Wml">
<rect key="frame" x="0.0" y="0.0" width="85" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="85" height="20.5"/>
...@@ -233,7 +257,7 @@ ...@@ -233,7 +257,7 @@
</subviews> </subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="25" id="0HE-lf-jTJ"/> <constraint firstAttribute="height" constant="25" id="0HE-lf-jTJ" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="L1M-6c-d8B" firstAttribute="centerY" secondItem="h6Q-rP-Oe8" secondAttribute="centerY" id="D0z-gN-bIq"/> <constraint firstItem="L1M-6c-d8B" firstAttribute="centerY" secondItem="h6Q-rP-Oe8" secondAttribute="centerY" id="D0z-gN-bIq"/>
<constraint firstAttribute="trailing" secondItem="UGd-Rq-jXs" secondAttribute="trailing" constant="16" id="RLo-xI-ZSe"/> <constraint firstAttribute="trailing" secondItem="UGd-Rq-jXs" secondAttribute="trailing" constant="16" id="RLo-xI-ZSe"/>
<constraint firstItem="UGd-Rq-jXs" firstAttribute="centerY" secondItem="h6Q-rP-Oe8" secondAttribute="centerY" id="Tu2-HA-DIa"/> <constraint firstItem="UGd-Rq-jXs" firstAttribute="centerY" secondItem="h6Q-rP-Oe8" secondAttribute="centerY" id="Tu2-HA-DIa"/>
...@@ -241,7 +265,7 @@ ...@@ -241,7 +265,7 @@
</constraints> </constraints>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qMQ-F9-Ot0"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qMQ-F9-Ot0">
<rect key="frame" x="0.0" y="25" width="272" height="25"/> <rect key="frame" x="0.0" y="25" width="366" height="25"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="BLY-gn-eoG"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="BLY-gn-eoG">
<rect key="frame" x="16" y="2.5" width="163" height="20"/> <rect key="frame" x="16" y="2.5" width="163" height="20"/>
...@@ -279,7 +303,7 @@ ...@@ -279,7 +303,7 @@
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="BRO-ae-LsD"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="BRO-ae-LsD">
<rect key="frame" x="127.5" y="2.5" width="128.5" height="20.5"/> <rect key="frame" x="221.5" y="2.5" width="128.5" height="20.5"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Save 89%" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vlW-CS-GGh"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Save 89%" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vlW-CS-GGh">
<rect key="frame" x="0.0" y="0.0" width="77.5" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="77.5" height="20.5"/>
...@@ -323,14 +347,15 @@ ...@@ -323,14 +347,15 @@
</view> </view>
</subviews> </subviews>
</stackView> </stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bp3-um-MZh">
<rect key="frame" x="24" y="649" width="366" height="64"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="L5f-PZ-BQ5" customClass="SpeakEleButton" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="L5f-PZ-BQ5" customClass="SpeakEleButton" customModule="SpeakEasyLearnEnglish" customModuleProvider="target">
<rect key="frame" x="24" y="388" width="272" height="60"/> <rect key="frame" x="0.0" y="0.0" width="366" height="64"/>
<color key="backgroundColor" red="0.2235293984413147" green="0.50196081399917603" blue="0.96470588445663452" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="60" id="ayg-6s-tFC"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Try Free"/> <state key="normal" title="Try Free" backgroundImage="icon_Plan_NorButton"/>
<state key="highlighted" backgroundImage="icon_Plan_button_click"/>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/> <integer key="value" value="1"/>
...@@ -343,8 +368,17 @@ ...@@ -343,8 +368,17 @@
<action selector="SpeakPayTaps:" destination="-1" eventType="touchUpInside" id="4ln-PQ-bQz"/> <action selector="SpeakPayTaps:" destination="-1" eventType="touchUpInside" id="4ln-PQ-bQz"/>
</connections> </connections>
</button> </button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="L5f-PZ-BQ5" secondAttribute="trailing" id="D2a-tP-Rau"/>
<constraint firstAttribute="height" constant="64" id="fdo-dQ-Xz5"/>
<constraint firstItem="L5f-PZ-BQ5" firstAttribute="leading" secondItem="bp3-um-MZh" secondAttribute="leading" id="ugj-iI-Owh"/>
<constraint firstAttribute="bottom" secondItem="L5f-PZ-BQ5" secondAttribute="bottom" id="zCI-Y4-Mv1"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Cancel Anytime &amp; Privacy|Terms" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NDv-gZ-gv3"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Cancel Anytime &amp; Privacy|Terms" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NDv-gZ-gv3">
<rect key="frame" x="24" y="464" width="272" height="20.5"/> <rect key="frame" x="24" y="729" width="366" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="20.5" id="LFD-3y-mnz"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="20.5" id="LFD-3y-mnz"/>
</constraints> </constraints>
...@@ -360,29 +394,65 @@ ...@@ -360,29 +394,65 @@
</userDefinedRuntimeAttribute> </userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Khu-4S-MSZ">
<rect key="frame" x="24" y="57" width="40" height="40"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="sp-Close"/>
<connections>
<action selector="SpeakCloseTaps:" destination="-1" eventType="touchUpInside" id="Ehx-8a-Yrb"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="B7F-jV-sWR">
<rect key="frame" x="308" y="60" width="82" height="34"/>
<color key="backgroundColor" red="0.10980392156862745" green="0.14901960784313725" blue="0.20392156862745098" alpha="0.29525403911564635" colorSpace="custom" customColorSpace="calibratedRGB"/>
<inset key="contentEdgeInsets" minX="10" minY="6" maxX="10" maxY="6"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Restore"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="14"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="corners">
<real key="value" value="17"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="SpeakRestoreTaps:" destination="-1" eventType="touchUpInside" id="6rr-yi-TGU"/>
</connections>
</button>
</subviews> </subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="GRD-E5-C2J" secondAttribute="trailing" constant="24" id="0vo-MP-eBw"/> <constraint firstAttribute="trailing" secondItem="GRD-E5-C2J" secondAttribute="trailing" constant="24" id="0vo-MP-eBw"/>
<constraint firstItem="GRD-E5-C2J" firstAttribute="top" secondItem="8r0-nd-l8p" secondAttribute="top" id="2VJ-32-x63"/> <constraint firstItem="0P2-EJ-LIF" firstAttribute="top" secondItem="ynQ-dm-w6L" secondAttribute="bottom" constant="24" id="39K-qA-OrK" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="0P2-EJ-LIF" firstAttribute="top" secondItem="ynQ-dm-w6L" secondAttribute="bottom" constant="24" id="39K-qA-OrK"/> <constraint firstItem="Khu-4S-MSZ" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="3fS-ep-MJO"/>
<constraint firstAttribute="trailing" secondItem="Lsd-C8-IAe" secondAttribute="trailing" id="41A-np-IzL"/>
<constraint firstItem="B7F-jV-sWR" firstAttribute="top" secondItem="8r0-nd-l8p" secondAttribute="top" constant="60" id="5MQ-kJ-ceh"/>
<constraint firstItem="ynQ-dm-w6L" firstAttribute="trailing" secondItem="GRD-E5-C2J" secondAttribute="trailing" id="68D-Of-BIX"/> <constraint firstItem="ynQ-dm-w6L" firstAttribute="trailing" secondItem="GRD-E5-C2J" secondAttribute="trailing" id="68D-Of-BIX"/>
<constraint firstItem="NDv-gZ-gv3" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="7Qx-G4-sj0"/> <constraint firstItem="NDv-gZ-gv3" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="7Qx-G4-sj0"/>
<constraint firstItem="wxf-67-vlh" firstAttribute="top" secondItem="0P2-EJ-LIF" secondAttribute="bottom" constant="16" id="EBT-5r-OXi"/> <constraint firstItem="Lsd-C8-IAe" firstAttribute="top" secondItem="8r0-nd-l8p" secondAttribute="top" id="9Dl-vj-LHy"/>
<constraint firstItem="wxf-67-vlh" firstAttribute="top" secondItem="0P2-EJ-LIF" secondAttribute="bottom" constant="16" id="EBT-5r-OXi" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="wxf-67-vlh" firstAttribute="leading" secondItem="0P2-EJ-LIF" secondAttribute="leading" id="FzA-wY-pyQ"/> <constraint firstItem="wxf-67-vlh" firstAttribute="leading" secondItem="0P2-EJ-LIF" secondAttribute="leading" id="FzA-wY-pyQ"/>
<constraint firstItem="GRD-E5-C2J" firstAttribute="top" secondItem="Lsd-C8-IAe" secondAttribute="bottom" id="GBR-zU-PiR"/>
<constraint firstItem="Lsd-C8-IAe" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" id="Gfw-Fs-0Jc"/>
<constraint firstItem="0P2-EJ-LIF" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="JuL-os-wpq"/> <constraint firstItem="0P2-EJ-LIF" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="JuL-os-wpq"/>
<constraint firstAttribute="trailing" secondItem="0P2-EJ-LIF" secondAttribute="trailing" constant="24" id="L4q-LI-Llq"/> <constraint firstAttribute="trailing" secondItem="0P2-EJ-LIF" secondAttribute="trailing" constant="24" id="L4q-LI-Llq"/>
<constraint firstAttribute="trailing" secondItem="VCy-0n-bSb" secondAttribute="trailing" constant="24" id="OOS-kG-VeX"/> <constraint firstAttribute="trailing" secondItem="VCy-0n-bSb" secondAttribute="trailing" constant="24" id="OOS-kG-VeX"/>
<constraint firstItem="bp3-um-MZh" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="Opq-Ef-Zlb"/>
<constraint firstItem="ynQ-dm-w6L" firstAttribute="top" secondItem="GRD-E5-C2J" secondAttribute="bottom" constant="8" id="V6V-5R-QUq"/> <constraint firstItem="ynQ-dm-w6L" firstAttribute="top" secondItem="GRD-E5-C2J" secondAttribute="bottom" constant="8" id="V6V-5R-QUq"/>
<constraint firstAttribute="trailing" secondItem="NDv-gZ-gv3" secondAttribute="trailing" constant="24" id="Wpz-Rv-pxb"/> <constraint firstAttribute="trailing" secondItem="NDv-gZ-gv3" secondAttribute="trailing" constant="24" id="Wpz-Rv-pxb"/>
<constraint firstAttribute="trailing" secondItem="bp3-um-MZh" secondAttribute="trailing" constant="24" id="WvW-Iz-uf0"/>
<constraint firstItem="wxf-67-vlh" firstAttribute="trailing" secondItem="0P2-EJ-LIF" secondAttribute="trailing" id="Ysf-kd-7ic"/> <constraint firstItem="wxf-67-vlh" firstAttribute="trailing" secondItem="0P2-EJ-LIF" secondAttribute="trailing" id="Ysf-kd-7ic"/>
<constraint firstAttribute="trailing" secondItem="L5f-PZ-BQ5" secondAttribute="trailing" constant="24" id="a2V-yp-XAH"/> <constraint firstItem="VCy-0n-bSb" firstAttribute="top" secondItem="wxf-67-vlh" secondAttribute="bottom" constant="16" id="a2x-OC-7yh" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="VCy-0n-bSb" firstAttribute="top" secondItem="wxf-67-vlh" secondAttribute="bottom" constant="16" id="a2x-OC-7yh"/> <constraint firstItem="bp3-um-MZh" firstAttribute="top" secondItem="VCy-0n-bSb" secondAttribute="bottom" constant="16" id="aIC-QR-Jnv" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstAttribute="trailing" secondItem="B7F-jV-sWR" secondAttribute="trailing" constant="24" id="d3T-0x-9FR"/>
<constraint firstItem="NDv-gZ-gv3" firstAttribute="top" secondItem="bp3-um-MZh" secondAttribute="bottom" constant="16" id="f8f-Cc-lRB" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="VCy-0n-bSb" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="fXA-eF-hel"/> <constraint firstItem="VCy-0n-bSb" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="fXA-eF-hel"/>
<constraint firstItem="B7F-jV-sWR" firstAttribute="centerY" secondItem="Khu-4S-MSZ" secondAttribute="centerY" id="kWu-yE-xfy"/>
<constraint firstItem="GRD-E5-C2J" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="rse-Mz-7Hy"/> <constraint firstItem="GRD-E5-C2J" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="rse-Mz-7Hy"/>
<constraint firstItem="L5f-PZ-BQ5" firstAttribute="leading" secondItem="8r0-nd-l8p" secondAttribute="leading" constant="24" id="sON-oO-7c6"/>
<constraint firstItem="NDv-gZ-gv3" firstAttribute="top" secondItem="L5f-PZ-BQ5" secondAttribute="bottom" constant="16" id="w3e-fI-gd5"/>
<constraint firstItem="L5f-PZ-BQ5" firstAttribute="top" secondItem="VCy-0n-bSb" secondAttribute="bottom" constant="16" id="wuV-cK-n8T"/>
<constraint firstAttribute="bottom" secondItem="NDv-gZ-gv3" secondAttribute="bottom" constant="20" id="zff-hh-lqu"/> <constraint firstAttribute="bottom" secondItem="NDv-gZ-gv3" secondAttribute="bottom" constant="20" id="zff-hh-lqu"/>
<constraint firstItem="ynQ-dm-w6L" firstAttribute="leading" secondItem="GRD-E5-C2J" secondAttribute="leading" id="zoX-2m-2s1"/> <constraint firstItem="ynQ-dm-w6L" firstAttribute="leading" secondItem="GRD-E5-C2J" secondAttribute="leading" id="zoX-2m-2s1"/>
</constraints> </constraints>
...@@ -396,42 +466,6 @@ ...@@ -396,42 +466,6 @@
<constraint firstItem="8r0-nd-l8p" firstAttribute="leading" secondItem="aYT-y7-hf8" secondAttribute="leading" id="jfp-Mc-j5g"/> <constraint firstItem="8r0-nd-l8p" firstAttribute="leading" secondItem="aYT-y7-hf8" secondAttribute="leading" id="jfp-Mc-j5g"/>
</constraints> </constraints>
</scrollView> </scrollView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Lsd-C8-IAe">
<rect key="frame" x="0.0" y="0.0" width="320" height="230"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="230" id="IiK-63-fWh"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Khu-4S-MSZ">
<rect key="frame" x="24" y="24" width="40" height="40"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="sp-Close"/>
<connections>
<action selector="SpeakCloseTaps:" destination="-1" eventType="touchUpInside" id="Ehx-8a-Yrb"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="B7F-jV-sWR">
<rect key="frame" x="214" y="27" width="82" height="34"/>
<color key="backgroundColor" red="0.10980392156862745" green="0.14901960784313725" blue="0.20392156862745098" alpha="0.29525403911564635" colorSpace="custom" customColorSpace="calibratedRGB"/>
<inset key="contentEdgeInsets" minX="10" minY="6" maxX="10" maxY="6"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Restore"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="1"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="14"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="corners">
<real key="value" value="17"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="SpeakRestoreTaps:" destination="-1" eventType="touchUpInside" id="6rr-yi-TGU"/>
</connections>
</button>
</subviews> </subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
...@@ -439,23 +473,19 @@ ...@@ -439,23 +473,19 @@
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="aYT-y7-hf8" secondAttribute="trailing" id="1vp-dD-GTQ"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="aYT-y7-hf8" secondAttribute="trailing" id="1vp-dD-GTQ"/>
<constraint firstItem="5SM-Lp-0MM" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="5Fy-iV-kqk"/> <constraint firstItem="5SM-Lp-0MM" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="5Fy-iV-kqk"/>
<constraint firstItem="5SM-Lp-0MM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="AjH-kD-Mkl"/> <constraint firstItem="5SM-Lp-0MM" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="AjH-kD-Mkl"/>
<constraint firstItem="B7F-jV-sWR" firstAttribute="centerY" secondItem="Khu-4S-MSZ" secondAttribute="centerY" id="Bw5-S7-H2b"/>
<constraint firstItem="Lsd-C8-IAe" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="Fki-Xb-cYE"/>
<constraint firstItem="5SM-Lp-0MM" firstAttribute="trailing" secondItem="fnl-2z-Ty3" secondAttribute="trailing" id="OXa-HW-56J"/> <constraint firstItem="5SM-Lp-0MM" firstAttribute="trailing" secondItem="fnl-2z-Ty3" secondAttribute="trailing" id="OXa-HW-56J"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="B7F-jV-sWR" secondAttribute="trailing" constant="24" id="OkQ-Ok-JoH"/>
<constraint firstItem="aYT-y7-hf8" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="P4U-QH-Kwb"/> <constraint firstItem="aYT-y7-hf8" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="P4U-QH-Kwb"/>
<constraint firstAttribute="bottom" secondItem="5SM-Lp-0MM" secondAttribute="bottom" id="jDz-gg-Zym"/> <constraint firstAttribute="bottom" secondItem="5SM-Lp-0MM" secondAttribute="bottom" id="jDz-gg-Zym"/>
<constraint firstItem="Lsd-C8-IAe" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="nor-hC-Mfu"/> <constraint firstItem="aYT-y7-hf8" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="nwe-aS-pBP"/>
<constraint firstItem="aYT-y7-hf8" firstAttribute="top" secondItem="Lsd-C8-IAe" secondAttribute="bottom" id="nwe-aS-pBP"/>
<constraint firstItem="Khu-4S-MSZ" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="4" id="pkS-QV-Hi6"/>
<constraint firstAttribute="bottom" secondItem="aYT-y7-hf8" secondAttribute="bottom" id="pp9-E9-aLs"/> <constraint firstAttribute="bottom" secondItem="aYT-y7-hf8" secondAttribute="bottom" id="pp9-E9-aLs"/>
<constraint firstItem="Khu-4S-MSZ" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="vI0-jI-GOv"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Lsd-C8-IAe" secondAttribute="trailing" id="xyZ-Aq-Zca"/>
</constraints> </constraints>
<point key="canvasLocation" x="11.25" y="-11.619718309859156"/> <point key="canvasLocation" x="11.25" y="-11.619718309859156"/>
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="icon_Iap_Top_bg" width="402" height="499"/>
<image name="icon_Plan_NorButton" width="354" height="64"/>
<image name="icon_Plan_button_click" width="354" height="60"/>
<image name="sp-Close" width="40" height="40"/> <image name="sp-Close" width="40" height="40"/>
<image name="sp-bg" width="402" height="874"/> <image name="sp-bg" width="402" height="874"/>
<systemColor name="systemBackgroundColor"> <systemColor name="systemBackgroundColor">
......
...@@ -11,7 +11,7 @@ class SpeakEleLaunchViewCtr: SpeakEleBaseViewCtr { ...@@ -11,7 +11,7 @@ class SpeakEleLaunchViewCtr: SpeakEleBaseViewCtr {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.ToPages() self.ToPages()
} }
} }
...@@ -26,7 +26,7 @@ class SpeakEleLaunchViewCtr: SpeakEleBaseViewCtr { ...@@ -26,7 +26,7 @@ class SpeakEleLaunchViewCtr: SpeakEleBaseViewCtr {
SpWindow.switchToController(nav) SpWindow.switchToController(nav)
}else{ }else{
let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleLoginGuideCtr()) let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleLoginGuideCtr())
SpWindow.switchToController(nav) SpWindow.rootViewController = nav
} }
break break
case .subscribe: case .subscribe:
......
...@@ -26,10 +26,17 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr { ...@@ -26,10 +26,17 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr {
super.viewWillAppear(animated) super.viewWillAppear(animated)
titleView.isHidden = true titleView.isHidden = true
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
var idx = 0
LoginBtns.forEach { btn in LoginBtns.forEach { btn in
if idx == 0 {
btn.setBackgroundImage(UIColor.black.generate(btn.size,20), for: .normal)
btn.setBackgroundImage(UIColor.black.generate(btn.size,20), for: .highlighted)
}else{
btn.setBackgroundImage(UIColor.white.generate(btn.size,20), for: .normal) btn.setBackgroundImage(UIColor.white.generate(btn.size,20), for: .normal)
btn.setBackgroundImage(UIColor.init(hex: 0x191919).generate(btn.size,20), for: .highlighted) btn.setBackgroundImage(UIColor.init(hex: 0x191919).generate(btn.size,20), for: .highlighted)
}
btn.clipsToBounds = false btn.clipsToBounds = false
idx += 1
} }
} }
...@@ -37,7 +44,7 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr { ...@@ -37,7 +44,7 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
LoginBtns.forEach { btn in LoginBtns.forEach { btn in
btn.shadow(cornerRadius: 20,shadowColor: .init(hex: 0x000000),offset: CGSize(width: 0, height: 2) ,opacity: 0.06,radius: 2) btn.shadow(cornerRadius: 20,shadowColor: .init(hex: 0x000000,alpha: 0.06),offset: CGSize(width: 0, height: 2) ,opacity: 1,radius: 5)
} }
} }
...@@ -93,8 +100,8 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr { ...@@ -93,8 +100,8 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr {
private func ToHome() -> Void { private func ToHome() -> Void {
updateUserInformation() updateUserInformation()
let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleTabbarViewCtr()) let nav = SpeakEleBaseNavigationCtr(rootViewController: SpeakEleTabbarViewCtr())
SpWindow.switchToController(nav) SpWindow.switchToController(nav)
} }
} }
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
...@@ -13,8 +12,8 @@ ...@@ -13,8 +12,8 @@
<connections> <connections>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
<outletCollection property="LoginBtns" destination="tzy-In-iLG" collectionClass="NSMutableArray" id="x2h-2J-DJF"/> <outletCollection property="LoginBtns" destination="tzy-In-iLG" collectionClass="NSMutableArray" id="x2h-2J-DJF"/>
<outletCollection property="LoginBtns" destination="zNk-df-Iyb" collectionClass="NSMutableArray" id="T6c-CG-CAW"/> <outletCollection property="LoginBtns" destination="zNk-df-Iyb" collectionClass="NSMutableArray" id="vmh-N0-yG5"/>
<outletCollection property="LoginBtns" destination="6Rf-Qc-Ph6" collectionClass="NSMutableArray" id="qIj-Pm-tlS"/> <outletCollection property="LoginBtns" destination="6Rf-Qc-Ph6" collectionClass="NSMutableArray" id="7WH-zj-sm9"/>
</connections> </connections>
</placeholder> </placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
...@@ -22,17 +21,24 @@ ...@@ -22,17 +21,24 @@
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-bg" translatesAutoresizingMaskIntoConstraints="NO" id="CC8-a0-0aA"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="CC8-a0-0aA">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</imageView> </imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Log_in_bg" translatesAutoresizingMaskIntoConstraints="NO" id="JoT-gG-CxX"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Log_in_bg" translatesAutoresizingMaskIntoConstraints="NO" id="JoT-gG-CxX">
<rect key="frame" x="24" y="0.0" width="345" height="353"/> <rect key="frame" x="0.0" y="0.0" width="393" height="402"/>
<constraints> <constraints>
<constraint firstAttribute="width" secondItem="JoT-gG-CxX" secondAttribute="height" multiplier="131:134" id="h8O-e2-1XI"/> <constraint firstAttribute="width" secondItem="JoT-gG-CxX" secondAttribute="height" multiplier="131:134" id="h8O-e2-1XI"/>
</constraints> </constraints>
</imageView> </imageView>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kxX-OL-tlV">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HUi-nl-TBg">
<rect key="frame" x="0.0" y="0.0" width="393" height="859.66666666666663"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="lW5-Fb-H2e"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="lW5-Fb-H2e">
<rect key="frame" x="24" y="353" width="345" height="62.333333333333314"/> <rect key="frame" x="24" y="388" width="345" height="62.333333333333314"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oCO-us-qr6"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oCO-us-qr6">
<rect key="frame" x="0.0" y="0.0" width="345" height="62.333333333333336"/> <rect key="frame" x="0.0" y="0.0" width="345" height="62.333333333333336"/>
...@@ -52,14 +58,8 @@ deletable anytime</string> ...@@ -52,14 +58,8 @@ deletable anytime</string>
</label> </label>
</subviews> </subviews>
</stackView> </stackView>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kxX-OL-tlV">
<rect key="frame" x="0.0" y="425.33333333333326" width="393" height="358.66666666666674"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HUi-nl-TBg">
<rect key="frame" x="0.0" y="0.0" width="393" height="400"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="yTj-k3-iGf"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="yTj-k3-iGf">
<rect key="frame" x="24" y="0.0" width="345" height="327.33333333333331"/> <rect key="frame" x="24" y="504.33333333333326" width="345" height="87"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Create an account to save your progress" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hf0-Cw-gx3"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Create an account to save your progress" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hf0-Cw-gx3">
<rect key="frame" x="0.0" y="0.0" width="345" height="17"/> <rect key="frame" x="0.0" y="0.0" width="345" height="17"/>
...@@ -76,16 +76,17 @@ deletable anytime</string> ...@@ -76,16 +76,17 @@ deletable anytime</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tzy-In-iLG"> <button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tzy-In-iLG">
<rect key="frame" x="0.0" y="27" width="345" height="60"/> <rect key="frame" x="0.0" y="27.000000000000057" width="345" height="60"/>
<color key="backgroundColor" red="0.098039215686274508" green="0.098039215686274508" blue="0.098039215686274508" alpha="1" colorSpace="calibratedRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="60" id="gLc-yU-1Ni"/> <constraint firstAttribute="height" constant="60" id="gLc-yU-1Ni" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
</constraints> </constraints>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/> <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Continue with Apple" image="sp-login-apple"> <state key="normal" title="Continue with Apple" image="sp-login-apple-w">
<color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state> </state>
<state key="highlighted" image="sp-login-apple-w"> <state key="highlighted" image="sp-login-apple">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state> </state>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
...@@ -103,10 +104,15 @@ deletable anytime</string> ...@@ -103,10 +104,15 @@ deletable anytime</string>
<action selector="LoginBtnTaps:" destination="-1" eventType="touchUpInside" id="m2Z-O4-Aff"/> <action selector="LoginBtnTaps:" destination="-1" eventType="touchUpInside" id="m2Z-O4-Aff"/>
</connections> </connections>
</button> </button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ybI-Iz-Djs">
<rect key="frame" x="24" y="607.33333333333337" width="345" height="156.33333333333337"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zNk-df-Iyb"> <button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zNk-df-Iyb">
<rect key="frame" x="0.0" y="97.000000000000057" width="345" height="60"/> <rect key="frame" x="0.0" y="0.0" width="345" height="60"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="60" id="QNr-Pd-DAu"/> <constraint firstAttribute="height" constant="60" id="QNr-Pd-DAu" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
</constraints> </constraints>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/> <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
...@@ -132,9 +138,9 @@ deletable anytime</string> ...@@ -132,9 +138,9 @@ deletable anytime</string>
</connections> </connections>
</button> </button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="———————— or ————————" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XMi-wK-wbM"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="———————— or ————————" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XMi-wK-wbM">
<rect key="frame" x="0.0" y="167.00000000000006" width="345" height="20.333333333333343"/> <rect key="frame" x="0.0" y="68" width="345" height="20.333333333333329"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/> <color key="textColor" red="0.098039215686274508" green="0.098039215686274508" blue="0.098039215686274508" alpha="0.26015093537414968" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
<userDefinedRuntimeAttributes> <userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont"> <userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
...@@ -146,9 +152,9 @@ deletable anytime</string> ...@@ -146,9 +152,9 @@ deletable anytime</string>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</label> </label>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6Rf-Qc-Ph6"> <button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6Rf-Qc-Ph6">
<rect key="frame" x="0.0" y="197.33333333333331" width="345" height="60"/> <rect key="frame" x="0.0" y="96.333333333333258" width="345" height="60"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="60" id="vTs-MU-bx9"/> <constraint firstAttribute="height" constant="60" id="vTs-MU-bx9" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
</constraints> </constraints>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/> <inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="-5" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
...@@ -173,10 +179,12 @@ deletable anytime</string> ...@@ -173,10 +179,12 @@ deletable anytime</string>
<action selector="LoginBtnTaps:" destination="-1" eventType="touchUpInside" id="cJ2-yp-sHA"/> <action selector="LoginBtnTaps:" destination="-1" eventType="touchUpInside" id="cJ2-yp-sHA"/>
</connections> </connections>
</button> </button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="n78-Ml-Gcc"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="n78-Ml-Gcc">
<rect key="frame" x="0.0" y="267.33333333333331" width="345" height="60"/> <rect key="frame" x="24" y="763.66666666666663" width="345" height="54"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="60" id="t1d-CW-NdJ"/> <constraint firstAttribute="height" constant="54" id="t1d-CW-NdJ" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
</constraints> </constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Log in"> <state key="normal" title="Log in">
...@@ -198,14 +206,21 @@ deletable anytime</string> ...@@ -198,14 +206,21 @@ deletable anytime</string>
</connections> </connections>
</button> </button>
</subviews> </subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstItem="yTj-k3-iGf" firstAttribute="top" secondItem="HUi-nl-TBg" secondAttribute="top" id="AdL-1t-DB3"/> <constraint firstItem="lW5-Fb-H2e" firstAttribute="leading" secondItem="HUi-nl-TBg" secondAttribute="leading" constant="24" id="4HD-SB-Usx"/>
<constraint firstItem="yTj-k3-iGf" firstAttribute="leading" secondItem="ybI-Iz-Djs" secondAttribute="leading" id="8es-33-Q5b"/>
<constraint firstItem="yTj-k3-iGf" firstAttribute="leading" secondItem="HUi-nl-TBg" secondAttribute="leading" constant="24" id="F1x-EH-F3t"/> <constraint firstItem="yTj-k3-iGf" firstAttribute="leading" secondItem="HUi-nl-TBg" secondAttribute="leading" constant="24" id="F1x-EH-F3t"/>
<constraint firstAttribute="height" constant="400" id="Xmf-9b-FVA"/> <constraint firstItem="n78-Ml-Gcc" firstAttribute="trailing" secondItem="yTj-k3-iGf" secondAttribute="trailing" id="Njs-D9-Rac"/>
<constraint firstItem="n78-Ml-Gcc" firstAttribute="top" secondItem="ybI-Iz-Djs" secondAttribute="bottom" id="Tel-Ay-cMZ"/>
<constraint firstItem="ybI-Iz-Djs" firstAttribute="top" secondItem="yTj-k3-iGf" secondAttribute="bottom" constant="16" id="Zb9-6b-qBb"/>
<constraint firstAttribute="bottom" secondItem="n78-Ml-Gcc" secondAttribute="bottom" constant="42" id="Zxz-ss-tlE" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstAttribute="trailing" secondItem="yTj-k3-iGf" secondAttribute="trailing" constant="24" id="fWC-qc-nHq"/> <constraint firstAttribute="trailing" secondItem="yTj-k3-iGf" secondAttribute="trailing" constant="24" id="fWC-qc-nHq"/>
<constraint firstItem="lW5-Fb-H2e" firstAttribute="top" secondItem="HUi-nl-TBg" secondAttribute="top" constant="388" id="gKE-NU-yYl" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="yTj-k3-iGf" firstAttribute="top" secondItem="lW5-Fb-H2e" secondAttribute="bottom" constant="54" id="hTW-0R-0vX" customClass="SpeakAutoLayout" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"/>
<constraint firstItem="yTj-k3-iGf" firstAttribute="trailing" secondItem="ybI-Iz-Djs" secondAttribute="trailing" id="jgx-qK-HOa"/>
<constraint firstItem="n78-Ml-Gcc" firstAttribute="leading" secondItem="yTj-k3-iGf" secondAttribute="leading" id="nB6-qi-NmL"/>
<constraint firstAttribute="trailing" secondItem="lW5-Fb-H2e" secondAttribute="trailing" constant="24" id="nNi-TU-Qwf"/>
</constraints> </constraints>
</view> </view>
</subviews> </subviews>
...@@ -219,36 +234,29 @@ deletable anytime</string> ...@@ -219,36 +234,29 @@ deletable anytime</string>
</scrollView> </scrollView>
</subviews> </subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="kxX-OL-tlV" secondAttribute="trailing" id="4BK-My-Ms7"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="kxX-OL-tlV" secondAttribute="trailing" id="4BK-My-Ms7"/>
<constraint firstItem="JoT-gG-CxX" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="AJh-vt-3ed"/> <constraint firstItem="JoT-gG-CxX" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="AJh-vt-3ed"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="JoT-gG-CxX" secondAttribute="trailing" constant="24" id="BRM-HX-tsx"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="JoT-gG-CxX" secondAttribute="trailing" id="BRM-HX-tsx"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="CC8-a0-0aA" secondAttribute="trailing" id="F9M-Ms-OrS"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="CC8-a0-0aA" secondAttribute="trailing" id="F9M-Ms-OrS"/>
<constraint firstItem="lW5-Fb-H2e" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="Op7-dM-Zvx"/>
<constraint firstItem="kxX-OL-tlV" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="S2V-Er-lox"/> <constraint firstItem="kxX-OL-tlV" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="S2V-Er-lox"/>
<constraint firstItem="kxX-OL-tlV" firstAttribute="top" secondItem="lW5-Fb-H2e" secondAttribute="bottom" constant="10" id="THL-1m-8Kq"/>
<constraint firstItem="CC8-a0-0aA" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="UND-Wk-NkN"/> <constraint firstItem="CC8-a0-0aA" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="UND-Wk-NkN"/>
<constraint firstAttribute="bottom" secondItem="CC8-a0-0aA" secondAttribute="bottom" id="Xcx-JF-lQz"/> <constraint firstAttribute="bottom" secondItem="CC8-a0-0aA" secondAttribute="bottom" id="Xcx-JF-lQz"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="lW5-Fb-H2e" secondAttribute="trailing" constant="24" id="bhH-8j-oYC"/>
<constraint firstItem="CC8-a0-0aA" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="eki-bV-hw0"/> <constraint firstItem="CC8-a0-0aA" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="eki-bV-hw0"/>
<constraint firstItem="JoT-gG-CxX" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="n9k-MI-sIQ"/> <constraint firstItem="JoT-gG-CxX" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="n9k-MI-sIQ"/>
<constraint firstItem="lW5-Fb-H2e" firstAttribute="top" secondItem="JoT-gG-CxX" secondAttribute="bottom" id="owf-aT-87Y"/> <constraint firstAttribute="bottom" secondItem="kxX-OL-tlV" secondAttribute="bottom" id="pZo-EZ-EYt"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="kxX-OL-tlV" secondAttribute="bottom" id="pZo-EZ-EYt"/> <constraint firstItem="kxX-OL-tlV" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="see-Oo-2JA"/>
</constraints> </constraints>
<point key="canvasLocation" x="130.53435114503816" y="-12.67605633802817"/> <point key="canvasLocation" x="130.53435114503816" y="-12.67605633802817"/>
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="Log_in_bg" width="402" height="402"/> <image name="Log_in_bg" width="402" height="402"/>
<image name="sp-bg" width="402" height="874"/>
<image name="sp-login-apple" width="24.333333969116211" height="24"/> <image name="sp-login-apple" width="24.333333969116211" height="24"/>
<image name="sp-login-apple-w" width="24" height="24"/> <image name="sp-login-apple-w" width="24" height="24"/>
<image name="sp-login-google" width="24.333333969116211" height="24"/> <image name="sp-login-google" width="24.333333969116211" height="24"/>
<image name="sp-login-mail" width="24" height="24"/> <image name="sp-login-mail" width="24" height="24"/>
<image name="sp-login-mail-w" width="24" height="24"/> <image name="sp-login-mail-w" width="24" height="24"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources> </resources>
</document> </document>
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XM7-aG-cye"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XM7-aG-cye">
<rect key="frame" x="0.0" y="0.0" width="272" height="60"/> <rect key="frame" x="0.0" y="0.0" width="272" height="60"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="gaoleyang@linkingplay.com" placeholder="E-mail address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="e0z-Rl-Mp2"> <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="E-mail address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="e0z-Rl-Mp2">
<rect key="frame" x="16" y="19" width="240" height="22"/> <rect key="frame" x="16" y="19" width="240" height="22"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
......
...@@ -12,6 +12,21 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr { ...@@ -12,6 +12,21 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr {
@IBOutlet weak var SpeakDescLabel: UILabel! @IBOutlet weak var SpeakDescLabel: UILabel!
@IBOutlet weak var TopIcon: UIImageView!
@IBOutlet weak var ShowTopImg: UIImageView!
@IBOutlet weak var ShowAniM1: UIImageView!
@IBOutlet weak var ShowAniM2: UIImageView!
@IBOutlet weak var ShowButtons: UIStackView!
@IBOutlet weak var centerBottonConst: NSLayoutConstraint!
@IBOutlet weak var TopWidthConst: NSLayoutConstraint!
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
} }
...@@ -19,6 +34,49 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr { ...@@ -19,6 +34,49 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr {
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
setDescription() setDescription()
self.startAni()
}
private func startAni() -> Void {
self.TopIcon.alpha = 1
ShowButtons.alpha = 0
ShowTopImg.alpha = 0
ShowAniM1.alpha = 1
self.ShowAniM1.isHidden = true
ShowAniM2.alpha = 0
TopWidthConst.constant = 302 * 2.0
ShowAniM2.alpha = 0
self.ShowButtons.alpha = 0
centerBottonConst.constant = 150
self.view.layoutIfNeeded()
DispatchQueue.main.async {
self.view.setNeedsDisplay()
UIView.animate(withDuration: 0.5) {
self.TopIcon.alpha = 0.0
} completion: { su in
if su {
self.ShowAniM1.isHidden = false
UIView.animate(withDuration: 0.6) {
self.ShowAniM1.alpha = 1
self.TopWidthConst.constant = 302 * 1.2
self.view.layoutIfNeeded()
} completion: { su in
if su {
UIView.animate(withDuration: 0.6) {
self.ShowAniM2.alpha = 1
self.ShowButtons.alpha = 1
self.TopWidthConst.constant = 302
self.centerBottonConst.constant = 80
self.view.layoutIfNeeded()
} completion: { su in
}
}
}
}
}
}
} }
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
......
...@@ -11,7 +11,14 @@ ...@@ -11,7 +11,14 @@
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleLoginGuideCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target"> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SpeakEleLoginGuideCtr" customModule="SpeakEasyLearnEnglish" customModuleProvider="target">
<connections> <connections>
<outlet property="ShowAniM1" destination="2Pj-ZL-FxO" id="BhB-kV-Thj"/>
<outlet property="ShowAniM2" destination="egF-1p-Cl5" id="Quz-kT-fdN"/>
<outlet property="ShowButtons" destination="veF-PY-V1F" id="PkJ-jw-li3"/>
<outlet property="ShowTopImg" destination="eyD-Iy-5pN" id="P19-KE-Kwa"/>
<outlet property="SpeakDescLabel" destination="jGO-Du-a3k" id="mxV-nA-Nwk"/> <outlet property="SpeakDescLabel" destination="jGO-Du-a3k" id="mxV-nA-Nwk"/>
<outlet property="TopIcon" destination="w7f-wU-Eto" id="rmc-Eq-U2D"/>
<outlet property="TopWidthConst" destination="aW6-vK-ZDa" id="O88-s0-sRq"/>
<outlet property="centerBottonConst" destination="NuM-ib-dld" id="cRg-ks-kKG"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections> </connections>
</placeholder> </placeholder>
...@@ -20,10 +27,13 @@ ...@@ -20,10 +27,13 @@
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="dengluye-login" translatesAutoresizingMaskIntoConstraints="NO" id="eyD-Iy-5pN"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="BBBBBBBBBGo.png" translatesAutoresizingMaskIntoConstraints="NO" id="w7f-wU-Eto">
<rect key="frame" x="0.0" y="0.0" width="393" height="465"/> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="dengluye-login" translatesAutoresizingMaskIntoConstraints="NO" id="eyD-Iy-5pN">
<rect key="frame" x="0.0" y="0.0" width="393" height="402"/>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="veF-PY-V1F"> <stackView opaque="NO" alpha="0.0" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="veF-PY-V1F">
<rect key="frame" x="24" y="589.66666666666663" width="345" height="170.33333333333337"/> <rect key="frame" x="24" y="589.66666666666663" width="345" height="170.33333333333337"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="pwZ-Zv-JRo"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="pwZ-Zv-JRo">
...@@ -89,22 +99,44 @@ ...@@ -89,22 +99,44 @@
</label> </label>
</subviews> </subviews>
</stackView> </stackView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-10000h+" translatesAutoresizingMaskIntoConstraints="NO" id="2Pj-ZL-FxO">
<rect key="frame" x="45.666666666666657" y="279" width="302" height="130"/>
<constraints>
<constraint firstAttribute="width" secondItem="2Pj-ZL-FxO" secondAttribute="height" multiplier="302:130" id="Axm-4a-6Mu"/>
<constraint firstAttribute="width" constant="302" id="aW6-vK-ZDa"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sp-SpeakEasyLearning" translatesAutoresizingMaskIntoConstraints="NO" id="egF-1p-Cl5">
<rect key="frame" x="24" y="509" width="345" height="67"/>
</imageView>
</subviews> </subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="veF-PY-V1F" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="0oh-4u-Nzo"/> <constraint firstItem="veF-PY-V1F" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="0oh-4u-Nzo"/>
<constraint firstItem="w7f-wU-Eto" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="2Fe-GS-bKr"/>
<constraint firstItem="egF-1p-Cl5" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="24" id="8nd-bH-4Et"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="veF-PY-V1F" secondAttribute="trailing" constant="24" id="9ao-KJ-und"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="veF-PY-V1F" secondAttribute="trailing" constant="24" id="9ao-KJ-und"/>
<constraint firstItem="eyD-Iy-5pN" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="9vZ-ko-bjl"/> <constraint firstItem="eyD-Iy-5pN" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="9vZ-ko-bjl"/>
<constraint firstItem="w7f-wU-Eto" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="BXz-Rl-pBh"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="egF-1p-Cl5" secondAttribute="trailing" constant="24" id="Bv4-yp-t6a"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="w7f-wU-Eto" secondAttribute="trailing" id="Cz8-3M-tyJ"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="veF-PY-V1F" secondAttribute="bottom" constant="24" id="NIU-Ch-1i2"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="veF-PY-V1F" secondAttribute="bottom" constant="24" id="NIU-Ch-1i2"/>
<constraint firstItem="egF-1p-Cl5" firstAttribute="bottom" secondItem="i5M-Pr-FkT" secondAttribute="centerY" constant="150" id="NuM-ib-dld"/>
<constraint firstItem="egF-1p-Cl5" firstAttribute="top" secondItem="2Pj-ZL-FxO" secondAttribute="bottom" constant="100" id="X1n-a6-Ev3"/>
<constraint firstItem="2Pj-ZL-FxO" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="aJ5-Rk-qcu"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="eyD-Iy-5pN" secondAttribute="trailing" id="bbE-PY-j4r"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="eyD-Iy-5pN" secondAttribute="trailing" id="bbE-PY-j4r"/>
<constraint firstAttribute="bottom" secondItem="w7f-wU-Eto" secondAttribute="bottom" id="clw-Ck-R1b"/>
<constraint firstItem="eyD-Iy-5pN" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="sGi-Ff-y6I"/> <constraint firstItem="eyD-Iy-5pN" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="sGi-Ff-y6I"/>
</constraints> </constraints>
<point key="canvasLocation" x="131" y="-12"/> <point key="canvasLocation" x="130.53435114503816" y="-12.67605633802817"/>
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="dengluye-login" width="402" height="465"/> <image name="BBBBBBBBBGo.png" width="402" height="874"/>
<image name="dengluye-login" width="402" height="402"/>
<image name="sp-10000h+" width="302" height="130"/>
<image name="sp-SpeakEasyLearning" width="318.66665649414062" height="67"/>
<systemColor name="systemBackgroundColor"> <systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor> </systemColor>
......
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xbG-3d-KMi"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xbG-3d-KMi">
<rect key="frame" x="0.0" y="0.0" width="272" height="60"/> <rect key="frame" x="0.0" y="0.0" width="272" height="60"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="yuanzhongqing@linkingplay.com" placeholder="E-mail address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="M4R-vQ-irk"> <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="E-mail address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="M4R-vQ-irk">
<rect key="frame" x="16" y="19" width="240" height="22"/> <rect key="frame" x="16" y="19" width="240" height="22"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
...@@ -141,7 +141,7 @@ ...@@ -141,7 +141,7 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="khn-vx-1Kx"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="khn-vx-1Kx">
<rect key="frame" x="0.0" y="142" width="272" height="60"/> <rect key="frame" x="0.0" y="142" width="272" height="60"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="666666" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="RcT-ZC-XJJ"> <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="RcT-ZC-XJJ">
<rect key="frame" x="16" y="19" width="190" height="22"/> <rect key="frame" x="16" y="19" width="190" height="22"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
......
...@@ -33,7 +33,8 @@ struct UserMode:Codable { ...@@ -33,7 +33,8 @@ struct UserMode:Codable {
var maxContinuousSignDays:Int? var maxContinuousSignDays:Int?
/// 当前签到 /// 当前签到
var currentContinuousSignDays:Int? var currentContinuousSignDays:Int?
/// 是否新用户
var newUser:Bool?
func isLogin() -> Bool { func isLogin() -> Bool {
return (self.token?.count ?? 0 > 0) return (self.token?.count ?? 0 > 0)
...@@ -55,7 +56,8 @@ struct UserMode:Codable { ...@@ -55,7 +56,8 @@ struct UserMode:Codable {
"learnedNative": \UserMode.learnedNative, "learnedNative": \UserMode.learnedNative,
"snowNum": \UserMode.snowNum, "snowNum": \UserMode.snowNum,
"maxContinuousSignDays": \UserMode.maxContinuousSignDays, "maxContinuousSignDays": \UserMode.maxContinuousSignDays,
"currentContinuousSignDays":\UserMode.currentContinuousSignDays "currentContinuousSignDays":\UserMode.currentContinuousSignDays,
"newUser":\UserMode.newUser
] ]
mutating func assign(from source: UserMode?) { mutating func assign(from source: UserMode?) {
...@@ -73,18 +75,6 @@ struct UserMode:Codable { ...@@ -73,18 +75,6 @@ struct UserMode:Codable {
break break
} }
} }
// let mirror = Mirror(reflecting: source)
// for child in mirror.children {
// if let key = child.label {
// // 使用键路径动态设置值
// if let value = child.value as? Int, let intKey = UserMode.keyPathMap[key] as? WritableKeyPath<UserMode, Int?> {
// self[keyPath: intKey] = value
// } else if let value = child.value as? String , let intKey = UserMode.keyPathMap[key] as? WritableKeyPath<UserMode, String?>{
// self[keyPath: intKey] = value
// }
// }
// }
} }
} }
...@@ -33,6 +33,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -33,6 +33,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
var isReStart = false var isReStart = false
var isMute = false var isMute = false
private var Translates = NSMutableSet() private var Translates = NSMutableSet()
let viewModel = SpeakDialogueViewModel() let viewModel = SpeakDialogueViewModel()
var dataLesssion:SpeakLessonDescpModel? var dataLesssion:SpeakLessonDescpModel?
...@@ -94,6 +95,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -94,6 +95,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
self.dataSource = viewModel.dialogLeassAsk self.dataSource = viewModel.dialogLeassAsk
self.SpeakLeassonTableView.reloadData() self.SpeakLeassonTableView.reloadData()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.tipsAnimateFinish()
self.scrollTop() self.scrollTop()
} }
} }
...@@ -111,6 +113,10 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -111,6 +113,10 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
vc.show() vc.show()
} }
} }
SpeakVideoPPPPPP.addSubview(SpeakAIVideoPlayManager.share)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
SpeakAIVideoPlayManager.share.PlayBg()
}
} }
override func setup() { override func setup() {
...@@ -126,21 +132,12 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -126,21 +132,12 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogLoadingCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogLoadingCell.id) SpeakLeassonTableView.register(UINib(nibName: SpeakDialogLoadingCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogLoadingCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIReviewCell.id) SpeakLeassonTableView.register(UINib(nibName: SpeakDialogAIReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogAIReviewCell.id)
SpeakLeassonTableView.register(UINib(nibName: SpeakDialogQuReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogQuReviewCell.id) SpeakLeassonTableView.register(UINib(nibName: SpeakDialogQuReviewCell.id, bundle: nil), forCellReuseIdentifier: SpeakDialogQuReviewCell.id)
if let ai = SpeakAIVideoPlayManager.share.SpeakAI.SpeakPlayerLayer ,
let bg = SpeakAIVideoPlayManager.share.backgoundAI.SpeakPlayerLayer {
self.SpeakVideoPPPPPP.layer.addSublayer(ai)
ai.videoGravity = .resizeAspectFill
self.SpeakVideoPPPPPP.layer.addSublayer(bg)
bg.videoGravity = .resizeAspectFill
SpeakAIVideoPlayManager.share.PlayBg()
}
} }
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
SpeakContentView.cornerRect(radius: 16, [.topLeft,.topRight]) SpeakContentView.cornerRect(radius: 16, [.topLeft,.topRight])
SpeakAIVideoPlayManager.share.SpeakAI.SpeakPlayerLayer?.frame = self.SpeakVideoPPPPPP.bounds SpeakAIVideoPlayManager.share.frame = self.SpeakVideoPPPPPP.bounds
SpeakAIVideoPlayManager.share.backgoundAI.SpeakPlayerLayer?.frame = self.SpeakVideoPPPPPP.bounds
} }
@IBAction func SpeakFavatorTaps(_ sender: UIButton) { @IBAction func SpeakFavatorTaps(_ sender: UIButton) {
...@@ -150,7 +147,13 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -150,7 +147,13 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
@IBAction func SoundTapCloseTaps(_ sender: UIButton) { @IBAction func SoundTapCloseTaps(_ sender: UIButton) {
sender.isSelected = !sender.isSelected sender.isSelected = !sender.isSelected
isMute = sender.isSelected
AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1) AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
for (i,_) in self.dataSource.enumerated() {
if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
cell.isMute = isMute
}
}
} }
...@@ -163,14 +166,16 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -163,14 +166,16 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
b == true{ b == true{
self?.didddd.isPaused = true self?.didddd.isPaused = true
self?.didddd.invalidate() self?.didddd.invalidate()
self?.display.isPaused = true
self?.display.invalidate() self?.display.invalidate()
//FIXME: test SpeakAIVideoPlayManager.share.removeFromSuperview()
SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = 600 //self?.studyTm SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm = self?.studyTm
SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime SpeakDayEveryManager.manager.SpeakDayData.studytime = self?.studyTime
SpeakDayEveryManager.manager.update() SpeakDayEveryManager.manager.update()
if let call = self?.view.callblack { if let call = self?.view.callblack {
call(self?.isSing) call(self?.isSing)
} }
AudioPlayerManager.shared.stop()
self?.navigationController?.popViewController(animated: true) self?.navigationController?.popViewController(animated: true)
} }
} }
...@@ -219,6 +224,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -219,6 +224,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
self?.isMute = isMate self?.isMute = isMate
self?.dataSource = self?.viewModel.dialogLeassAsk ?? [] self?.dataSource = self?.viewModel.dialogLeassAsk ?? []
self?.scrollTop() self?.scrollTop()
self?.tipsAnimateFinish()
} }
} }
self?.navigationController?.pushViewController(call, animated: true) self?.navigationController?.pushViewController(call, animated: true)
...@@ -236,16 +242,9 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr { ...@@ -236,16 +242,9 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
return input return input
}() }()
override func viewWillDisappear(_ animated: Bool) { override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated) super.viewWillDisappear(animated)
} SpeakAIVideoPlayManager.share.stop()
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.display.isPaused = true
self.didddd.isPaused = true
AudioPlayerManager.shared.stop()
} }
private lazy var didddd: CADisplayLink = { private lazy var didddd: CADisplayLink = {
...@@ -277,7 +276,7 @@ extension SpeakDialogueViewCtr { ...@@ -277,7 +276,7 @@ extension SpeakDialogueViewCtr {
private func tipsAnimateFinish() { private func tipsAnimateFinish() {
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
if let last = self.dataSource.last, if let last = self.dataSource.last,
last.AniState == .loading, last.AniState == .loading,
last.role == .AI { last.role == .AI {
......
...@@ -120,7 +120,7 @@ class SpeakDialogueViewModel: NSObject { ...@@ -120,7 +120,7 @@ class SpeakDialogueViewModel: NSObject {
let idx = SpeakElePublicManager.share.PublicData.AIerIndex let idx = SpeakElePublicManager.share.PublicData.AIerIndex
let airs = SpeakHomeViewModel().AIser()[safe: idx] let airs = SpeakHomeViewModel().AIser()[safe: idx]
let vodioID = airs?.voiceId let vodioID = airs?.voiceId
net.SpeakAILeasson(param: ["lessonId":lessonId,"isReStart":isReStart ,"userAnswer":userAnswer, "isSub":/*IAPViewModel.share.isSubscribed*/true ,"voiceId":vodioID]) {[weak self] ( su ,data:SpeakdialogueTalkModel?) in net.SpeakAILeasson(param: ["lessonId":lessonId,"isReStart":isReStart ,"userAnswer":userAnswer, "isSub":IAPViewModel.share.isSubscribed ,"voiceId":vodioID]) {[weak self] ( su ,data:SpeakdialogueTalkModel?) in
if su { if su {
self?.isSpeech = true self?.isSpeech = true
if var setD = data, if var setD = data,
......
//
// SpeakAutoLayout.swift
// SpeakEasyLearnEnglish
//
// Created by edy on 2025/9/3.
//
import UIKit
class SpeakAutoLayout: NSLayoutConstraint {
static private let standardHeight: CGFloat = 874
override func awakeFromNib() {
super.awakeFromNib()
updateConstant()
}
private func updateConstant() {
let screenHeight = UIScreen.main.bounds.height
guard SpeakAutoLayout.standardHeight.isFinite && screenHeight.isFinite else {
self.constant = 0
return
}
let calculatedConstant = (screenHeight / SpeakAutoLayout.standardHeight) * self.constant
if calculatedConstant.isFinite {
self.constant = calculatedConstant
} else {
self.constant = 0
}
}
}
...@@ -7,48 +7,73 @@ ...@@ -7,48 +7,73 @@
import UIKit import UIKit
class SpeakAIVideoPlayManager: NSObject { class SpeakAIVideoPlayManager: UIView {
static let share = SpeakAIVideoPlayManager() static let share = SpeakAIVideoPlayManager()
var backgoundAI = SpeakVideoPlayer() private var backgoundAI = SpeakVideoPlayer()
var SpeakAI = SpeakVideoPlayer() private var SpeakAI = SpeakVideoPlayer()
private override init() { private override init(frame: CGRect) {
super.init() super.init(frame: frame)
self.loadVideo()
NotificationCenter.default.addObserver(self, selector: #selector(Foreground), name: UIApplication.willEnterForegroundNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(Foreground), name: UIApplication.willEnterForegroundNotification, object: nil)
SpeakAI.PlayFinish = { [weak self] in SpeakAI.PlayFinish = { [weak self] in
self?.PlayBg() self?.PlayBg()
} }
} }
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func Foreground() -> Void { @objc private func Foreground() -> Void {
PlayBg() PlayBg()
} }
func loadVideo() -> Void { func loadVideo() -> Void {
self.layer.sublayers?.forEach({$0.removeFromSuperlayer()})
backgoundAI.loadVideo(state: .none) backgoundAI.loadVideo(state: .none)
SpeakAI.loadVideo(state: .runloop) SpeakAI.loadVideo(state: .runloop)
if let bg = backgoundAI.SpeakPlayerLayer,
let ai = SpeakAI.SpeakPlayerLayer{
self.layer.insertSublayer(bg, at: 10)
self.layer.insertSublayer(ai, at: 15)
Print("添加AI动画成功")
}
} }
func PlaySpeak(_ duration:Double) -> Void { func PlaySpeak(_ duration:Double) -> Void {
SpeakAI.SpeakPlayerLayer?.zPosition = 1 SpeakAI.SpeakPlayerLayer?.zPosition = 15
backgoundAI.stop()
backgoundAI.SpeakPlayerLayer?.zPosition = 0 backgoundAI.SpeakPlayerLayer?.zPosition = 10
backgoundAI.play()
let vduration = SpeakAI.duration let vduration = SpeakAI.duration
let count = ceil(duration / vduration) let count = ceil(duration / vduration)
let rate = (count*vduration)/duration + 0.03 let rate = (count*vduration)/duration + 0.03
SpeakAI.videoPlayer(rate, playCount: Int(count)) SpeakAI.videoPlayer(rate, playCount: Int(count))
} }
func PlayBg() -> Void { func PlayBg() -> Void {
SpeakAI.SpeakPlayerLayer?.zPosition = 0 SpeakAI.SpeakPlayerLayer?.zPosition = 10
SpeakAI.play()
backgoundAI.SpeakPlayerLayer?.zPosition = 15
backgoundAI.play()
}
override func layoutSubviews() {
super.layoutSubviews()
self.layoutIfNeeded()
SpeakAI.SpeakPlayerLayer?.frame = self.bounds
backgoundAI.SpeakPlayerLayer?.frame = self.bounds
}
func stop() -> Void {
SpeakAI.stop() SpeakAI.stop()
backgoundAI.videoPlayer() backgoundAI.stop()
backgoundAI.SpeakPlayerLayer?.zPosition = 1
} }
} }
...@@ -18,17 +18,16 @@ class SpeakVideoPlayer { ...@@ -18,17 +18,16 @@ class SpeakVideoPlayer {
var SpeakPlayer:AVPlayer? var SpeakPlayer:AVPlayer?
var SpeakPlayerLayer:AVPlayerLayer? var SpeakPlayerLayer:AVPlayerLayer?
var SpeakPlayCount:Int = 0 private var SpeakPlayCount:Int = 0
var SpeakCurrentPlay:Int = 0 private var SpeakCurrentPlay:Int = 0
var duration:Double = 1 var duration:Double = 1
var PlayFinish:(()->Void)? var PlayFinish:(()->Void)?
open func videoPlayer(_ rate:Double = 1 , playCount:Int = 0) -> Void { open func videoPlayer(_ rate:Double = 1 , playCount:Int = 0) -> Void {
self.stop()
SpeakPlayCount = playCount SpeakPlayCount = playCount
SpeakCurrentPlay = 0 SpeakCurrentPlay = 0
SpeakPlayer?.play()
DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
self.play()
self.SpeakPlayer?.rate = Float(rate) self.SpeakPlayer?.rate = Float(rate)
} }
} }
...@@ -47,21 +46,16 @@ class SpeakVideoPlayer { ...@@ -47,21 +46,16 @@ class SpeakVideoPlayer {
} }
} }
// 初始化多个视频播放器
private func setupPlayers(videoURL: URL) { private func setupPlayers(videoURL: URL) {
let asset = AVAsset(url: videoURL)
let playerItem = AVPlayerItem(url: videoURL) let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem) let player = AVPlayer(playerItem: playerItem)
self.SpeakPlayer = player self.SpeakPlayer = player
let playerLayer = AVPlayerLayer(player: player) let playerLayer = AVPlayerLayer(player: self.SpeakPlayer)
playerLayer.videoGravity = .resizeAspectFill playerLayer.videoGravity = .resizeAspectFill
playerLayer.shouldRasterize = true playerLayer.shouldRasterize = true
playerLayer.rasterizationScale = UIScreen.main.nativeScale playerLayer.rasterizationScale = UIScreen.main.nativeScale
self.SpeakPlayerLayer = playerLayer self.SpeakPlayerLayer = playerLayer
playerItem.preferredPeakBitRate = 1
let asset = AVAsset(url: videoURL)
asset.loadValuesAsynchronously(forKeys: ["duration"]) { [weak self] in asset.loadValuesAsynchronously(forKeys: ["duration"]) { [weak self] in
DispatchQueue.main.async { DispatchQueue.main.async {
var error: NSError? var error: NSError?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment