Convert NSRange in Objective-C to Swift - swift

How do I convert this to Swift:
NSString *searchString = [NSString stringWithFormat:#"%#", #"Apple_HFS "];
NSRange range = [tempString rangeOfString:searchString];
NSUInteger *idx = range.location + range.length;
Thanks

If you use String, you can just reference endIndex:
let searchString: String = "Apple_HFS "
if let range: Range<String.Index> = tempString.rangeOfString(searchString) {
let index = range.endIndex
let stringAfter = tempString.substringFromIndex(index)
// do something with `stringAfter`
} else {
// not found
}
I included the types so you could see what's going on, but generally I'd just write:
let searchString = "Apple_HFS "
if let range = tempString.rangeOfString(searchString) {
let stringAfter = tempString.substringFromIndex(range.endIndex)
// do something with `stringAfter`
} else {
// not found
}

Is that what you're looking for ?
var str : NSString = "A string that include the searched string Apple_HFS inside"
let searchString : NSString = "Apple_HFS "
let range : NSRange = str.rangeOfString(searchString) // (42, 10)
let idx : Int = range.location + range.length // 52
Demonstration : http://swiftstub.com/831969865/

Simple solution without using ANY objc methods or types:
Suppose you have:
let nsrange = NSRange(location: 3, length: 5)
let string = "My string"
And now you need to convert NSRange to Range:
let range = Range(start: advance(string.startIndex, nsrange.location), end: advance(string.startIndex, nsrange.location + nsrange.length))

Related

Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range<Index>' (aka 'Range<String.CharacterView.Index>')

I Have a error in my code like "Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range' (aka 'Range')" but I don't know how to solve this please any one help me?
Here I post my code.
NSUserDefaults.standardUserDefaults().setObject("Hey I have started using this Chat App", forKey: "Status")
var strNumber: String = txtPhoneNumber.text!
var myRange: NSRange = NSMakeRange(0, 2)
var myRange1: NSRange = NSMakeRange(0, 1)
var ran: String = strNumber.substringWithRange(myRange) ------> //This line error shows.
var ran1: String = strNumber.substringWithRange(myRange1)
if (ran == "00") || (ran == "60") || (ran == "62") || (ran == "65") || (ran == "91") || (ran == "44") {
strNumber = strNumber.stringByReplacingOccurrencesOfString(ran, withString: "") as String
}
else if (ran1 == "0") {
strNumber = strNumber.stringByReplacingOccurrencesOfString(ran1, withString: myRange1) as NSString
//str_number = str_number.stringByReplacingOccurrencesOfString(ran1, withString: "", options: NSCaseInsensitiveSearch, range: myRange1)
}
You should convert strNumber to NSString: var strNumber: NSString = txtPhoneNumber.text!
More here: NSRange to Range<String.Index>
Swift 4:
First typecaste to a string, and then use the class method on this typecasted string
let typeCasteToStringFirst = textField.text as NSString?
let newString = typeCasteToStringFirst?.replacingCharacters(in: range, with: string)
substringWithRange method works for NSString type
var strNumber: String = txtPhoneNumber.text!
change above line
var strNumber: NSString = txtPhoneNumber.text as! NSString

How do you limit UILabel characters in swift?

I'm trying to set a limit in my label to 10 characters, I'm a complete newbie to programming in general so its my 3rd month so far... anyway thanks in advance :-)
You can also create a String extension and reuse it with any text string.. You can do it in the following way:
create the extension:
extension String {
func maxLength(length: Int) -> String {
var str = self
let nsString = str as NSString
if nsString.length >= length {
str = nsString.substring(with:
NSRange(
location: 0,
length: nsString.length > length ? length : nsString.length)
)
}
return str
}
}
you can use the extension in the following way:
label.text = "This is a Very Long Label".maxLength(length: 10)
the previous code was tested in Swift 5.0
If you want to limit the UILabel to just 10 characters then
you just have to assign it with a text with length of 10.
You can use NSString and NSRange to extract the text you need.
let str = "This is a Very Long Label"
let nsString = str as NSString
if nsString.length >= 10
{
label.text = nsString.substringWithRange(NSRange(location: 0, length: nsString.length > 10 ? 10 : nsString.length))
}
Check out this answer: https://stackoverflow.com/a/39677331/2548473
My version is (Swift 5+):
extension String {
func shorted(to symbols: Int) -> String {
guard self.count > symbols else {
return self
}
return self.prefix(symbols) + " ..."
}
}
SWIFT 3
let str = GL_GetNews[indexPath.row]["n_body"].stringValue
let nsString = str as NSString
if nsString.length > 0
{
cell.newsDescription.text = nsString.substring(with: NSRange(location: 0, length: nsString.length > 200 ? 200 : nsString.length))
}

