2017-01-13 3 views
1

짧은 설명 :Swift3 Extension on "Any?" - 계급?

종종 "대상"을 확장하려고합니다. 대상은 대개 Any?입니다. 하지만 Any에 확장명을 사용할 수는 없습니다. 그것을하는 방법?


이 고려

, 우수

extension UIViewController {  
    func add(tap v:UIView, _ action:Selector) { 
     let t = UITapGestureRecognizer(target: self, action: action) 
     v.addGestureRecognizer(t) 
    } 
} 

, 당신은 어떤 뷰 컨트롤러 ... ... 지금

self.tap(redButton, #selector(clickedRedButton)) 

을 할 수 있습니다.

하지만 같은 목표를 달성 할 수 있습니다.

그래서,

extension UIGestureRecognizerDelegate { 
     func add(tap v:UIView, _ action:Selector) { 
     let t = UITapGestureRecognizer(target: self, action: action) 
     v.addGestureRecognizer(t) 
    } 
} 

UITapGestureRecognizer의 대상 인수가 실제로 Any?

입니다 .... 당신은 또한이 있어야, 말하는있는 UITableViewCell에 확장자를 사용하는, 당신은이 작업을 수행 할 수 없습니다 ...

extension Any { 

해결책은 무엇입니까? UITapGestureRecognizer의 첫 번째 인수와 같이 Any?에서 작동하는 확장 프로그램을 만드는 방법은 무엇입니까? 오히려 복사하고 두 번을 붙여보다

extension UIViewController or UIView { 

:

또는 Conner'c 코멘트에서 알 수 있듯이

, 할 수있는 방법이 있나요?

+0

이를 매우 로터리입니다. 매개 변수의 함수 ('addGestureRecognizer')를 호출 한 함수는 모든 확장에 붙여 넣을 수 있습니다. 컨트롤러 또는 뷰가 아닌 다른 곳에서 제스처 인식기를 추가 할 수 있다는 것은 좋은 디자인 결정이 아닙니다. – Connor

+0

안녕하세요 @ConnorNeville - 물론 컨트롤러 또는보기 ** 중 하나라고 말하십시오. 그래서, 현재 두 개의 확장 기능이 필요합니다. 하나는 컨트롤러 용이고 다른 하나는보기 용입니다. 그래서 그것을 일반화하는 방법은? 확장자가 하나 뿐이니? – Fattie

+0

"대상"을 확장하는 것이 매우 간단합니다 ... 대상은 대개 '모두?'입니다. 그것을하는 방법? – Fattie

답변

4

"모든"은 모든 구조체/클래스에서 (수동적으로) 준수됩니다. Any를 확장하면 해당 기능이 언어 및 코드의 모든 단일 유형에 추가됩니다. 이것은 현재 가능하지 않으며, 나는 그것이 (또는 있어야한다고) 의심합니다.

어쨌든, 다음은이 문제를 해결하는 몇 가지 방법입니다. 어떤을 복제 할 필요없이이 고의로 당신을 강제로

protocol TapGestureAddable { 
    func addTapGestureRecognizer(to view: UIView, with action: Selector) -> UITapGestureRecognizer 
} 

extension TapGestureAddable { 
    func addTapGestureRecognizer(to view: UIView, with action: Selector) -> UITapGestureRecognizer { 
     let recognizer = UITapGestureRecognizer(target: self, action: action) 
     view.addGestureRecognizer(recognizer) 
     return recognizer 
    } 
} 

extension UIViewController: TapGestureAddable { } 
extension UIView: TapGestureAddable { } 

지정된 클래스 (IMO 좋은 일)에 기능을 추가하는를 선택

내 환경 설정 기능을 추가하는 프로토콜 확장 의미있는 코드.

func addTapGestureRecognizer(to view: UIView, with responder: Any, for action: Selector) -> UITapGestureRecognizer { 
    let recognizer = UITapGestureRecognizer(target: responder, action: action) 
    view.addGestureRecognizer(recognizer) 
    return recognizer 
} 
+0

좋은 생각! – Fattie

2

Any이의 클래스되지 않습니다 : 단지 글로벌 기능을, 그렇지 않으면

extension UIView { 

    func addTapGestureRecognizer(with responder: Any, for action: Selector) -> UITapGestureRecognizer { 
     let recognizer = UITapGestureRecognizer(target: responder, action: action) 
     self.addGestureRecognizer(recognizer) 
     return recognizer 
    } 

    func addTapGestureRecognizer(with action: Selector) -> UITapGestureRecognizer { 
     let recognizer = UITapGestureRecognizer(target: self, action: action) 
     self.addGestureRecognizer(recognizer) 
     return recognizer 
    } 
} 

:

아마도 더 나은 옵션은이 논리를 대신하여 UIView의 확장을하는 것입니다 그런 식으로 NSObject입니다. 변수/상수/매개 변수가 모든 객체 또는 구조체 인스턴스를 참조 할 수 있음을 Swift 컴파일러에 알리는 키워드 일 뿐이므로 Any을 확장 할 수 없습니다.당신은 당신이 무엇을하려고 고려하는 경우

, 당신은 어쨌든이 개 확장 사이에 미묘한 차이가있을 것입니다;

  • UIViewController 확장이 self 될 것 같은
  • 동안, UIView 확장을 위해, 당신은 v 필요하지 않습니다 (당신의 v) 매개 변수 대상보기를 받아 들일 필요가있다; 제스처 인식기를 다른 사람에게 설치하는 것은 의미가 없습니다 UIView. UIView 확장을위한
  • , 당신은 선택에 대해 다른 대상을 지정 할 수 있습니다.
  • 당신은 그것을하지 않도록, 의미, 이런 식으로 UIViewController을 확장 할 수는있는 UIViewController에 제스처 인식기를 추가하지 마십시오.

    self.redButton.add(Selector(("handleTap")), tapHandler: self) 
    

    동안 UIView에 : 당신이 뭔가 같은 말을 할 수있는 UIViewController에 지금

    extension UIView { 
        func add(_ action:Selector,tapHandler target:Any = self) { 
         let t = UITapGestureRecognizer(target: target, action: action) 
         self.addGestureRecognizer(t) 
        } 
    } 
    

    :

그래서, 나에게, 논리적 확장이 같은 뭔가를해야만 보이는 것 같다 서브 클래스 당신은 말할 수 :

self.add(Selector(("handleTap"))) 
+0

("UIView 확장 프로그램의 경우 v는 필요 없지만이 기능은 자체 기능이므로 다른 UIView에 제스처 인식기를 설치하는 것은 의미가 없습니다"... 하위보기에서 공통적입니다.) – Fattie

+1

So 하위보기에 추가하십시오. 요점은, 제공해야 할 제스처 인식기를 추가하는 것이 아니라 동작의 대상입니다. – Paulw11