Swift Character Count - swift

I'm new to xcode, need to find the character count of the String in the UILabel
#IBAction func buttonPressed(_ sender: Any) {
curr_channel.text = ""
let tag = (sender as! UIButton).tag
if((curr_channel.text?.character.count())! < 2){
curr_channel.text = curr_channel.text! + String(tag)
}
}

I guess this is what you need :
#IBAction func buttonPressed(_ sender: Any) {
let tag = (sender as! UIButton).tag
if let text = curr_channel.text, text.count < 2 {
curr_channel.text = "\(text) \(tag)"
}
}

Here's how you can print/ get the character count in a UILable.
#IBOutlet weak var myLabel: UILabel!
#IBAction func buttonPressed(_ sender: Any) {
let countOfCharsInLabel = myLabel.text?.count
print("\(countOfCharsInLabel)")
}

Related

ViewController doesn't pass data on completion

I have 2 ViewControllers.
TimerViewController passes a variable to the EditTimerViewConroller. EditTimerViewConroller edits it and should pass it back, but it looks like code in .completion is not executed.
Any advice how to fix it?
My code is:
TimerViewController
import UIKit
import AVFoundation //play sounds
class TimerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var player: AVAudioPlayer!
var timer = Timer()
var totalTime = 10.0
var secondsRemaining = 10.0
var secondsPassed = 0.0
let timerStep = 0.1
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var progressBar: UIProgressView!
#IBAction func startPressed(_ sender: UIButton) {
//works fine
}
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
func playSound(fileName: String) {
//works fine
}
#objc func updateTimer() {
//works fine
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
}
}
EditTimerViewController
import UIKit
class EditTimerViewController: UIViewController {
let maxDuration = 60
var duration: Int? //timer duraton is passed from Timer
public var completion: ((Int?) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
durationSlider.minimumValue = 0
durationSlider.maximumValue = Float(maxDuration)
durationSlider.value = Float(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBOutlet weak var durationLabel: UILabel!
#IBOutlet weak var durationSlider: UISlider!
#IBAction func durationSliderChanged(_ sender: UISlider) {
duration = Int(sender.value)
print(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBAction func cancelPressed(_ sender: UIButton) {
print("Cancel pressed, dismissing Edit screen")
self.dismiss(animated: true, completion: nil)
}
#IBAction func savePressed(_ sender: UIButton) {
print("Save pressed, duration is \(duration!)")
completion?(duration!)
self.dismiss(animated: true, completion: nil)
}
}
In the output after pressing Save button I see
Save pressed, duration is 11
but after it there is no sign of
editTimer completed, totalTime now is 11
and timer duration never changes
Change
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
To
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
}
And move completion inside prepare
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
destinationVC.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \ (self?.totalTime)")
}
}
}
}

How can I make variables inside an IBAction public to all view controllers?

So I'm trying to make a Chess Time app, where both players have access to a clock and they change the time between bullet(3minutes), Blitz(5minutes), and Rapid(10Minutes). Well in my second view controller SettingsController I made 3 IBActions UIButtons for this.
#IBAction func bulletPressed(_ sender: UIButton) {
var storedTime = bullet
self.delegate?.storedTimeTimer()
self.navigationController?.popViewController(animated: true)
}
#IBAction func blitzPressed(_ sender: UIButton) {
var storedTime = blitz
}
#IBAction func rapidPressed(_ sender: UIButton) {
var storedTime = rapid
}
This is my SettingsController, my whole point is trying to get the storedTime into the first controller. I tried to use a delegate, but I couldn't get it to work.
Here is the full First Controller:
import UIKit
class ChessTimer: UIViewController {
#IBOutlet weak var playerTimer1: UILabel!
#IBOutlet weak var playerTimer2: UILabel!
var timer = Timer()
var time = 10
var isTimerRunning = false
override func viewDidLoad() {
super.viewDidLoad()
if isTimerRunning == false {
runTimer()
}
}
#IBAction func restartButton(_ sender: UIButton) {
}
#IBAction func pausePressed(_ sender: UIButton) {
timer.invalidate()
}
#IBAction func settingsPressed(_ sender: UIButton) {
performSegue(withIdentifier: "goToSettings", sender: self)
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self,selector:
(#selector(ChessTimer.updateTimer)),userInfo: nil, repeats: true)
isTimerRunning = true
}
#objc func updateTimer() {
if storedTime! < 1 {
timer.invalidate()
playerTimer1.text = "00:00"
playerTimer2.text = "00:00"
}
else {
storedTime! -= 1
playerTimer1.text = prodTimeString(time: TimeInterval(storedTime)!)
}
}
func prodTimeString(time: TimeInterval) -> String {
let prodMinutes = Int(time) / 60 % 60
let prodSeconds = Int(time) % 60
return String(format: "%02d:%02d", prodMinutes, prodSeconds)
}
#IBAction func playerButton1(_ sender: UIButton) {
}
#IBAction func playerButton2(_ sender: UIButton) {
}
}
extension ChessTimer: SettingsControllerDelegate {
func storedTimeTimer() {
}
}
This is the second full controller
import UIKit
class SettingsController: UIViewController {
var bullet = "03:00"
var blitz = "05:00"
var rapid = "10:00"
var storedTime = 0
var delegate: SettingsControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func bulletPressed(_ sender: UIButton) {
var storedTime = bullet
self.delegate?.storedTimeTimer()
self.navigationController?.popViewController(animated: true)
}
#IBAction func blitzPressed(_ sender: UIButton) {
var storedTime = blitz
}
#IBAction func rapidPressed(_ sender: UIButton) {
var storedTime = rapid
}
}
protocol SettingsControllerDelegate {
func storedTimeTimer()
}
This can be achieved using a Constants.swift file.
Click File -> New -> File -> Swift File and then name it Constants.swift.
In Constants.swift, declare var storedTime = 0.
Delete var storedTime = 0 from your view controllers, you'll only need it in Constants.swift. (So delete it from SettingsController, etc.)
The storedTime variable will now be public to all view controllers. 👍
Hope this helps someone!

