Retain countdown timer value when switching between view controllers - ios

I'm working on a trip countdown app that also has weather forecast built in.
Things are working pretty well, but when I switch from countdown timer to weather forecast, then come back, the countdown timer is reset.
Here's my countdown view controller code:
import UIKit
class CountdownVC: UIViewController {
var timer = Timer()
let userCalendar = Calendar.current
let requestedComponent: Set<Calendar.Component> = [.day,.hour,.minute,.second]
var departureDateTime: Date?
#IBOutlet weak var imageView: UIImageView!
let images = [
UIImage(named: "MK.png")!,
UIImage(named: "SSE1.png")!,
UIImage(named: "TofT.png"),
UIImage(named: "TofL1.png")!]
var index = 0
let animationDuration: TimeInterval = 0.25
let switchingInterval: TimeInterval = 15
func animateImageView()
{
CATransaction.begin()
CATransaction.setAnimationDuration(animationDuration)
CATransaction.setCompletionBlock {
DispatchQueue.main.asyncAfter(deadline: .now() + self.switchingInterval) {
self.animateImageView()
}
}
let transition = CATransition()
transition.type = kCATransitionFade
imageView.layer.add(transition, forKey: kCATransition)
imageView.image = images[index]
imageView.contentMode = .scaleAspectFill
imageView.alpha = 0.5
CATransaction.commit()
index = index < images.count - 1 ? index + 1 : 0
}
#IBOutlet weak var departureDateTimePicker: UIDatePicker!
#IBAction func departureDateTimePicker(_ sender: Any) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy H:mm:ss"
departureDateTimePicker.addTarget(self, action: #selector(handler), for: UIControlEvents.valueChanged)
}
#IBOutlet weak var selectDepartureDateTimeLabel: UILabel!
#IBOutlet weak var daysLabel: UILabel!
#IBOutlet weak var hoursLabel: UILabel!
#IBOutlet weak var minutesLabel: UILabel!
#IBOutlet weak var secondsLabel: UILabel!
func handler(sender: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy H:mm:ss"
let departureDateTimeString = dateFormatter.string(from: departureDateTimePicker.date)
departureDateTime = dateFormatter.date(from: departureDateTimeString)
}
func printTime() {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy H:mm:ss"
let startTime = Date()
let endTime = departureDateTime
let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)
let startTimeDouble: Double = startTime.timeIntervalSinceReferenceDate
var endTimeDouble: Double?
endTimeDouble = (endTime?.timeIntervalSinceReferenceDate)
if endTimeDouble! > startTimeDouble {
daysLabel.text = "\(timeDifference.day!) Days"
hoursLabel.text = "\(timeDifference.hour!) Hours"
minutesLabel.text = "\(timeDifference.minute!) Minutes"
secondsLabel.text = "\(timeDifference.second!) Seconds"
} else {
timer.invalidate()
daysLabel.text = ""
hoursLabel.text = ""
minutesLabel.text = ""
secondsLabel.text = ""
}
}
func runTimer() {
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printTime), userInfo: nil, repeats: true)
timer.fire()
}
#IBOutlet weak var startBtn: UIButton!
#IBAction func startBtnPressed(_ sender: Any) {
handler(sender: departureDateTimePicker)
printTime()
runTimer()
selectDepartureDateTimeLabel.text = "Time to departure"
departureDateTimePicker.isHidden = true
startBtn.isHidden = true
}
#IBOutlet weak var resetBtn: UIButton!
#IBAction func resetBtnPressed(_ sender: Any) {
timer.invalidate()
selectDepartureDateTimeLabel.text = "Select departure date & time"
departureDateTimePicker.isHidden = false
startBtn.isHidden = false
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy H:mm:ss"
let startTime = Date()
let endTime = startTime
let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime)
daysLabel.text = "\(timeDifference.day!) Days"
hoursLabel.text = "\(timeDifference.hour!) Hours"
minutesLabel.text = "\(timeDifference.minute!) Minutes"
secondsLabel.text = "\(timeDifference.second!) Seconds"
}
#IBAction func goToWeatherBtnPressed(_ sender: Any) {
performSegue(withIdentifier: "goToWeatherVC", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
super.viewDidLoad()
imageView.image = images[index+1]
animateImageView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Related

How to add mutiple progress views to a timer?

here is all of the code that I am using for this project. I have four progress views and when the first end an alarm goes off and then the next start eminently and then goes to the next and then to the fourth one where the timer ends after that and the timer goes off one more time and then the timers stop.
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btnPressed4(_ sender: Any) {
let currentDateTime = Date()
let formatter = DateFormatter()
formatter.timeStyle = .short
let dateTimeString = formatter.string(from: currentDateTime)
timePrint4.text = dateTimeString
btnPressed4.titleLabel?.textColor = UIColor.white
}
#IBAction func btnPressed3(_ sender: Any) {
let currentDateTime = Date()
let formatter = DateFormatter()
formatter.timeStyle = .short
let dateTimeString = formatter.string(from: currentDateTime)
timePrint3.text = dateTimeString
btnPressed3.titleLabel?.textColor = UIColor.white
}
#IBAction func btnPressed2(_ sender: UIButton) {
let currentDateTime = Date()
let formatter = DateFormatter()
formatter.timeStyle = .short
let dateTimeString = formatter.string(from: currentDateTime)
timePrint2.text = dateTimeString
btnPressed2.titleLabel?.textColor = UIColor.green
}
#IBAction func btnPressed1(_ sender: UIButton) {
let currentDateTime = Date()
let formatter = DateFormatter()
formatter.timeStyle = .short
let dateTimeString = formatter.string(from: currentDateTime)
timePrint1.text = dateTimeString
}
#IBOutlet weak var btnPressed1: UIButton!
#IBOutlet weak var btnPressed2: UIButton!
#IBOutlet weak var btnPressed3: UIButton!
#IBOutlet weak var btnPressed4: UIButton!
#IBOutlet weak var timePrint1: UILabel!
#IBOutlet weak var timePrint2: UILabel!
#IBOutlet weak var timePrint4: UILabel!
#IBOutlet weak var timePrint3: UILabel!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var progressBar1: UIProgressView!
#IBOutlet weak var progressBar2: UIProgressView!
#IBOutlet weak var progressBar3: UIProgressView!
#IBOutlet weak var progressBar4: UIProgressView!
let start = 5
var timer = Timer()
var player: AVAudioPlayer!
var totalTime = 0
var secondsPassed = 0
#IBAction func startButtonPressed(_ sender: UIButton) {
let startB = sender.titleLabel?.text
totalTime = start
progressBar1.progress = 0.0
secondsPassed = 0
titleLabel.text = "coffee timer"
btnPressed1.titleLabel?.textColor = UIColor.white
timer = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector: #selector(updateTimer), userInfo:nil, repeats: true)
}
#objc func updateTimer() {
if secondsPassed < totalTime {
secondsPassed += 1
progressBar1.progress = Float(secondsPassed) / Float(totalTime)
print(Float(secondsPassed) / Float(totalTime))
} else {
timer.invalidate()
titleLabel.text = "check coffee"
btnPressed1.titleLabel?.textColor = UIColor.green
let url = Bundle.main.url(forResource: "alarm_sound", withExtension: "mp3")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
}
}
There's lots of different ways to handle this. Here is an outline of a possible approach:
Have an instance variable currentProgress, of type Int? If it's nil, none of your progress indicators is running.
Have an instance var stepCompletedInterval: Double
Create a struct to hold the different views you use to manage a progress step:
struct ProgressInfo {
let aButton: UIButton
let aLabel: UILabel
let aProgressIndicator: UIProgressIndicator
let secondsForThisStep: Int
}
Create an array of ProgressInfo, (let's call it progressInfoArray) and populate it with the buttons, labels, and progress indicators you have above. Also give each entry a value for secondsForThisStep.
When the user starts the process, set currentProgress to 0 (The first progress indicator.)
Now, for each step, set a stepCompletedInterval to the current time plus progressInfoArray[currentProgress].secondsForThisStep (The time at which the current step should complete.
Also start a 1-second repeating timer. Each time the timer fires, check to see if the current time is greater than stepCompletedInterval. If it is, increment currentProgress if there are still more steps to complete, and repeat the "now for each step" part above.
That is a rough outline of how you might go about it. I'm not completely clear on what your start buttons and btnPressed1 to btnPressed4 are supposed to do, so I'll leave that for you.
You'll need to adapt the approach I've outlined to your needs. It isn't code, it's an approach. I'm not going to give you code.

Decrease the value of the variable containing the current time with UISlider

I don't know how to make the current time value (returned by the dateFormatter variable) change when scrolling the slider.
I tried to convert the dateFormatter variable to double but without success.
var c: Double
c = Double(dateFormatter.string(from: Date())
I would like to decrease the value of the time -1 hour for each shift of the slider thumb.
The changeTime function has to take care of changing the time value when moving the slider.
#IBOutlet weak var sliderTime: UISlider!
#IBOutlet var labelTime: UILabel!
var timer = Timer()
var dateFormatter = DateFormatter()
override func viewDidLoad()
{
dateFormatter.timeStyle = .short
labelTime.text = dateFormatter.string(from: Date())
timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(updateTimeLabel), userInfo: nil, repeats: true);
}
#objc func updateTimeLabel() {
labelTime.text = dateFormatter.string(from: Date())
}
#IBAction func changeTime(_ sender: Any) {
}
Swift 5
Whenever you update the date, decrease the number of hours dedicated by slider from the current date, try this:
class ViewController: UIViewController
{
#IBOutlet weak var simpleSlider: UISlider!
#IBOutlet weak var dateLabel: UILabel!
var timer = Timer()
var currentSliderStep: Int = 0
var dateFormatter = DateFormatter()
override func viewDidLoad()
{
dateFormatter.timeStyle = .short
labelTime.text = dateFormatter.string(from: Date())
timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(updateTimeLabel), userInfo: nil, repeats: true);
}
#objc func updateTimeLabel()
{
let newDate = Calendar.current.date(byAdding: .hour, value: -currentSliderStep, to: Date())!
labelTime.text = dateFormatter.string(from: newDate)
}
#IBAction func sliderMoved(sender: AnyObject)
{
let value = simpleSlider.value
let step: Float = 1
let roundedValue = round(value / step) * step
currentSliderStep = Int(roundedValue)
}
}
Note: With the Slider, the "Primary Action Triggered" event is triggered when it is adjusted. This is the perfect event to handle (link this event to sliderMoved).

