Browse Source

[Update] Slider in home screen

v0.17
Dibya Malla 2 years ago
parent
commit
cea0925672
  1. 12
      GME Remit.xcodeproj/project.pbxproj
  2. 11
      GME Remit/Extensions/String+Ext.swift
  3. 67
      GME Remit/Modules/Home/User Interface/View/Cell/CarouselCell.swift
  4. 207
      GME Remit/Modules/Home/User Interface/View/Custom/HomeCarouselView.swift
  5. 51
      GME Remit/Modules/Home/User Interface/View/Custom/HomeExchangeRateView.swift
  6. 2
      GME Remit/Modules/Home/User Interface/View/Home.storyboard
  7. 14
      GME Remit/Modules/Home/User Interface/View/HomeViewController.swift
  8. 21
      GME Remit/Supported Files/Assets.xcassets/exchangeRateButton.imageset/Contents.json
  9. 10
      GME Remit/Supported Files/Assets.xcassets/exchangeRateButton.imageset/exchangeRateButton.svg
  10. 130
      GME Remit/Utilities/CustomUI/CustomPageControl.swift
  11. 9
      GME Remit/Utilities/ExchangeRateCustomView.swift

12
GME Remit.xcodeproj/project.pbxproj

@ -44,6 +44,9 @@
2454866D29BA2AE60065E1DD /* volte-lightitalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2454866329BA2AE60065E1DD /* volte-lightitalic.otf */; };
2454866E29BA2AE60065E1DD /* volte-semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2454866429BA2AE60065E1DD /* volte-semibold.otf */; };
2454866F29BA2AE60065E1DD /* volte-regularitalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2454866529BA2AE60065E1DD /* volte-regularitalic.otf */; };
247222DE29C7419800732E55 /* HomeCarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 247222DD29C7419800732E55 /* HomeCarouselView.swift */; };
247222E029C7425700732E55 /* CarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 247222DF29C7425700732E55 /* CarouselCell.swift */; };
247222E529C74AE600732E55 /* CustomPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 247222E429C74AE600732E55 /* CustomPageControl.swift */; };
247A601629B4428500922B7F /* CustomTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 247A601529B4428500922B7F /* CustomTabBar.swift */; };
24A4502029B831EF0049CE29 /* HomeExchangeRateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A4501F29B831EF0049CE29 /* HomeExchangeRateView.swift */; };
24A4502229B83A710049CE29 /* HomeExchangeRateCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A4502129B83A710049CE29 /* HomeExchangeRateCollectionViewCell.swift */; };
@ -878,6 +881,9 @@
2454866329BA2AE60065E1DD /* volte-lightitalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "volte-lightitalic.otf"; sourceTree = "<group>"; };
2454866429BA2AE60065E1DD /* volte-semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "volte-semibold.otf"; sourceTree = "<group>"; };
2454866529BA2AE60065E1DD /* volte-regularitalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "volte-regularitalic.otf"; sourceTree = "<group>"; };
247222DD29C7419800732E55 /* HomeCarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCarouselView.swift; sourceTree = "<group>"; };
247222DF29C7425700732E55 /* CarouselCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselCell.swift; sourceTree = "<group>"; };
247222E429C74AE600732E55 /* CustomPageControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPageControl.swift; sourceTree = "<group>"; };
247A601529B4428500922B7F /* CustomTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabBar.swift; sourceTree = "<group>"; };
24A4501F29B831EF0049CE29 /* HomeExchangeRateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeExchangeRateView.swift; sourceTree = "<group>"; };
24A4502129B83A710049CE29 /* HomeExchangeRateCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeExchangeRateCollectionViewCell.swift; sourceTree = "<group>"; };
@ -1847,6 +1853,7 @@
children = (
244C69B629B7A01600D7B69A /* HomeAccountDetailView.swift */,
24A4501F29B831EF0049CE29 /* HomeExchangeRateView.swift */,
247222DD29C7419800732E55 /* HomeCarouselView.swift */,
);
path = Custom;
sourceTree = "<group>";
@ -3333,6 +3340,7 @@
7384B27F22CB375400DD04D9 /* GMEAlert */,
4099AF0025235C45003FA012 /* CircleBorderedView.swift */,
4073BA9125295F5B0043258E /* GradientView.swift */,
247222E429C74AE600732E55 /* CustomPageControl.swift */,
);
path = CustomUI;
sourceTree = "<group>";
@ -6083,6 +6091,7 @@
D9AFE855215C7166005F3A25 /* HomeCollectionTableViewCell.swift */,
D923EBB8215C7421008A3026 /* HomeCollectionCollectionViewCell.swift */,
24A4502129B83A710049CE29 /* HomeExchangeRateCollectionViewCell.swift */,
247222DF29C7425700732E55 /* CarouselCell.swift */,
);
path = Cell;
sourceTree = "<group>";
@ -7653,6 +7662,7 @@
D95B5E4121311057000C0B33 /* GmeContactsViewInterface.swift in Sources */,
73157BA022DC1EEC009B836F /* PopupNotificationPresenter.swift in Sources */,
73157BA322DC1EEC009B836F /* PopupNotificationViewInterface.swift in Sources */,
247222DE29C7419800732E55 /* HomeCarouselView.swift in Sources */,
7388A6D822E17F9400A57891 /* CountryEnum.swift in Sources */,
D97785A6215DC55F00754079 /* TransactionHistoryViewController.swift in Sources */,
40218EFB24D2B1940047FBF5 /* UserRegistrationInteractor.swift in Sources */,
@ -7721,6 +7731,7 @@
73FBBF2C23F231A8009D7627 /* DetailNotificationViewController.swift in Sources */,
D9DC107A21639078008F3C51 /* MessageComposeService.swift in Sources */,
7EDBFBFE24B3031B00AD5D4D /* WithdrawFromWalletModuleInterface.swift in Sources */,
247222E029C7425700732E55 /* CarouselCell.swift in Sources */,
73FBBF2623F231A8009D7627 /* DetailNotificationInteractor.swift in Sources */,
28AB139B28E552C200191695 /* NotificationDetailViewController.swift in Sources */,
D96A4FD521460B4A00CFD507 /* SplashScreenService.swift in Sources */,
@ -8151,6 +8162,7 @@
7318534E230EACA400BA9AE3 /* SendMoneyTransFerReasonViewModel.swift in Sources */,
281EF60528ACCC4D0092E5E6 /* HowToDepositPresenter.swift in Sources */,
73195ABB22FD14D500151434 /* SetupRecipientViewModelInterface.swift in Sources */,
247222E529C74AE600732E55 /* CustomPageControl.swift in Sources */,
7389601922C2FADD003FEA90 /* TableCell.swift in Sources */,
D92B802A2140C3CB00A25B26 /* MainPresenter.swift in Sources */,
738714B4237CE86E0038FCB1 /* InboundReceiptServiceType.swift in Sources */,