Trying to pass Doubles from a view to an another but it doesn't work

Hey I'm a newbie to Swift and Xcode and I am trying to make a little app but I have an error and can't fix it.
I'm trying to passe a double from a view to another but it says
Binary operator '+=' cannot be applied to operands of type 'String' and "int"
That's my first view :
#IBOutlet weak var Rned: UILabel!
var ArgentC: Double = 0
override func viewDidLoad() {
super.viewDidLoad()
Rned.text = String(ArgentC)
Rned.backgroundColor = UIColor(patternImage: UIImage(named: "Rectangle2")!)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let SecondViewController = segue.destination as! SacocheVCp2
SecondViewController.ArgentCV = Rned.text!
}
#IBAction func Reset(_ sender: Any) {
Rned.text = String(0)
ArgentC = 0
}
#IBAction func CashButton(_ sender: Any) {
performSegue(withIdentifier: "segueSac", sender: self)
}
and that is my second view with the error, and the error appears when I want to add numbers to my doubles.
#IBOutlet weak var Rend2Label: UILabel!
var ArgentCV = String()
override func viewDidLoad() {
super.viewDidLoad()
Rend2Label.backgroundColor = UIColor(patternImage: UIImage(named: "Label")!)
Rend2Label.text = ArgentCV
// Do any additional setup after loading the view.
}
#IBAction func CinqEur(_ sender: Any) {
ArgentCV += 5 // <== Here
Rend2Label.text = ArgentCV
}
#IBAction func DixEur(_ sender: Any) {
ArgentCV += 10 // <== Here
}
#IBAction func VingtEur(_ sender: Any) {
ArgentCV += 20 // <== Here
}
#IBAction func CinquanteEur(_ sender: Any) {
ArgentCV += 50 // <== Here
}
Thanks for your time.
You don't have to send it as a String , you can send it as Int
secondViewController.argentCV = Int(rned.text) ?? 0 // ?? to avoid crashes but make sure it doesn't destroy logic
Then inside SacocheVCp2
var argentCV = 0 // 0 is default
Finally
argentCV += 5 // <== Here
rend2Label.text = "\(argentCV)"

Swift OSX NSImageView Drag and Drop

