How do you create a simple login screen in Xcode? - swift

I am making an app that uses a login screen I made. The input is this Text Field that you type in your username. How do I make it respond to different usernames? For example the username is UK. How do I make it respond to if it is or is not 'UK'? I am a complete beginner to Xcode so could you please walk me through the steps please?
I tried using this if(Username!.text, isEqual: "Hello") that I saw from a video, but an error pops up saying:
'(String?, isEqual: String)' is not convertible to 'Bool'.
I have no idea what it means and how to get around it.
import UIKit
class ViewController: UIViewController {
#IBOutlet var ftest: UILabel!
#IBOutlet var Username: UITextField?
#IBOutlet var Password: UITextField!
#IBAction func SignIn(_ sender: Any) {
if(Username!.text, isEqual: "Hello")
}
//this code above is the code I tried to do based on a video and it did not work.
override func viewDidLoad() {
super.viewDidLoad()
}
}
I want it to print "Hi" or something. I just want it to react to:
If the username is 'UK' and
If the username is not 'UK'.

You can just simply use == as follow
#IBAction func SignIn(_ sender: Any) {
if(Username!.text == "Hello" || Username!.text == "UK") {
print("Hi")
}
}
|| means OR
&& means AND
Hope this help!

You can do it in this way
#IBAction func SignIn(_ sender: Any) {
if Username!.text == "UK"
{
print("Hi")
}
else
{
// do your stuff
}
}
Moreover you can also use a variable to check whether a string contained in your textfield or not like this:
var Str = "UK"
if Str.contains(self.Username!.text!) {
print("Hi")
}
Extension way:
extension String {
func contains(find: String) -> Bool{
return self.range(of: find) != nil
}
}
var value = self.Username!.text // You can put value as of your textfield.text and then check
print(value.contains("UK")) // true
print(value.contains("THIS")) // false
if value.contains("UK") == true
{
print("Hi")
}
else
{
// do your stuff
}

Related

Cant get access to an object's values of a cell in TableView [Swift]

I created a class called BlogPost and a tableView. The tableView get filled with many cells and each cell presents the data of a different user (a blogPost object). In each cell there's a button with a phone icon and I want that everytime the user presses on the phone button in each cell, it will call the number of the specific object in that cell. The problem is that in the button function there is no access to the objects value. The line:
var num = blogPost.phone
works inside the setBlogPost function, but not in the button function outside the setBlogPost function :
#IBAction func whatsAppButton(_ sender: Any) {
//doesnt work
var num = blogPost.phone
openWhatsapp(number: num)
}
num gets an error of "Use of unresolved identifier 'blogPost'.
Full code:
import UIKit
class Tavla: UITableViewCell {
#IBOutlet weak var nameLabelTavla: UILabel!
#IBOutlet weak var locationButtonTavla: UIButton!
#IBOutlet weak var phoneButtonTavla: UIButton!
fileprivate let application = UIApplication.shared
func setBLogPost(blogPost: BlogPost) {
nameLabelTavla.text = blogPost.name
if blogPost.elsertext != "" {
locationButtonTavla.backgroundColor = UIColor(red: 135/255, green: 197/255, blue: 113/255, alpha: 0.5)
locationButtonTavla.setTitle("", for: .normal)
}
else{
}
//num works fine
var num = blogPost.phone
}
#IBAction func whatsAppButton(_ sender: Any) {
//num gets an error of "Use of unresolved identifier 'blogPost'
var num = blogPost.phone
openWhatsapp(number: num)
}
func openWhatsapp(number: String){
let urlWhats = "whatsapp://send?phone=\(number)&abid=12354&text=לעדכן מיקום באפליקציה"
if let urlString = urlWhats.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) {
if let whatsappURL = URL(string: urlString) {
if UIApplication.shared.canOpenURL(whatsappURL) {
UIApplication.shared.open(whatsappURL)
} else {
print("Install Whatsapp")
}
}
}
}
}
Make num a member var:
class Tavla: UITableViewCell {
var num: Int?
// ...
func setBLogPost(blogPost: BlogPost) {
// ...
num = blogPost.phone
}
#IBAction func whatsAppButton(_ sender: Any) {
guard let num = num else { return }
openWhatsapp(number: num)
}
assign the blogPost id to button tag like
button.tag = post.id
in CellForItemAt function, Now you have reference to the blogpost.You can get the clicked blogpost using the button tag like this
#IBAction func whatsAppButton(_ sender: Any) {
let post = blogPostsArray.filter({$0.id == sender.tag})[0]
var num = post.phone
openWhatsapp(number: num)
}
You just set num value in setBlog method as an inner variable. Then num variable can only access the setBlog method. And blogPost object can accessible on setBlog method, not in another method in this class. If you need to access blogPost object in this class then you need to maintain a variable in this class.
Like this:
class Tavla: UITableViewCell {
var blogPost: BlogPost?
...
func setBLogPost(blogPost: BlogPost) {
self.blogPost = blogPost
....
//num works fine
var num = blogPost.phone // because it's access the param value
}
#IBAction func whatsAppButton(_ sender: Any) {
// Now can access the blogPost variable on this class
if let num = self.blogPost?.phone {
openWhatsapp(number: num)
}
}
}
Now the blogPost object can be accessible in whatsAppButton method.

