I am trying to change the label that you see in my screenshot that has a green background and says We Are Open.
I would like the bottom label to turn RED and say "Sorry we are closed" whenever the listed opening times have passed and then go back to GREEN and say "We Are Open" at the correct opening times.
I've managed to import date and time successfully into the top label but I'm not sure how do the bottom label.
Here is the code:
import UIKit
import Firebase
import FirebaseInstanceID
import FirebaseMessaging
class FirstViewController: UIViewController {
var timer = Timer()
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var openStatusLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
FIRMessaging.messaging().subscribe(toTopic: "/topics/news")
self.timer = Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(FirstViewController.tick),
userInfo: nil,
repeats: true)
}
#objc func tick() {
timeLabel.text = DateFormatter.localizedString(from: NSDate() as Date,
dateStyle: .medium,
timeStyle: .medium)
}
}
Below code i have try and it will work fine. Initially i created two UILabel with proper constraints. Then Create outlets for two label to view controller. Then try this code.
import UIKit
extension NSDate {
func dayOfWeek() -> Int? {
guard
let calender: NSCalendar = NSCalendar.currentCalendar(),
let component: NSDateComponents = calender.components(.Weekday, fromDate: self) else { return nil }
return component.weekday
}
}
class ViewController: UIViewController {
#IBOutlet var timeOfTheDay: UILabel! //Top Label for showing current time
#IBOutlet var Status: UILabel! //Status Label for showing open or close
override func viewDidLoad() {
super.viewDidLoad()
self.dateCheck()
}
func dateCheck()
{
let today = NSDate().dayOfWeek()
if today == 1
{
//print("Sunday")
self.closed()
}
else if today == 2
{
//print("Monday")
self.closed()
}
else if today == 3
{
//print("Tuesday")
self.uptoEvening()
}
else if today == 4
{
//print("Wednesday")
self.uptoNight()
}
else if today == 5
{
// print("Thursday")
self.uptoNight()
}
else if today == 6
{
//print("Friday")
self.uptoNight()
}
else
{
//print("Saturday")
self.uptoEvening()
}
}
func getTime() -> (hour:Int, minute:Int, second:Int) {
let currentDateTime = NSDate()
let calendar = NSCalendar.currentCalendar()
let component = calendar.components([.Hour,.Minute,.Second], fromDate: currentDateTime)
let hour = component.hour
let minute = component.minute
let second = component.second
return (hour,minute,second)
}
func closed()
{
timeOfTheDay.text = String(getTime().hour)+" : "+String(getTime().minute)+" : "+String(getTime().second)
timeOfTheDay.backgroundColor = UIColor.redColor()
timeOfTheDay.textColor = UIColor.whiteColor()
Status.text = "Sorry! Today, We are Closed!"
Status.backgroundColor = UIColor.redColor()
Status.textColor = UIColor.whiteColor()
}
func opened(endTime:String)
{
timeOfTheDay.text = String(getTime().hour)+" : "+String(getTime().minute)+" : "+String(getTime().second)
timeOfTheDay.backgroundColor = UIColor.greenColor()
timeOfTheDay.textColor = UIColor.whiteColor()
Status.text = "Hi! still we are opened upto "+endTime
Status.backgroundColor = UIColor.greenColor()
Status.textColor = UIColor.whiteColor()
}
func uptoEvening()
{
let time = getTime().hour
switch time
{
case 09...16: opened("17") //set time for 09:00 to 16:59
default:closed()
}
}
func uptoNight()
{
let time = getTime().hour
switch time
{
case 09...20: opened("21") //set time for 09:00 to 20:59
default:closed()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Extension for swift 3:
extension Date {
func dayOfWeek() -> Int? {
let calender: Calendar = Calendar.current
let component: DateComponents = (calender as NSCalendar).components(.weekday, from: self)
return component.weekday
}
}
Related
I am doing calendar view for my swift project. I have to pass From Date and To Fate to server.
So, As per our design I have to show 2 calendars in UI.
So, I design 2 calendars in UI and I am using following library to achieve it.
https://github.com/shoheiyokoyama/Koyomi
But, I have to disable future dates and user should not select them. Also It should not navigates to future months too.
Also I am not getting how to give actions to next and previous buttons action, Since I could not found them in that library.
Also I have to change colour for current date.
Any suggestions to achieve these.
Here is code
Viewcontroller.swift
//
// ViewController.swift
// Koyomi
//
// Created by shoheiyokoyama on 10/09/2016.
// Copyright (c) 2016 shoheiyokoyama. All rights reserved.
//
import UIKit
import Koyomi
class ViewController: UIViewController {
#IBOutlet fileprivate weak var startDateCalenderSelectedDateLabel: UILabel!
#IBOutlet fileprivate weak var ednDateCalenderSelectedDateLabel: UILabel!
#IBOutlet fileprivate weak var startDateCalender: Koyomi! {
didSet {
startDateCalender.circularViewDiameter = 0.2
startDateCalender.calendarDelegate = self
startDateCalender.inset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
startDateCalender.weeks = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
startDateCalender.style = .standard
startDateCalender.dayPosition = .center
startDateCalender.selectionMode = .single(style: .background)
startDateCalender.selectedStyleColor = UIColor.systemBlue
startDateCalender.isHiddenOtherMonth = true
startDateCalender.select(date: Date())
startDateCalender
.setDayFont(size: 14)
.setWeekFont(size: 10)
}
}
#IBOutlet fileprivate weak var endDateCalender: Koyomi! {
didSet {
endDateCalender.circularViewDiameter = 0.2
endDateCalender.calendarDelegate = self
endDateCalender.inset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
endDateCalender.weeks = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
endDateCalender.style = .standard
endDateCalender.dayPosition = .center
endDateCalender.selectionMode = .single(style: .background)
endDateCalender.selectedStyleColor = UIColor.systemBlue
endDateCalender.isHiddenOtherMonth = true
endDateCalender
.setDayFont(size: 14)
.setWeekFont(size: 10)
}
}
fileprivate let invalidPeriodLength = 90
override func viewDidLoad() {
super.viewDidLoad()
// currentDateLabel.text = startDateCalender.currentDateString()
}
#IBAction func startDateNextButtonTap(_button: Any) {
}
#IBAction func startDatePreviousButtonTap(_button: Any) {
}
#IBAction func endDateNextButtonTap(_button: Any) {
}
#IBAction func endDatePreviousButtonTap(_button: Any) {
}
// MARK: - Utility -
fileprivate func date(_ date: Date, later: Int) -> Date {
var components = DateComponents()
components.day = later
return (Calendar.current as NSCalendar).date(byAdding: components, to: date, options: NSCalendar.Options(rawValue: 0)) ?? date
}
}
// MARK: - Tap Action
extension ViewController {
#IBAction func tappedControl(_ sender: UISegmentedControl) {
let month: MonthType = {
switch sender.selectedSegmentIndex {
case 0: return .previous
case 1: return .current
default: return .next
}
}()
startDateCalender.display(in: month)
}
// Change koyomi style
// Utility
func configureStyle(_ style: KoyomiStyle) {
startDateCalender.style = style
startDateCalender.reloadData()
}
}
// MARK: - KoyomiDelegate -
extension ViewController: KoyomiDelegate {
func koyomi(_ koyomi: Koyomi, didSelect date: Date?, forItemAt indexPath: IndexPath) {
if koyomi == startDateCalender {
print("startDateCalender Selected: \(date)")
startDateCalenderSelectedDateLabel.text = "\(date!)"
} else if koyomi == endDateCalender {
ednDateCalenderSelectedDateLabel.text = "\(date!)"
}
}
func koyomi(_ koyomi: Koyomi, currentDateString dateString: String) {
if koyomi == startDateCalender {
startDateCalenderSelectedDateLabel.text = dateString
} else if koyomi == endDateCalender {
ednDateCalenderSelectedDateLabel.text = dateString
}
}
#objc(koyomi:shouldSelectDates:to:withPeriodLength:)
func koyomi(_ koyomi: Koyomi, shouldSelectDates date: Date?, to toDate: Date?, withPeriodLength length: Int) -> Bool {
if length > invalidPeriodLength {
print("More than \(invalidPeriodLength) days are invalid period.")
return false
}
return true
}
}
How can I make calendar view in Swift
https://cocoapods.org/pods/JTAppleCalendar
Try using this pod.
Looks like Pod Koyomi is old and not able to build using Xcode 12.
I have a tabbed app that starts recording on one tab, and plots the mic levels on another tab.
In the first VC, I'm gathering mic levels and storing them in an array in the model. I'm using another method in the model to update the data, and I'm calling it in the second VC in order to update the view.
What I want to do is update the chart in the second view controller from the first view controller (where the logic for storing data in the model is)
Model:
Chart.swift
import Charts
class Chart {
static let sharedInstance = Chart()
var lineChartView: LineChartView!
func setChartValues() {
let entries = (0..<GraphData.sharedInstance.array.count).map { (i) -> ChartDataEntry in
let val = GraphData.sharedInstance.array[i]
print(ChartDataEntry(x: Double(i), y: val))
return ChartDataEntry(x: Double(i), y: val)
}
let set1 = LineChartDataSet(values: entries, label: "DataSet 1")
let data = LineChartData(dataSet: set1)
lineChartView.data = data
}
}
GraphData.swift
class GraphData {
static let sharedInstance = GraphData()
var array = [Double]()
}
View Controllers:
First VC: (complete code per comment)
import UIKit
import AVFoundation
class SoundController: UIViewController, AVAudioRecorderDelegate {
var recordingSession: AVAudioSession!
var audioRecorder: AVAudioRecorder!
var timer = Timer()
#IBOutlet weak var errorLbl: UILabel!
#IBOutlet weak var recordBtn: UIButton!
#IBAction func recordButton(_ sender: UIButton) {
if audioRecorder == nil {
startRecording()
} else {
finishRecording(success: true)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
errorLbl.text = ""
}
override func viewDidLoad() {
super.viewDidLoad()
recordPermission()
}
func recordPermission() {
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { allowed in
DispatchQueue.main.async {
if allowed {
print("recording allowed")
} else {
self.errorLbl.text = "Recording Permission was Denied. Please open settings and allow Cry It Out to access the microphone."
}
}
}
} catch {
self.errorLbl.text = "Recording Permission was Denied. Please open settings and allow the app to access the microphone."
}
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func startRecording() {
if recordBtn.titleLabel?.text == "Tap to Re-record" {
//reset values array
GraphData.sharedInstance.array = []
}
let audioFilename = getDocumentsDirectory().appendingPathComponent("baby.m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.delegate = self
audioRecorder.isMeteringEnabled = true
runTimer()
audioRecorder.record()
runTimer()
recordBtn.setTitle("Tap to Stop", for: .normal)
} catch {
finishRecording(success: false)
}
}
func levelTimerCallback() -> Float {
if audioRecorder != nil {
audioRecorder.updateMeters()
//If we are beyond a threshold value (-15)
if audioRecorder.averagePower(forChannel: 0) > -15 {
return audioRecorder.averagePower(forChannel: 0)
}
}
return 0
}
func finishRecording(success: Bool) {
//stop recording and reset recorder to nil for other checks
audioRecorder.stop()
audioRecorder = nil
if success {
recordBtn.setTitle("Tap to Re-record", for: .normal)
if timer.isValid {
timer.invalidate()
}
} else {
//Recording Failed
recordBtn.setTitle("Tap to Record", for: .normal)
//disable timer if running (might be running or might not)
if timer.isValid {
timer.invalidate()
}
}
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
if !flag {
finishRecording(success: false)
}
}
//MARK: Timers
#objc func updateTimer() {
if levelTimerCallback() != 0 {
let date = Date()
let calendar = Calendar.current
let month = calendar.component(.month, from: date)
let day = calendar.component(.day, from: date)
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)
let seconds = calendar.component(.second, from: date)
let prettyDate = "\(month)/\(day) \(hour):\(minutes) and \(seconds) seconds"
print(prettyDate)
GraphData.sharedInstance.array.append(Double(levelTimerCallback()))
//does this run the method? It should
GraphController.sharedInstance.lineChartView?.data = Chart.sharedInstance.setChartValues()
}
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(SoundController.updateTimer)), userInfo: nil, repeats: true)
}
func stopTimer() {
timer.invalidate()
}
}
Second VC:
import UIKit
import Charts
class GraphController: UIViewController {
static let sharedInstance = GraphController()
#IBOutlet weak var lineChartView: LineChartView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
self.lineChartView.data = Chart.sharedInstance.setChartValues()
}
}
Try this solution without lambda functions. You don't need use static values.
1. Prepare your GraphController to have a function to receive data
class GraphController: UIViewController {
...
func dataReceived ( gData : GraphData ) {
DispatchQueue.main.async {
// Update your chart with gData
}
}
}
2. Get the reference of GraphController and use the function of step 1 to make your updates.
Please, get the reference of your GraphController from tab and use this reference to call a function to make your chart updates. I don't know exactely your situation, but if you have problems to make it, please look this: https://stackoverflow.com/a/39499751/5140756
class SoundController: UIViewController, AVAudioRecorderDelegate {
var graphController : GraphController?
...
override func viewDidLoad() {
super.viewDidLoad()
...
// get graph controller reference from tabbar.
self.graphController = self.tabBarController.viewControllers![INDEX_OF_VIEW_CONTROLLER] as! GraphController
}
// finally on your function call the function's graph controller receive data
#objc func updateTimer() {
if levelTimerCallback() != 0 {
let date = Date()
let calendar = Calendar.current
let month = calendar.component(.month, from: date)
let day = calendar.component(.day, from: date)
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)
let seconds = calendar.component(.second, from: date)
let prettyDate = "\(month)/\(day) \(hour):\(minutes) and \(seconds) seconds"
print(prettyDate)
GraphData.sharedInstance.array.append(Double(levelTimerCallback()))
//does this run the method? It should
//GraphController.sharedInstance.lineChartView?.data = Chart.sharedInstance.setChartValues()
if graphController != nil {
self.graphController!.dataReceived( gData: GraphData.sharedInstance )
}
}
}
}
Please, look the code, and make some changes that you need, I tried automate the max that I can.
I am wondering what would be the best practice when I want to pass data from model to controller.
What I want to do
I would like to update a label when the time changes.
CurrentTime.swift (Model)
var timer: Timer?
var currentTime: String?
init() {
if timer == nil{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCurrentTime), userInfo: nil, repeats: true)
}
}
#objc private func updateCurrentTime(){
let df = DateFormatter()
df.dateFormat = "HH:mm"
df.timeZone = TimeZone.current
let timezoneDate = df.string(from: Date())
currentTime = timezoneDate
}
ViewController.swift
class ViewController: UIViewController {
#IBOutlet var timeLabel: UILabel!
var currentTime = CurrentTime()
override func viewDidLoad() {
}
#IBAction func closeBtnWasPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
Option 1
1- Add this var
weak var delegate: ViewController?
2- in viewDidLoad of the vc
currentTime.delegate = self
3-
let timezoneDate = df.string(from: Date())
currentTime = timezoneDate
delegate?.update(currentTime)
4- inside the vc
func update(_ data:String) {
lbl.text = data
}
off course you can do
delegate?.lbl.text = currentTime
but above is MVC
Option 2
var ob:NSKeyValueObservation!
and in viewDidLoad
ob = currentTime.observe(\CurrentTime.currentTime, options: .new) { cur, tex in
timeLabel.text = tex
}
You should define a Dynamic class like this:
class Dynamic<T> {
var bind: (T) -> Void = { _ in }
var value: T? {
didSet {
bind(value!)
}
}
init(_ v: T) {
value = v
}
}
In your model change definition of the currentTime property like this:
var currentTime: Dynamic<String>
In your controller in viewDidLoad method add these codes:
yourModel.currentTime.bind = { [weak self] time in
self?.timeLabel.text = time
}
My issue is this I have two viewControllers connected with a modal segue like normal A--->B, A has the controls like textFields, switches, buttons and a mapView where I get the userLocation. B hast only a button, and a mapView at the moment, but when I tap the exit button it does successfully dismisses viewController B and shows A only controls are frozen, can't tap anything anymore, I don't know why. Any help?
B code
import UIKit
import MapKit
import Parse
import CoreLocation
class MapaMososViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapMozosFollow: MKMapView!
var totlaAutomozo: String!
var fechaRegistro: String!
override func viewDidLoad() {
super.viewDidLoad()
mapMozosFollow.delegate = self
mapMozosFollow.showsUserLocation = true
mapMozosFollow.showsTraffic = false
mapMozosFollow.showsScale = false
print(mapMozosFollow.userLocation.location)
}
override func viewDidAppear(_ animated: Bool) {
self.displayError(error: "Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo!) la fecha registrada \(fechaRegistro!)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillDisappear(_ animated: Bool) {
}
#IBAction func salirTapped(_ sender: UIButton) {
self.dismiss(animated: true, completion: {
print("here dismissing")
})
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations.last!.coordinate)
centerMapOnLocation(locations.last!)
}
let regionRadius: CLLocationDistance = 2000
func centerMapOnLocation(_ location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapMozosFollow.setRegion(coordinateRegion, animated: true)
}
}
EDIT 1: A ViewController code.
import UIKit
import Parse
import MapKit
import BraintreeDropIn
import Braintree
class ViewController: UIViewController, PayPalPaymentDelegate, PayPalFuturePaymentDelegate, PayPalProfileSharingDelegate, CLLocationManagerDelegate, UITextFieldDelegate, MKMapViewDelegate, BTDropInViewControllerDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var mapaLugar: MKMapView!
#IBOutlet weak var numeroExteriorTextField: UITextField!
#IBOutlet weak var telefonoTextField: UITextField!
#IBOutlet weak var lavadoSwitch: UISwitch!
#IBOutlet weak var lavadoYAspiradSwitch: UISwitch!
#IBOutlet weak var numeroCarrosTextField: UITextField!
#IBOutlet weak var numeroMinivanTextField: UITextField!
#IBOutlet weak var numeroPickUpsTextField: UITextField!
#IBOutlet weak var numeroVansTextField: UITextField!
#IBOutlet weak var numeroAspiradoCarrosTextField: UITextField!
#IBOutlet weak var numeroAspiradoMinivanTextField: UITextField!
#IBOutlet weak var numeroAspiradoPickUpsTextField: UITextField!
#IBOutlet weak var numeroAspiradoVansTextField: UITextField!
#IBOutlet weak var botonRealizarPedido: UIButton!
#IBOutlet weak var botonInstrucciones: UIButton!
#IBOutlet weak var totalLabel: UILabel!
var showAlertFirstTime: Bool = true
var locationManager: CLLocationManager = CLLocationManager()
var ubicacion: CLLocationCoordinate2D!
var environment:String = PayPalEnvironmentSandbox {
willSet(newEnvironment) {
if (newEnvironment != environment) {
PayPalMobile.preconnect(withEnvironment: newEnvironment)
}
}
}
var braintreeClient: BTAPIClient?
let defaults = UserDefaults.standard
var resultText = "" // empty
var payPalConfig = PayPalConfiguration() // default
var total: NSDecimalNumber!
var vistaDeMozos: Bool = false
var fechaRegistro: String!
var totalToSend: String!
#IBOutlet weak var constrainSizeMap: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
botonInstrucciones.backgroundColor = UIColor(colorLiteralRed: (200.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0)
botonInstrucciones.layer.cornerRadius = 3
botonInstrucciones.layer.borderWidth = 2
botonInstrucciones.layer.borderColor = UIColor.clear.cgColor
botonInstrucciones.layer.shadowColor = UIColor(colorLiteralRed: (100.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0).cgColor
botonInstrucciones.layer.shadowOpacity = 1.0
botonInstrucciones.layer.shadowRadius = 1.0
botonInstrucciones.layer.shadowOffset = CGSize(width: 0, height: 3)
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
NotificationCenter.default.post(name: Notification.Name(rawValue: "keyPressed"), object: nil)
numeroCarrosTextField.delegate = self
numeroMinivanTextField.delegate = self
numeroPickUpsTextField.delegate = self
numeroVansTextField.delegate = self
numeroAspiradoCarrosTextField.delegate = self
numeroAspiradoMinivanTextField.delegate = self
numeroAspiradoPickUpsTextField.delegate = self
numeroAspiradoVansTextField.delegate = self
do {
if defaults.object(forKey: "clientId") == nil || clientId == "000" {
let idTest = try PFCloud.callFunction("newCutomer", withParameters: nil)
print(idTest)
clientId = idTest as! String
defaults.set(clientId, forKey: "clientId")
} else {
print(self.clientId)
}
} catch let error {
print(error)
}
if defaults.object(forKey: "clientId") == nil {
} else {
clientId = defaults.string(forKey: "clientId")!
print(clientId)
}
fetchClientToken()
NotificationCenter.default.addObserver(
self,
selector: #selector(ViewController.keyboardWillShow(notification:)),
name: NSNotification.Name.UIKeyboardWillShow,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(ViewController.keyboardWillHide(notification:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil
)
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.interactive
let touch = UITapGestureRecognizer(target: self, action: #selector(ViewController.singleTapGestureCaptured(gesture:)))
scrollView.addGestureRecognizer(touch)
}
func singleTapGestureCaptured(gesture: UITapGestureRecognizer){
self.view.endEditing(true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if showAlertFirstTime {
showAlertFirstTime = false
} else {
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
PayPalMobile.preconnect(withEnvironment: environment)
print("stop test")
}
#IBAction func realizarPedidoTapped(_ sender: UIButton) {
let numeroExterior = numeroExteriorTextField.text!
let numeroMotosLavado = numeroCarrosTextField.text!
let numeroDeportivosLavado = numeroMinivanTextField.text!
let numeroCarroLavado = numeroPickUpsTextField.text!
let numeroCamionLavado = numeroVansTextField.text!
let numeroMotoLavadoAspirado = numeroAspiradoCarrosTextField.text!
let numeroDeportivoLavadoAspirado = numeroAspiradoMinivanTextField.text!
let numeroCarroLavadoAspirado = numeroAspiradoPickUpsTextField.text!
let numeroCamionLavadoAspirado = numeroAspiradoVansTextField.text!
let numeroTelefono = telefonoTextField.text!
if numeroExterior == "" || numeroTelefono == "" {
displayError("Error", message: "Te falto llenar tu numero exterior y/o telefono")
} else {
//Braintree init
self.braintreeClient = BTAPIClient(authorization: clientToken)
let items = [item1]
let subtotal = PayPalItem.totalPrice(forItems: items)
//var subtotal = PayPalItem.totalPrice(forItems: items)
let shipping = NSDecimalNumber(string: "0.00")
let tax = NSDecimalNumber(string: "0.00")
//details ???
let paymentDetails = PayPalPaymentDetails(subtotal: subtotal, withShipping: shipping, withTax: tax)
self.total = subtotal.adding(shipping).adding(tax)
let payment = PayPalPayment(amount: total, currencyCode: "MXN", shortDescription: "Automozo inc", intent: .sale)
payment.items = items
payment.paymentDetails = paymentDetails
print("\(payment.localizedAmountForDisplay)")
self.showDropIn(clientTokenOrTokenizationKey: clientToken)
if (payment.processable) {
let paymentViewController = PayPalPaymentViewController(payment: payment, configuration: payPalConfig, delegate: self)
}
else {
print("Payment not processalbe: \(payment.description)")
print("payment not processable \(payment)")
displayError("Error", message: "Hubo un error al procesar tu pago, por favor intenta de nuevo.")
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "MapaMozosSegue" {
let mapaMozosVC = segue.destination as! MapaMososViewController
mapaMozosVC.totlaAutomozo = totalToSend!
mapaMozosVC.fechaRegistro = fechaRegistro
locationManager.stopUpdatingLocation()
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.resignFirstResponder()
print("test text field ended")
if textField.text == "" {
textField.text = "0"
}
var numeroCarrosLavadoVar = numeroCarrosTextField.text!
var numeroMinivansLavadoVar = numeroMinivanTextField.text!
var numeroPickUpsLavadoVar = numeroPickUpsTextField.text!
var numeroVansLavadoVar = numeroVansTextField.text!
var numeroCarrosLavadoAspiradoVar = numeroAspiradoCarrosTextField.text!
var numeroMinivansLavadoAspiradoVar = numeroAspiradoMinivanTextField.text!
var numeroPickUpsLavadoAspiradoVar = numeroAspiradoPickUpsTextField.text!
var numeroVansLavadoAspiradoVar = numeroAspiradoVansTextField.text!
if numeroCarrosLavadoVar == "" {
numeroCarrosLavadoVar = "0"
numeroCarrosTextField.text = "0"
}
if numeroMinivansLavadoVar == "" {
numeroMinivansLavadoVar = "0"
numeroMinivanTextField.text = "0"
}
if numeroPickUpsLavadoVar == "" {
numeroPickUpsLavadoVar = "0"
numeroPickUpsTextField.text = "0"
}
if numeroVansLavadoVar == "" {
numeroVansLavadoVar = "0"
numeroVansTextField.text = "0"
}
if numeroCarrosLavadoAspiradoVar == "" {
numeroCarrosLavadoAspiradoVar = "0"
numeroAspiradoCarrosTextField.text = "0"
}
if numeroMinivansLavadoAspiradoVar == "" {
numeroMinivansLavadoAspiradoVar = "0"
numeroMinivanTextField.text = "0"
}
if numeroPickUpsLavadoAspiradoVar == "" {
numeroPickUpsLavadoAspiradoVar = "0"
numeroAspiradoPickUpsTextField.text = "0"
}
if numeroVansLavadoAspiradoVar == "" {
numeroVansLavadoAspiradoVar = "0"
numeroVansTextField.text = "0"
}
let priceOfLavadoCarro = Int(numeroCarrosLavadoVar)! * pricesLavado["LavadoCarro"]!
let priceOfLavadoMinivan = Int(numeroMinivansLavadoVar)! * pricesLavado["LavadoMinivan"]!
let priceOfLavadoPickUp = Int(numeroPickUpsLavadoVar)! * pricesLavado["LavadoPickUp"]!
let priceOfLavadoVan = Int(numeroVansLavadoVar)! * pricesLavado["LavadoVan"]!
//Lavado y Aspirado
let priceOfLavadoYAspiradoCarro = Int(numeroCarrosLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoCarro"]!
let priceOfLavadoYAspiradoMinivan = Int(numeroMinivansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoMinivan"]!
let priceOfLavadoYAspiradoPickUp = Int(numeroPickUpsLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoPickUp"]!
let priceOfLavadoYAspiradoVan = Int(numeroVansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoVan"]!
let totalAutomozo = priceOfLavadoCarro + priceOfLavadoMinivan + priceOfLavadoPickUp + priceOfLavadoVan + priceOfLavadoYAspiradoCarro + priceOfLavadoYAspiradoMinivan + priceOfLavadoYAspiradoPickUp + priceOfLavadoYAspiradoVan
print(totalAutomozo)
totalLabel.text = "\(totalAutomozo).00"
textField.resignFirstResponder()
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if (textField.text?.characters.count)! == 1 {
print("text quota meet")
textField.resignFirstResponder()
self.view.endEditing(true)
return true
} else {
textField.text = "0"
}
return true
}
let regionRadius: CLLocationDistance = 100
func centerMapOnLocation(_ location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapaLugar.setRegion(coordinateRegion, animated: true)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
centerMapOnLocation(locations.last!)
ubicacion = locations.last!.coordinate
}
// Mark - Braintree methods
func showDropIn(clientTokenOrTokenizationKey: String) {
var value: Bool = false
var totlaAutomozo = self.totalLabel.text
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd YYYY HH:mm"
dateFormatter.timeZone = NSTimeZone.local
fechaRegistro = dateFormatter.string(from: Date())
let request = BTDropInRequest()
request.amount = "\(total)"
request.currencyCode = "MXN"
print(request.description)
BTUIKAppearance.darkTheme()
BTUIKAppearance.sharedInstance().activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
// request.
let dropIn = BTDropInController(authorization: clientTokenOrTokenizationKey, request: request)
{ (controller, result, error) in
if (error != nil) {
print("ERROR")
} else if (result?.isCancelled == true) {
print("CANCELLED")
} else if let result = result {
// Use the BTDropInResult properties to update your UI
print(result.paymentOptionType)
print("payment method: \(result.paymentMethod?.nonce)")
print("ppayment desc \(result.paymentDescription)")
print(result.paymentIcon.description)
value = self.postNonceToServer(paymentMethodNonce: (result.paymentMethod?.nonce)!)
}
controller.dismiss(animated: true, completion: nil)
if value {
self.locationManager.stopUpdatingLocation()
self.performSegue(withIdentifier: "MapaMozosSegue", sender: self)
self.vistaDeMozos = true
} else {
self.displayError("Alerta", message: "El pedido ha sido cancelado exitosamente.")
//top row
self.numeroCarrosTextField.text = "0"
self.numeroMinivanTextField.text = "0"
self.numeroPickUpsTextField.text = "0"
self.numeroVansTextField.text = "0"
//bottom row
self.numeroAspiradoCarrosTextField.text = "0"
self.numeroAspiradoMinivanTextField.text = "0"
self.numeroAspiradoPickUpsTextField.text = "0"
self.numeroAspiradoVansTextField.text = "0"
//data
self.telefonoTextField.text = ""
self.telefonoTextField.text = ""
}
}
self.present(dropIn!, animated: true, completion: nil)
}
func userDidCancelPayment() {
self.dismiss(animated: true, completion: nil)
}
func postNonceToServer(paymentMethodNonce: String) -> Bool {
var val = true
do {
var response = try PFCloud.callFunction("checkout", withParameters: ["payment_method_nonce":paymentMethodNonce, "amount":"\(total!).00", "customerId": clientId])
print(response)
} catch let error {
print(error.localizedDescription)
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM. dd, YYYY HH:mm"
dateFormatter.timeZone = NSTimeZone.local
fechaRegistro = dateFormatter.string(from: Date())
let usuarioPagado: PFObject = PFObject(className: "Ordenes")
let location: PFGeoPoint = PFGeoPoint(latitude: ubicacion.latitude, longitude: ubicacion.longitude)
usuarioPagado["Ubicacion"] = location
usuarioPagado["NumeroExterior"] = numeroExteriorTextField.text!
usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
usuarioPagado["LavadoCarro"] = numeroCarrosTextField.text!
usuarioPagado["LavadoMiniVan"] = numeroMinivanTextField.text!
usuarioPagado["LavadoPickUp"] = numeroPickUpsTextField.text!
usuarioPagado["LavadoDeVan"] = numeroVansTextField.text!
usuarioPagado["LavadoAspiradoCarro"] = numeroAspiradoCarrosTextField.text!
usuarioPagado["LavadoAspiradoMiniVan"] = numeroAspiradoMinivanTextField.text!
usuarioPagado["LavadoAspiradoPickUp"] = numeroAspiradoPickUpsTextField.text!
usuarioPagado["LavadoAspiradoDeVan"] = numeroAspiradoVansTextField.text!
usuarioPagado["Monto"] = totalLabel.text!
usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
usuarioPagado["TipoDeCelular"] = "iPhone"
usuarioPagado["FechaDeOrden"] = fechaRegistro
self.totalToSend = self.totalLabel.text!
usuarioPagado.saveInBackground() {
(success: Bool, error: Error?) -> Void in
if error == nil {
//done
print("saved object")
val = false
} else {
//not done
print("not saved because \(error?.localizedDescription)")
}
}
numeroCarrosTextField.text = "0"
numeroMinivanTextField.text = "0"
numeroPickUpsTextField.text = "0"
numeroVansTextField.text = "0"
numeroAspiradoCarrosTextField.text = "0"
numeroAspiradoMinivanTextField.text = "0"
numeroAspiradoPickUpsTextField.text = "0"
numeroAspiradoVansTextField.text = "0"
totalLabel.text = "00.00"
self.lavadoSwitch.isOn = false
self.lavadoYAspiradSwitch.isOn = false
self.numeroExteriorTextField.text = ""
self.telefonoTextField.text = ""
self.numeroCarrosTextField.isHidden = true
self.numeroMinivanTextField.isHidden = true
self.numeroPickUpsTextField.isHidden = true
self.numeroVansTextField.isHidden = true
self.numeroAspiradoCarrosTextField.isHidden = true
self.numeroAspiradoMinivanTextField.isHidden = true
self.numeroAspiradoPickUpsTextField.isHidden = true
self.numeroAspiradoVansTextField.isHidden = true
return val
}
func drop(inViewControllerDidLoad viewController: BTDropInViewController) {
print("did load view drop")
}
func drop(inViewControllerDidCancel viewController: BTDropInViewController) {
print("did cancel drop payment")
}
func drop(inViewControllerWillComplete viewController: BTDropInViewController) {
print("drop will complete payment")
}
func drop(_ viewController: BTDropInViewController, didSucceedWithTokenization paymentMethodNonce: BTPaymentMethodNonce) {
var totlaAutomozo = totalLabel.text
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd YYYY HH:mm"
dateFormatter.timeZone = NSTimeZone.local
fechaRegistro = dateFormatter.string(from: Date())
print("did succeeded with tokenization")
print(" \(paymentMethodNonce.nonce)")
var value = postNonceToServer(paymentMethodNonce: paymentMethodNonce.nonce)
self.dismiss(animated: true, completion: nil)
if value {
displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo ?? "00.00") la fecha registrada \(fechaRegistro)")
} else {
self.displayError("Error", message: "Hubo un error al guardar tu informacion, ponte en contacto con nosotros.")
}
}
func fetchClientToken() {
do {
let response = try PFCloud.callFunction("generateToken", withParameters: ["clientId": clientId])
self.clientToken = response as! String
} catch let error {
print(error)
}
}
func keyboardWillShow(notification:NSNotification){
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.scrollView.contentInset
contentInset.bottom = keyboardFrame.size.height
self.scrollView.contentInset = contentInset
}
func keyboardWillHide(notification:NSNotification){
let contentInset:UIEdgeInsets = UIEdgeInsets.zero
self.scrollView.contentInset = contentInset
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.view.endEditing(true)
}
func showFullMap() {
if vistaDeMozos {
self.telefonoTextField.isHidden = true
self.botonRealizarPedido.isHidden = true
self.lavadoSwitch.isHidden = true
self.lavadoYAspiradSwitch.isHidden = true
self.botonRealizarPedido.isHidden = true
self.numeroExteriorTextField.isHidden = true
self.numeroCarrosTextField.isHidden = true
self.numeroMinivanTextField.isHidden = true
self.numeroPickUpsTextField.isHidden = true
self.numeroVansTextField.isHidden = true
self.numeroAspiradoCarrosTextField.isHidden = true
self.numeroAspiradoMinivanTextField.isHidden = true
self.numeroAspiradoPickUpsTextField.isHidden = true
self.numeroAspiradoVansTextField.isHidden = true
self.view.layoutSubviews()
} else {
}
}
}
Did you try pausing the app with the debugger to inspect the stack frames? Sometimes that can help you spot deadlocks or infinite loops. You'll find the pause button in the bar between the code editor and the debugger (or at the bottom if the debugger is hidden):
Look at the stack frames in the Debug Navigator on the left-hand side of the Xcode window. Can you see anything suspicious? Here is a stack frame that indicates the app is idling on the main run loop:
That's usually perfectly normal as the app is waiting for user input. If you see something like the following you are likely dealing with a deadlock:
The semaphore stops the thread from continuing until some other thread opens the semaphore again. You are dealing with a deadlock if two or more threads are stopped waiting for each other. If the main thread is involved the app will be frozen.
The third possibility I can think of is an infinite loop on the main thread:
Of course this one is pretty easy to spot :)
The darker entries in stack frames are from your own code. You can click on those entries to find the exact locations and use the debugger to inspect variables. The other entries will show you assembly.
If you could not find anything suspicious by pausing the debugger I would start to remove those parts of code bit by bit, trying to reproduce the problem each time. There are two possible results:
You remove some harmless looking code and suddenly it works as expected. You can then take a closer look at the code you removed, making it easier to figure the issue out.
You end up with a minimal project exhibiting the issue. This is now much easier to debug and reason about because there is nothing else distracting you from the problem. You also have a much higher probability of getting help from coworkers or here on Stack Overflow when your code sample is as small as possible.
A third attack vector is checking the View Debugger:
Are there any transparent views above the frozen view controller blocking user events?
Is user interaction enabled on the controls and views involved? Select a view and check the Object Inspector on the right-hand side:
Try to remove DispatchQueue.main.async or the A viewController won't get notified. It's interaction has been disabled because the segue
//DispatchQueue.main.async {
self.dismiss(animated: true, completion: {
print("here dismissing")
})
//}
Make sure to check if any NSDelayedPerforming methods are blocking the main thread (Foundation > NSRunloop). i.e. performSelector afterDelay...
In my case (Objective-C) I had to use cancelPreviousPerformRequestsWithTarget in the viewDidDisappear instance method of the ViewController.
[NSObject cancelPreviousPerformRequestsWithTarget:self];
I think the same applies when using NSTimer.scheduledTimerWithTimeInterval (Swift) without invalidating the timer in the proper life cycle method.
I have a UIViewController. I have made a MyProfile section. Now what i want to do is that if a person has only one picture then the 4 images section (which is a uiview) disappear and my UI (AboutLabel and TextSection comes up) will set according to that
Please see this picture: https://www.dropbox.com/s/gwokb8ge4pu5cw3/MyProfile.png?dl=0
class MyProfileViewController: UIViewController , UIImagePickerControllerDelegate{
#IBOutlet weak var sidebarButton: UIBarButtonItem!
#IBOutlet weak var profilePic: UIImageView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var ageLabel: UILabel!
#IBOutlet weak var totalPicView: UIView!
#IBOutlet weak var aboutMeLabel: UITextView!
var imagesArray = [UIImageView]()
var tag: Int?
var check = false
var myUserInfo: UsersInformation!
var age: Int?
override func viewDidLoad() {
super.viewDidLoad()
if revealViewController() != nil
{
// revealViewController().rearViewRevealWidth = 62
sidebarButton.target = revealViewController()
sidebarButton.action = #selector(SWRevealViewController.revealToggle(_:))
//revealViewController().rightViewRevealWidth = 150
//rightReveal.target = revealViewController()
//rightReveal.action = "rightRevealToggle:"
view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
if NSUserDefaults.standardUserDefaults().valueForKey(KEY_UID) != nil
{
let uid = DataService.ds.currentUserID
DataService.ds.currentUserRef.observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot]
{
if let userDictionary = snapshot.value as? Dictionary<String , AnyObject>
{
print("ProfileData")
self.myUserInfo = UsersInformation(id:uid, userInfo: userDictionary)
}
}
/*SavingDataFUnction*/
self.setProfileData()
})
}
}
func setProfileData()
{
age = giveMeAge()
let width = view.frame.width
let height = view.frame.height
print("w:\(width) ; h \(height)")
/*Basic Information*/
self.nameLabel.text = myUserInfo.uName
self.ageLabel.text = "Age: " + String(age!)
self.aboutMeLabel.text = myUserInfo.about
if myUserInfo.imageUrl[0] == noImageUrl
{
profilePic.image = UIImage(named: "Profile")
/*Hide totalPicView and Adjust aboutLabel and TextView*/
//totalPicView.viewWithTag(101)?.hidden = true
//totalPicView.frame.size.height = 0
}
else if myUserInfo.imageUrl.count >= 1
{
/*FirstPic is Profile Pic*/
let profile = myUserInfo.imageUrl[0]
profilePic.kf_setImageWithURL(NSURL(string: profile))
for i in 0 ... 3
{
let url = self.myUserInfo.imageUrl[i]
let imgOne = UIImageView(frame: CGRectMake(89.5 * CGFloat(i), 0, 89.5, totalPicView.frame.height))
imgOne.kf_setImageWithURL(NSURL(string: url))
imgOne.tag = 11 + i
imagesArray.append(imgOne)
self.totalPicView.addSubview(imgOne)
}
for image: UIImageView in imagesArray
{
image.userInteractionEnabled = true
image.clipsToBounds = true
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.setImage))
image.addGestureRecognizer(tapGesture)
}
}
}
func setImage(gesture: UITapGestureRecognizer) {
print(gesture.view?.tag)
tag = gesture.view?.tag
performSegueWithIdentifier("showImages", sender: self)
//presentViewController(imagePicker, animated: true, completion: nil)
}
func setMyUI(imageView: UIImageView)
{
aboutMeLabel.layer.borderColor = UIColor.blackColor().CGColor
aboutMeLabel.layer.cornerRadius = 5
aboutMeLabel.layer.borderWidth = 1
}
func giveMeAge() -> Int
{
let dob = myUserInfo.dob
let todaysDate = NSDate() //dateFromString("2015-02-04 23:29:28", format: "yyyy-MM-dd HH:mm:ss")
let dateFormater = NSDateFormatter()
dateFormater.dateFormat = "MM/dd/yyyy"
let currentDate = dateFormater.dateFromString(dateFormater.stringFromDate(todaysDate))
let myDob = dateFormater.dateFromString(dob)
let calendar: NSCalendar = NSCalendar.currentCalendar()
let age = calendar.components(.Year, fromDate: myDob! , toDate: currentDate!, options: [])
return age.year
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "showImages"
{
let dest = segue.destinationViewController as! ProfileImages
dest.arrarayOfImages = imagesArray
dest.tag = tag
dest.uname = myUserInfo.uName
dest.myage = age
}
}
}
Ok if I understand correctly you want to remove the UIView section with the 4 UIImageViews if the user has just one/no picture/s. Why not try with an if statement in your viewDidLoad (Swift 3 syntax):
if(yourImageViewArray.count <= 1){
yourUIViewForImages.isHidden = true
}
Once your UIView yourUIViewForImages is hidden, your stack should adjust accordingly. Unless you have hardcoded CGRect values (x,y) for your About sections. It would really help to post your code as already mentioned in your comments section.