in advance thanks for help.
I am trying to make calculator application (for specific purposes) and I would like to know, if there exist a way how to convert Double() to NSMutableAttributedString. I need this for label output answer.
Reason of using NSMutableAttributedString is because I would like to have answer with subscripts and upper-scripts.
//example of my code
var a = Double(), b = Double(), c = Double()
a = Double(textField1.text!)
b = Double(textField2.text!)
c = a + b
let font:UIFont? = UIFont(name: "Courier", size:12)
let fontSuper:UIFont? = UIFont(name: "Courier", size:10)
//for x_1 (subscript for "1")
x1_t:NSMutableAttributedString = NSMutableAttributedString(string: "x1", attributes: [NSFontAttributeName:font!])
x1_t.setAttributes([NSFontAttributeName:fontSuper!,NSBaselineOffsetAttributeName:-4], range: NSRange(location:1,length:1))
var result = NSMutableAttributedText()
// what to do to get output for a label like "x_1 = String(c) m"
If there exist another way like append String() to NSAtributedString() - I am looking forward for answers.
As I understand it, your input strings (named "prestring1" and "afterstring1" in your own answer) could just be normal strings without attributes, because you only need the final result to be an attributed string.
This would drastically simplify your function, for example you could use string interpolation first and then only make an attributed string and move up (or down) the last part (or any part you want, I'm using an hardcoded range in my example but it's just an example).
Like:
let randomstring = "Random ="
let afterstring = "m2"
let result: Double = 42.1
func stringer (pre: String,
result: Double,
post: String) -> NSMutableAttributedString
{
let base = "\(pre) \(result) \(post)"
let mutable = NSMutableAttributedString(string: base)
mutable.addAttribute(NSBaselineOffsetAttributeName, value: 4,
range: NSRange(location: mutable.length - 2, length: 2))
return mutable
}
let attributedString = stringer(pre: randomstring, result: result, post: afterstring)
Gives:
I am still not quit sure how to do it, but I could create simple function, which is approximately doing what I need. Here I am sharing my answer in case someone has the same question, but in case someone knows better answer, share it with others :)
var randomstring = "Random ="
var prestring1 = NSMutableAttributedString(string: randomstring)
var afterstring1 = NSMutableAttributedString(string: "m2")
var result1 = Double()
result1 = 42.1
func stringer (prestring: NSMutableAttributedString, result: Double, afterstring: NSMutableAttributedString) -> NSMutableAttributedString {
var mutableatributedresult = NSMutableAttributedString(string: String(result))
var mutableaddition = NSMutableAttributedString(string: " ")
var alltext = NSMutableAttributedString()
alltext.append(prestring)
alltext.append(mutableaddition)
alltext.append(mutableatributedresult)
alltext.append(mutableaddition)
alltext.append(afterstring)
return alltext
}
stringer(prestring: prestring1, result: result1, afterstring: afterstring1)
//This should give result of "Random = 42.1 m2"
If someone knows better solution I am curious.
I have a large file (25 MB) of text. I read it into a NSString var. I want to use "uppercaseString" to convert every char to upper case. But the function in so terribly slow, it needs minutes.
Any tip to get it work much faster?
Added code:
if let path = NSBundle.mainBundle().pathForResource("GERMANU", ofType: "txt") {
var error: NSError?
if let data = NSData(contentsOfFile: path, options: NSDataReadingOptions(), error: &error) {
if let datastring = NSString(data: data, encoding: NSMacOSRomanStringEncoding) {
var upper = datastring.uppercaseString
...
That's the code which works, but is slow. Only last row needs all the time.
String::uppercaseString is instantaneous; creating the string is not.
# Long time
12> var st : String = "".join(Array(count:25000000, repeatedValue: "a"))
st: String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..."
# Short time
13> st.uppercaseString
$R8: String = "AAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
Given that you are using the Roman encoding, it is possible that the conversion to uppercase is non-trivial. Perhaps you can try another encoding (if any others are appropriate)? You might try the init?(... usedEncoding ...) variant and invoke fastestEncoding on the result to explore a bit.
Note: you can create a Swift string directly from a file with a particular encoding using:
if let datastring = String(contentsOfFile: path, encoding: ... , error: &error) {
var upper = datastring.uppercaseString
}
To me it looks like a poor library implementation. Using NSString.uppercaseString() is realy fast (half a second). So I will use this, but I'm developing in Swift because I like the language. So I don't want to switch back to old stuff.
So far it was:
let string = "my example string"
if count(string) >= 3 { ... }
But now I get an error:
count is unavailable: access the count property on the collection. Type String doesn't conform to protocol CollectionType
Oh, it is simple:
string.characters.count
Again more simplified version
In Swift 4.0 and Above
let strLength = string.count
It should be like that
let string = "my example string"
let length = string.characters.count
Because in Swift 2.0 Apple changed global functions to protocol extensions.
This is my current way of converting a CGFloat to String in Swift:
let x:Float = Float(CGFloat)
let y:Int = Int(x)
let z:String = String(y)
Is there a more efficient way of doing this?
You can use string interpolation:
let x: CGFloat = 0.1
let string = "\(x)" // "0.1"
Or technically, you can use the printable nature of CGFloat directly:
let string = x.description
The description property comes from it implementing the Printable protocol which is what makes string interpolation possible.
The fast way:
let x = CGFloat(12.345)
let s = String(format: "%.3f", Double(x))
The better way, because it takes care on locales:
let x = CGFloat(12.345)
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .DecimalStyle
numberFormatter.minimumFractionDigits = 3
numberFormatter.maximumFractionDigits = 3
let s = numberFormatter.stringFromNumber(x)
This worked for me
let newstring = floatvalue.description
How can I remove last character from String variable using Swift? Can't find it in documentation.
Here is full example:
var expression = "45+22"
expression = expression.substringToIndex(countElements(expression) - 1)
Swift 4.0 (also Swift 5.0)
var str = "Hello, World" // "Hello, World"
str.dropLast() // "Hello, Worl" (non-modifying)
str // "Hello, World"
String(str.dropLast()) // "Hello, Worl"
str.remove(at: str.index(before: str.endIndex)) // "d"
str // "Hello, Worl" (modifying)
Swift 3.0
The APIs have gotten a bit more swifty, and as a result the Foundation extension has changed a bit:
var name: String = "Dolphin"
var truncated = name.substring(to: name.index(before: name.endIndex))
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Or the in-place version:
var name: String = "Dolphin"
name.remove(at: name.index(before: name.endIndex))
print(name) // "Dolphi"
Thanks Zmey, Rob Allen!
Swift 2.0+ Way
There are a few ways to accomplish this:
Via the Foundation extension, despite not being part of the Swift library:
var name: String = "Dolphin"
var truncated = name.substringToIndex(name.endIndex.predecessor())
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Using the removeRange() method (which alters the name):
var name: String = "Dolphin"
name.removeAtIndex(name.endIndex.predecessor())
print(name) // "Dolphi"
Using the dropLast() function:
var name: String = "Dolphin"
var truncated = String(name.characters.dropLast())
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Old String.Index (Xcode 6 Beta 4 +) Way
Since String types in Swift aim to provide excellent UTF-8 support, you can no longer access character indexes/ranges/substrings using Int types. Instead, you use String.Index:
let name: String = "Dolphin"
let stringLength = count(name) // Since swift1.2 `countElements` became `count`
let substringIndex = stringLength - 1
name.substringToIndex(advance(name.startIndex, substringIndex)) // "Dolphi"
Alternatively (for a more practical, but less educational example) you can use endIndex:
let name: String = "Dolphin"
name.substringToIndex(name.endIndex.predecessor()) // "Dolphi"
Note: I found this to be a great starting point for understanding String.Index
Old (pre-Beta 4) Way
You can simply use the substringToIndex() function, providing it one less than the length of the String:
let name: String = "Dolphin"
name.substringToIndex(countElements(name) - 1) // "Dolphi"
The global dropLast() function works on sequences and therefore on Strings:
var expression = "45+22"
expression = dropLast(expression) // "45+2"
// in Swift 2.0 (according to cromanelli's comment below)
expression = String(expression.characters.dropLast())
Swift 4:
let choppedString = String(theString.dropLast())
In Swift 2, do this:
let choppedString = String(theString.characters.dropLast())
I recommend this link to get an understanding of Swift strings.
Swift 4/5
var str = "bla"
str.removeLast() // returns "a"; str is now "bl"
This is a String Extension Form:
extension String {
func removeCharsFromEnd(count_:Int) -> String {
let stringLength = count(self)
let substringIndex = (stringLength < count_) ? 0 : stringLength - count_
return self.substringToIndex(advance(self.startIndex, substringIndex))
}
}
for versions of Swift earlier than 1.2:
...
let stringLength = countElements(self)
...
Usage:
var str_1 = "Maxim"
println("output: \(str_1.removeCharsFromEnd(1))") // "Maxi"
println("output: \(str_1.removeCharsFromEnd(3))") // "Ma"
println("output: \(str_1.removeCharsFromEnd(8))") // ""
Reference:
Extensions add new functionality to an existing class, structure, or enumeration type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.)
See DOCS
Use the function removeAtIndex(i: String.Index) -> Character:
var s = "abc"
s.removeAtIndex(s.endIndex.predecessor()) // "ab"
Swift 4
var welcome = "Hello World!"
welcome = String(welcome[..<welcome.index(before:welcome.endIndex)])
or
welcome.remove(at: welcome.index(before: welcome.endIndex))
or
welcome = String(welcome.dropLast())
The easiest way to trim the last character of the string is:
title = title[title.startIndex ..< title.endIndex.advancedBy(-1)]
import UIKit
var str1 = "Hello, playground"
str1.removeLast()
print(str1)
var str2 = "Hello, playground"
str2.removeLast(3)
print(str2)
var str3 = "Hello, playground"
str3.removeFirst(2)
print(str3)
Output:-
Hello, playgroun
Hello, playgro
llo, playground
let str = "abc"
let substr = str.substringToIndex(str.endIndex.predecessor()) // "ab"
var str = "Hello, playground"
extension String {
var stringByDeletingLastCharacter: String {
return dropLast(self)
}
}
println(str.stringByDeletingLastCharacter) // "Hello, playgroun"
Short answer (valid as of 2015-04-16): removeAtIndex(myString.endIndex.predecessor())
Example:
var howToBeHappy = "Practice compassion, attention and gratitude. And smile!!"
howToBeHappy.removeAtIndex(howToBeHappy.endIndex.predecessor())
println(howToBeHappy)
// "Practice compassion, attention and gratitude. And smile!"
Meta:
The language continues its rapid evolution, making the half-life for many formerly-good S.O. answers dangerously brief. It's always best to learn the language and refer to real documentation.
With the new Substring type usage:
Swift 4:
var before: String = "Hello world!"
var lastCharIndex: Int = before.endIndex
var after:String = String(before[..<lastCharIndex])
print(after) // Hello world
Shorter way:
var before: String = "Hello world!"
after = String(before[..<before.endIndex])
print(after) // Hello world
Use the function advance(startIndex, endIndex):
var str = "45+22"
str = str.substringToIndex(advance(str.startIndex, countElements(str) - 1))
A swift category that's mutating:
extension String {
mutating func removeCharsFromEnd(removeCount:Int)
{
let stringLength = count(self)
let substringIndex = max(0, stringLength - removeCount)
self = self.substringToIndex(advance(self.startIndex, substringIndex))
}
}
Use:
var myString = "abcd"
myString.removeCharsFromEnd(2)
println(myString) // "ab"
Another way If you want to remove one or more than one character from the end.
var myStr = "Hello World!"
myStr = (myStr as NSString).substringToIndex((myStr as NSString).length-XX)
Where XX is the number of characters you want to remove.
Swift 3 (according to the docs) 20th Nov 2016
let range = expression.index(expression.endIndex, offsetBy: -numberOfCharactersToRemove)..<expression.endIndex
expression.removeSubrange(range)
The dropLast() function removes the last element of the string.
var expression = "45+22"
expression = expression.dropLast()
Swift 4.2
I also delete my last character from String (i.e. UILabel text) in IOS app
#IBOutlet weak var labelText: UILabel! // Do Connection with UILabel
#IBAction func whenXButtonPress(_ sender: UIButton) { // Do Connection With X Button
labelText.text = String((labelText.text?.dropLast())!) // Delete the last caracter and assign it
}
I'd recommend using NSString for strings that you want to manipulate. Actually come to think of it as a developer I've never run into a problem with NSString that Swift String would solve... I understand the subtleties. But I've yet to have an actual need for them.
var foo = someSwiftString as NSString
or
var foo = "Foo" as NSString
or
var foo: NSString = "blah"
And then the whole world of simple NSString string operations is open to you.
As answer to the question
// check bounds before you do this, e.g. foo.length > 0
// Note shortFoo is of type NSString
var shortFoo = foo.substringToIndex(foo.length-1)
Swift 3: When you want to remove trailing string:
func replaceSuffix(_ suffix: String, replacement: String) -> String {
if hasSuffix(suffix) {
let sufsize = suffix.count < count ? -suffix.count : 0
let toIndex = index(endIndex, offsetBy: sufsize)
return substring(to: toIndex) + replacement
}
else
{
return self
}
}
complimentary to the above code I wanted to remove the beginning of the string and could not find a reference anywhere. Here is how I did it:
var mac = peripheral.identifier.description
let range = mac.startIndex..<mac.endIndex.advancedBy(-50)
mac.removeRange(range) // trim 17 characters from the beginning
let txPower = peripheral.advertisements.txPower?.description
This trims 17 characters from the beginning of the string (he total string length is 67 we advance -50 from the end and there you have it.
I prefer the below implementation because I don't have to worry even if the string is empty
let str = "abc"
str.popLast()
// Prints ab
str = ""
str.popLast() // It returns the Character? which is an optional
// Print <emptystring>