Why is the else part of my if else statement is not executing?

The if else statement takes the boolean return from a function that is called, but the true part executes yet the false part doesn't. I checked the syntax and it is correct so there must be something I'm missing.
I tried using a while loop, but that won't work because it doesn't let me do anything if the return is false.
import UIKit
class ViewController: UIViewController {
var word: String = ""
#IBOutlet weak var Label: UILabel!
//This is the text field
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func wordButtonTapped(_ sender: Any) {
word = textField.text!
userInput()
if true {
Label.text = "This is a Palindrme."
} else {
Label.text = "This is not a Palindrome."
}
}
func userInput() {
Util.shared.isPalindrome(word: word)
}
}
Im expecting the text to display in my label field.
That's because it makes a comparison "is true == true?" and it will always return true, therefore never entering the else part
Your function isn't returning anything and you're branching on an if true which is obviously always true (there should be a compiler warning here).
You need to update your function to actually return the value:
func userInput() -> Bool {
return Util.shared.isPalindrome(word: word)
}
And use that value for your if statement:
if userInput() {
Label.text = "This is a Palindrme."
} else {
Label.text = "This is not a Palindrome."
}
if true condition is always satisfied. You should modify your userInput() method to return a boolean value, if you want to use it.
func userInput() -> Bool {
return Util.shared.isPalindrome(word: word)
}
And then handle the result:
if userInput() {
// do something
} else {
// do something else
}

my UIswitch value is nil even when its on I have to turn swich off and then back on for it to set value

using UIswitch to set value
my variable is static because im using them in diffrent swift file
so when I run program and click registration button it prints nil
even tho its on (button stays the way it was left when closing app)
I have to toggle it and then click registration button for it to print optional(true)
what can i do so user dont have to togggle everytime they open app or when it shows on when app opened but value is nil
also I just want it to print true/false (how do i unwrap)
class FirstViewController: UIViewController, UITextFieldDelegate {
static var FirstColor: Bool!
#IBAction func home(_ sender: RoundButton) {
}
#IBAction func Registration(_ sender: RoundButton) {
print(FirstViewController.FirstColor)
}
#IBAction func ColorSwitch(_ sender: UISwitch) {
if sender.isOn{
FirstViewController.FirstColor = true
}else{FirstViewController.FirstColor = false }
}
}
If you want to persist the switch status you need to store it in UserDefaults. Don't add a static property in FirstViewController. Create a separate class like this with a computed property
class Color {
static var firstColor: Bool {
get { return UserDefaults.standard.bool(forKey: "firstColor") }
set { UserDefaults.standard.set(newValue, forKey: "firstColor") }
}
}
In FirstViewController's viewDidLoad get last status and update
override func viewDidLoad() {
super.viewDidLoad()
mySwitch.isOn = Color.firstColor
}
In Switch's action change it
#IBAction func ColorSwitch(_ sender: UISwitch) {
sender.isOn = !sender.isOn
Color.firstColor = sender.isOn
}
You could try to use the value of the isOn property directly. Does this help? Also I suggest that you use better names for your handlers.
class FirstViewController: UIViewController, UITextFieldDelegate
{
static var FirstColor: Bool!
#IBAction func registrationTapped(_ sender: RoundButton)
{
print(FirstViewController.FirstColor)
}
#IBAction func colorChanged(_ sender: UISwitch)
{
FirstViewController.FirstColor = sender.isOn
}
}

How to set up a NSComboBox using prepare for segue or init?