How to capture the elapsed time when a timer is paused

I have put together a count down timer so the user can recored their practice seasons. I have it working fine except for one part. The user is allowed to pause the session. The problem with the code thus far, is that the timer code pauses but the time keeps running.
For example, if the user sets the timer for 5 minutes and taps the start button, then midway through the user taps pauses and waits 2 minutes (which means the elapsed time is now 7 minutes) the practice time presented when the timer ends is 7 minutes instead fo 5 minutes. If the user cancels the session it's fine but only because I'm setting a hard start and end time.
My question is how do I capture the practice time if the user pauses the timer?
Here's an explanation of the UI:
The timerLabel contains the running time
The minutesLabel shows the number of minutes the user set the timer to
The hoursLabel shows the number of hours the user set the timer to
There are two sliders. One for setting the minutes and one fo setting the hours
There are also two buttons. A Play/Cancel button and a Pause/Resume button
Thanks in advance!
import UIKit
import AVFoundation
class Practice_Timmer_VC: UIViewController
{
#IBOutlet weak var navBar: UINavigationItem!
#IBOutlet weak var viewLabel: DesignableLabel!
#IBOutlet weak var timerLabel: DesignableLabel!
#IBOutlet weak var theTabbar: UITabBar!
#IBOutlet weak var minutesLabel: UILabel!
#IBOutlet weak var hoursLabel: UILabel!
var seconds: Int = 60
var timer = Timer()
var isTimerRunning: Bool = false
var resumeTapped: Bool = false
var theTime: String = ""
var startTime: Date = Date()
var endTime: Date = Date()
var total: Int = 0
var chimeSoundEffect: AVAudioPlayer?
override func viewDidLoad()
{
super.viewDidLoad()
theTabbar.selectedItem = theTabbar.items![4]
view.backgroundColor = UIColor(patternImage: UIImage(named: "Carbon.png")!)
startButton.isEnabled = true
pauseButton.isEnabled = false
populateTheTimer()
}// End of viewDidLoad
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
startButton.setImage(UIImage(named: "Play"), for: .normal)
}
func populateTheTimer()
{
let theName = ModelData.getTheTrickName()
navBar.title = theName
}
func getTheDifference(start: Date, end: Date)
{
let theFormatter = DateComponentsFormatter()
theFormatter.allowedUnits = [.hour, .minute]
theFormatter.unitsStyle = .full
theTime = theFormatter.string(from: start, to: end) ?? ""
}
func formattedDate() -> String
{
let formatter = DateFormatter()
let date = Date()
formatter.locale = Locale.current
formatter.dateStyle = .medium
return formatter.string(from: date)
}
func timeString(time: TimeInterval) -> String
{
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i:%02i", hours, minutes, seconds)
}
func runTimer()
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(self.updateTimer)), userInfo: nil, repeats: true)
isTimerRunning = true
pauseButton.isEnabled = true
}
#objc func updateTimer()
{
if seconds < 1
{
timer.invalidate()
endTime = Date()
getTheDifference(start: startTime, end: endTime)
startButton.setImage(UIImage(named: "Play"), for: .normal)
startButton.isEnabled = true
pauseButton.isEnabled = false
playTheSound()
showAlert()
} else {
seconds -= 1
timerLabel.text = timeString(time: TimeInterval(seconds))
}
}
func showAlert()
{
let theAlert = UIAlertController(title: "Practice Ended", message: "\(formattedDate())\nPracticed for: \(theTime)", preferredStyle: .alert)
let saveTheInfo = UIAlertAction(title: "Save Practice", style: .default) { (saveAction) in
self.gotoAddEdit()
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (cancelAction) in
}
theAlert.addAction(saveTheInfo)
theAlert.addAction(cancel)
present(theAlert, animated: true)
}
func playTheSound()
{
let path = Bundle.main.path(forResource: "chime.mp3", ofType: nil)!
let theURL = URL(fileURLWithPath: path)
do {
chimeSoundEffect = try AVAudioPlayer(contentsOf: theURL)
chimeSoundEffect?.play()
} catch {
}
}
func gotoAddEdit()
{
let sb = UIStoryboard(name: "Main", bundle: nil)
if let addEdit = sb.instantiateViewController(withIdentifier: "Practice_Log_VC") as? Practice_Log_VC
{
addEdit.passData = "\(formattedDate())\nPracticed for: \(theTime)"
addEdit.delegate = self as? Timer2PracticeLog_Delegate
self.navigationController?.pushViewController(addEdit, animated: ModelData.isAnimation())
self.navigationController?.view.semanticContentAttribute = .forceLeftToRight
}
}
#IBOutlet weak var startButton: DesignableButton!
#IBAction func startButtonTapped(_ sender: DesignableButton)
{
let minutes2Seconds = Int(minutesSliderOutlet.value) * 60
let hours2Seconds = Int(hoursSliderOutlet.value) * 3600
seconds = Int(minutes2Seconds + hours2Seconds)
if isTimerRunning == false // Start
{
if seconds > 0
{
startTime = Date()
sender.setImage(UIImage(named: "Cancel_Video"), for: .normal)
runTimer()
} else {
view.sendConfirmationAlert(theTitle: "Error! Practice time is set to 0.", theMessage: "Please set the practice time.", buttonTitle: "OK")
minutesSliderOutlet.value = 1
minutesLabel.text = "1 Minute"
}
} else { // Cancel
endTime = Date()
timer.invalidate()
seconds = 0
getTheDifference(start: startTime, end: endTime)
sender.setImage(UIImage(named: "Play"), for: .normal)
minutesSliderOutlet.value = 1
minutesLabel.text = "1 Minute"
hoursSliderOutlet.value = 0
hoursLabel.text = "0 Hours"
timerLabel.text = timeString(time: TimeInterval(seconds))
isTimerRunning = false
pauseButton.isEnabled = false
showAlert()
}
}
#IBOutlet weak var pauseButton: DesignableButton!
#IBAction func pauseButtonTapped(_ sender: DesignableButton)
{
if resumeTapped == false
{
timer.invalidate()
resumeTapped = true
sender.setImage(UIImage(named: "Resume"), for: .normal)
} else {
runTimer()
resumeTapped = false
sender.setImage(UIImage(named: "Pause"), for: .normal)
}
}
#IBOutlet weak var minutesSliderOutlet: UISlider!
#IBAction func minuteSlider(_ sender: UISlider)
{
let minutes = Int(sender.value)
if minutes > 1
{
minutesLabel.text = String(minutes) + " Minutes"
} else {
minutesLabel.text = String(minutes) + " Minute"
}
}
#IBOutlet weak var hoursSliderOutlet: UISlider!
#IBAction func hoursSlider(_ sender: UISlider)
{
let hours = Int(sender.value)
if hours > 1
{
hoursLabel.text = String(hours) + " Hours"
} else {
hoursLabel.text = String(hours) + " Hour"
}
}
}// End of Class
Get the time when the user pauses the app as a new date(), and also the time when the user resumes the app. Get the difference between those two dates/times and subtract that from the total time to get the correct total time for the practice session.
For example, you could have a variable that keeps track of total pause time:
var totalPauseTime: TimeInterval = 0
var pauseStartTime: Date?
It gets recalculated every time a user taps the pause button to resume (after previously having tapped it to pause):
#IBAction func pauseButtonTapped(_ sender: DesignableButton)
{
if resumeTapped == false
{
pauseStartTime = Date()
timer.invalidate()
resumeTapped = true
sender.setImage(UIImage(named: "Resume"), for: .normal)
} else {
if let pauseStartTime = pauseStartTime {
totalPauseTime += Date().timeIntervalSinceReferenceDate - pauseStartTime.timeIntervalSinceReferenceDate
}
runTimer()
resumeTapped = false
sender.setImage(UIImage(named: "Pause"), for: .normal)
}
}
Haven't actually tested the above code but it should give an idea. Then you subtract totalPauseTime at the point in your code where you calculate the total session time.

