1

Is there a way to change a paragraph of text on swipe gesture ?. I want to change the paragraph with another predefined paragraph, when the user swipe on paragraph.

I'm stuck to detect the paragraph, can we insert hidden tag on it or something else to detect paragraph on gesture ?

I can get the index of the character, but how can i get the paragraph object or a way to ?

override func viewDidLoad()
{
    super.viewDidLoad()

    // set delegate for text view
    self.textView.delegate = self

    // set the swipeGesture to the UITextView
    let swipe = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeOnce(_:)))
    swipe.delegate = self
    swipe.direction = UISwipeGestureRecognizerDirection.left
    self.textView.addGestureRecognizer(swipe)

    // data
    var arrString = [String]()

    arrString.append("\n"+"5 Comme quelques-uns parlaient du temple, qui était orné de belles pierres et d'objets apportés en offrandes, Jésus dit:")
    arrString.append("\n"+"6 «Les jours viendront où il ne restera pas pierre sur pierre de ce que vous voyez, tout sera détruit.»")
    arrString.append("\n"+"7 Ils lui demandèrent: «Maître, quand donc cela arrivera-t-il et à quel signe reconnaîtra-t-on que ces événements vont se produire?»")
    arrString.append("\n"+"8 Jésus répondit: «Faites bien attention à ne pas vous laisser égarer. En effet, beaucoup viendront sous mon nom en disant:'C'est moi', et:'Le moment est arrivé.'Ne les suivez pas.")
    arrString.append("\n"+"9 Quand vous entendrez parler de guerres et de soulèvements, ne vous laissez pas effrayer, car il faut que ces choses arrivent d'abord. Cependant, ce ne sera pas encore la fin.»")
    arrString.append("\n"+"10 Puis il leur dit: «Une nation se dressera contre une nation et un royaume contre un royaume;")
    arrString.append("\n"+"11 il y aura de grands tremblements de terre en divers endroits, ainsi que des pestes et des famines; il y aura des phénomènes terrifiants et de grands signes dans le ciel.")
    arrString.append("\n"+"12 Mais, avant tout cela, on mettra la main sur vous et l'on vous persécutera, on vous livrera aux synagogues, on vous jettera en prison, on vous traînera devant des rois et devant des gouverneurs à cause de mon nom.")

    // set font
    let font = UIFont(name: "SourceSansPro-Regular", size: 20)
    let textFont = [NSFontAttributeName:font]

    let concat = NSMutableAttributedString()

    // set the paragraphe
    let count = arrString.count-1

    for x in 0...count {

        // Create a string that will be our paragraph
        let para = NSMutableAttributedString()

        // Create locally formatted strings
        let attrString = NSAttributedString(string: arrString[x], attributes:(textFont as Any as! [String : Any]))


        para.append(attrString)

        // Define paragraph styling
        let paraStyle = NSMutableParagraphStyle()
        //paraStyle.firstLineHeadIndent = 15.0
        //paraStyle.paragraphSpacingBefore = 10.0
        paraStyle.lineSpacing = 5

        // Apply paragraph styles to paragraph
        para.addAttribute(NSParagraphStyleAttributeName, value: paraStyle, range: NSRange(location: 0,length: para.length))

        // concat paragraphe
        concat.append(para)

    }

    // assign para
    textView.attributedText = concat
}

func swipeOnce(_ gestureRecognizer: UITapGestureRecognizer)
{
    // Get the location of the gesture recogniser in the text view
    let point:CGPoint = gestureRecognizer.location(in: self.textView)

    // Get the character index of the swipe
    let index:Int = self.textView.layoutManager.characterIndex(for: point, in: self.textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

    print(index);
}

thanks.

Hugues Gauthier
  • 639
  • 8
  • 18
  • Make your array of Strings a class property so you can access it from the swipe gesture recognizer's action method. – nathangitter May 01 '17 at 21:22

1 Answers1

1

You're problem is object-oriented programming, not anything with Swift or the UIKit API's.

Here is a general structure of a possible solution:

1: Declare your data in a class property.

var arrString: [String] {
    var arrString = [String]()
    arrString.append("\n"+"5 Comme quelques-uns parlaient du temple, qui était orné de belles pierres et d'objets apportés en offrandes, Jésus dit:")
    arrString.append("\n"+"6 «Les jours viendront où il ne restera pas pierre sur pierre de ce que vous voyez, tout sera détruit.»")
    arrString.append("\n"+"7 Ils lui demandèrent: «Maître, quand donc cela arrivera-t-il et à quel signe reconnaîtra-t-on que ces événements vont se produire?»")
    arrString.append("\n"+"8 Jésus répondit: «Faites bien attention à ne pas vous laisser égarer. En effet, beaucoup viendront sous mon nom en disant:'C'est moi', et:'Le moment est arrivé.'Ne les suivez pas.")
    arrString.append("\n"+"9 Quand vous entendrez parler de guerres et de soulèvements, ne vous laissez pas effrayer, car il faut que ces choses arrivent d'abord. Cependant, ce ne sera pas encore la fin.»")
    arrString.append("\n"+"10 Puis il leur dit: «Une nation se dressera contre une nation et un royaume contre un royaume;")
    arrString.append("\n"+"11 il y aura de grands tremblements de terre en divers endroits, ainsi que des pestes et des famines; il y aura des phénomènes terrifiants et de grands signes dans le ciel.")
    arrString.append("\n"+"12 Mais, avant tout cela, on mettra la main sur vous et l'on vous persécutera, on vous livrera aux synagogues, on vous jettera en prison, on vous traînera devant des rois et devant des gouverneurs à cause de mon nom.")
    return arrString
}

This will allow the data to be accessed anywhere within the class.

2: Create another property to keep track of the current paragraph.

var paragraphIndex = 0

3: Modify the swipe gesture recognizer's action to update the text in the text view.

func swipeOnce(_ gestureRecognizer: UISwipeGestureRecognizer) {
    paragraphIndex += 1
    if paragraphIndex > arrString.count - 1 { return }
    textView.text = arrString[paragraphIndex]
}

This will increment the paragraph tracker, check to make sure it's a valid index, and replace the text in the text view.

This is not the most optimal or cleanest solution, but requires the fewest number of changes between your current code and a working solution.

nathangitter
  • 9,607
  • 3
  • 33
  • 42
  • thanks for your time, but maybe i'ad not express myself correctly, or i do not understand your code, but my need is ex: the text 5 to 12 is displayed on the iPhone screen by the viewDidLoad() fund, and i swipe the on the text 9, i want with the swipeOnce func, detect that i swiped the text 9, and eventually replace that text. :P – Hugues Gauthier May 02 '17 at 20:55
  • So just use multiple UITextViews, one for each paragraph. Use a swipe gesture recognizer on each text view. – nathangitter May 02 '17 at 20:58
  • Wow that's a great idea ! – Hugues Gauthier May 02 '17 at 21:53