I am really struggling to pass the contents of one array from a view controller to another to set up the contents of a nscombobox. I have tried everything I can think of, prepare for segue, init; but nothing seems to work.
the program flow is as follows: the user enter a number into a text field and based on it an array with the size of the number is created. Once the user presses a button the next VC appears that has a combo box and inside that combo box those numbers need to appear. All my attempts result in an empty array being passed. Could someone please take a bit of time and help me out. Im sure I'm doing a silly mistake but cannot figure out what.
Code listing below:
Class that take the user input. At this stage I'm trying to pass the contents of the array in the next class as I gave up on prepare for segue because that one crashes because of nil error. Please note that prepare for segue is uncommented in the code listing just for formatting purposes here. Im my program it is commented out as I am using perform segue at the moment.
Any solution would be nice please. Thank you.
import Cocoa
class SetNumberOfFloorsVC: NSViewController {
//MARK: - Properties
#IBOutlet internal weak var declaredNumber: NSTextField!
internal var declaredFloorsArray = [String]()
private var floorValue: Int {
get {
return Int(declaredNumber.stringValue)!
}
}
//MARK: - Actions
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction private func setNumberOfFloors(_ sender: NSButton) {
if declaredNumber.stringValue.isEmpty {
let screenAlert = NSAlert.init()
screenAlert.messageText = "Please specify the number of floors!"
screenAlert.addButton(withTitle: "Got it!")
screenAlert.runModal()
} else if floorValue == 0 || floorValue < 0 {
let screenAlert = NSAlert.init()
screenAlert.messageText = "Please input a correct number of floors!"
screenAlert.addButton(withTitle: "Got it!")
screenAlert.runModal()
} else {
for i in 0...floorValue - 1 {
declaredFloorsArray.append(String(i))
}
print("\(declaredFloorsArray)")
let declareNumberOfRoomsVC = SetNumberOfRoomsForFloorVC(boxData: declaredFloorsArray)
declareNumberOfRoomsVC.boxData = declaredFloorsArray
performSegue(withIdentifier: "set number of rooms", sender: self)
}
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "set number of rooms" {
if let addRoomsVC = segue.destinationController as? SetNumberOfRoomsForFloorVC {
addRoomsVC.floorBox.addItems(withObjectValues: declaredFloorsArray)
}
}
}
}
this is the class for the next VC with the combo box:
import Cocoa
class SetNumberOfRoomsForFloorVC: NSViewController, NSComboBoxDelegate, NSComboBoxDataSource {
//MARK: - Properties
#IBOutlet internal weak var floorBox: NSComboBox!
#IBOutlet private weak var numberOfRoomsTxtField: NSTextField!
internal var boxData = [String]()
//MARK: - Init
convenience init(boxData: [String]) {
self.init()
self.boxData = boxData
}
//MARK: - Actions
override func viewDidLoad() {
super.viewDidLoad()
floorBox.usesDataSource = true
floorBox.dataSource = self
floorBox.delegate = self
print("\(boxData)")
}
#IBAction private func setRoomsForFloor(_ sender: NSButton) {
}
//MARK: - Delegates
func numberOfItems(in comboBox: NSComboBox) -> Int {
return boxData.count
}
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
return boxData[index]
}
}
First you should remove the following code.
let declareNumberOfRoomsVC = SetNumberOfRoomsForFloorVC(boxData: declaredFloorsArray)
declareNumberOfRoomsVC.boxData = declaredFloorsArray
I assume you think that the viewController you created here is passed to prepareForSegue. However the storyboard instantiates a new viewController for you.
After that you need to set your declaredFloorsArray as the the boxData of the new viewController in prepareForSegue and you should be good to go.

Why won't swift recalculate the 'if' statement?

I'm trying to create a very simple 'guessing game' where the user has to guess how many fingers the computer has up (maximum 5 fingers).
Here's the thing. When the code executes and I press submit, even when the print logs registers a correct number, the app still prints the if statement for incorrect. Where am I going wrong?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var fingerInput: UITextField!
#IBOutlet weak var fingerResult: UILabel!
#IBAction func fingerSubmit(sender: AnyObject) {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if fingerInput != realNumberofFingers {
fingerResult.text = "Gosh darn, that's wrong!"
} else if fingerInput == realNumberofFingers {
fingerResult.text = "Thats right!"
}
}
}
You are comparing the actual UITextField fingerInput with the realNumberofFingers. That is wrong and will always yield false. What you should do instead is parse the string from the fingerInput and check if the integer contained in that string is equal to realNumberofFingers:
#IBAction func fingerSubmit(sender: AnyObject) {
let input = Int(fingerInput.text!)
if let enteredFingers = input {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if enteredFingers == realNumberofFingers {
fingerResult.text = "Thats right!"
} else {
fingerResult.text = "Gosh darn, that's wrong!"
}
} else {
fingerResult.text = "Please enter a correct guess - an integer!"
}
}