2016-11-09 3 views
2

스위프트의 인수를 선택기를 작성하는 방법을 ... (내가 의도적으로 테이블 뷰 방법을 떠난)스위프트 2에서이 작업을 사용하는 3

import Foundation 
import UIKit 

private extension Selector { 
    static let didTapButton = #selector(TableVC.buttonTapped(_ :)) 

} 

class TableVC: UITableViewController{ 

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     let btnAccView:UIButton = UIButton(frame: CGRectMake(0, 0, 27, 27)) 
     btnAccView.addTarget(self, action: .didTapButton, forControlEvents: UIControlEvents.TouchUpInside) 
     btnAccView.tag = indexPath.row 
    } 


    func buttonTapped(sender: UIButton){ 
     print("button tapped at row \(sender.tag)") 
    } 

} 

스위프트 3에서이 오류가 발생합니다 " TableVC에는 buttonTapped 멤버가 없습니다. "

인수를 취하는 선택기를 작성하면됩니다. 나는 내가 생각할 수있는 모든 방법으로 문법을 부단히 시도했지만 아무 것도 효과가 없었다. 도움을 주셔서 감사합니다

+1

을 [이 질문은] (http://stackoverflow.com/q/24814646/5513562)의 대답을, 그것은 될 수 없습니다 끝난. –

+1

http://fuckingclosuresyntax.com/ http://fuckingswiftblocksyntax.com/ –

+0

질문을 복제본으로 표시하고 원래 질문을 참조하지 않는 것은 기록에있어 아무에게도 전혀 쓸모가 없습니다. 원본이 중복 된 경우? – GED125

답변

3

우선 첫 번째 인수 레이블이 표시되지 않도록 buttonTapped을 수정해야합니다. 그것은 다음과 같습니다 있도록 내부 인수 라벨 전에 밑줄을 삽입 :

func buttonTapped(_ sender: UIButton) { 

하기 전에, 그 메소드 서명은 TableVC.buttonTapped(sender:)이었고, 지금은 서명 TableVC.buttonTapped(_:) 될 것입니다. 확장 프로그램에서 밑줄과 콜론 사이의 공백을 제거해야 할 수도 있지만 그 후에는 작동합니다.

여기에 Selector에 내선 번호를 사용하는 특별한 이유가 있습니까? 이 확장 모델은 일반적으로 쉽게 맞춤법이 잘못 될 수있는 알림 이름과 같은 것들을 사용하면 가장 유용합니다. 이로 인해 까다로운 버그가 발생합니다. Swift 컴파일러는 배치 위치에 상관없이 자동으로 #selector 선언의 유효성을 검사하므로 코드를 확장 할 필요없이 바로 삽입 할 수 있습니다.

1

컴파일러에서 함수 서명의 일부를 유추하여 슬픔을 덜어 줄 수 있습니다. 귀하의 경우에는 ...

class TableVC: UIViewController { 
    func buttonTapped(sender: UIButton) { /*...*/ } 
} 

당신도 같이 TableVC 클래스 외부에서 참조 할 수 있습니다 :

  • #selector(TableVC.buttonTapped(sender:))
  • #selector(TableVC.buttonTapped)

두 번째 작품 하나가 있기 때문에 buttonTapped의 기능은 TableVC이므로 컴파일러는이를 명확하게하기 위해 전체 서명이 필요하지 않습니다. .

TableVC의 코드에서 더 이상 간단하게 #selector(buttonTapped)을 사용할 수 있습니다. 그 시점에서 클래스 범위에 있고 클래스의 메서드를 안전하게 추론 할 수 있기 때문입니다.

(당신의 방법을 func buttonTapped(_ sender: UIButton)로 선언 된 경우에만이 작업을 사용중인 #selector(TableVC.buttonTapped(_:)) 라인 사용 사례의 경우,이 sender 매개 변수가 인수 레이블이 있는지 여부는 중요하지 않습니다 -. 당신이 거의 일치해야 func 선언과 #selector 표현식 사이입니다.

@Bob 메모와 같이 컴파일러가 이미 선택기의 유효성을 검사하므로 Selector 확장이 필요하지 않습니다. 버튼 동작에 대한 선택 구현하는 방법은 다음과

0

사용 :에 따르면

import UIKit 
class MyViewController: UIViewController { 
    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) 

    override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     let action = #selector(MyViewController.tappedButton) 
     myButton.addTarget(self, action: action, forControlEvents: .touchUpInside) 
    } 

    func tappedButton(sender: UIButton?) { 
     print("tapped button") 
    } 

    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
    } 
}