Remove the UIView at Runtime and Automatically Correct the UI

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.

Use of unresolved identifier userDefaults

What is causing this to happen? the two instances of this error apear at the very bottom of my view controller in which the lines start with "userDefaults". here is my code
import UIKit
class SecondViewController : UIViewController,UITextFieldDelegate {
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var datePicker: UIDatePicker!
var aRandomDate = NSDate()
override func viewDidLoad() {
super.viewDidLoad()
datePicker.addTarget(self, action: Selector("datePickerChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerChanged(datePicker:UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
var strDate = dateFormatter.stringFromDate(datePicker.date)
dateLabel.text = strDate
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true;
}
#IBAction func Save(sender: UIButton) {
var t = EventSaver(pEventName: "Drinking Coffee", pEventDate: aRandomDate )
let encodedEventName = NSKeyedArchiver.archivedDataWithRootObject(t.EventName)
let encodedEventDate = NSKeyedArchiver.archivedDataWithRootObject(t.EventDate)
var encodedArray: [NSData] = [encodedEventName,]
userDefaults.setObject(encodedArray, forKey: "Event")
userDefaults.synchronize()
println("saved")
}
}
Make it like this:
#IBAction func Save(sender: UIButton) {
var t = EventSaver(pEventName: "Drinking Coffee", pEventDate: aRandomDate )
var userDefaults = NSUserDefaults.standardUserDefaults()
let encodedEventName = NSKeyedArchiver.archivedDataWithRootObject(t.EventName)
let encodedEventDate = NSKeyedArchiver.archivedDataWithRootObject(t.EventDate)
var encodedArray: [NSData] = [encodedEventName,]
userDefaults.setObject(encodedArray, forKey: "Event")
userDefaults.synchronize()
println("saved")
}
It seems like you haven't declared the constant userDefaults.
Add the following line before you set the encodedArray object in the userDefaults:
let userDefaults = NSUserDefaults.standardUserDefaults()
You aren't declaring userDefauts
let userDefaults = NSUserDefaults.standardUserDefaults()

Resources