Getting the value from a button - swift

I've got a series of buttons that all contain randomly generated letters (ie. Button one is Z, button 2 is X... and so on). When the user tap on a button, I want to grab the value of that button and create a new label with that value.
This is the code I have now
#IBAction func zeroB(sender : UIButton) {
buttonPress(sender) // highlight the button
var label = UILabel(frame: CGRectMake(0, 0, 250, 50))
label.text = "\(sender.currentTitle))"
label.font = UIFont.systemFontOfSize(26)
letterView.addSubview(label)
}
It creates a label, but the text in the label displays as Optional("Z")).
What am I missing?
I should add that i'm completely new to iOS programming. I'm making an app to teach myself.
Thanks.

Since currentTitle of a UIButton is an optional string, you would be getting the Optional(...) part.
If you know that the title has been set to a non-nil string, use exclamation point to unwrap it:
label.text = "\(sender.currentTitle!))"
This will produce Z) in the label (I am assuming that the extra closing parenthesis is not a typo, and you actually want it in the title of your label). If you do not want the extra parentheses after the title, use
label.text = sender.currentTitle!

current Title is an optional. You can extract the optional in one of two ways:
1)
let labelText = sender.currentTitle!
label.text = labelText
or 2)
if let labelText = sender.currentTitle {
label.text = labelText
}

Related

Binary operator '==' cannot be applied to operands of type 'UILabel?' and 'String'

