Tappable portions within a string for SwiftUI - text

I'm trying to add tappable segments to a Text and I have most of it but I cannot make an array of Texts with .onTapGestures. How can I add the tap gestures to the Texts.
The goal is to have a string such as "here is a phone: xxx-xxx-xxxx and here is a link: xxx.com. Go for it." and have xxx-xx-xxx and xxx.com tappable.
#available(iOS 14, *)
struct ConversationText: View {
var text: String
var connectMessageType: ConnectMessageType
var stringArray = [String]()
var phones = [String]()
var weblinks = [String]()
var textArray = [Text]()
init(text: String, connectMessageType: ConnectMessageType) {
self.text = text
self.connectMessageType = connectMessageType
stringArray = text.components(separatedBy: " ")
phones = phones(from: text) ?? [String]()
weblinks = weblinks(from: text) ?? [String]()
textArray = makeTexts(from: stringArray)
}
var myColor: Color {
connectMessageType == .me ? .secondaryYellow : .primaryBlue
}
var body: some View {
textArray.reduce(Text(""), { $0 + $1 })
}
func phones(from text: String) -> [String]? {
Tappables().getPhoneNumbers(from: self.text)
}
func weblinks(from text: String) -> [String]? {
Tappables().getWebLinks(from: self.text)
}
func makeTexts(from stringArray: [String]) -> [Text] {
var textArray = [Text]()
for string in stringArray {
if phones.contains(string) {
let text = Text(string+" ")
.foregroundColor(myColor)
// .onTapGesture {
// startCall(number: string, user: nil)
// }
textArray.append(text)
} else if weblinks.contains(string) {
let text = Text(string+" ")
.foregroundColor(myColor)
// .onTapGesture {
// if let url = URL(string: string),
// UIApplication.shared.canOpenURL(url){
// UIApplication.shared.open(url)
// }
textArray.append(text)
} else {
textArray.append(Text(string+" "))
}
}
return textArray
}
}```

Here is possible approach - use string formatted by Markdown.
Tested with Xcode 13.3 / iOS 15.4
A main part:
Text("here is a phone: [xxx-xxx-xxxx](tel:xxx-xxx-xxxx) and here is a link: [xxx.com](asperi://apple.com). Go for it.")
.onOpenURL {
print(">> got: \($0)")
}
Complete findings & code

Related

multiply two value from textfield by using core data in swiftui

i try to make an invoice app by using core data, i have 4 attribute: Article String, Price String , Quantity String and Taxe String and i try to make a fonction to multiply price * quantity and the result of them i want to make another function for calculate the taxe for each article
Like this ->
Article:
Price $:
Quantity x:
Taxe %:
Total taxe %:
Total price taxe incl $:
and then at the end i want sum total price and total taxe of my list created by user in textfield in 2 diffrent textView
like this ->
Total taxe %:
Total prie incl taxe $:
struct Facturation: View {
#Environment(\.managedObjectContext) private var viewContext
#FetchRequest(entity: FacturationCoreData.entity(), sortDescriptors: []) private var factures: FetchedResults<FacturationCoreData>
#State private var article = ""
#State private var prix = ""
#State private var quantite = ""
#State private var tvac = ""
#State private var tva = [0, 6, 12, 21]
#State private var tipIndex = 2
#AppStorage("textChange") private var textChange = ""
func prixQuantite() -> Double {
let fact = FacturationCoreData(context: viewContext)
let prix = fact.prix ?? ""
let quan = fact.quantite ?? ""
let sum = ((Double(prix) ?? 00) * (Double(quan) ?? 00))
return sum
}
func calculeTvaC() ->Double {
let fact = FacturationCoreData(context: viewContext)
let prixEtQuantite = prixQuantite()
let tva = fact.tva ?? ""
let prixTTC = ((prixEtQuantite / 100 * (Double(tva ?? "") ?? 00)) +
prixEtQuantite)
return prixTTC
}
var body: some View {
NavigationView{
VStack {
Form {
Section("Article"){
TextField("Article", text: $article)
.disableAutocorrection(true)
}
HStack{
Section("Q"){
TextField("Quantite", text: $quantite)
.keyboardType(.decimalPad)
}
Section("P") {
TextField("Prix", text: $prix)
.keyboardType(.decimalPad)
}
Section("T") {
TextField("TVA", text: $tvac)
.keyboardType(.decimalPad)
}
}
Button {
let facture = FacturationCoreData(context: viewContext)
facture.article = article
facture.quantite = quantite
facture.prix = prix
facture.tva = tvac
do{
try viewContext.save()
}catch{
print(error)
}
} label: {
Image(systemName: "square.and.arrow.down.fill")
.font(.title)
}
List{
ForEach(factures) { facture in
VStack(alignment: .leading){
Text("Artile: " + (facture.article ?? ""))
Text("Quantité: " + (facture.quantite ?? "") + "x")
Text("Prix: " + (facture.prix ?? "") + "€")
Text("Tva: " + (facture.tva ?? "") + "%")
Text("Total price:\(prixQuantite())$ ")
Text("Total taxe:\(calculeTvaC())$ ")
}.onTapGesture {
textChange = facture.article ?? ""
}
}.onDelete { indexSet in
indexSet.forEach { index in
let deletfacture = factures[index]
viewContext.delete(deletfacture)
do{
try viewContext.save()
}catch{
print(error)
}
}
}
}
}
Text(textChange)
}
.navigationTitle("Facturation")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink {
Client()
} label: {
Image(systemName: "person.badge.plus")
}
}
ToolbarItem(placement: .navigationBarLeading) {
NavigationLink {
ClientList()
} label: {
Image(systemName: "list.bullet")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
}
}
}
You can use an extension
extension FacturationCoreData{
var prixQuantite : Double {
let prix = self.prix ?? ""
let quan = self.quantite ?? ""
let sum = ((Double(prix) ?? 00) * (Double(quan) ?? 00))
return sum
}
var calculeTvaC : Double {
let prixEtQuantite = prixQuantite
let tva = self.tva ?? ""
let prixTTC = ((prixEtQuantite / 100 * (Double(tva ?? "") ?? 00)) +
prixEtQuantite)
return prixTTC
}
}
Then you can use
Text("Total price:\(facture.prixQuantite)$ ")
Text("Total taxe:\(facture.calculeTvaC)$ ")

Bold between two special characters in a String SwiftUI 2.0 | NSRegularExpression

Question:
( * test * ) The place where these two characters are is made bold, but after the bold operation is completed, a space is formed between these two characters. Why ?
As you can see in the json output, I can use the \n character, but the \n character does not work. Why ?
If you examine the image I added and my JSON data, there should be no spaces in the places I have shown with a red line in the image.
JSON:
"singular": ["*der* Mann","*des* Mann*es*\n*des* Man*s*","*dem* Mann\n*dem* Mann*e*","*den* Mann"]
Model:
struct TextGroup: Identifiable {
let id = UUID()
let content: String
let isBold: Bool
init(content: String, isBold: Bool) {
var content = content.trimmingCharacters(in: .whitespacesAndNewlines)
if isBold {
content = content.replacingOccurrences(of: "*", with: "")
}
self.content = content
self.isBold = isBold
}
}
String Extension:
extension String {
/// Parses the input text and returns a collection of rich text elements.
/// Currently supports asterisks only. E.g. "Save *everything* that *inspires* your ideas".
///
/// - Returns: A collection of rich text elements.
func parseRichTextElements() -> [TextGroup] {
let regex = try! NSRegularExpression(pattern: "\\*{1}(.*?)\\*{1}")
let range = NSRange(location: 0, length: count)
/// Find all the ranges that match the regex *CONTENT*.
let matches: [NSTextCheckingResult] = regex.matches(in: self, options: [], range: range)
let matchingRanges = matches.compactMap { Range<Int>($0.range) }
var elements: [TextGroup] = []
// Add the first range which might be the complete content if no match was found.
// This is the range up until the lowerbound of the first match.
let firstRange = 0..<(matchingRanges.count == 0 ? count : matchingRanges[0].lowerBound)
self[firstRange].components(separatedBy: " ").forEach { (word) in
guard !word.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
elements.append(TextGroup(content: String(word), isBold: false))
}
// Create elements for the remaining words and ranges.
for (index, matchingRange) in matchingRanges.enumerated() {
let isLast = matchingRange == matchingRanges.last
// Add an element for the matching range which should be bold.
let matchContent = self[matchingRange]
elements.append(TextGroup(content: matchContent, isBold: true))
// Add an element for the text in-between the current match and the next match.
let endLocation = isLast ? count : matchingRanges[index + 1].lowerBound
let range = matchingRange.upperBound..<endLocation
self[range].components(separatedBy: " ").forEach { (word) in
guard !word.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
elements.append(TextGroup(content: String(word), isBold: false))
}
}
return elements
}
/// - Returns: A string subscript based on the given range.
subscript(range: Range<Int>) -> String {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
let endIndex = index(self.startIndex, offsetBy: range.upperBound)
return String(self[startIndex..<endIndex])
}
}
RichText:
struct RichText: View {
let elements: [TextGroup]
init(_ content: String) {
elements = content.parseRichTextElements()
}
var body: some View {
var content = text(for: elements.first!)
elements.dropFirst().forEach { (element) in
content = content + self.text(for: element)
}
return content
}
private func text(for element: TextGroup) -> Text {
let postfix = shouldAddSpace(for: element) ? " " : ""
if element.isBold {
return Text(element.content + postfix)
.fontWeight(.bold)
} else {
return Text(element.content + postfix)
}
}
private func shouldAddSpace(for element: TextGroup) -> Bool {
return element.id != elements.last?.id
}
}
Using:
ForEach(singular.indices, id: \.self) { index in
RichText(singular[index])
}

SwifUI: How to get manual list to refresh when updating CoreData records?

I have a CoreData table that has several repeated records that don't need to be stored but do need to be displayed in my user interface. I have manually created my arrays based on the CoreData table. I have made them Observable Objects so they should automatically update and I have made them Hashable and Equatable.
My problem is that the list does not update when the database records are updated. This works fine when records are being added.
Here is my much simplified code in full that demonstrates the problem:
import SwiftUI
let persistentContainerQueue = OperationQueue()
let firstNames = ["Michael", "Damon", "Jacques", "Mika", "Fernando", "Kimi", "Lewis", "Jenson", "Sebastion", "Nico"]
let lastNames = ["Schumacher", "Hill", "Villeneuve", "Hakkinen", "Alonso", "Raikkonen", "Hamilton", "Button", "Vettel", "Rosberg"]
class RepeatedPerson: ObservableObject, Hashable
{
#Published var person: Person
#Published var index: Int
#Published var tested: Bool
init (person: Person, index: Int, tested: Bool)
{
self.person = person
self.index = index
self.tested = tested
}
func hash(into hasher: inout Hasher)
{
hasher.combine(person.firstName)
hasher.combine(person.lastName)
hasher.combine(index)
}
static func == (lhs: RepeatedPerson, rhs: RepeatedPerson) -> Bool
{
return lhs.person.firstName == rhs.person.firstName &&
lhs.person.lastName == rhs.person.lastName &&
lhs.index == rhs.index
}
}
class RepeatedPeople: ObservableObject
{
#Published var people: [RepeatedPerson] = []
}
func getRepeatedPeople() -> [RepeatedPerson]
{
var repeatedPeople:[RepeatedPerson] = []
let records = allRecords(Person.self)
for person in records
{
for index in 1...3
{
repeatedPeople.append(RepeatedPerson(person: person, index: index, tested: true))
}
}
return repeatedPeople
}
struct ContentView: View
{
#Environment(\.managedObjectContext) private var viewContext
#ObservedObject var repeatedPeople = RepeatedPeople()
init()
{
repeatedPeople.people = getRepeatedPeople()
}
var body: some View
{
VStack
{
List()
{
ForEach(repeatedPeople.people, id: \.self)
{ repeatedPerson in
Text("\(repeatedPerson.index)) \(repeatedPerson.person.firstName!) \(repeatedPerson.person.lastName!)")
}
}
HStack
{
Button("Add Record", action:
{
addItem()
repeatedPeople.people = getRepeatedPeople()
})
Button("Change Record", action:
{
let q = allRecords(Person.self)
let oldLastName = q[0].lastName
q[0].lastName = lastNames.randomElement()!
print ("changed \(q[0].firstName!) \(oldLastName!) -> \(q[0].firstName!) \(q[0].lastName!)")
saveDatabase()
})
Button("Reset Database", action:
{
deleteAllRecords(Person.self)
})
}
}
}
private func addItem()
{
withAnimation
{
let newItem = Person(context: viewContext)
newItem.timestamp = Date()
newItem.firstName = firstNames.randomElement()!
newItem.lastName = lastNames.randomElement()!
print ("added \(newItem.firstName!) \(newItem.lastName!)")
saveDatabase()
}
}
}
func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
let context = PersistenceController.shared.container.viewContext
let request = T.fetchRequest()
if let sortDescriptor = sort
{
request.sortDescriptors = [sortDescriptor]
}
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func deleteAllRecords<T: NSManagedObject>(_ type : T.Type)
{
let context = PersistenceController.shared.container.viewContext
let results = allRecords(T.self)
for record in results
{
context.delete(record as NSManagedObject)
}
saveDatabase()
}
func saveDatabase()
{
persistentContainerQueue.addOperation()
{
let context = PersistenceController.shared.container.viewContext
context.performAndWait
{
try? context.save()
}
}
}
To reproduce the problem, add a few records. These will be shown in the list. Then click the 'Update Record' button. The CoreData record will be updated (you can see this the next time you run the app) but the changes will not be shown.
How do I get the new changes to show?
If you add another record the changes will then be shown. A side effect is that the list introduces wild spaces between the records. I have seen this is in other places. Is this a SwiftUI bug?
OK it turned out to be really quite simple. All I actually had to do was remove some of the #Published and provide a UUID for the repeatedPerson record (and for == and hash).
import SwiftUI
import CoreData
let persistentContainerQueue = OperationQueue()
let firstNames = ["Michael", "Damon", "Jacques", "Mika", "Fernando", "Kimi", "Lewis", "Jenson", "Sebastion", "Nico"]
let lastNames = ["Schumacher", "Hill", "Villeneuve", "Hakkinen", "Alonso", "Raikkonen", "Hamilton", "Button", "Vettel", "Rosberg"]
class RepeatedPerson: ObservableObject, Hashable
{
var id: UUID = UUID()
var index: Int
var person: Person?
init (person: Person, index: Int)
{
self.person = person
self.index = index
}
func hash(into hasher: inout Hasher)
{
hasher.combine(id)
}
static func == (lhs: RepeatedPerson, rhs: RepeatedPerson) -> Bool
{
return lhs.id == rhs.id
}
}
class RepeatedPeople: ObservableObject
{
#Published var people: [RepeatedPerson] = []
}
func getRepeatedPeople() -> [RepeatedPerson]
{
var repeatedPeople:[RepeatedPerson] = []
let records = allRecords(Person.self)
for person in records
{
for index in 1...3
{
repeatedPeople.append(RepeatedPerson(person: person, index: index))
}
}
return repeatedPeople
}
struct ContentView: View
{
#Environment(\.managedObjectContext) private var viewContext
#ObservedObject var repeatedPeople = RepeatedPeople()
init()
{
repeatedPeople.people = getRepeatedPeople()
}
var body: some View
{
VStack
{
List()
{
ForEach(repeatedPeople.people, id: \.self)
{ repeatedPerson in
Text("\(repeatedPerson.index)) \(repeatedPerson.person!.firstName!) \(repeatedPerson.person!.lastName!)")
}
}
HStack
{
Button("Add Record", action:
{
addItem()
repeatedPeople.people = getRepeatedPeople()
})
Button("Change Record", action:
{
let q = allRecords(Person.self)
let r = q.randomElement()!
let oldLastName = r.lastName
r.lastName = lastNames.randomElement()!
print ("changed \(r.firstName!) \(oldLastName!) -> \(r.firstName!) \(r.lastName!)")
saveDatabase()
repeatedPeople.people = getRepeatedPeople()
})
Button("Reset Database", action:
{
print ("Reset database")
deleteAllRecords(Person.self)
repeatedPeople.people = getRepeatedPeople()
})
}
}
}
private func addItem()
{
withAnimation
{
let newItem = Person(context: viewContext)
newItem.timestamp = Date()
newItem.firstName = firstNames.randomElement()!
newItem.lastName = lastNames.randomElement()!
print ("added \(newItem.firstName!) \(newItem.lastName!)")
saveDatabase()
}
}
}
func query<T: NSManagedObject>(_ type : T.Type, predicate: NSPredicate? = nil, sort: NSSortDescriptor? = nil) -> [T]
{
let context = PersistenceController.shared.container.viewContext
let request = T.fetchRequest()
if let sortDescriptor = sort
{
request.sortDescriptors = [sortDescriptor]
}
if let predicate = predicate
{
request.predicate = predicate
}
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}
func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
return query(T.self, sort: sort)
}
func deleteAllRecords<T: NSManagedObject>(_ type : T.Type)
{
let context = PersistenceController.shared.container.viewContext
let results = allRecords(T.self)
for record in results
{
context.delete(record as NSManagedObject)
}
saveDatabase()
}
func saveDatabase()
{
persistentContainerQueue.addOperation()
{
let context = PersistenceController.shared.container.viewContext
context.performAndWait
{
try? context.save()
}
}
}

Highlight only one word of a string [duplicate]

Hello I'm new to Swift and am using SwiftUI for my project where I download some weather data and I display it in the ContentView().
I would like to highlight some part of the Text if it contains some specific word, but I don't have any idea how to start.
In ContentView(), I have tried to set a function receiving the string downloaded from web and return a string. I believe this is wrong, because SwiftUI does not apply the modifiers at the all for the Text.
For example, in my ContentView() I would like the word thunderstorm to have the .bold() modifier:
struct ContentView: View {
let testo : String = "There is a thunderstorm in the area"
var body: some View {
Text(highlight(str: testo))
}
func highlight(str: String) -> String {
let textToSearch = "thunderstorm"
var result = ""
if str.contains(textToSearch) {
let index = str.startIndex
result = String( str[index])
}
return result
}
}
If that requires just simple word styling then here is possible solution.
Tested with Xcode 11.4 / iOS 13.4
struct ContentView: View {
let testo : String = "There is a thunderstorm in the area. Added some testing long text to demo that wrapping works correctly!"
var body: some View {
hilightedText(str: testo, searched: "thunderstorm")
.multilineTextAlignment(.leading)
}
func hilightedText(str: String, searched: String) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }
var result: Text!
let parts = str.components(separatedBy: searched)
for i in parts.indices {
result = (result == nil ? Text(parts[i]) : result + Text(parts[i]))
if i != parts.count - 1 {
result = result + Text(searched).bold()
}
}
return result ?? Text(str)
}
}
Note: below is previously used function, but as commented by #Lkabo it has limitations on very long strings
func hilightedText(str: String) -> Text {
let textToSearch = "thunderstorm"
var result: Text!
for word in str.split(separator: " ") {
var text = Text(word)
if word == textToSearch {
text = text.bold()
}
result = (result == nil ? text : result + Text(" ") + text)
}
return result ?? Text(str)
}
iOS 13, Swift 5. There is a generic solution described in this medium article. Using it you can highlight any text anywhere with the only catch being it cannot be more then 64 characters in length, since it using bitwise masks.
https://medium.com/#marklucking/an-interesting-challenge-with-swiftui-9ebb26e77376
This is the basic code in the article.
ForEach((0 ..< letter.count), id: \.self) { column in
Text(letter[column])
.foregroundColor(colorCode(gate: Int(self.gate), no: column) ? Color.black: Color.red)
.font(Fonts.futuraCondensedMedium(size: fontSize))
}
And this one to mask the text...
func colorCode(gate:Int, no:Int) -> Bool {
let bgr = String(gate, radix:2).pad(with: "0", toLength: 16)
let bcr = String(no, radix:2).pad(with: "0", toLength: 16)
let binaryColumn = 1 << no - 1
let value = UInt64(gate) & UInt64(binaryColumn)
let vr = String(value, radix:2).pad(with: "0", toLength: 16)
print("bg ",bgr," bc ",bcr,vr)
return value > 0 ? true:false
}
You can concatenate with multiple Text Views.
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
var body: some View{
let testo : String = "There is a thunderstorm in the area"
let stringArray = testo.components(separatedBy: " ")
let stringToTextView = stringArray.reduce(Text(""), {
if $1 == "thunderstorm" {
return $0 + Text($1).bold() + Text(" ")
} else {
return $0 + Text($1) + Text(" ")
}
})
return stringToTextView
}
}
PlaygroundPage.current.setLiveView(ContentView())
If you are targeting iOS15 / macOS12 and above, you can use AttributedString. For example:
private struct HighlightedText: View {
let text: String
let highlighted: String
var body: some View {
Text(attributedString)
}
private var attributedString: AttributedString {
var attributedString = AttributedString(text)
if let range = attributedString.range(of: highlighted)) {
attributedString[range].backgroundColor = .yellow
}
return attributedString
}
}
If you want your match to be case insensitive, you could replace the line
if let range = attributedString.range(of: highlighted)
with
if let range = AttributedString(text.lowercased()).range(of: highlighted.lowercased())
The answer of #Asperi works well. Here is a modified variant with a search by array of single words:
func highlightedText(str: String, searched: [String]) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }
var result: Text!
let parts = str.components(separatedBy: " ")
for part_index in parts.indices {
result = (result == nil ? Text("") : result + Text(" "))
if searched.contains(parts[part_index].trimmingCharacters(in: .punctuationCharacters)) {
result = result + Text(parts[part_index])
.bold()
.foregroundColor(.red)
}
else {
result = result + Text(parts[part_index])
}
}
return result ?? Text(str)
}
Usage example:
let str: String = "There is a thunderstorm in the area. Added some testing long text to demo that wrapping works correctly!"
let searched: [String] = ["thunderstorm", "wrapping"]
highlightedText(str: str, searched: searched)
.padding()
.background(.yellow)
You can also make AttributedString with markdown this way
do {
return try AttributedString(markdown: foreignSentence.replacing(word.foreign, with: "**\(word.foreign)**"))
} catch {
return AttributedString(foreignSentence)
}
and just use Text
Text(foreignSentenceMarkdown)

Easiest way to create a word wrap from a string in swift

What is the easiest way to create a word wrap in Swift from a string? Let's say I have a string with 150 characters and I wish to start a new line every 50 characters. Your thoughts are most appreciated.
How about something like this:
extension String {
public func wrap(columns: Int = 80) -> String {
let scanner = NSScanner(string: self)
var result = ""
var currentLineLength = 0
var word: NSString?
while scanner.scanUpToCharactersFromSet(NSMutableCharacterSet.whitespaceAndNewlineCharacterSet(), intoString: &word), let word = word {
let wordLength = word.length
if currentLineLength != 0 && currentLineLength + wordLength + 1 > columns {
// too long for current line, wrap
result += "\n"
currentLineLength = 0
}
// append the word
if currentLineLength != 0 {
result += " "
currentLineLength += 1
}
result += word as String
currentLineLength += wordLength
}
return result
}
}
With tests:
func testWrapSimple() {
let value = "This is a string that wraps!".wrap(10)
XCTAssertEqual(value, "This is a\nstring\nthat\nwraps!")
}
func testWrapLongWords() {
let value = "Thesewordsare toolongforasingle line".wrap(10)
XCTAssertEqual(value, "Thesewordsare\ntoolongforasingle\nline")
}
Here is a crude swift word wrap program. Feel free to comment - because everyday is a school day!
import UIKit
class ViewController: UIViewController {
var string1: String = "I think this is a good word wrap method, but I must try many times!"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let arr = split(string1, { $0 == " "}, maxSplit: Int.max, allowEmptySlices: false)
println(arr)
for words in arr {
println("variable string1 has \(countElements(words)) characters!")
}
var firstThirtyFive: String = string1.substringToIndex(advance(string1.startIndex, 35))
println(firstThirtyFive)
var arr2 = split(firstThirtyFive, { $0 == " "}, maxSplit: Int.max, allowEmptySlices: false)
println(arr2.count)
var removed = arr2.removeLast()
println(arr2)
println(removed)
var fromThirtyFive:String = string1.substringFromIndex(advance(string1.startIndex,35))
println(fromThirtyFive)
var arr3 = split(fromThirtyFive, { $0 == " "}, maxSplit: Int.max, allowEmptySlices: false)
var removeFirst = arr3.removeAtIndex(0)
var newWord:String = removed + removeFirst
println(removeFirst)
println(arr3)
println(newWord)
arr3.insert(newWord, atIndex: 0)
println(arr3)
let res1 = join(" ", arr2)
let res2 = join(" ", arr3)
println(res1)
println(res2)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Resources