mega-noob question:
So right now I'm just trying to test my variable system in my gpa project. When popup button is altered it alters the value of a courses point total for example
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
func UPDTmathG(_ sender: Any) {
if let title = (sender as AnyObject).titleOfSelectedItem, title == "A+" {
mathPoints = 4.3;
}
if let title = (sender as AnyObject).titleOfSelectedItem, title == "A" {
mathPoints = 4;
}
Now to test that these variables are actually changing an learn how to change string values.
testLabel.stringValue = String(mathPoints);
Ideally, when this added to the func UPDTmathG(_ sender: Any) {.
It would update the string value of the label to be the value of the variable, but the string isn't updating. Any ideas?
Thanks:)
Is there a way to check if the login item already exists (with bundleIdentifier of the app?) I want to be able to see if there is a login item and if it is enable.
I was trying to check my checkbox in applicationDidFinishLuanching when the login item is enabled using this:
if (SMLoginItemSetEnabled(("bundleIDOfMyApp" as CFStringRef), true)) {
self.startAtLoginButton.state = 1
} else {
self.startAtLoginButton.state = 0
}
It does its thing, but it also launches my helper application.
Another thing is this:
#IBAction func startAtLoginButtonChecked(sender: NSButton) {
var enabled = false
if sender.state == 0 { enabled = false }
if sender.state == 1 { enabled = true }
if !SMLoginItemSetEnabled(("bundleIDOfMyApp" as CFStringRef), enabled) {
print("Login was not successful")
}
}
As far as I am concerned this is the way you implement checkbox to enable/disable login item.
What it does in my app is every time I check the box it launches the helper app (which launches my app again).
Although the method SMCopyAllJobDictionaries() is deprecated this is the usual way to check if the job is enabled, SMLoginItemSetEnabled is only be used to set the value
import ServiceManagement
let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as NSArray as! [[String:AnyObject]]
let label = "bundleIDOfMyApp"
let jobEnabled = jobDicts.filter { $0["Label"] as! String == label }.isEmpty == false
The double casting is needed to cast CFArray to NSArray and then to Array<String,AnyObject>
Also usually the checkbox is bound to a property via KVC. The lines above are the getter and SMLoginItemSetEnabled is the setter for example
let helperBundleIdentifier = "bundleIDOfMyApp"
#available(OSX, deprecated=10.10) // this line suppresses the 'deprecated' warning
dynamic var startAtLogin : Bool {
get {
guard let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as NSArray as? [[String:AnyObject]] else { return false }
return jobDicts.filter { $0["Label"] as! String == helperBundleIdentifier }.isEmpty == false
} set {
if !SMLoginItemSetEnabled(helperBundleIdentifier, newValue) {
print("SMLoginItemSetEnabled failed.")
}
}
}
Swift 3:
#available(OSX, deprecated: 10.10)
dynamic var startAtLogin : Bool {
get {
guard let jobDicts = SMCopyAllJobDictionaries( kSMDomainUserLaunchd ).takeRetainedValue() as? [[String:Any]] else { return false }
return jobDicts.first(where: { $0["Label"] as! String == helperBundleIdentifier }) != nil
} set {
if !SMLoginItemSetEnabled(helperBundleIdentifier as CFString, newValue) {
print("SMLoginItemSetEnabled failed.")
}
}
}
Side note: A launchd job requires the key Label so it's 100% safe to unwrap the optional in the filter function.
I work on a custom keyboard (My Keyboard is no xib or StoryBoard),
I want to know if I can choose the background to remain constant
according to the choice The custom keyboard on
For example: When I choose the keyboard to keyboard Dark then stay in the selected mode "Dark".
And when I want to change the background again to be in the Light then again to stay in the selected mode "Light".
This would look like:
KeyboardInputTraits.swift
func pollTraits() {
if let proxy = (self.textDocumentProxy as? UITextInputTraits) {
if let layout = self.layout {
let appearanceIsDark = (proxy.keyboardAppearance == UIKeyboardAppearance.Dark)
if appearanceIsDark != layout.darkMode {
self.updateAppearances(appearanceIsDark)
}
}
}
}
KeyboardViewController.swift
func darkMode() -> Bool {
var darkMode = { () -> Bool in
if let proxy = self.textDocumentProxy as? UITextDocumentProxy {
return proxy.keyboardAppearance == UIKeyboardAppearance.Dark
}
else {
return false
}
}()
return darkMode
}
I am working on the code below to check the textField1 and textField2 text fields whether there is any input in them or not.
The IF statement is not doing anything when I press the button.
#IBOutlet var textField1 : UITextField = UITextField()
#IBOutlet var textField2 : UITextField = UITextField()
#IBAction func Button(sender : AnyObject)
{
if textField1 == "" || textField2 == ""
{
//then do something
}
}
Simply comparing the textfield object to the empty string "" is not the right way to go about this. You have to compare the textfield's text property, as it is a compatible type and holds the information you are looking for.
#IBAction func Button(sender: AnyObject) {
if textField1.text == "" || textField2.text == "" {
// either textfield 1 or 2's text is empty
}
}
Swift 2.0:
Guard:
guard let text = descriptionLabel.text where !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text where !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Swift 3.0:
Guard:
guard let text = descriptionLabel.text, !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text, !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Better and more beautiful use
#IBAction func Button(sender: AnyObject) {
if textField1.text.isEmpty || textField2.text.isEmpty {
}
}
another way to check in realtime textField source :
#IBOutlet var textField1 : UITextField = UITextField()
override func viewDidLoad()
{
....
self.textField1.addTarget(self, action: Selector("yourNameFunction:"), forControlEvents: UIControlEvents.EditingChanged)
}
func yourNameFunction(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
if let ... where ... {
Swift 3:
if let _text = theTextField.text, _text.isEmpty {
// _text is not empty here
}
Swift 2:
if let theText = theTextField.text where !theTextField.text!.isEmpty {
// theText is not empty here
}
guard ... where ... else {
You can also use the keyword guard :
Swift 3:
guard let theText = theTextField.text where theText.isEmpty else {
// theText is empty
return // or throw
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
Swift 2:
guard let theText = theTextField.text where !theTextField.text!.isEmpty else {
// the text is empty
return
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
This is particularly great for validation chains, in forms for instance. You can write a guard let for each validation and return or throw an exception if there's a critical error.
As now in swift 3 / xcode 8 text property is optional you can do it like this:
if ((textField.text ?? "").isEmpty) {
// is empty
}
or:
if (textField.text?.isEmpty ?? true) {
// is empty
}
Alternatively you could make an extenstion such as below and use it instead:
extension UITextField {
var isEmpty: Bool {
return text?.isEmpty ?? true
}
}
...
if (textField.isEmpty) {
// is empty
}
use this extension
extension String {
func isBlankOrEmpty() -> Bool {
// Check empty string
if self.isEmpty {
return true
}
// Trim and check empty string
return (self.trimmingCharacters(in: .whitespaces) == "")
}
}
like so
// Disable the Save button if the text field is empty.
let text = nameTextField.text ?? ""
saveButton.isEnabled = !text.isBlankOrEmpty()
A compact little gem for Swift 2 / Xcode 7
#IBAction func SubmitAgeButton(sender: AnyObject) {
let newAge = String(inputField.text!)
if ((textField.text?.isEmpty) != false) {
label.text = "Enter a number!"
}
else {
label.text = "Oh, you're \(newAge)"
return
}
}
Maybe i'm a little too late, but can't we check like this:
#IBAction func Button(sender: AnyObject) {
if textField1.text.utf16Count == 0 || textField2.text.utf16Count == 0 {
}
}
Okay, this might be late, but in Xcode 8 I have a solution:
if(textbox.stringValue.isEmpty) {
// some code
} else {
//some code
}
I used UIKeyInput's built in feature hasText: docs
For Swift 2.3 I had to use it as a method instead of a property (as it is referenced in the docs):
if textField1.hasText() && textField2.hasText() {
// both textfields have some text
}
Swift 4.x Solution
#IBOutlet var yourTextField: UITextField!
override func viewDidLoad() {
....
yourTextField.addTarget(self, action: #selector(actionTextFieldIsEditingChanged), for: UIControlEvents.editingChanged)
}
#objc func actionTextFieldIsEditingChanged(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
Swift 4.2
You can use a general function for your every textField just add the following function in your base controller
// White space validation.
func checkTextFieldIsNotEmpty(text:String) -> Bool
{
if (text.trimmingCharacters(in: .whitespaces).isEmpty)
{
return false
}else{
return true
}
}
I just tried to show you the solution in a simple code
#IBAction func Button(sender : AnyObject) {
if textField1.text != "" {
// either textfield 1 is not empty then do this task
}else{
//show error here that textfield1 is empty
}
}
It's too late and its working fine in Xcode 7.3.1
if _txtfield1.text!.isEmpty || _txtfield2.text!.isEmpty {
//is empty
}
Swift 4/xcode 9
IBAction func button(_ sender: UIButton) {
if (textField1.text?.isEmpty)! || (textfield2.text?.isEmpty)!{
..............
}
}
Easy way to Check
if TextField.stringValue.isEmpty {
}
I have to find the number of lines of a UITextView. There is no property available, like anumberOfLines, on UITextView. I use the following formula, but it not doesn't work. Does anybody have an idea about this?
int numLines = txtview.contentSize.height/txtview.font.lineHeight;
If you are using iOS 3, you need to use the leading property:
int numLines = txtview.contentSize.height / txtview.font.leading;
If you are using iOS 4, you need to use the lineHeight property:
int numLines = txtview.contentSize.height / txtview.font.lineHeight;
And, as #thomas pointed out, be careful of rounding if you need an exact result.
Swift 4 way to calculate number of lines in UITextView using UITextInputTokenizer:
public extension UITextView {
/// number of lines based on entered text
public var numberOfLines: Int {
guard compare(beginningOfDocument, to: endOfDocument).same == false else {
return 0
}
let direction: UITextDirection = UITextStorageDirection.forward.rawValue
var lineBeginning = beginningOfDocument
var lines = 0
while true {
lines += 1
guard let lineEnd = tokenizer.position(from: lineBeginning, toBoundary: .line, inDirection: direction) else {
fatalError()
}
guard compare(lineEnd, to: endOfDocument).same == false else {
break
}
guard let newLineBeginning = tokenizer.position(from: lineEnd, toBoundary: .character, inDirection: direction) else {
fatalError()
}
guard compare(newLineBeginning, to: endOfDocument).same == false else {
return lines + 1
}
lineBeginning = newLineBeginning
}
return lines
}
}
public extension ComparisonResult {
public var ascending: Bool {
switch self {
case .orderedAscending:
return true
default:
return false
}
}
public var descending: Bool {
switch self {
case .orderedDescending:
return true
default:
return false
}
}
public var same: Bool {
switch self {
case .orderedSame:
return true
default:
return false
}
}
}
You can look at the contentSize property of your UITextView to get the height of the
text in pixels, and divide by the line spacing of the UITextView's font to get the
number of text lines in the total UIScrollView (on and off screen), including both wrapped and line broken text.
int numLines = txtview.contentSize.height/txtview.font.leading;