Error : Binary operator '==' cannot be applied to operands of type 'UILabel?' and 'String'
import UIKit
class ViewController: UIViewController {
let Soft = 5
let Medium = 8
let Hard = 12
#IBAction func hardnessSelected(_ sender: UIButton) {
let hardness = sender.titleLabel
if hardness == "Soft"{
print(Soft)
}
else if hardness == "Medium"{
print (Medium)
}
else {
print (Hard)
}
}
}
How can i fix this error?
You don't give the line number the error is on, but looking at the text it mentions operation == so I'm guessing it's one of these:
if hardness == "Soft"{
else if hardness == "Medium"{
"Soft" and "Medium" are the strings, so hardness must be a 'UILabel?. Those types can't be compared to each other. You must want the text displayed on the button? Looking at the UILabel docs, there is a text property so you probably want to change this line to grab the string representing the button's text:
let hardness = sender.titleLabel.text
Are you using dynamic buttons? It would be less error prone to just compare the sender with the button your are checking for. Comparing hard-coded strings to the text of the button can lead to run-time errors. Maybe you didn't get the case right, misspelled the text, or decided to localize later so the text may be different in a different language. These errors wouldn't be caught at compile-time.
You're trying to compare two different types. To get the actual text of UILabel, you'll need hardness.text.
UIButton.titleLabel is a UILabel and it stores its text in UILabel.text property:
let hardness = sender.titleLabel.text
In the case of UIButton you can also access UIButton.currentTitle property:
let hardness = sender.currentTitle
An UIButton exposes its label through an UILabel that manage the drawing of its text. Thus change:
let hardness = sender.titleLabel
to
let hardness = sender.titleLabel.text
UIKit docs says:
UIButton
var titleLabel: UILabel?
A view that displays the value of the currentTitle property for a button.
and:
UILabel
var text: String?
The current text that is displayed by the label.
There is also a more direct way using the currentTitle:
UIButton
var currentTitle: String?
The current title that is displayed on the button.
Thus:
let hardness = sender.currentTitle
will also work.

How to make `attributedReadMoreText` in `ReadMoreTextView` library not selectable - swift

I am a new iOS programming. Now i am creating a sample app which display text using ReadMoreTextView library. My content may contain many lines but by using this library i can maximumNumberOfLines to display how many lines of content should be displayed. I implement those content in cell of UITableView and i have problem is that, when i use label.attributedReadMoreText = NSAttributedString(string: "...") then end of content will display ... and when i click on it and then whole content will be display so, my question is that: How to not letting user click on that ... because i want user to click on cell then i will show another view and display whole content there?
How can i achieve something like this? Thank in advance.
This is how i set UITextView
lazy var categoryShortDetailLabel: ReadMoreTextView = {
let label = ReadMoreTextView()
label.font = UIFont(name: "SFCompactText-Regular", size: 16)
label.textColor = .black
label.isEditable = false
label.isSelectable = false
label.maximumNumberOfLines = 3
label.shouldTrim = true
label.attributedReadMoreText = NSAttributedString(string: "...")
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
Looking at the code here, I found that, the ReadMoreTextView is meant to provide you the feature like, ReadMore and ReadLess for the larger texts in textView.
However your requirement is to stop that functionality. Now, if you take a look at the code here, you will get the idea, that the function shoreMoreText and it's a private function so, can't override it. and this function is expanding the texts and setting the numberOfLines to zero. so, what you can do is, comment the code within and return from function to stop doing the action. Also as the ReadMoreTextView is Licensed as MIT(Read licence here) so, it's okay to modify the code.
private func showMoreText() {
return
/*if let readLessText = readLessText, text.hasSuffix(readLessText) { return }
shouldTrim = false
textContainer.maximumNumberOfLines = 0
if let originalAttributedText = _originalAttributedText?.mutableCopy() as? NSMutableAttributedString {
attributedText = _originalAttributedText
let range = NSRange(location: 0, length: text.count)
if let attributedReadLessText = attributedReadLessText {
originalAttributedText.append(attributedReadLessText)
}
textStorage.replaceCharacters(in: range, with: originalAttributedText)
}
invalidateIntrinsicContentSize()
invokeOnSizeChangeIfNeeded()*/
}
Try and share your results.
Hope it helps!

total of label click on two buttons

I have two UIButton if I click onto button1 the value of label1 is 250, if I click again onto button1 the value of label1 should be 0. The same logic is applied to my button2 and label2. I want to store the addition of label1 and label2 into label3. . My code is:
func PickUpCarCost() {
if (!isclick){
imgCheck.image = UIImage(named: "check.png")
isclick=true
//Pickup fare conver into integer
let PickUp = String(self.PickUpPrice)
PickUpFare.text = PickUp
self.pickCost = Int( PickUpFare.text!)
self.PAyAmount = ((self.PayFareWithSecurity)+(self.pickCost))
print("PaybleAmount: \(self.PAyAmount)")
self.AmountPay1 = ((self.PAyAmount)+(self.DeliverCost))
PaybleAmount.text=String(self.AmountPay1!)
}
else
{
imgCheck.image = UIImage(named: "uncheck.png")
PickUpFare.text = "0"
self.PickUpElse=Int(PickUpFare.text!)
print("PickUpElse: \(self.PickUpElse)")
self.PAyAmount = (self.PayFareWithSecurity)+(self.PickUpElse)
PaybleAmount.text=String(self.PAyAmount!)
isclick=false
}
}
func CarDeliverCost() {
if (!isclick){
imgUnCheck.image = UIImage(named: "check.png")
isclick=true
let DeliverPrice = String(self.deliveryPrice)
DeliverFare.text = DeliverPrice
self.DeliverCost = Int(DeliverFare.text!)
self.PAyAmount = ((self.PayFareWithSecurity)+(self.DeliverCost))
print("PaybleAmount: \(self.PAyAmount)")
PaybleAmount.text=String(self.PAyAmount!)
}
else
{
imgUnCheck.image = UIImage(named: "uncheck.png")
let deliveryelse = String(0)
DeliverFare.text = deliveryelse
self.deliver = Int(DeliverFare.text!)
PaybleAmount.text=String(self.PAyAmount!)
isclick=false
}
}
The first issue that you're facing is that you are using the same boolean isClick for two different scenarios. Your logic is that the user could decide to click onto both buttons or a single one. So if I click onto the first button then your flag is turn on, since the second button also uses the same boolean then you'll get that uncheck behavior automatically.
Thus you should use two different booleans such as hasPressOntoFirstButton and hasPressOntoSecondButton, where both set to false at the beginning, and each variable is used in their respective scene.
You mentioned that you want to add the label1 to label2, the easier way would be add the variable that set these labels. i.e
let label1 = UILabel()
let label2 = UILabel()
let label3 = UILabel()
let data1: Double = 83.0
let data2: Double = 82.0
var total: Double { // have a computed variable to adds automatically
return data1 + data2
}
label1.text = "\(data1)"
label2.text = "\(data2)"
label3.text = "\(data1 + data2)" // or "\(total)"
Remarks:
(1) your naming convention are really misleading, you should separate UI object naming from data. i.e you can have deliveryFareLabel.text instead of DeliverFare.text
(2) avoid using !, unwrapped all optional using either nil coalescing ??, or if let or guard statements

Update the value of an NSSlider in realtime

In my swift 3 app, I have an NSSlider that I created like this:
self.myAwesomeSlider = NSSlider(frame:CGRect(x: 10, y: 100, width: 20, height: 300))
self.myAwesomeSlider?.cell = NSSlider()
self.myAwesomeSlider?.maxValue = 127
self.myAwesomeSlider?.target = self
self.myAwesomeSlider?.isContinuous = true
self.view?.addSubview(self.myAwesomeSlider!)
What I want to do now, is (from another function) update the value of this slider in realtime.
I tried to do it very basic like this:
self.myAwesomeSlider?.integerValue = Int(value)
but it doesnt update the dot. What I wish to get is new value gets calculated and dot on slider does move according to the value.
Is this possible?
thank you
Edit
self.myAwesomeSlider?.integerValue = Int(value)
Apparently, this does work, however, I have to click on another application before I see actual change.
myAwesomeSlider.addTarget(self, action: "sliderValueChanged:",
forControlEvents: UIControlEvents.ValueChanged)
func sliderValueChanged() {
var slider = sender as! UISlider
label.text = "\(slider.value)"
}

UIlabel toggle bold

I've managed to bold a UILabel using the following line:
self.nameLabel.font = UIFont.boldSystemFont(ofSize: self.nameLabel.font.pointSize)
But I want to put this in an if statement that will make the UIlabel bold is it isn't bold, and unbold if it is.
Is there a way to do such a thing?
Although there are many other ways, I would suggest you to create a variable that stores whether the label is bold.
var isLabelBold = false
I would imagine that you have the bold/unbold label code put in a button's IBAction method. Now in that method, check whether isLabelBold is true:
if isLabelBold { // if label is bold
// unbold it!
self.nameLabel.font = UIFont.systemFont(ofSize: self.nameLabel.font.pointSize)
isLabelBold = false
} else { // if label is not bold
// bold it!
self.nameLabel.font = UIFont.boldSystemFont(ofSize: self.nameLabel.font.pointSize)
}