I made a timer and then I added a slider with a label that presented its value. What I want to do is have my last label (Moneyadded) show a multiplication of the slider value by the current amount of seconds with NStimer.
import UIKit
class ViewController: UIViewController {
var timercount = 0
var timerRunning = false
var timer = NSTimer()
var myVaribale: Int = 0
override func viewDidLoad() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
func update() {
// fired once a second
myVaribale += 258
}
#IBOutlet weak var timerlabel: UILabel!
func counting(){
timercount += 1
timerlabel.text = "\(timercount)"
var timerValue = timercount.value
}
#IBAction func Clockin(sender: UIButton) {
if timerRunning == false{
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counting"), userInfo: nil, repeats: true)
timerRunning = true
}
}
#IBAction func Clockout(sender: UIButton) {
if timerRunning == true{
timer.invalidate()
timerRunning = false
}
}
#IBAction func Restart(sender: UIButton) {
timercount = 0
timerlabel.text = "0"
}
#IBOutlet weak var Slider: UISlider!
#IBOutlet weak var Label: UILabel!
#IBAction func valuechanged(sender: UISlider) {
var currentValue = Int(Slider.value)
Label.text = "\(currentValue)"
}
#IBOutlet weak var Moneyadded: UILabel!
\\this is for the label (text) that I want the NStimer to be multiplied by the slider value.
Change your counting function to the following:
/** Gets triggered once every second */
func counting(){
timercount += 1
timerlabel.text = "\(timercount)"
Moneyadded.text = "\(timercount * Int(Slider.value))"
}
Related
It crash inside runTimer() because of two args. If I put only one or nothing - it works normal.
Crash forward to AppDelegate and error is
Thread 1: EXC_BAD_ACCESS (code=1, address=0x4)
var timer = Timer()
var seconds = Int()
#IBOutlet weak var twoMinView: UIView!
#IBOutlet weak var twoMinLabel: UILabel!
#objc func twoMinTimer() {
seconds = 120
runTimer(view: twoMinView, label: twoMinLabel)
}
#objc func runTimer(view: UIView, label: UILabel) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MyViewController.updateTimer(view:withLabel:)), userInfo: nil, repeats: true)
}
#objc func updateTimer(view: UIView, withLabel label: UILabel) {
seconds -= 1
if seconds < 1 {
view.isHidden = true
timer.invalidate()
if view == twoMinView {
streamView.isHidden = false
}
}
label.text = timeString(time: TimeInterval(seconds))
}
#objc func timeString(time: TimeInterval) -> String {
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format: "%02i : %02i", minutes, seconds)
}
Just delete updateTimer and replace runTimer with next one
#objc func runTimer(view: UIView, label: UILabel) {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
if self.seconds < 1 {
view.isHidden = true
timer.invalidate()
if view == self.twoMinView {
self.streamView.isHidden = false
}
}
label.text = self.timeString(time: TimeInterval(self.seconds))
self.seconds -= 1
})
}
I want a solution in my problem.
I have text field in Xcode and I wanna Xcode calculate string thats user input as:
var x = 1
var y = 2
like this
I wanna if the user input xy inside text field, the Xcode calculate like: 1+2
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var label1: UILabel!
#IBOutlet var label2: UILabel!
#IBOutlet var label3: UILabel!
#IBOutlet var label4: UILabel!
#IBOutlet var tex1: UITextField!
#IBOutlet var tex2: UITextField!
override function viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tex1.delegate = self
tex2.delegate = self
}
override function didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
function textFieldShouldReturn(_ textField: UITextField) -> Bool{
tex1.resignFirstResponder()
tex2.resignFirstResponder()
return true
}
#IBAction function close(_ sender: UIButton) {
tex1.resignFirstResponder()
tex2.resignFirstResponder()
}
#IBAction function pushAction(_ sender: UIButton) {
label4.text = String(Int(tex1.text)+Int(tex2.text))
}
}
var temp = 0
var prevCount = -1
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var txtAfterUpdate:NSString = textField.text! as NSString
txtAfterUpdate = txtAfterUpdate.replacingCharacters(in: range, with: string).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) as NSString
let newString:String! = String(txtAfterUpdate)
if(prevCount > newString.characters.count - 1){
if(newString.characters.count - 1 != -1){
self.enterAmount = self.enterAmount - Double(textField.text![(textField.text?.characters.count)! - 1])!
}else{
self.enterAmount = 0
}
}else{
self.enterAmount = Double(newString[newString.characters.count - 1])! + self.enterAmount
}
print("YOUR TOTAL \(self.enterAmount)")
prevCount = newString.characters.count - 1
return true
}
extension String{
subscript(i: Int) -> String {
guard i >= 0 && i < characters.count else { return "" }
return String(self[index(startIndex, offsetBy: i)])
}
subscript(range: Range<Int>) -> String {
let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) ?? endIndex
return substring(with: lowerIndex..<(index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) ?? endIndex))
}
subscript(range: ClosedRange<Int>) -> String {
let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) ?? endIndex
return substring(with: lowerIndex..<(index(lowerIndex, offsetBy: range.upperBound - range.lowerBound + 1, limitedBy: endIndex) ?? endIndex))
}
}
you can use like this
label4.text = "\(((tex1.text?.characters.count)! + (tex2.text?.characters.count)!))"
I have an app that has two ViewControllers. On the first there is a count of current speed in realtime through CLLocationManager. Also there is a label that shows current speed with update by timer (NSTimer). In second ViewController there is another Label, where this current speed has to be shown too. It shows it, but don't update. I tried to set second timer (different ways: in first VC, in second VC - there is always was an error or just nothing).
Will be grateful for help, thanks!
First VC
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var currentSpeedLabel: UILabel!
var manager = CLLocationManager()
var currentSpeed: CLLocationSpeed = CLLocationSpeed()
var timer = NSTimer()
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapType = MKMapType.Hybrid
trackingMe()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func HUDMapView(sender: AnyObject) {
speedCount()
}
#IBAction func findMe(sender: AnyObject) {
trackingMe()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0] as CLLocation
manager.stopUpdatingLocation()
let location = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
}
func trackingMe() {
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
mapView.showsUserLocation = true
currentSpeedUpdate()
}
func currentSpeedUpdate() {
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("speedCount"), userInfo: nil, repeats: true)
}
func speedCount() {
currentSpeed = manager.location!.speed
currentSpeedLabel.text = String(format: "%.0f km/h", currentSpeed * 3.6)
}
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
let speedController = segue.destinationViewController as! speedViewController
currentSpeed = manager.location!.speed
speedController.showSpeed = currentSpeedLabel.text
}
}
Second VC
import UIKit
class speedViewController: UIViewController {
#IBOutlet weak var secondSpeedLabel: UILabel!
var showSpeed: String!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
secondSpeedLabel.text = showSpeed
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func back(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Project Link
You could use a Singleton to hold the LocationManager. Then you can access it from all over your app. When you move to a second VC you can either change the delegate to the second VC or just get the needed data manually.
Remember that a delegate can only point to one "receiver". Changing the delegate will stop updates in the first VC. but since it is now a Singleton you can also store information in there about past locations / speeds. When dismissing the second VC get the stored data and update.
This will keep running until you call stop()
The code was simplified a bit to illustrate the idea.
VC Code:
import UIKit
import CoreLocation
class ViewController: UIViewController, TrackerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
Tracker.shared.delegate = self
Tracker.shared.start()
}
func speedUpdate(speed: CLLocationSpeed) {
print(speed)
}
}
Singleton Code:
import UIKit
import MapKit
import CoreLocation
class Tracker: NSObject, CLLocationManagerDelegate {
static var shared = Tracker()
private var manager = CLLocationManager()
private var timer = NSTimer()
var region : MKCoordinateRegion?
var currentSpeed: CLLocationSpeed = CLLocationSpeed()
weak var delegate : TrackerDelegate?
private override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
}
internal func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
let userLocation: CLLocation = locations[0] as CLLocation
let coordinates2D = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
region = MKCoordinateRegion(center: coordinates2D, span: span)
currentSpeed = userLocation.speed
guard let del = delegate else {
return
}
del.speedUpdate(currentSpeed)
}
func start() {
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.startUpdatingLocation()
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("loopUpdate"), userInfo: nil, repeats: true)
}
func stop() {
timer.invalidate()
}
internal func loopUpdate() {
// restart updating
manager.startUpdatingLocation()
}
}
Delegate for the Singleton:
Add more functions, or more values to the current function to get more feedback.
protocol TrackerDelegate : class {
func speedUpdate(speed:CLLocationSpeed)
}
I am using the code below to unhide UITextFields. It works great until I try to unhide a UITextView. It crashes with an error of trying to unwrap a nil value. My question is what do I need to implement to make the UITextView unhide like the UITextFields? Or do I need to use something beside a UITextView to allow a paragraph style input?
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
#IBOutlet weak var notesInput: UITextView!
#IBOutlet weak var scrollView: UIScrollView!
var activeTextField: UITextField!
// MARK: - View
override func viewDidLoad() {
super.viewDidLoad()
self.textField1.delegate = self
self.textField2.delegate = self
// self.textField3.delegate = self
// self.textField4.delegate = self
// self.textField5.delegate = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.unregisterFromKeyboardNotifications()
}
// MARK: - Keyboard
// Call this method somewhere in your view controller setup code.
func registerForKeyboardNotifications() {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
center.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}
func unregisterFromKeyboardNotifications () {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
// Called when the UIKeyboardDidShowNotification is sent.
func keyboardWasShown (notification: NSNotification) {
let info : NSDictionary = notification.userInfo!
let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
var aRect = self.view.frame
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
self.scrollView.scrollRectToVisible(self.activeTextField.frame, animated: true)
}
}
// Called when the UIKeyboardWillHideNotification is sent
func keyboardWillBeHidden (notification: NSNotification) {
let contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
// MARK: - Text Field
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
self.activeTextField = nil
}
So far I have this app that tracks the number of hits versus misses when the user touches a moving bug on the screen. I am able to register the touches for every time the bug is missed, however not when the bug is touched. Could someone help me understand what I am doing incorrectly and perhaps point me towards a possible solution. Thank you much.
import UIKit
class myViewController2: UIViewController {
#IBOutlet weak var lblBugAmount: UILabel!
var isBuggin = false
var hits = 0
var misses = 0
#IBOutlet weak var lblMissAmount: UILabel!
#IBOutlet weak var lblHitAmount: UILabel!
override func touchesBegan(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
++misses
--hits
lblMissAmount.text = String(misses)
lblHitAmount.text = String(hits)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btnStop(sender: UIButton) {
isBuggin = false
super.viewDidLoad()
}
#IBOutlet var bugs : UIImageView!
#IBOutlet weak var numberOfBugsSlider: UISlider!
#IBAction func btnAnimate(sender: UIButton) {
let numberOfBugs = Int(self.numberOfBugsSlider.value) //cast to Int, otherwise slider is decimal
for loopNumber in 0...numberOfBugs+3{
// constants for the animation
let duration = 1.0
let options = UIViewAnimationOptions.CurveLinear | UIViewAnimationOptions.Autoreverse
// randomly assign a delay of 0.3 to 1s
let delay = NSTimeInterval( ((Int(rand()) % 1000)+100.0) / 1000.0)
// constants for the bugs
let size : CGFloat = CGFloat( Int(rand()) % 80 + 100.0) //sizes
let yPosition : CGFloat = CGFloat( Int(rand()) % 200 + 20.0) + 80
// create the bugs
let bugs = UIImageView()
bugs.image = UIImage(named: "bug")
bugs.frame = CGRectMake(0-size, yPosition, size, size)
self.view.addSubview(bugs)
// define the animation
UIView.animateWithDuration(duration, delay: delay, options: options, animations: {
// move the bugs
bugs.frame = CGRectMake(320, yPosition, size, size)
}, completion: { animationFinished in
// remove the bugs
bugs.removeFromSuperview()
})
}
}
#IBAction func bugs(outlet: UIView) {
++hits
--misses
lblHitAmount.text = String(hits)
lblMissAmount.text = String(misses)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
EDIT:
touchesBegan & touchesMoved
override func touchesBegan(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
var touch : UITouch! = touches.anyObject() as UITouch
location = touch.locationInView(self.view)
self.bugs = touch.locationInView(self.view)
}
override func touchesMoved(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
var touch : UITouch! = touches.anyObject() as UITouch
location = touch.locationInView(self.view)
bugs.center = location
}
User interaction is disabled by default for UIViews and its descendants, you have to explicitly enable it:
// create the bugs
let bugs = UIImageView()
bugs.image = UIImage(named: "bug")
bugs.frame = CGRectMake(0-size, yPosition, size, size)
bugs.userInteractionEnabled = true // <--
self.view.addSubview(bugs)