2015-02-03 13 views
0

아래 코드는 UITapGestureRecognizer의 인스턴스에 'self'를 설정할 때 작동하지만 'SkinViewTransitionHelper'인스턴스에 설정하면 앱이 다운되고 Xcode가 도움이되는 정보를 표시하지 않으며, 실제로 아무 것도하지 않고 앱이 작동을 멈추었을 때 (녹색 표시기) AppDelegate로 이동합니다. 또한 스택 추적은 크래시와 관련이없는 일부 스레드 만 표시하면 비어 있습니다. 나는 많은 것을 검색하고 UIGestureRecognizer의 문서를 다시 읽었으나 도움을받지 못했습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? Xcode 버전 6.2 (6C107a)에서 응용 프로그램을 코딩하고 있습니다. 또한 iOS 시뮬레이터 버전 8.2 (553.8)에서 앱을 테스트하고 있습니다. 또한 targetUITapGestureRecognizer 클래스의 약한 속성입니다 그래서 SkinViewTransitionHelper의 인스턴스가 UITapGestureRecognizer에 의해에 의해 유지되지 않습니다 때문에 충돌 UITapGestureRecognizer calling another class클래스를 'self'대신 UITapGestureRecognizer의 대상으로 설정할 때 앱이 충돌합니다

/** 
    Manages the view that contains logo and button. 
    */ 
    class LaunchView: UIView { 
     // MARK: Instance variables 
     /** Logo image view */ 
     private var logoImageView: UIImageView! 
     /** x Button image view */ 
     private var xButtonImageView: UIImageView! 

     // MARK: Designated Initializer 

     /** 
      Initialize LaunchView view with logo and button. 

      :param: frame  Frame of this view 
      :param: logoImage Logo Image used at the top of the view 
      :param: xButtonImage Button Image used at the bottom of the view 
     */ 
     init(frame: CGRect, logoImage: UIImage, xButtonImage: UIImage){ 
      super.init(frame: frame) 

      // Initialize the logoImageView 
      logoImageView = UIImageView(frame: frame) 
      // Set the image of logoImageView 
      logoImageView.image = logoImage 

      // Initialize the capriceButtonImage 
      // Note: It's kinda hard coding the (x,y) values. Look for a generic way. 
      xButtonImageView = UIImageView(frame: CGRect(x: frame.size.width/4 + 20, y: frame.size.height - 200, width: xButtonImage.size.width, height: xButtonImage.size.height)) 
      // Set the image of xButtonImageView 
      xButtonImageView.image = xButtonImage 

      // SingleTap recognizer for xButtonImageView 
      // Note: Find a generic solution instead of writing method name in "". It's kinda horrible; Maybe I forget to write the name of function correctly. 
      // Note: Still not possible in Swift. reflect() helps if we want information about properties. 
      // Note: https://github.com/ksm/SwiftInFlux#reflection 
      // FIXME: App crashes using SkinViewTransitionHelper() as target 
      let singleTapGestureRecognizer: UITapGestureRecognizer = 
        UITapGestureRecognizer(target: SkinViewTransitionHelper(), action: "handleGesture:") 

      // works like a charm if I remove the comment and comment above line 
      // let singleTapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "handleGesture:") 

      // Set the nunmber of taps required 
      singleTapGestureRecognizer.numberOfTapsRequired = 1 
      singleTapGestureRecognizer.numberOfTouchesRequired = 1 

      // Add tap gesture to xButtonImageView 

      xButtonImageView.addGestureRecognizer(singleTapGestureRecognizer) 

      xButtonImageView.userInteractionEnabled = true 

      // Add logoImageView to the view 
      self.addSubview(logoImageView) 
      // Add xButtonImageView to the view 
      self.addSubview(xButtonImageView) 
     } 

     required init(coder aDecoder: NSCoder) { 
      fatalError("init(coder:) has not been implemented") 
     } 

     // func handleGesture(gestureRecongnizer: UIGestureRecognizer) { 
      // if .Ended == gestureRecongnizer.state { 
       // T0D0: Notify LaunchViewController of gesture 
      // } 
     // } 
    } 

    /** 
    Handle gesture recognized by a UIView instance 
    */ 
    class SkinViewTransitionHelper { 
     // MARK: Gesture Handler 

     /** 
     Handle gesture recognized by a UIView instance 
     */ 
     func handleGesture(gestureRecongnizer: UIGestureRecognizer) { 
      println(__FUNCTION__) 

      if .Ended == gestureRecongnizer.state { 
       // TODO: Load SkinViewController 
      } 
     } 
    } 

import UIKit 

class LaunchViewViewController: UIViewController { 

    override func viewDidLoad() { 
     println(self) 
     println(__FUNCTION__) 

     super.viewDidLoad() 
    } 

    override func loadView() { 
     println(self) 
     println(__FUNCTION__) 

     // Set LaunchView as the view of LaunchViewViewController 
     self.view = LaunchView(frame: UIScreen.mainScreen().bounds, logoImage: ImagesCatalog.Logo, xButtonImage: ImagesCatalog.xButton) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

답변

0

을 확인했다.

SKinViewTransitionHelper 유형의 속성을 만들고 인스턴스를 저장하고 UITapGestureRecognizer 대상으로 설정하십시오. 당신이 변수로 상점을 SkinViewTransitionHelper에게 그 가치를 인스턴스화하는 경우

class LaunchView { 

    var skinViewHelper : SKinViewTransitionHelper! 

    init(frame: CGRect, logoImage: UIImage, xButtonImage: UIImage){ 

     //Your code 
     self.skinViewHelper = SKinViewTransitionHelper() 
     let singleTapGestureRecognizer: UITapGestureRecognizer = 
        UITapGestureRecognizer(target: self.skinViewHelper, action: "handleGesture:") 
    } 
} 

은 또한 당신이 어떻게 되나요 @objc

class SkinViewTransitionHelper { 

    @objc func handleGesture(gestureRecongnizer: UIGestureRecognizer) { 
     println(__FUNCTION__) 

     if .Ended == gestureRecongnizer.state { 
      // TODO: Load SkinViewController 
     } 
    } 
} 
0

와 선택으로 참조 할 기능을 표시합니다 (아마도 클래스 속성이어야합니다) 다음 목표로 지정 하시겠습니까?

SkinViewTransitionHelper 인스턴스는 아무 곳에서나 하드 참조가 없으므로 '대상'할당 후에 할당 취소 될 수 있습니다.