11
GME Remit/Extensions/String+Ext.swift

@ -7,6 +7,7 @@
//
import Foundation
import UIKit
enum CurrencyType {
case usd
@ -128,3 +129,13 @@ extension String{
return predicate.evaluate(with: self)
}
}
extension String {
func attributedText(color: UIColor, font: UIFont) -> NSMutableAttributedString {
let range = (self as NSString).range(of: self)
let attributedString = NSMutableAttributedString(string:self)
attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range)
attributedString.addAttribute(NSAttributedString.Key.font, value: font, range: range)
return attributedString
}
}

67
GME Remit/Modules/Home/User Interface/View/Cell/CarouselCell.swift

@ -0,0 +1,67 @@
//
import Foundation
import UIKit
import SDWebImage
class CarouselCollectionCell: UICollectionViewCell{
static let identifier: String = "CarouselCollectionCellID"
private let backgroundImgView: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let containerView: UIView = {
let view = UIView()
view.backgroundColor = .clear
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let titleLabel: UILabel = {
let view = UILabel()
view.font = UIFont.sanfrancisco(.bold, size: 21)
view.textColor = .themeWhite
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setup(){
containerView.backgroundColor = .blue
containerView.layer.cornerRadius = 10
containerView.clipsToBounds = true
contentView.addSubview(containerView)
containerView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16).isActive = true
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16).isActive = true
containerView.addSubview(backgroundImgView)
backgroundImgView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
backgroundImgView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
backgroundImgView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
backgroundImgView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
}
func update(_ event: String){
DispatchQueue.main.async {
//let imageUrl = UrlManager.sharedInstance.baseImageUrl + "/" + "\(event.imageUrl ?? "")"
self.backgroundImgView.sd_setImage(with: URL(string: event), placeholderImage: UIImage(named: "flag_bahamas"))
}
}
}

