-1

complete error:

Left side of mutating operator isn't mutable: 'abc' is a 'let' constant

Happens because I am trying to change value of a variable sent by parameter to function.
Can I get rid of this, or find some other solution?
Code(My code is much complex, but in effect doing the same as this):

func generateABC() {
var abc = "this"
abc += "is"

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(abc)) )
tapGesture.delegate = self
webView.addGestureRecognizer(tapGesture)

abc += "function"
}

handleTap function :

@objc
func handleTap(_ someString: String) {   
     someString += "my"          
}
faris97
  • 402
  • 4
  • 24
  • Why not directly access and modify the variable instead of passing it and modifying the parameter? Parameters of a function are 'constants' by default. If you really wish to modify the passed parameter, you could mark it as an `inout` parameter, but I would recommend against it for something like this... – Lokesh SN Feb 17 '20 at 09:43
  • Hahaha sure I would do that directly, but as I said in my Question, my code is much more complex than this with ABC – faris97 Feb 17 '20 at 09:45
  • 2
    Okay, I get that. But, don't you think you need to provide more context to at least understand the complexity? The way it is right now, it is more likely to perceived as a simple question – Lokesh SN Feb 17 '20 at 09:57

4 Answers4

5

Short story: It's impossible to add custom parameters to (any) target/action

Either there is no parameter

@objc
func handleTap() { ...

or the affected recognizer is the parameter

@objc
func handleTap(_ recognizer : UITapGestureRecognizer) { ...

That's it. In both cases the corresponding declaration is

UITapGestureRecognizer(target: self, action: #selector(handleTap))

You have to use a temporary variable to handle the string.

vadian
  • 274,689
  • 30
  • 353
  • 361
1

For passing parameters using UITapGestureRecognizer, One approach would be to subClass UITapGestureRecognizer and then set a property as example below:

class SampleGesture: UITapGestureRecognizer {
    var someString = String()
}

class ViewController: UIViewController {

    let tapGesture = SampleGesture(target: self, action: #selector(self.handleTap))
    tapGesture.delegate = self
    webView.addGestureRecognizer(tapGesture)
    tapGesture.someString = //your text
}

And as for error others already said in answers that Parameters of a function are 'constants' by default

@objc func handleTap(sender: SampleGesture) {
     var newTitle: String = sender.someString   // you can declare as globally
     newTitle += "my"   
}
Kishan Bhatiya
  • 2,175
  • 8
  • 14
0

You can not change a Passed variable's value within function. If you want to change value of someString then you have to store it into another variable and use it further like this.

@objc
func handleTap(_ someString: String) {  
     var newString: String = someString 
     newString += "my"          
}
shraddha11
  • 783
  • 4
  • 17
-1

All parameters passed into a Swift function are constants, so you can’t change them. If you want, you can pass in one or more parameters as inout, which means they can be changed inside your function, and those changes reflect in the original value outside the function.

func doubleInPlace(number: inout Int) {
    number *= 2
}

Credit: Paul Hudson https://www.hackingwithswift.com/sixty/5/10/inout-parameters

Be careful if you are going with this approach, because you can end up with unexpected sideffects. You can also simply use a temp variable inside your function, and assign the parameter to it

@objc
func handleTap(_ someString: String)-> String {
     var tempString = someString   
     tempString += "Whatever" 
     return tempString         
}
Simone
  • 91
  • 1
  • 8
  • 2
    This action will never be called. – vadian Feb 17 '20 at 09:56
  • @vadian This is the solution to edit a parameter inside the body of a function. However, declaring the tapGesture variable, the error which is thrown is different, so the question is very misunderstanding. – Simone Feb 17 '20 at 10:59
  • Please see my answer. The syntax `handleTap(_ someString: String) -> String` is invalid. – vadian Feb 17 '20 at 11:31