Get index of string in an array of NSAttributedString in swift

I have an array of NSattributedstring. I want to get the index of a string in the array. I am using the following code.
let textToSearch = "My name is Amrit"
let index = find(myArray, textToSearch)
myArray is an array of NsattributedString. As both the types of array and textTosearch are different.
indexArray = ["1. THE OPENING","2. THE COW","3. THE FAMILY OF IMRAN","4. WOMEN","5. THE FEAST","6. LIVESTOCK","7. THE HEIGHTS","8. BATTLE GAINS","9. REPENTANCE","10. JONAH","11. HUD","12. JOSEPH","13. THUNDER","14. ABRAHAM","15. AL-HIJR","16. THE BEE","17. THE NIGHT JOURNEY","18. THE CAVE","19. MARY","20. TA HA","21. THE PROPHETS","22. THE PILGRIMAGE","23. THE BELIEVERS","24. LIGHT","25. THE DIFFERENTIATOR","26. THE POETS","27. THE ANTS","28. THE STORY","29. THE SPIDER","30. THE BYZANTINES","31. LUQMAN","32. BOWING DOWN IN WORSHIP","33. THE JOINT FORCES","34. SHEBA","35. THE CREATOR","36. YA SIN","37. RANGED IN ROWS","38. SAD","39. THE THRONGS","40. THE FORGIVER","41. [VERSES] MADE DISTINCT","42. CONSULTATION","43. ORNAMENTS OF GOLD","44. SMOKE","45. KNEELING","46. THE SAND DUNES","47. MUHAMMAD","48. TRIUMPH","49. THE PRIVATE ROOMS","50. QAF","51. SCATTERING [WINDS]","52. THE MOUNTAIN","53. THE STAR","54. THE MOON","55. THE LORD OF MERCY","56. THAT WHICH IS COMING","57. IRON","58. THE DISPUTE","59. THE GATHERING [OF FORCES]","60. WOMEN TESTED","61. SOLID LINES","62. THE DAY OF CONGREGATION","63. THE HYPOCRITES","64. MUTUAL NEGLECT","65. DIVORCE","66. PROHIBITION","67. CONTROL","68. THE PEN","69. THE INEVITABLE HOUR","70. THE WAYS OF ASCENT","71. NOAH","72. THE JINN","73. ENFOLDED","74. WRAPPED IN HIS CLOAK","75. THE RESURRECTION","76. MAN","77. [WINDS] SENT FORTH","78. THEANNOUNCEMENT","79. THE FORCEFUL CHARGERS","80. HE FROWNED","81. SHROUDED IN DARKNESS","82. TORN APART","83. THOSE WHO GIVE SHORT MEASURE","84. RIPPED APART","85. THE TOWERING CONSTELLATIONS","86. THE NIGHT-COMER","87. THE MOST HIGH","88. THE OVERWHELMING EVENT","89. DAYBREAK","90. THE CITY","91. THE SUN","92. THE NIGHT","93. THE MORNING BRIGHTNESS","94. RELIEF","95. THE FIG","96. THE CLINGING FORM","97. THE NIGHT OF GLORY","98. CLEAR EVIDENCE","99. THE EARTHQUAKE","100. THE CHARGING STEEDS","101. THE CRASHING BLOW","102. STRIVING FOR MORE","103. THE DECLINING DAY","104. THE BACKBITER","105. THE ELEPHANT","106. QURAYSH","107. COMMON KINDNESSES","108. ABUNDANCE","109. THE DISBELIEVERS","110. HELP","111. PALM FIBRE","112. PURITY [OF FAITH]","113. DAYBREAK","114. PEOPLE"]
if let rtfPath = NSBundle.mainBundle().URLForResource("quaran3", withExtension: "rtf") {
let attributedStringWithRtf = NSMutableAttributedString(fileURL: rtfPath, options: [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType], documentAttributes: nil, error: nil)!
var lengthOfRtf = attributedStringWithRtf.length
divideFactor = Int(lengthOfRtf/endIndex)
println(divideFactor)
self.updateTextFont(attributedStringWithRtf) (valueFactor: divideFactor) (totalRange: lengthOfRtf)
self.getTheIndexNumber(attributedStringWithRtf) (valueFactor: divideFactor)
}
func updateTextFont(mystring:NSMutableAttributedString) (valueFactor:Int) (totalRange : Int) {
let screenSizeMain: CGRect = UIScreen.mainScreen().bounds
let myAttriText:NSMutableAttributedString = mystring.mutableCopy() as! NSMutableAttributedString
myAttriText.beginEditing()
myAttriText.enumerateAttributesInRange(NSMakeRange(0, myAttriText.length), options: NSAttributedStringEnumerationOptions.Reverse) { (attribute, range, stop) -> Void in
var mutableAttributes = NSDictionary(dictionary: attribute)
var font:UIFont = mutableAttributes.objectForKey(NSFontAttributeName) as! UIFont
var newFont:UIFont = font.fontWithSize(font.pointSize)
if DeviceType.IS_IPAD
{
newFont = font.fontWithSize(font.pointSize+7)
}
var fontProperties:UIFontDescriptor = font.fontDescriptor()
let sizeNumber:Float = fontProperties.fontAttributes()[UIFontDescriptorSizeAttribute] as! Float
myAttriText.addAttribute(NSFontAttributeName, value: newFont, range: range)
}
for var i=0; i <= valueFactor; i++ {
// if valueFactor*
if startIndex == 885819 {
}
//let checkCurrentRange = valueFactor*endIndex
let exactEndIndex : Int = endIndex
if (totalRange - startIndex) < endIndex
{
endIndex = totalRange - startIndex
let rangeFinal = NSMakeRange(startIndex, endIndex)
var nsTextFinal = myAttriText.attributedSubstringFromRange(rangeFinal)
pageText.append(nsTextFinal)
endIndex = exactEndIndex
return
}
let range = NSMakeRange(startIndex, endIndex)
var nsText = myAttriText.attributedSubstringFromRange(range)
for index in endIndex..<endIndex+100
{
let rangeNew = NSMakeRange(endIndex + startIndex-1,1)
var checkSpace = myAttriText.attributedSubstringFromRange(rangeNew)
let stirngNew = checkSpace.string
if stirngNew == " "
{
break;
}
else
{
endIndex++
}
}
let rangeFinal = NSMakeRange(startIndex, endIndex)
var nsTextFinal = myAttriText.attributedSubstringFromRange(rangeFinal)
pageText.append(nsTextFinal)
println(startIndex)
startIndex = startIndex + endIndex
endIndex = exactEndIndex
}
myAttriText.endEditing()
}
func visibleRangeOfTextView(textView: NSAttributedString) -> NSRange {
return NSMakeRange(startIndex, endIndex)
}
func getTheIndexNumber(attribSring:NSMutableAttributedString) (valueFactor:Int) //-> NSMutableArray
{
for index in 0..<indexArray.count {
let text = indexArray.objectAtIndex(index) as! NSString
var lengthOfRtf = attribSring.length
var textNew = attribSring.attributedSubstringFromRange(NSMakeRange(0, lengthOfRtf))
var stirngNew : NSMutableString = attribSring.mutableString.mutableCopy() as! NSMutableString
// println(stirngNew)
var range: NSRange = (stirngNew as NSString).rangeOfString(text as String)
var checkSpace = attribSring.attributedSubstringFromRange(range)
let stirngNewCheck = checkSpace.string
let pageIndex = (range.location / endIndex)
indeArryInt.addObject(pageIndex)
}
}
You can try this:
let index = myArray.indexOf { $0.string == textToSearch }
This returns an Int?, the first index where a match is found. If there's no match, it will return nil.
If you are using Swift 1.2 you will need to map array of NSAttributedString to String array so find function can be called with correct values
let index = find(myArray.map({ attributedString in
return attributedString.string
}), textToSearch)
#ZoffDino answer would work like a charm in Swift 2.0