I am trying to execute an action after dropping an image on a drag and drop NSImageView but it is not working. How can I control the drag and drop operations?
I have the logoFornecedorImageView that is an NSImageView outlet. My class inherits from NSDraggingDestinatio and the dragged types are registered, but when I run the software and drag an image on it nothing happens, nothing is printed in the console.
import Cocoa
class InserirFornecedorViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate, NSDraggingDestination {
#IBOutlet weak var tituloJanelaLabel: NSTextField!
#IBOutlet weak var logoFornecedorImageView: NSImageView!
#IBOutlet weak var nomeFornecedorTextField: NSTextField!
#IBOutlet weak var materialFornecidoTextField: NSTextField!
#IBOutlet weak var materiaisTableView: NSTableView!
#IBOutlet weak var indicadorAtividadeProgressIndicator: NSProgressIndicator!
#IBOutlet weak var salvarFornercedorButton: NSButton!
var fornecedor: Fornecedor?
var logoFornecedorSelecionada = false
override func viewDidLoad() {
super.viewDidLoad()
materiaisTableView.dataSource = self
materiaisTableView.delegate = self
logoFornecedorImageView.register(forDraggedTypes: logoFornecedorImageView.registeredDraggedTypes)
fornecedor = Fornecedor()
}
func draggingEnded(_ sender: NSDraggingInfo?) {
print("END")
logoFornecedorSelecionada = true
}
func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
print("ENTERED")
return .generic
}
func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
print("UPDATED")
return .generic
}
func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
return true
}
func numberOfRows(in tableView: NSTableView) -> Int {
return fornecedor?.materiais.count ?? 0
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
var cell: NSTableCellView?
//if tableColumn == tableView.tableColumns[0]
if fornecedor?.materiais.count != 0 {
let identificadorCell = "materialCellView"
let material = fornecedor?.materiais[row]
cell = tableView.make(withIdentifier: identificadorCell, owner: nil) as? NSTableCellView
cell?.textField?.stringValue = material!
}
return cell
}
#IBAction func selecionarImagemButtonClicked(_ sender: NSButton) {
let panel = NSOpenPanel()
panel.canChooseFiles = true
panel.canChooseDirectories = false
panel.allowsMultipleSelection = false
panel.canCreateDirectories = false
//panel.allowedFileTypes = ["jpg","png","pct","bmp", "tiff"]
panel.allowedFileTypes = NSImage.imageTypes()
panel.beginSheetModal(for: view.window!) { (result) in
if result == NSFileHandlingPanelOKButton {
self.logoFornecedorImageView.image = NSImage(byReferencing: panel.url!)
self.logoFornecedorSelecionada = true
}
}
}
#IBAction func removerImagemButtonClicked(_ sender: NSButton) {
logoFornecedorImageView.image = NSImage(named: "LogoImagemTexto")
logoFornecedorSelecionada = false
}
#IBAction func adicionarMaterialButton(_ sender: NSButton) {
if materialFornecidoTextField.stringValue.isEmpty {
mostrarErro(mensagem: "Erro de preenchimento", informativo: "Informe o material")
materialFornecidoTextField.becomeFirstResponder()
} else {
fornecedor?.materiais.append(materialFornecidoTextField.stringValue)
materialFornecidoTextField.stringValue = ""
fornecedor?.materiais.sort {
$0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending
}
materiaisTableView.reloadData()
}
}
#IBAction func voltarButton(_ sender: NSButton) {
//let usarSoftViewController = presenting as! UsarSoftViewController
//usarSoftViewController.ativarBoxPrincipal()
//usarSoftViewController.usuario = usuario
//usarSoftViewController.fazerLogin()
dismiss(self)
}
func mostrarErro(mensagem: String, informativo: String) {
let alert = NSAlert()
alert.messageText = mensagem
alert.informativeText = informativo
alert.addButton(withTitle: "Fechar")
alert.alertStyle = .critical
alert.runModal()
}
}
Thanks everyone
I just performed an action and it worked fine.
#IBAction func logoFornecedorImageDropped(_ sender: NSImageView) {
self.logoFornecedorSelecionada = true
}
To add a little more clarity around this, you can connect a regular IBAction to your Editable NSImageView and get the image. You don't have to do any subclassing or dragging delegates.
Just do this:
#IBAction func imageChange(_ sender: NSImageView) {
if let image = sender.image{
let imageData = image.tiffRepresentation
}
}
I hope that helps. :)

UIButtons won't click in simulator swift

Sorry if this is a dumb question. I just can't find why the UIbuttons are not working. They were working for awhile. Not sure what happened.
import UIKit
class ViewController: UIViewController
{
#IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTypingNumber = false
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingNumber {
display.text = display.text! + digit
}
else {
display.text = digit
userIsInTheMiddleOfTypingNumber = true
}
}
var operandStack = Array<Double>()
#IBAction func enter() {
userIsInTheMiddleOfTypingNumber = false
operandStack.append(displayValue)
println("operandStack = \(operandStack)")
}
var displayValue: Double {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTypingNumber = false
}
}
}
chances are that after having made the IBAction connect you would change the name of the function, which untying its storyboard to your ViewController, if this were the case consult the storyboard and unlink the above, then should link to new.
Also I suggest you check this out:
#IBAction func enter(sender: AnyObject) {}
or
#IBAction func enter(sender: UIButton!) {}