pass parameter create swift selector nstimer

parameter - swift create selector



@selector() en Swift? (21)

Además, si su clase (Swift) no desciende de una clase Objective-C, debe tener dos puntos al final de la cadena de nombre del método de destino y debe usar la propiedad @objc con su método de destino, por ejemplo

var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method")) @objc func method() { // Something cool here }

de lo contrario, obtendrá un error de "Selector no reconocido" en el tiempo de ejecución.

Estoy tratando de crear un NSTimer en Swift pero estoy teniendo algunos problemas.

NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)

test() es una función en la misma clase.

Me sale un error en el editor:

No se pudo encontrar una sobrecarga para ''init'' que acepte los argumentos proporcionados

Cuando cambio selector: test() a selector: nil el error desaparece.

He intentado:

  • selector: test()
  • selector: test
  • selector: Selector(test())

Pero nada funciona y no puedo encontrar una solución en las referencias.


Aquí hay un ejemplo rápido de cómo usar la clase Selector en Swift:

override func viewDidLoad() { super.viewDidLoad() var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method")) self.navigationItem.rightBarButtonItem = rightButton } func method() { // Something cool here }

Tenga en cuenta que si el método pasado como una cadena no funciona, fallará en tiempo de ejecución, no en tiempo de compilación, y bloqueará su aplicación. Ten cuidado


Cambie como una simple cadena de nombres en el método que requiere la sintaxis del selector

var timer1 : NSTimer? = nil timer1= NSTimer(timeInterval: 0.1, target: self, selector: Selector("test"), userInfo: nil, repeats: true)

Después de eso, escriba func test ().


Cuando se usa performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval() su método (que coinciden con el selector) deben marcarse como

@objc For Swift 2.0: { //... self.performSelector(“performMethod”, withObject: nil , afterDelay: 0.5) //... //... btnHome.addTarget(self, action: “buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside) //... //... NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector : “timerMethod”, userInfo: nil, repeats: false) //... } @objc private func performMethod() { … } @objc private func buttonPressed(sender:UIButton){ …. } @objc private func timerMethod () { …. }

Para Swift 2.2, debe escribir ''#selector ()'' en lugar de la cadena y el nombre del selector, por lo que las posibilidades de error ortográfico y bloqueo debido a eso ya no estarán allí. Abajo es ejemplo

self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)


Desde que se publica Swift 3.0, es incluso un poco más sutil declarar un targetAction apropiado

class MyCustomView : UIView { func addTapGestureRecognizer() { // the "_" is important let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyCustomView.handleTapGesture(_:))) tapGestureRecognizer.numberOfTapsRequired = 1 addGestureRecognizer(tapGestureRecognizer) } // since Swift 3.0 this "_" in the method implementation is very important to // let the selector understand the targetAction func handleTapGesture(_ tapGesture : UITapGestureRecognizer) { if tapGesture.state == .ended { print("TapGesture detected") } } }


El uso de #selector comprobará su código en el momento de la compilación para asegurarse de que el método al que desea llamar realmente exista. Aún mejor, si el método no existe, obtendrás un error de compilación: Xcode se negará a construir tu aplicación, eliminando así otra posible fuente de errores.

override func viewDidLoad() { super.viewDidLoad() navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: #selector(addNewFireflyRefernce)) } func addNewFireflyReference() { gratuitousReferences.append("Curse your sudden but inevitable betrayal!") }


En caso de que alguien más tenga el mismo problema que tuve con NSTimer, donde ninguna de las otras respuestas solucionó el problema, es realmente importante mencionar que, si está utilizando una clase que no hereda de NSObject, ni directamente ni en la jerarquía ( por ejemplo, archivos swift creados manualmente), ninguna de las otras respuestas funcionará incluso cuando se especifique de la siguiente manera:

let timer = NSTimer(timeInterval: 1, target: self, selector: "test", userInfo: nil, repeats: false) func test () {}

Sin cambiar nada más que simplemente hacer que la clase se hereda de NSObject, dejé de recibir el error "Selector no reconocido" y conseguí que mi lógica funcionara como se esperaba.


Encontré que muchas de estas respuestas eran útiles, pero no estaba claro cómo hacer esto con algo que no fuera un botón. Estaba agregando un reconocedor de gestos a un UILabel en Swift y tuve problemas, así que esto es lo que encontré que funcionó para mí después de leer todo lo anterior:

let tapRecognizer = UITapGestureRecognizer( target: self, action: "labelTapped:")

Donde el "Selector" fue declarado como:

func labelTapped(sender: UILabel) { }

Tenga en cuenta que es público y que no estoy usando la sintaxis Selector (), pero también es posible hacerlo.

let tapRecognizer = UITapGestureRecognizer( target: self, action: Selector("labelTapped:"))


Los selectores son una representación interna de un nombre de método en Objective-C. En Objective-C "@selector (methodName)" convertiría un método de código fuente en un tipo de datos de SEL. Como no puede usar la sintaxis de @selector en Swift (rickster está en ese punto), tiene que especificar manualmente el nombre del método como un objeto String directamente, o pasando un objeto String al tipo Selector. Aquí hay un ejemplo:

var rightBarButton = UIBarButtonItem( title: "Logout", style: UIBarButtonItemStyle.Plain, target: self, action:"logout" )

o

var rightBarButton = UIBarButtonItem( title: "Logout", style: UIBarButtonItemStyle.Plain, target: self, action:Selector("logout") )


Para futuros lectores, encontré que experimenté un problema y recibí un unrecognised selector sent to instance error de unrecognised selector sent to instance que fue causado al marcar la func destino como privada.

La func DEBE ser visible públicamente para ser llamada por un objeto con una referencia a un selector.


Puede ser útil anotar dónde configura el control que desencadena los asuntos de acción.

Por ejemplo, he encontrado que al configurar un UIBarButtonItem, tuve que crear el botón dentro de viewDidLoad o de lo contrario obtendría una excepción de selector no reconocida.

override func viewDidLoad() { super.viewDidLoad() // add button let addButton = UIBarButtonItem(image: UIImage(named: "746-plus-circle.png"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("addAction:")) self.navigationItem.rightBarButtonItem = addButton } func addAction(send: AnyObject?) { NSLog("addAction") }


Si desea pasar un parámetro a la función desde el NSTimer, aquí está su solución:

var somethingToPass = "It worked" let timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "tester:", userInfo: somethingToPass, repeats: false) func tester(timer: NSTimer) { let theStringToPrint = timer.userInfo as String println(theStringToPrint) }

Incluya los dos puntos en el texto del selector (probador :), y sus parámetros van en userInfo.

Su función debe tomar NSTimer como un parámetro. Luego simplemente extrae userInfo para obtener el parámetro que pasó.


Swift no utiliza selectores; varios patrones de diseño que en Objective-C hacen uso de los selectores funcionan de manera diferente en Swift. (Por ejemplo, use el encadenamiento opcional en los tipos de protocolo o pruebas / as lugar de performSelector: y use cierres siempre que pueda en lugar de performSelector: para una mejor seguridad de tipo / memoria).

Pero todavía hay una serie de API importantes basadas en ObjC que utilizan selectores, incluidos los temporizadores y el patrón de destino / acción. Swift proporciona el tipo de Selector para trabajar con estos. (Swift usa esto automáticamente en lugar del tipo SEL de ObjC).

En Swift 2.2 (Xcode 7.3) y posteriores (incluidos Swift 3 / Xcode 8 y Swift 4 / Xcode 9):

Puede construir un Selector partir de un tipo de función Swift usando la expresión #selector .

let timer = Timer(timeInterval: 1, target: object, selector: #selector(MyClass.test), userInfo: nil, repeats: false) button.addTarget(object, action: #selector(MyClass.buttonTapped), for: .touchUpInside) view.perform(#selector(UIView.insertSubview(_:aboveSubview:)), with: button, with: otherButton)

Lo bueno de este enfoque? El compilador Swift comprueba una referencia de función, por lo que puede usar la expresión #selector solo con los pares de clase / método que realmente existen y son elegibles para su uso como selectores (consulte "Disponibilidad del selector" a continuación). También tiene la libertad de hacer que su referencia de función sea tan específica como necesite, según las reglas de Swift 2.2+ para la denominación de tipo de función .

(Esto es en realidad una mejora con respecto a la directiva @selector() de @selector() , porque la -Wundeclared-selector del compilador -Wundeclared-selector verifica solo que exista el selector nombrado. La referencia de la función Swift que pasa a #selector comprueba la existencia, la pertenencia a una clase y la firma de tipo .)

Hay un par de advertencias adicionales para las referencias de funciones que se pasan a la expresión #selector :

  • Múltiples funciones con el mismo nombre base se pueden diferenciar por sus etiquetas de parámetros usando la sintaxis mencionada anteriormente para las referencias de funciones (por ejemplo, insertSubview(_:at:) vs insertSubview(_:aboveSubview:) ). Pero si una función no tiene parámetros, la única manera de desambiguarla es usar un tipo con la firma del tipo de la función (por ejemplo, foo as () -> () vs foo(_:) ).
  • Hay una sintaxis especial para los pares de obtención / establecimiento de propiedades en Swift 3.0+. Por ejemplo, dada una var foo: Int , puedes usar #selector(getter: MyClass.foo) o #selector(setter: MyClass.foo) .

Notas generales:

Casos donde #selector no funciona, y nombres: a veces no tiene una referencia de función para hacer un selector con (por ejemplo, con métodos registrados dinámicamente en el tiempo de ejecución de ObjC). En ese caso, puede construir un Selector partir de una cadena: por ejemplo, Selector("dynamicMethod:") , aunque pierda la comprobación de validez del compilador. Cuando haga eso, deberá seguir las reglas de denominación de ObjC, incluidos los dos puntos (:) para cada parámetro.

Disponibilidad del selector: el método al que hace referencia el selector debe estar expuesto al tiempo de ejecución de ObjC. En Swift 4, cada método expuesto a ObjC debe tener su declaración precedida con el atributo @objc . (En versiones anteriores obtuviste ese atributo gratis en algunos casos, pero ahora debes declararlo explícitamente).

Recuerde que private símbolos private no están expuestos también al tiempo de ejecución, su método debe tener al menos visibilidad internal .

Trayectorias clave: están relacionadas con los selectores, pero no tanto. También hay una sintaxis especial para estos en Swift 3: por ejemplo, chris.valueForKeyPath(#keyPath(Person.friends.firstName)) . Ver SE-0062 para más detalles. Y aún más cosas de KeyPath en Swift 4 , así que asegúrese de usar la API correcta basada en KeyPath en lugar de los selectores, si corresponde.

Puede leer más sobre los selectores en Interactuar con las API de Objective-C utilizando Swift con Cocoa y Objective-C .

Nota: Antes de Swift 2.2, el Selector ajustaba a StringLiteralConvertible , por lo que podría encontrar un código antiguo donde se pasan las cadenas desnudas a las API que toman selectores. #selector ejecutar "Convertir a la sintaxis Swift actual" en Xcode para obtener los que utilizan #selector .


usted crea el selector como abajo.
1.

UIBarButtonItem( title: "Some Title", style: UIBarButtonItemStyle.Done, target: self, action: "flatButtonPressed" )

2.

flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

Tenga en cuenta que la sintaxis de @selector desaparece y se reemplaza por una cadena simple que designa el método a llamar. Hay un área en la que todos podemos estar de acuerdo con la verbosidad que se interpone en el camino. Por supuesto, si declaramos que existe un método de destino llamado flatButtonPressed: es mejor que escribamos uno:

func flatButtonPressed(sender: AnyObject) { NSLog("flatButtonPressed") }

configurar el temporizador:

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("flatButtonPressed"), userInfo: userInfo, repeats: true) let mainLoop = NSRunLoop.mainRunLoop() //1 mainLoop.addTimer(timer, forMode: NSDefaultRunLoopMode) //2 this two line is optinal

Para estar completo, aquí está el flatButtonPressed

func flatButtonPressed(timer: NSTimer) { }


Para Swift 3

// Código de ejemplo para crear temporizador

Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true) WHERE timeInterval:- Interval in which timer should fire like 1s, 10s, 100s etc. [Its value is in secs] target:- function which pointed to class. So here I am pointing to current class. selector:- function that will execute when timer fires. func updateTimer(){ //Implemetation } repeats:- true/false specifies that timer should call again n again.


Para swift 3

let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.test), userInfo: nil, repeats: true)

Declaración de función en la misma clase

func test() { // my function }


Swift 2.2+ y Swift 3 Update

Use la nueva expresión #selector , que elimina la necesidad de usar literales de cadena, lo que hace que el uso sea menos propenso a errores. Para referencia:

Selector("keyboardDidHide:")

se convierte en

#selector(keyboardDidHide(_:))

Ver también: Swift Evolution Proposal.

Nota (Swift 4.0):

Si usas #selector deberías marcar la función como @objc

Ejemplo:

@objc func something(_ sender: UIButton)


Swift 4.0

usted crea el selector como abajo.

1.add el evento a un botón como:

button.addTarget(self, action: #selector(clickedButton(sender:)), for: UIControlEvents.touchUpInside)

y la función será como a continuación:

@objc func clickedButton(sender: AnyObject) { }


Swift 4.1
Con muestra de gesto de tap.

let gestureRecognizer = UITapGestureRecognizer() self.view.addGestureRecognizer(gestureRecognizer) gestureRecognizer.addTarget(self, action: #selector(self.dismiss(completion:))) // Use destination ''Class Name'' directly, if you selector (function) is not in same class. //gestureRecognizer.addTarget(self, action: #selector(DestinationClass.dismiss(completion:))) @objc func dismiss(completion: (() -> Void)?) { self.dismiss(animated: true, completion: completion) }

Consulte el documento de Apple para obtener más detalles sobre: Expresión de selector


// for swift 2.2 // version 1 buttton.addTarget(self, action: #selector(ViewController.tappedButton), forControlEvents: .TouchUpInside) buttton.addTarget(self, action: #selector(ViewController.tappedButton2(_:)), forControlEvents: .TouchUpInside) // version 2 buttton.addTarget(self, action: #selector(self.tappedButton), forControlEvents: .TouchUpInside) buttton.addTarget(self, action: #selector(self.tappedButton2(_:)), forControlEvents: .TouchUpInside) // version 3 buttton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside) buttton.addTarget(self, action: #selector(tappedButton2(_:)), forControlEvents: .TouchUpInside) func tappedButton() { print("tapped") } func tappedButton2(sender: UIButton) { print("tapped 2") } // swift 3.x button.addTarget(self, action: #selector(tappedButton(_:)), for: .touchUpInside) func tappedButton(_ sender: UIButton) { // tapped } button.addTarget(self, action: #selector(tappedButton(_:_:)), for: .touchUpInside) func tappedButton(_ sender: UIButton, _ event: UIEvent) { // tapped }


Create Refresh control using Selector method. var refreshCntrl : UIRefreshControl! refreshCntrl = UIRefreshControl() refreshCntrl.tintColor = UIColor.whiteColor() refreshCntrl.attributedTitle = NSAttributedString(string: "Please Wait...") refreshCntrl.addTarget(self, action:"refreshControlValueChanged", forControlEvents: UIControlEvents.ValueChanged) atableView.addSubview(refreshCntrl)

// Actualizar el método de control

func refreshControlValueChanged(){ atableView.reloadData() refreshCntrl.endRefreshing() }