UILabel shows Optional("P") - ios

I have a UILabel where i set its texts property, and
let firstCharacter: String = "\(user.name.characters.first)" ?? ""
print(firstCharacter)
userNameLabel.text = firstCharacter
Output: Optional("P")

String Interpolating user.name.characters.first will always create a String because even if user.name.characters.first is nil then the interpolated string will be "nil".
The correct solution is
userNameLabel.text = "" //set the default value as ""
//if the name contains atleast one char then set it
if let firstCharacter = user.name.characters.first {
userNameLabel.text = "\(firstCharacter)"
}

Wrap optional like so:
if let userName = user.name.characters.first {
userNameLabel.text = userName
}

IF you need to get first character you can use following code and it would be more correct than taking first character
let firstCharacter = user.name.substringToIndex(user.name.startIndex.advancedBy(1))
But note that you need to check before this call if the string is not empty.

Print like this.
println(firstCharacter!)
it will work.

Related

How to remove 1 component in a string? Swift

I have this string "01:07:30" and I would like to remove the zero in "01" and keep everything else the same. My final string should look like this
"1:07:30"
Is there a way to do so in Swift? Thank you so much!
Try the following. This will create a string, check to see if the first character is 0 if it is remove it. Otherwise do nothing.
var myString = "01:07:30"
if myString.first == "0" {
myString.remove(at: myString.startIndex)
}
print(myString) // 1:07:30
The final result is the string will now be 1:07:30 instead of 01:07:30.
If I'm best understanding your question, you want to replace the occurrences of "01" with "1" in your string, so you can use regex or the string functionality it self
simply:
let searchText = "01"
let replaceWithValue = "1"
let string = "01:07:08:00:01:01"
let newString = string.replacingOccurrences(of: searchText, with: replaceWithValue) // "1:07:08:00:1:1"
If you want to replace the fist occurrence only, simply follow this answer:
https://stackoverflow.com/a/33822186/3911553
If you just want to deal with string here is one of many solution:
var myString = "01:07:30"
let list = myString.components(separatedBy: ":")
var finalString = ""
for var obj in list{
if obj.first == "0" {
obj.removeFirst()
}
finalString += finalString.count == 0 ? "\(obj)" : ":\(obj)"
}
print(finalString)

how to make retrieve button for previous Value

can someone help me
i make button to retrieve previous Values
but i have two TextFiled
i must write in two TextFiled for work retrieve button
i do not want this happens
i want when I write in the first TextFiled, retrieve button work without any problem
but if i write in first TextFiled and second TextFiled at the same time i want retrieve button work without any problem
var previousValues: [String] = [String]();
var previousValues1: [String] = [String]();
previousValues.append(TextFailde.text ?? "error");
previousValues1.append(TextFilde1.text ?? "error");
if self.previousValues.count > 0 {
let previousValue = self.previousValues.removeLast()
let subtracted = (Int(self.lblZeroUs.text!)!) - (Int(previousValue)!)
self.lblZeroUs.text = "\(subtracted)"
}
else if self.previousValues1.count > 0 {
let previousValue = self.previousValues1.removeLast()
let subtracted2 = (Int(self.lblZeroThey.text!)!) - (Int(previousValue)!)
self.lblZeroThey.text = "\(subtracted2)"
}
and here the error
There are many errors, first of all you dont declare your properties with the first letter in uppercase, it's considered a bad practice.
Then, when you involve your properties in mathematical operations what do you need is to assign them a start value, especially if your code try to convert strings.
In Swift, you don’t need to write semicolons at the end of every statement.
I dont know the rest of your code, but your lines crash because you attempt to run mathematical operations using properties have nil as value.
This below it's just an example to avoid the first crashing for nil:
textFailde.text = "0"
textFilde1.text = "0"
previousValues.append(textFailde.text ?? String(0))
previousValues1.append(textFilde1.text ?? String(0))
self.lblZeroUs.text = String(0)
self.lblZeroThey.text = String(0)
if self.previousValues.count > 0 {
let subtracted = (Int(self.lblZeroUs.text!)!) - (Int(self.previousValues.last!))!
self.previousValues.removeLast()
self.lblZeroUs.text = "\(subtracted)"
}
else if self.previousValues1.count > 0 {
let subtracted2 = (Int(self.lblZeroThey.text!)!) - (Int(self.previousValues1.last!))!
self.previousValues1.removeLast()
self.lblZeroThey.text = "\(subtracted2)"
}
previousValues.append(TextFailde.text ?? "error");
previousValues.append(TextFilde1.text ?? "error");
You added to the same array twice, try changing the code to
previousValues.append(TextFailde.text ?? "error");
previousValues1.append(TextFilde1.text ?? "error");

Replace part of string with lower case letters - Swift