207
GME Remit/Modules/Home/User Interface/View/Custom/HomeCarouselView.swift

@ -0,0 +1,207 @@
//
import Foundation
import UIKit
class HomeCarouselView: UIView {
private var events: [String] = []
private var timer: Timer?
private let collectionView: UICollectionView = {
let flowlayout = UICollectionViewFlowLayout()
flowlayout.scrollDirection = .horizontal
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: flowlayout)
view.register(CarouselCollectionCell.self, forCellWithReuseIdentifier: CarouselCollectionCell.identifier)
view.backgroundColor = .white
view.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
view.showsHorizontalScrollIndicator = false
view.translatesAutoresizingMaskIntoConstraints = false
view.isPagingEnabled = true
return view
}()
private let pageControl: CustomPageControl = {
let view = CustomPageControl(frame: .zero)
view.currentPageIndicatorTintColor = .theme2E89FF
view.pageIndicatorTintColor = .themeGray2
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
static let identifier: String = "HomeCarouselCellID"
/// whether or not dragging has ended
fileprivate var endDragging = false
/// the current page
@objc open dynamic var currentIndex: Int = 0 {
didSet {
updateAccessoryViews()
}
}
func updateAccessoryViews() {
pageControl.currentPage = currentIndex
}
override init(frame: CGRect) {
super.init(frame: .zero)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup(){
self.backgroundColor = .themeWhite
self.addSubview(pageControl)
pageControl.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
pageControl.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
pageControl.heightAnchor.constraint(equalToConstant: 30).isActive = true
self.addSubview(collectionView)
collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
collectionView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: pageControl.topAnchor, constant: 0).isActive = true
collectionView.delegate = self
collectionView.dataSource = self
}
override open func layoutSubviews() {
super.layoutSubviews()
collectionView.performBatchUpdates(nil, completion: nil)
moveToPage(currentIndex, animated: false)
}
open func moveToPage(_ page: Int, animated: Bool) {
// outside the range
if page < 0 || page >= collectionView.numberOfItems(inSection: 0) {
return
}
currentIndex = page
collectionView.scrollToItem(at: IndexPath(item: currentIndex, section: 0),
at: .left, animated: animated)
}
func update(_ events: [String]){
self.events = events
pageControl.numberOfPages = events.count
self.collectionView.reloadData()
stopTimer()
startTimer()
}
/**
Scroll to Next Cell
*/
@objc func scrollToNextCell(){
let nextpage = self.currentIndex + 1
if nextpage >= self.events.count{
moveToPage(0, animated: true)
}else{
moveToPage(nextpage, animated: true)
}
}
/**
Invokes Timer to start Automatic Animation with repeat enabled
*/
private func startTimer() {
self.timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(self.scrollToNextCell), userInfo: nil, repeats: true)
}
private func stopTimer(){
self.timer?.invalidate()
self.timer = nil
}
}
//MARK:- UICollectionViewDelegate
extension HomeCarouselView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CarouselCollectionCell.identifier, for: indexPath) as! CarouselCollectionCell
cell.update(self.events[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.events.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.001
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.001
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//self.didSelect?(self.events[indexPath.row])
}
/**
size of the collection view
- parameter collectionView: the collection view
- parameter collectionViewLayout: the collection view flow layout
- parameter indexPath: the index path
*/
// public func collectionView(_ collectionView: UICollectionView,
// layout collectionViewLayout: UICollectionViewLayout,
// sizeForItemAt indexPath: IndexPath) -> CGSize {
// return collectionView.bounds.size
// }
/**
scroll view did end dragging
- parameter scrollView: the scroll view
- parameter decelerate: wether the view is decelerating or not.
*/
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
endScrolling(scrollView)
} else {
endDragging = true
}
}
/**
Scroll view did end decelerating
*/
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if endDragging {
endDragging = false
endScrolling(scrollView)
}
}
/**
end scrolling
*/
fileprivate func endScrolling(_ scrollView: UIScrollView) {
let width = scrollView.bounds.width
let page = (scrollView.contentOffset.x + (0.5 * width)) / width
currentIndex = Int(page)
self.stopTimer()
self.startTimer()
}
}

