2016-09-06 1 views
0

문제 :인터페이스 빌더 대신 런타임시 뷰에 클래스를 설정하는 방법

내가보기 myView에 부착 된 아래의 클래스 myShadow 있습니다.

클래스는 인터페이스 작성기에서 사용자 정의 클래스로보기에 첨부됩니다.

그러나 앱이 실행되는 동안 클래스를 설정해야 할 때가 있습니다.

enter image description here

질문 : 내가 대신 프로그래밍 방식으로 사용자가 버튼 myButton 도청 예를 들어보기 실행시 myView에 클래스 myShadow을 설정하는 방법

? 클래스를 정규 함수로 호출하는 방법이 있나요? ViewController?

코드 :

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var myView: UIView! 

    @IBAction func myButton(sender: AnyObject) { 


     //// How to set `myShadow` class on `myView` here when tapping `myButton`? //// 


    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 

class myShadow: UIView { 

    var shadowLayer: CAShapeLayer! 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     if shadowLayer == nil { 
      shadowLayer = CAShapeLayer() 
      shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
      shadowLayer.fillColor = UIColor.yellowColor().CGColor 
      shadowLayer.shadowColor = UIColor.blackColor().CGColor 
      shadowLayer.shadowPath = shadowLayer.path 
      shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
      shadowLayer.shadowOpacity = 1 
      shadowLayer.shadowRadius = 5 
      layer.insertSublayer(shadowLayer, atIndex: 0) 
     } 
    } 
} 

답변

1

스위프트는 강력한 형식의 언어입니다. 이 기능은 버그가 아닙니다. 변수를 선언하면 해당 변수가 그대로 유지됩니다. swizzling과 다른 트릭은 objective-c와 같이보다 역동적 인 언어로 작동하지만, swift는 유형을 적용합니다.

섀도우 레이어를 추가하고 제거하려면 UIView의 확장명을 사용하는 것이 좋습니다. 예를 들어 :

extension UIView 
{ 
    func applyShadow() 
    { 
     let shadowLayer = CAShapeLayer() 
     shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
     shadowLayer.fillColor = UIColor.yellowColor().CGColor 
     shadowLayer.shadowColor = UIColor.blackColor().CGColor 
     shadowLayer.shadowPath = shadowLayer.path 
     shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
     shadowLayer.shadowOpacity = 1 
     shadowLayer.shadowRadius = 5 
     layer.insertSublayer(shadowLayer, atIndex: 0) 
    } 

    func removeShadow() 
    { 
     guard let sublayers = layer.sublayers where sublayers.count > 0 else { return } 
     let shadowLayer = sublayers[0] 
     if shadowLayer.shadowPath != nil 
     { 
      shadowLayer.removeFromSuperlayer() 
     } 
    } 

} 

그런 다음 당신은 말할 수 :

@IBAction func myButton(sender: AnyObject) { 
    if let button = sender as? UIButton 
    { 
     button.applyShadow() // if you want to apply it to the button 
     myView.applyShadow() // if you want to apply it to some other view 
    } 
} 

이 어떤 UIView 또는 UIView의 서브 클래스와 함께 작동,하지만 당신은 뷰의 레이어 계층 구조에 대한 가정을 만들고 있어요.

또는 다음과 같은 말을 shouldShowShadow

class MyShadow: UIView { 

    var shadowLayer: CAShapeLayer! 
    var shouldShowShadow = false 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     if shadowLayer == nil && shouldShowShadow 
     { 
      shadowLayer = CAShapeLayer() 
      shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
      shadowLayer.fillColor = UIColor.yellowColor().CGColor 
      shadowLayer.shadowColor = UIColor.blackColor().CGColor 
      shadowLayer.shadowPath = shadowLayer.path 
      shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
      shadowLayer.shadowOpacity = 1 
      shadowLayer.shadowRadius = 5 
      layer.insertSublayer(shadowLayer, atIndex: 0) 
     } 
     else if shadowLayer != nil && !shouldShowShadow 
     { 
      shadowLayer.removeFromSuperlayer() 
      shadowLayer = nil 
     } 
    } 
} 

같은 MyShadow에 부울 속성을 추가 : MyShadow의 인스턴스에

@IBAction func myButton(sender: AnyObject) { 
    self.shadowView.shouldShowShadow = true 
    self.shadowView.setNeedsLayout() 
} 

이 유일한 작품.

+0

감사합니다. 이것들은 좋은 옵션입니다! – user4806509

1

나는 그 수를 생각하지 않습니다. 프로그래밍 방식으로 클래스 객체를 생성해야한다면 init 객체를 할당해야합니다.

MyShadow *myShadow = [[MyShadow alloc] init]; 

수정하려는 클래스에 특정 상속 된 계층 구조가있는 경우 특정 개체를 입력 할 수 있습니다.

MyShadow *myShadow = (MyShadow *)myShadow; 

또는 당신은하지 클래스에 메소드에 일반적으로 적용 objc/런타임 라이브러리를 사용하여 런타임에 스위 즐링을 할 수 있습니다.

제안 사항 : "MyShadow"를 "MyShadow"의 하위 클래스로 지정하십시오.

+0

감사합니다. 곧 답변 드리겠습니다. – user4806509

관련 문제