UIView扩展中的新属性,用于自定义枚举案例

时间:2019-02-15 23:34:51

标签: ios swift

我正在尝试在UIView上应用某些情况,例如通过设置新颜色的动画来更改颜色或平滑地隐藏视图

在这里我创建了一个小枚举来容纳我所有的动画盒:

enum ViewAnimation {
    case changeColor(to: UIColor, duration: TimeInterval)
    case hideView(duruation: TimeInterval)
}

在这里我想为UIView创建一个属性:

extension UIView {


var animate: ViewAnimation {
    get {
        return .changeColor(to: .red, duration: 1) // actually I don't know what to add in the getter !
    }
    set {
        switch self.animate {
        case .changeColor(let newColor, let duration):
            UIView.animate(withDuration: duration) {
                self.backgroundColor = newColor
            }
        case .hideView(let duration):
            UIView.animate(withDuration: duration) {
                self.alpha = 0
                self.isHidden = true
            }
        }
    }
}

}

这是我的课:

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    let smallView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.addSubview(smallView)
    smallView.backgroundColor = .red
    smallView.center = view.center

    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        smallView.animate = .changeColor(to: .blue, duration: 3)
    }
}
}

问题是当我打电话给smallView.animate = .changeColor(to: .blue, duration: 3)时,什么都没有改变!

有人知道为什么它不起作用吗?

3 个答案:

答案 0 :(得分:2)

为什么要在扩展程序中创建属性?您甚至不需要吸气剂。 恕我直言,最好创建一个方法。

extension UIView {
    func animate(animation: ViewAnimation) {
        switch animation {
        case .changeColor(let newColor, let duration):
            UIView.animate(withDuration: duration) {
                self.backgroundColor = newColor
            }
        case .hideView(let duration):
            UIView.animate(withDuration: duration) {
                self.alpha = 0
                self.isHidden = true
            }
        }
    }
}

并命名为smallView.animate(animation: .changeColor(to: .blue, duration: 3))

但是,如果您确实要使用该属性,则不能执行switch self.animate,因为它将调用getter。 尝试执行switch newValue,因为每个set都有一个称为newValue的隐式局部变量,这是分配的当前值。

答案 1 :(得分:1)

您正在检查开关箱中的旧值。 您需要这样做:

switch newValue {
    case .changeColor(let newColor, let duration):
        UIView.animate(withDuration: duration) {
            self.backgroundColor = newColor
        }
    case .hideView(let duration):
        UIView.animate(withDuration: duration) {
            self.alpha = 0
            self.isHidden = true
        }
    }
如果您实现newValue之类的集合,则默认为

set{ 或者您可以执行以下操作:

set(abc){
  switch abc {

答案 2 :(得分:0)

我相信开关实际上是在调用吸气剂,因此始终将背景设置为红色。

测试用例:

var helpme: Int {
    get {
        return 1
    }
    set {
        switch helpme {
        default:
            print(helpme)
        }
    }
}

func testme() {
    helpme = 20
    print(helpme)
}

output:
1
1

    switch self.animate { //  calls the getter which returns red
    case .changeColor(let newColor, let duration):
        UIView.animate(withDuration: duration) {
            self.backgroundColor = newColor
        }
    case .hideView(let duration):
        UIView.animate(withDuration: duration) {
            self.alpha = 0
            self.isHidden = true
        }
    }

我认为对于您想做的事情来说,属性太有限了。

我建议为每个动画使用一个函数,并且可能具有属性状态animationType:AnimationType?如果您想知道视图的当前动画状态。尽管这将需要使用animationType属性创建一个新的UIView类,因为您不能在扩展中声明变量。

class AnimatingView: UIView {
  var animationType: AnimationType?
}


enum AnimationType {
  case changingColor
  case hidingView
}

func changeColor() {
  animationType = .changingColor
  // change color
}