51
GME Remit/Modules/Home/User Interface/View/Custom/HomeExchangeRateView.swift

@ -75,6 +75,14 @@ class HomeExchangeRateView: UIView {
return button
}()
private let exchangeButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.heightAnchor.constraint(equalToConstant: 32).isActive = true
button.widthAnchor.constraint(equalToConstant: 32).isActive = true
return button
}()
//exRate
private var transferFeeIncluded: UIStackView!
@ -140,6 +148,7 @@ class HomeExchangeRateView: UIView {
containerView.addSubviews(collectionView,
sendMoneyView,
exchangeButton,
recivedMoneyView,
transferFeeIncluded,
guranteedView,
@ -172,6 +181,14 @@ class HomeExchangeRateView: UIView {
paddingRight: 0
)
exchangeButton.anchor(top: sendMoneyView.bottomAnchor,
paddingTop: -8,
bottom: recivedMoneyView.topAnchor,
paddingBottom: 8,
left: sendMoneyView.leadingAnchor,
paddingLeft: 16)
transferFeeIncluded.anchor(
top: recivedMoneyView.bottomAnchor,
paddingTop: 16,
@ -221,6 +238,14 @@ class HomeExchangeRateView: UIView {
recivedMoneyView.set(borderWidth: 2, of: .black)
recivedMoneyView.set(cornerRadius: 10)
recivedMoneyView.title = "receipient_gets_text".localized()
exchangeButton.setTitle("", for: .normal)
exchangeButton.setImage(UIImage(named: "exchangeRateButton"), for: .normal)
exchangeButton.layer.cornerRadius = 10
exchangeButton.backgroundColor = .themeGray1
exchangeButton.layer.borderWidth = 2
exchangeButton.layer.borderColor = UIColor.black.cgColor
}
func textChanged() {
@ -249,11 +274,35 @@ class HomeExchangeRateView: UIView {
func set(_ model: ExchangeRateDetailModel?) {
guard let model = model else {
return
return
}
sendMoneyView.updatedText = model.senderAmount?.likeCommaMoney()
recivedMoneyView.updatedText = model.recipientAmount?.likeCommaMoney()
let transferFee = ("\(model.transferFee?.likeCommaMoney() ?? "" ) JPY ")
.attributedText(color: .themeBlack, font: .sanfrancisco(.semibold, size: 14))
let transferInfo = "transfer_fee_included_text".localized().attributedText(color: .theme2E89FF, font: .sanfrancisco(.semibold, size: 14))
let transfer = NSMutableAttributedString()
transfer.append(transferFee)
transfer.append(transferInfo)
transferFeeIncludedText.attributedText = transfer
let exchangeRate = model.exchangeRate ?? ""
let exchangeRateAttributed = ("1000 JPY = \(exchangeRate) \(selectedExchangeRateModel?.currency ?? "") ").attributedText(color: .themeBlack, font: .sanfrancisco(.semibold, size: 14))
let exchangeRateInfo = ("Guranteed rate for 24 hr").attributedText(color: .theme2E89FF, font: .sanfrancisco(.semibold, size: 14))
let gurrantedText = NSMutableAttributedString()
gurrantedText.append(exchangeRateAttributed)
gurrantedText.append(exchangeRateInfo)
guranteedRateText.attributedText = gurrantedText
}
func set(_ model: ExchangeRateModel?) {

2
GME Remit/Modules/Home/User Interface/View/Home.storyboard

@ -239,7 +239,7 @@
<tabBarItem key="tabBarItem" title="Home" image="branch" id="If6-UM-LN6"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="NbY-y6-481">
<rect key="frame" x="0.0" y="0.0" width="320" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>

14
GME Remit/Modules/Home/User Interface/View/HomeViewController.swift

@ -46,7 +46,14 @@ class HomeViewController: UIViewController {
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let homeCarouselView: HomeCarouselView = {
let view = HomeCarouselView()
view.translatesAutoresizingMaskIntoConstraints = false
view.heightAnchor.constraint(equalToConstant: 132).isActive = true
return view
}()
@IBOutlet weak var accountDetailView: UIView!
@IBOutlet weak var notificationItem: UIBarButtonItem!
@ -321,6 +328,8 @@ class HomeViewController: UIViewController {
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(exchangeRateView)
stackView.addArrangedSubview(homeCarouselView)
exchangeRateView.openCountryList = { [weak self] in
self?.showCountryList()
}
@ -428,7 +437,7 @@ class HomeViewController: UIViewController {
walletNumberLabel.text = walletNumber == "" ? "N/A" : walletNumber
copyButton.setTitle("", for: .normal)
mainContainerView.setupCornerRadius(20,maskedCorners: [.layerMinXMaxYCorner, .layerMaxXMaxYCorner])
userName.title = "HI" + " " + (GMEDB.shared.user.string(.userId) ?? "")
userName.title = " HI Rabin"//"HI" + " " + (GMEDB.shared.user.string(.userId) ?? "")
}
private func configureText() {
@ -760,6 +769,7 @@ extension HomeViewController: HomeViewInterface {
func setModel(with model: ExchangeRateDetailModel?) {
self.exchangeRateDetailModel = model
self.exchangeRateView.set(model)
self.homeCarouselView.update(["test1", "test2", "test3671"])
//reload(0, Sections.collection.rawValue)
}

21
GME Remit/Supported Files/Assets.xcassets/exchangeRateButton.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "exchangeRateButton.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

10
GME Remit/Supported Files/Assets.xcassets/exchangeRateButton.imageset/exchangeRateButton.svg

@ -0,0 +1,10 @@
<svg id="_24px_43_" data-name="24px (43)" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path id="Path_1000" data-name="Path 1000" d="M0,0H20V20H0Z" fill="none"/>
<g id="icons8-up-down-arrow" transform="translate(0.799 1.587)">
<path id="Path_38524" data-name="Path 38524" d="M.694,0A.693.693,0,0,0,.2,1.181l3.081,3.11a1,1,0,0,0,1.424,0l3.081-3.11A.693.693,0,0,0,7.3,0Z" transform="translate(10.413 12.022)"/>
<path id="Path_38525" data-name="Path 38525" d="M3.2,7.19V1.6A1.6,1.6,0,0,0,0,1.6V7.19Z" transform="translate(12.81 5.255)"/>
<circle id="Ellipse_1881" data-name="Ellipse 1881" cx="1.5" cy="1.5" r="1.5" transform="translate(12.457)"/>
<path id="Path_38526" data-name="Path 38526" d="M7.787,3.407,4.707.3A1,1,0,0,0,3.283.3L.2,3.407A.693.693,0,0,0,.694,4.588H2.4V9.381a1.6,1.6,0,0,0,3.2,0V4.588H7.3A.693.693,0,0,0,7.787,3.407Z" transform="translate(0 0.217)" opacity="0.35"/>
<circle id="Ellipse_1882" data-name="Ellipse 1882" cx="1.5" cy="1.5" r="1.5" transform="translate(2.947 13.826)" opacity="0.35"/>
</g>
</svg>

130
GME Remit/Utilities/CustomUI/CustomPageControl.swift

@ -0,0 +1,130 @@
//
import Foundation
import UIKit
@IBDesignable
class CustomPageControl: UIControl {
//MARK:- Properties
private var numberOfDots = [UIView]() {
didSet{
if numberOfDots.count == numberOfPages {
setupViews()
}
}
}
@IBInspectable var numberOfPages: Int = 0 {
didSet{
for tag in 0 ..< numberOfPages {
let dot = getDotView()
dot.tag = tag
dot.backgroundColor = pageIndicatorTintColor
self.numberOfDots.append(dot)
}
}
}
var currentPage: Int = 0 {
didSet{
onPageControlSwipe()
}
}
@IBInspectable var pageIndicatorTintColor: UIColor? = .blue
@IBInspectable var currentPageIndicatorTintColor: UIColor? = .green
private lazy var stackView = UIStackView.init(frame: self.bounds)
private lazy var constantSpace = ((stackView.spacing) * CGFloat(numberOfPages - 1) + ((self.bounds.height * 0.45) * CGFloat(numberOfPages)) - self.bounds.width)
override var bounds: CGRect {
didSet{
self.numberOfDots.forEach { (dot) in
self.setupDotAppearance(dot: dot)
}
}
}
//MARK:- Intialisers
convenience init() {
self.init(frame: .zero)
}
init(withNoOfPages pages: Int) {
self.numberOfPages = pages
self.currentPage = 0
super.init(frame: .zero)
setupViews()
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupViews() {
self.numberOfDots.forEach { (dot) in
self.stackView.addArrangedSubview(dot)
}
stackView.alignment = .center
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(stackView)
self.addConstraints([
stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
stackView.heightAnchor.constraint(equalTo: self.heightAnchor),
])
self.numberOfDots.forEach { dot in
self.addConstraints([
dot.centerYAnchor.constraint(equalTo: self.stackView.centerYAnchor),
dot.widthAnchor.constraint(equalToConstant: 7),
dot.heightAnchor.constraint(equalToConstant: 7),
])
}
self.numberOfDots.forEach { dot in
dot.layer.cornerRadius = dot.bounds.height / 2
}
}
@objc private func onPageControlSwipe() {
_ = numberOfDots.map { (dot) in
setupDotAppearance(dot: dot)
if dot.tag == currentPage {
UIView.animate(withDuration: 0.2, animations: {
dot.layer.cornerRadius = dot.bounds.height / 5
dot.transform = CGAffineTransform.init(scaleX: 2, y: 1)
dot.backgroundColor = self.currentPageIndicatorTintColor
})
}
}
}
//MARK: Helper methods...
private func getDotView() -> UIView {
let dot = UIView()
self.setupDotAppearance(dot: dot)
dot.translatesAutoresizingMaskIntoConstraints = false
return dot
}
private func setupDotAppearance(dot: UIView) {
dot.transform = .identity
dot.layer.cornerRadius = dot.bounds.height / 2
dot.layer.masksToBounds = true
dot.backgroundColor = pageIndicatorTintColor
}
}

9
GME Remit/Utilities/ExchangeRateCustomView.swift

@ -35,6 +35,7 @@ class ExchangeRateCustomView: UIView {
private var textfield: CurrencyTextField = {
let textfield = CurrencyTextField()
textfield.tintColor = .theme2E89FF
textfield.textColor = .init(hex: "#2E89FF").withAlphaComponent(0.87)
textfield.font = .sanfrancisco(.semibold, size: 16)
textfield.translatesAutoresizingMaskIntoConstraints = false
@ -124,6 +125,9 @@ class ExchangeRateCustomView: UIView {
paddingY: 0)
rightStackView.leadingAnchor.constraint(greaterThanOrEqualTo: leftStackView.trailingAnchor, constant: 8).isActive = true
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
leftStackView.addGestureRecognizer(tap)
}
@ -136,6 +140,7 @@ class ExchangeRateCustomView: UIView {
titleLabel.textColor = .themeBlack.withAlphaComponent(0.6)
titleLabel.font = .sanfrancisco(.semibold, size: 14)
if(isReciver) {
countryListTapGuesture = UITapGestureRecognizer(target: self, action: #selector(showCurrencyCountryPickerview))
rightStackView.addGestureRecognizer(countryListTapGuesture ?? UITapGestureRecognizer())
@ -144,6 +149,10 @@ class ExchangeRateCustomView: UIView {
}
}
@objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
textfield.becomeFirstResponder()
}
@objc private func showCurrencyCountryPickerview() {
didSelectCountry?()
}

Loading…
Cancel
Save