About AttributeString - making multiple occurrences bold

I am trying to make multiple occurrences in a attributed string bold using something like the following
[attrStr setFont:[UIFont ...] range:[attrStr.string rangeOfString:#"hello world"]];
As you know, 'rangeOfString' always return the FIRST occurrence of the match... I am still quite new to iOS, just wondering what's the best way to set all occurrences to bold... Is there any function provided in NSString or something?
Thanks in advance!
You should first try to get all ranges in the string and then set the attribute for every range. There are some great code examples right here on stackoverflow: https://stackoverflow.com/a/4653266/381870
Edit:
Here's an example for you
- (NSArray *)rangesOfString:(NSString *)searchString inString:(NSString *)str {
NSMutableArray *results = [NSMutableArray array];
NSRange searchRange = NSMakeRange(0, [str length]);
NSRange range;
while ((range = [str rangeOfString:searchString options:0 range:searchRange]).location != NSNotFound) {
[results addObject:[NSValue valueWithRange:range]];
searchRange = NSMakeRange(NSMaxRange(range), [str length] - NSMaxRange(range));
}
return results;
}
Usage:
NSArray *results = [self rangesOfString:#"foo" inString:#"foo bar foo"];
NSLog(#"%#", results);
gives you
(
"NSRange: {0, 3}",
"NSRange: {8, 3}"
)
Converting Tim's answer to Swift 4:
extension NSString {
open func ranges(of searchString: String) -> [NSRange] {
var ranges = [NSRange]()
var searchRange = NSRange(location: 0, length: self.length)
var range: NSRange = self.range(of: searchString)
while range.location != NSNotFound {
ranges.append(range)
searchRange = NSRange(location: NSMaxRange(range), length: self.length - NSMaxRange(range))
range = self.range(of: searchString, options: [], range: searchRange)
}
return ranges
}
}
Also did it to Swift's String primitive:
extension String {
func ranges(of substring: String, options: CompareOptions = [], locale: Locale? = nil) -> [Range<Index>] {
var ranges: [Range<Index>] = []
while let range = self.range(of: substring, options: options, range: (ranges.last?.upperBound ?? self.startIndex)..<self.endIndex, locale: locale) {
ranges.append(range)
}
return ranges
}
}
You will like have to use NSScanner to scan through the text and replace it.You can find an example for NSScanner here.

Replace only the first instance of a substring in an NSString

So if you have an NSString that goes:
#"My blue car is bigger than my blue shoes or my blue bicycle";
I would like a method that replaces only the first instance of blue with green, to produce:
#"My green car is bigger than my blue shoes or my blue bicycle";
How does one do this?
Assuming the following inputs:
NSString *myString = #"My blue car is bigger then my blue shoes or my blue bicycle";
NSString *original = #"blue";
NSString *replacement = #"green";
The algorithm is quite simple:
NSRange rOriginal = [myString rangeOfString:original];
if (NSNotFound != rOriginal.location) {
myString = [myString stringByReplacingCharactersInRange:rOriginal withString:replacement];
}
SWIFT 3 and 4 UPDATE:
extension String
{
func stringByReplacingFirstOccurrenceOfString(
target: String, withString replaceString: String) -> String
{
if let range = self.range(of: target) {
return self.replacingCharacters(in: range, with: replaceString)
}
return self
}
}
A more Swift'y version of the implementations posted here. This one matches the syntax replacingOccurrences(of:with:) in Swift 5.1
extension String {
func replacingFirstOccurrence(of target: String, with replacement: String) -> String {
guard let range = self.range(of: target) else { return self }
return self.replacingCharacters(in: range, with: replacement)
}
}
An example of usage:
let string = "I like bacon, please give me some more bacon!"
let newString = string.replacingFirstOccurrence(of: "bacon", with: "meat")
Swift 4 version:
func replacingFirstOccurrence(of string: String, with replacement: String) -> String {
guard let range = self.range(of: string) else { return self }
return replacingCharacters(in: range, with: replacement)
}
In Swift is useful extends String in this way:
public extension String {
func stringByReplacingFirstOccurrenceOfString(target: String, withString replaceString: String) -> String {
if let range = self.rangeOfString(target) {
return self.stringByReplacingCharactersInRange(range, withString: replaceString)
}
return self
}
}
In this way you can call wherever:
let s = "The red red cat".stringByReplacingFirstOccurrenceOfString("red", withString: "fat")
print(s) // "The fat red cat"
NSString *initialString = #"My blue car is bigger then my blue shoes or my blue bicycle";
NSRange range = [initialString rangeOfString:#"blue"];
NSString *replacedString = [initialString stringByReplacingCharactersInRange:range withString:#"green"];
NSLog(#"replacedString: %#", replacedString);
First locate the substring, and then make the replacement. Example :
NSString *aString = #"foo bar foo";
NSRange firstFooRange = [aString rangeOfString:#"foo"];
NSString *anotherString = [aString stringByReplacingOccurrencesOfString:#"foo"
withString:#"bar"
options:0
range:firstFooRange];
NSString documentation.
-(NSString*) replaceFirstOccuarnceFromString: (NSString*)input withOriginal:(NSString*) original AndReplacment:(NSString*)replacement
{
NSRange rOriginal = [input rangeOfString: original];
if (NSNotFound != rOriginal.location) {
input = [input
stringByReplacingCharactersInRange: rOriginal
withString: replacement];
}
return input;
}