I have a Swift based iOS app and one of the features allows you to comment on a post. Anyway, users can add "#mentions" in their posts to tag other people. However I want to stop the user from adding a username with a capital letter.
Is there anyway I can convert a string, so that the #usernames are all in lowercase?
For example:
I really enjoy sightseeing with #uSerABC (not allowed)
I really enjoy sightseeing with #userabc (allowed)
I know there is a property for the string in swift called .lowercaseString - but the problem with that, is that it makes the entire string lowercase and thats not what I want. I only want the #username to be in lower case.
Is there any way around this with having to use the .lowercase property.
Thanks for your time, Dan.
This comes from a code I use to detect hashtags, I've modified to detect mentions:
func detectMentionsInText(text: String) -> [NSRange]? {
let mentionsDetector = try? NSRegularExpression(pattern: "#(\\w+)", options: NSRegularExpressionOptions.CaseInsensitive)
let results = mentionsDetector?.matchesInString(text, options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, text.utf16.count)).map { $0 }
return results?.map{$0.rangeAtIndex(0)}
}
It detects all the mentions in a string by using a regex and returns an NSRange array, by using a range you have the beginning and the end of the "mention" and you can easily replace them with a lower case version.
Split the string into two using the following command -
let arr = myString.componentsSeparatedByString("#")
//Convert arr[1] to lower case
//Append to arr[0]
//Enjoy
Thanks to everyone for their help. In the end I couldn't get any of the solutions to work and after a lot of testing, I came up with this solution:
func correctStringWithUsernames(inputString: String, completion: (correctString: String) -> Void) {
// Create the final string and get all
// the seperate strings from the data.
var finalString: String!
var commentSegments: NSArray!
commentSegments = inputString.componentsSeparatedByString(" ")
if (commentSegments.count > 0) {
for (var loop = 0; loop < commentSegments.count; loop++) {
// Check the username to ensure that there
// are no capital letters in the string.
let currentString = commentSegments[loop] as! String
let capitalLetterRegEx = ".*[A-Z]+.*"
let textData = NSPredicate(format:"SELF MATCHES %#", capitalLetterRegEx)
let capitalResult = textData.evaluateWithObject(currentString)
// Check if the current loop string
// is a #user mention string or not.
if (currentString.containsString("#")) {
// If we are in the first loop then set the
// string otherwise concatenate the string.
if (loop == 0) {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = currentString.lowercaseString
}
else {
// The username does not contain capital letters.
finalString = currentString
}
}
else {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = "\(finalString) \(currentString.lowercaseString)"
}
else {
// The username does not contain capital letters.
finalString = "\(finalString) \(currentString)"
}
}
}
else {
// The current string is NOT a #user mention
// so simply set or concatenate the finalString.
if (loop == 0) {
finalString = currentString
}
else {
finalString = "\(finalString) \(currentString)"
}
}
}
}
else {
// No issues pass back the string.
finalString = inputString
}
// Pass back the correct username string.
completion(correctString: finalString)
}
Its certainly not the most elegant or efficient solution around but it does work. If there are any ways of improving it, please leave a comment.

Swift: Cannot convert from string to int (using slider tag)

let device = devices[indexPath.row]
let deviceTag = device["deviceID"] as? String
cell.slider.tag = deviceTag
I get an error from the above: Cannot assign value of type 'String?' to type 'Int'
This doesn't work (below):
cell.slider.tag = Int(deviceTag)
or what "fix-it" provides:
cell.slider.tag = Int(deviceTag!)!
You need to set optional while casting from string. Try the below code.
let device = devices[indexPath.row]
let deviceTag = device["deviceID"] as! String
cell.slider.tag = Int(deviceTag)
Unless you're 100% sure the value of the dictionary device is an Int you shouldn't implicitly unwrap those optionals.
You can use:
if let deviceTag = deviceTag, tag = Int(deviceTag) { cell.slider.tag = tag }
or
cell.slider.tag = Int(deviceTag) ?? 0
But looking at your examples, it seems like deviceTag isn't a number at all. Perhaps you should look in your debug area (left panel) to see what the value is or simply print(deviceTag) to see what the value is.

IOS insert line break to data retrieved from parse.com

i am trying to retrieve some string data from parse.com and i've added "\n, \n & \r" into the data, but it still does not give me the line breaks, how do format the line below to get line breaks.
self.label.text = [NSString stringWithFormat:#"%#", [object objectForKey:#"ParseStringDate"]];
if you get the text that should be presented in multiple lines then you should try to set for your label this property:
self.label.numberOfLines = 0;
it basically means that label can be multiline, make sure that frame of that label is sufficient to show more that one line of text
if some has the same challenge in swift - please find attached a short string extension:
extension String {
func formatStringFromParseWithLineBreaks() -> String {
let sourceString: String = self
let resultString = sourceString.stringByReplacingOccurrencesOfString("\\n", withString: "\n")
return resultString
}
}
It is easy to use:
let stringFromParse = "Great\\nExample"
let newString = stringFromParse.formatStringFromParseWithLineBreaks()
Have fun
self.label.text = [NSString stringWithFormat:#"first\n%#\n another", [object objectForKey:#"ParseStringDate"]];
Make sure you have numberOfLines of the label set to 0. This should work.

Resources